Tools
Tools: Why Every MCP Setup Guide Is Teaching You to Store API Keys Wrong
2026-03-03
0 views
admin
What You Just Did ## Why the Guides Tell You to Do This ## The Better Pattern ## Fix 1: Environment Variables from the OS (Better Than Config Files) ## Fix 2: Zero-Knowledge MCP Integration (The Right Answer) ## What the OS Keychain Actually Means ## The Config File You Should Actually Have ## For Teams ## The Pattern to Follow From Now On 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: 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. 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: 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. 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. 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. Instead of putting the value in the config file, reference an environment variable that lives in your shell profile: Add to your ~/.zshrc or ~/.bashrc: 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. AgentSecrets runs as an MCP server that gives your AI assistant access to credentials without ever putting values in any file. That last command auto-configures both Claude Desktop and Cursor. Your config file now looks like this: 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: 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. 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. After running agentsecrets mcp install, your Claude Desktop config looks like this: 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. 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: 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. When you set up any MCP server that needs credentials: 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 Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx" } } }
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx" } } }
} CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx" } } }
} CODE_BLOCK:
"Hey, can you show me my MCP config file so I can debug something?" Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
"Hey, can you show me my MCP config file so I can debug something?" CODE_BLOCK:
"Hey, can you show me my MCP config file so I can debug something?" CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } } }
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } } }
} CODE_BLOCK:
{ "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } } }
} CODE_BLOCK:
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx" Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx" CODE_BLOCK:
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx" COMMAND_BLOCK:
# 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 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
# 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 COMMAND_BLOCK:
# 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 CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} CODE_BLOCK:
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 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
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 CODE_BLOCK:
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 CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} CODE_BLOCK:
{ "mcpServers": { "agentsecrets": { "command": "agentsecrets", "args": ["mcp", "serve"] } }
} COMMAND_BLOCK:
# 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 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
# 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 COMMAND_BLOCK:
# 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 - 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
how-totutorialguidedev.toailinuxserverbashshellswitchgitgithub