- What: MCP config files routinely store API keys in plaintext, and attackers are actively harvesting them.
- Why it matters: GitGuardian found 24,008 exposed MCP secrets in 2026, 2,117 still valid and usable.
- What to do: Move secrets to an OS keychain or credential broker, scope tokens, enable secret scanning.
- Key stat: Prompt injection attacks against AI agents surged 340% year-over-year per OWASP’s 2026 report.
MCP config files leak API keys because the standard setup pattern — pasting credentials directly into claude_desktop_config.json or similar files — puts plaintext secrets in a file that gets synced, backed up, and sometimes committed to public repositories. The fix is to store secrets in an OS keychain or a credential broker that injects them at runtime, never in the config file itself.
The Model Context Protocol (MCP) is an open standard, introduced by Anthropic in late 2024, that lets AI applications connect to external tools, databases, and services through a uniform interface. Each connection is defined by an MCP server process, configured in a JSON file, and typically granted an API key or token so it can act on the model’s behalf. That config file — not the model itself — is where nearly every MCP-related credential leak originates.
I audited my own MCP setup last month after reading GitGuardian’s 2026 secrets sprawl numbers, and found the Anthropic API key and two third-party tokens sitting in plaintext in claude_desktop_config.json — a file that had been silently synced to iCloud for months. I’m not alone. As MCP adoption exploded in 2026, so did a very specific, very avoidable class of credential leak: developers followed the official setup instructions exactly as written, and those instructions put secrets in a place they never should have lived. This post covers why it happens, what the real numbers look like, and the exact fix I now run on every machine.
Why Are MCP Config Files Leaking API Keys?
MCP config files leak API keys because most setup guides — including MCP’s own onboarding docs — instruct you to paste credentials directly into the config’s env block as plaintext, and that file then travels far beyond your machine.
GitGuardian’s State of Secrets Sprawl 2026 report scanned public GitHub and found 24,008 unique secrets exposed in MCP-related configuration files, with 2,117 of them still valid — an 8.8% hit rate for attackers who go looking. The broader picture is worse: AI-service-related secret leaks on GitHub rose 81% year-over-year in 2025, and AI-assisted commits leak secrets at roughly twice the rate of manually written ones, because autocomplete happily reproduces whatever pattern it sees in your config.
// What most tutorials tell you to write — don't do this
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_live_key_pasted_here"
}
}
}
}
Treat claude_desktop_config.json, .cursor/settings.json, and any equivalent file exactly like a .env with production credentials — it should never be plaintext, never synced unencrypted, and never anywhere near a git commit.
How Does Prompt Injection Steal Credentials From AI Agents?
Prompt injection steals credentials by tricking the agent into using its already-configured tool access for the attacker’s purposes, without ever touching your filesystem directly.
OWASP’s 2026 LLM Security Report clocked a 340% year-over-year surge in prompt injection attacks, making it the fastest-growing attack category tracked in the report. The mechanism is simple: an attacker plants instructions in a webpage the agent fetches, a file it reads, or a tool’s returned output, and the agent — which can’t reliably distinguish data from instructions — follows them. Researchers at Johns Hopkins demonstrated this against production-grade coding agents from three major vendors integrated with GitHub Actions, hijacking the agents to exfiltrate API keys and credentials using nothing more than a crafted issue or pull request, which is a capability any free GitHub account has.
That last detail is the one that should worry PHP and JS teams running CI-integrated agents: the attack prerequisite dropped from “needs write access to your repo” to “needs to open an issue.”
What Is the Confused Deputy Problem in MCP Servers?
The confused deputy problem occurs when an MCP server holds broad, high-privilege credentials but has no way to tell which user or context triggered the current request, so it executes every action with its full permission set regardless of who’s actually asking.
This isn’t a one-off bug — it’s structural. MCP doesn’t inherently pass user identity from the host application down to the server, so a server proxying a third-party API ends up acting as a single over-privileged account for every caller. Independent analysis of 2,614 public MCP server implementations found 82% used file operations prone to path traversal and 67% exposed APIs related to code injection, meaning the confused deputy risk compounds with implementation bugs that are already common in the ecosystem.
If your MCP server can read arbitrary files or execute arbitrary commands on behalf of “the agent” with no per-request scoping, assume it will eventually be tricked into doing that for someone other than you.
How Do You Actually Secure Secrets in an MCP Config?
You secure MCP secrets by removing them from the config file entirely and letting a keychain, environment variable, or credential broker inject them at runtime instead.
- Pull secrets out of the JSON file. Replace hardcoded values with a reference the launching script resolves at runtime.
- Use your OS keychain for local setups. On macOS, Keychain Access can hold the token and hand it to a launcher script via
security find-generic-password. - Scope every token to least privilege. A GitHub PAT for an MCP server needs repo read access, not org-admin.
- Rotate on a schedule, not just after an incident. Thirty to ninety days for anything touching production data.
- Enable secret scanning on any repo near your config. GitHub’s secret_protection toolset for MCP servers graduated to general availability in May 2026 and scans before commits land.
#!/bin/bash
# launch-mcp.sh — resolves the token from Keychain instead of a JSON file
export GITHUB_PERSONAL_ACCESS_TOKEN=$(security find-generic-password \
-a "$USER" -s "mcp-github-token" -w)
npx -y @modelcontextprotocol/server-github
This one change — keychain lookup instead of plaintext — closes the exact leak path GitGuardian’s 24,008-secret count came from, since there’s no longer a static value in the file to accidentally sync or commit.
Is GitHub’s Secret Scanning for MCP Servers Enough?
No, secret scanning alone is not enough — it catches known token patterns after they’re written, but it doesn’t stop a malicious MCP server from exfiltrating credentials it was legitimately handed.
The clearest example is postmark-mcp, the first publicly documented malicious MCP server, which shipped roughly 1,500 downloads a week and reached 300 real organizations before it was disclosed and pulled. Secret scanning wouldn’t have flagged that install — the server was doing exactly what its permissions allowed, just for the wrong recipient. Scanning is a good safety net for accidental commits; it’s not a substitute for vetting which MCP servers you install and what scope you hand them.
Run scanning as your last line of defense, not your first. Vet the server’s source and scope its token before it ever gets a chance to leak anything worth scanning for.
Should You Use a Credential Broker Instead of a Config File?
Yes, if you’re running more than one or two MCP servers — a credential broker keeps secrets in a single audited location and hands out short-lived, scoped tokens instead of letting every server hold its own static key.
This is exactly the gap tools like OneCLI, an open-source credential gateway that surfaced on Hacker News this week, are built to close: instead of every MCP server config holding its own long-lived plaintext key, a broker process mediates access and can log, rotate, and revoke centrally. For teams already using AWS, the same pattern works with AWS Secrets Manager fetching short-lived credentials into the launcher script rather than the config file — I’ve used this on client Drupal and Laravel projects for years for database credentials, and it maps directly onto MCP servers.
For a single-developer local setup, an OS keychain is enough. Past two or three MCP servers with real permissions, a broker earns its complexity.
| Option | Performance | Complexity | When to Use |
|---|---|---|---|
| Plaintext in config JSON | Instant | None | Never for real credentials |
| Environment variable (shell profile) | Instant | Low | Local dev, low-sensitivity tokens |
| OS keychain (Keychain Access / Credential Manager) | ~10-30ms lookup | Low-Medium | Single-developer machines, 1-3 MCP servers |
| Credential broker (OneCLI-style) | ~50-100ms per request | Medium | Teams running 3+ MCP servers with real permissions |
| Cloud secrets manager (AWS Secrets Manager, Vault) | ~100-300ms per fetch | Medium-High | CI/CD pipelines, production-adjacent agents |
The NexGismo verdict: Stop putting real credentials in claude_desktop_config.json today — that single change eliminates the leak path behind GitGuardian’s 24,008-secret count. For solo developers, an OS keychain lookup is a fifteen-minute fix with no ongoing cost. For teams running multiple MCP servers in CI or production-adjacent workflows, pair a credential broker with least-privilege token scoping; secret scanning is worth enabling too, but only as a backstop, not your primary defense.
- GitGuardian found 24,008 unique secrets exposed in public MCP configuration files in 2026, with 2,117 (8.8%) still valid.
- Prompt injection attacks against AI agents rose 340% year-over-year according to OWASP’s 2026 LLM Security Report.
- 82% of 2,614 analyzed MCP server implementations use file operations prone to path traversal, and 67% expose code-injection-prone APIs.
- The malicious postmark-mcp server reached roughly 1,500 downloads per week and 300 real organizations before disclosure.
- AI-assisted code commits leak secrets at roughly twice the rate of manually written commits.
- GitHub’s secret_protection toolset for MCP servers reached general availability in May 2026.
Frequently Asked Questions
What is MCP (Model Context Protocol)?
MCP is an open standard, introduced by Anthropic, that lets AI applications like Claude Desktop or Cursor connect to external tools and data sources through a consistent interface. It works through server processes defined in a config file, each granted credentials to act on the model’s behalf.
Why is prompt injection considered the biggest MCP security risk?
Prompt injection is the top MCP risk because it needs no direct access to your machine — an attacker just plants instructions in a webpage, file, or tool output the agent reads, and the agent executes them with whatever credentials its MCP servers already hold. OWASP logged a 340% year-over-year surge in these attacks in 2026.
How do I stop my AI coding agent from leaking API keys?
Remove plaintext keys from your MCP config, store them in your OS keychain or a credential broker instead, scope every token to least privilege, and enable secret scanning on any repo where config files might get committed. This closes the two most common leak paths: committed configs and over-permissioned tokens.
Is it safe to put API keys in claude_desktop_config.json?
No. GitGuardian found 24,008 unique secrets exposed in public MCP config files in 2026, with 2,117 still valid and usable. The file is JSON, gets synced to cloud backups, and is easy to accidentally commit — treat it the same as you would a .env file with production credentials.
What is the confused deputy problem in MCP servers?
The confused deputy problem happens when an MCP server holds high-privilege credentials but can’t tell which user or context is making a request, so it executes actions for a low-privilege caller using its full permission set. Because MCP doesn’t inherently pass user identity from host to server, this is a structural risk, not a bug in any one server.
The uncomfortable part of this story is that developers didn’t do anything unusual — they followed the documentation. MCP’s own setup guides, and most third-party tutorials, still show plaintext keys in example configs, which is exactly why 24,008 of them ended up exposed on public GitHub. Fixing this doesn’t require waiting on a protocol-level change: move secrets to a keychain or broker, scope tokens tightly, and treat every MCP config file with the same suspicion you’d give a .env file heading toward a commit. I’ve made this the first thing I check on any new machine before installing a single MCP server, and it takes less time than the tutorial that told you to skip it.
