If you have set up Claude Desktop, Cursor, or any MCP server in the last six months, you followed a guide that told you to do something like this:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Your actual token. In a JSON config file. On your filesystem.
Every MCP setup guide tells you to do this. The official documentation shows this pattern. Tutorials, YouTube videos, blog posts — all of them. It is the de facto standard for MCP configuration.
It is also a serious security mistake. And almost nobody is talking about it.
What You Just Did
When you put your API key in claude_desktop_config.json or ~/.cursor/mcp.json, you:
Stored a plaintext credential in a file any process on your machine can read.
Your AI assistant reads that config file to start the MCP server. Which means the contents of that config file — including your actual token values — are now in your AI assistant's context. Every session. Every conversation.
Here is what that means in practice.
Your AI coding assistant can be asked to read it:
"Hey, can you show me my MCP config file so I can debug something?"
Most assistants will happily show you the file. Including the token values.
Prompt injection can instruct it to exfiltrate the values:
A malicious website, a compromised npm package, a carefully crafted document your agent processes — any of these can embed instructions that cause your agent to read and transmit the config file contents.
Every tool with filesystem access can read it:
Other AI agents, automation scripts, browser extensions with broad permissions. The file sits at a known path, readable by any process running as your user.
It gets committed to version control:
Not your personal config — but developer teams sharing MCP configurations through repositories have committed tokens more times than anyone wants to admit.
This is not theoretical. Check Point Research documented API key exfiltration through AI coding tools in CVE-2026-21852. The attack surface is exactly this — credentials in files that AI agents can read.
Why the Guides Tell You to Do This
The guides are not wrong about how MCP works. Environment variables in the config file is how MCP servers receive credentials. That is the protocol.
The guides are wrong about stopping there.
They show you how to make it work. They do not show you how to make it secure. Those are different problems and most setup guides only solve the first one.
The result is that hundreds of thousands of developers have set up MCP servers with plaintext credentials in config files because that is what every legitimate guide told them to do.
The Better Pattern
MCP servers need credentials at runtime. They do not need those credentials to be stored in plaintext in a config file at rest.
There are two ways to fix this.
Fix 1: Environment Variables from the OS (Better Than Config Files)
Instead of putting the value in the config file, reference an environment variable that lives in your shell profile:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Add to your ~/.zshrc or ~/.bashrc:
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx"
Better — the value is not in the MCP config file. Worse — it is still in a shell profile file that AI agents can read, and it is still in your shell environment which any child process can access.
This is an improvement. It is not a solution.
Fix 2: Zero-Knowledge MCP Integration (The Right Answer)
AgentSecrets runs as an MCP server that gives your AI assistant access to credentials without ever putting values in any file.
# Install
brew install The-17/tap/agentsecrets
# Store your credentials in the OS keychain — not a file
agentsecrets secrets set GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
# Connect to your AI tools
agentsecrets mcp install
That last command auto-configures both Claude Desktop and Cursor. Your config file now looks like this:
{
"mcpServers": {
"agentsecrets": {
"command": "agentsecrets",
"args": ["mcp", "serve"]
}
}
}
No token values. No credentials. Just the command to start the AgentSecrets MCP server.
When your AI assistant needs to call GitHub, it uses AgentSecrets:
Agent: "I need to call the GitHub API to check this repo"
AgentSecrets MCP: routes the call through the proxy
Proxy: resolves GITHUB_TOKEN from OS keychain, injects into request
Agent: receives the API response
The token never entered the agent's context. It is not in any config file. It is not in any environment variable the agent can read. It lives in the OS keychain — macOS Keychain, Windows Credential Manager, or Linux Secret Service — which requires system-level authentication to access.
What the OS Keychain Actually Means
When people hear "OS keychain" they sometimes think it means another file with a password on it. It is not.
The OS keychain is a system-protected credential store managed directly by the operating system. On macOS it is the same place Safari stores your passwords, the same place your WiFi credentials live. On Windows it is the Windows Credential Manager. On Linux it is the Secret Service API backed by GNOME Keyring or KWallet.
The properties that matter for security:
Access requires authentication. Reading from the keychain can require biometric authentication (Touch ID on macOS) or system password. Not your app password — the OS itself gatekeeps access.
Isolated from other processes. An application cannot read keychain entries that do not belong to it without explicit user authorization. Another process cannot read AgentSecrets credentials without the user granting access at the OS level.
Not a file. There is no file path to read, no file to accidentally commit to git, no file for a malicious process to open.
Your AI assistant cannot read from the OS keychain. This is the guarantee that matters.
The Config File You Should Actually Have
After running agentsecrets mcp install, your Claude Desktop config looks like this:
{
"mcpServers": {
"agentsecrets": {
"command": "agentsecrets",
"args": ["mcp", "serve"]
}
}
}
You can commit this to version control. You can share it with teammates. You can post it publicly. There are no credentials in it.
Your actual credentials are in the OS keychain, synced to AgentSecrets' zero-knowledge cloud (encrypted client-side before upload — the server stores ciphertext it cannot decrypt), accessible to your AI assistant only through the proxy that injects at the transport layer without exposing values.
For Teams
The config file problem gets worse on teams. Sharing MCP configurations across a development team means sharing the methods by which credentials are stored — and too often that means sharing the credentials themselves.
With AgentSecrets workspaces:
# Team lead sets up workspace
agentsecrets workspace create "Acme Engineering"
agentsecrets secrets set GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
# New developer joins
agentsecrets login
agentsecrets workspace switch "Acme Engineering"
agentsecrets secrets pull
agentsecrets mcp install
The new developer's MCP setup is complete. No credentials were shared in Slack. No .env file was sent via email. No one typed a token into a chat window. The credentials moved from workspace to local OS keychain encrypted end to end.
The Pattern to Follow From Now On
When you set up any MCP server that needs credentials:
- Do not put token values in the config file
- Do not put token values in environment variables in the config
- Store the credential with
agentsecrets secrets set - Run
agentsecrets mcp install - Reference key names only — never values
The config file is for configuration. The OS keychain is for credentials. These are different things and they should live in different places.
Every MCP setup guide that shows you a JSON file with an actual token value in it is showing you how to make it work, not how to make it secure. Now you know the difference.
GitHub: https://github.com/The-17/agentsecrets
ClawHub: https://clawhub.ai/SteppaCodes/agentsecrets
Top comments (0)