Skip to main content
SEP 2026 Latest guide updates. Latest: Skill Governance Skill Lifecycle Skills vs Harnesses Changelog →
T15 Advanced Technical

MCP Secrets Management

Managing MCP server credentials without exposing them

The core problem

MCP servers need API keys and credentials to function. Storing them in plaintext in settings.json or .mcp.json creates a real risk: accidental commit to Git, exposure in logs, or lateral movement after a compromise. The absolute rule is that secrets must never appear in versioned files.

Three approaches depending on context

ApproachSecurityComplexityIdeal for
OS KeychainHighMediumSolo devs, macOS/Linux
.env + .gitignoreMediumLowSmall teams, prototyping
Secret VaultsVery highHighEnterprise, SOC 2, HIPAA

The secret is encrypted at rest by the OS and accessible only to authorized processes. The MCP configuration exposes only a retrieval command, never the value.

Terminal window
# macOS: store a GitHub token
security add-generic-password \
-a "claude-mcp" -s "github-token" \
-w "ghp_your_token_here"
{
"mcpServers": {
"github": {
"command": "bash",
"args": ["-c", "GITHUB_TOKEN=$(security find-generic-password -s 'github-token' -w) npx @github/mcp-server"]
}
}
}

Linux: use secret-tool (libsecret, GNOME Keyring or KWallet) with the same wrapper script logic.

Approach 2: .env + .gitignore

Simple and sufficient for solo use or a small team with good discipline.

Terminal window
# Create the secrets file
cat > ~/.claude/.env << EOF
GITHUB_TOKEN=ghp_your_token
OPENAI_KEY=sk-your_key
EOF
chmod 600 ~/.claude/.env # Restrictive permissions
echo ".env" >> ~/.claude/.gitignore

In the MCP config, reference with "${GITHUB_TOKEN}" in the env field. Claude Code resolves environment variables at server startup.

Template for teams: commit mcp-config.template.json with placeholders, generate the real file via envsubst. Never commit the generated file.

Approach 3: Secret Vaults (enterprise)

HashiCorp Vault, AWS Secrets Manager, or 1Password CLI enable automated rotation, centralized auditing, and granular access control. The principle remains identical: a wrapper script retrieves the secret at runtime and exports it as an environment variable before launching the MCP server.

Terminal window
# HashiCorp Vault
export GITHUB_TOKEN=$(vault kv get -field=token secret/claude/github)
npx @github/mcp-server

What to never do

Hardcode a token directly in the command or args value of a versioned MCP server. Even in a private repo, secrets in plaintext in Git remain in the history even after deletion and can be exposed by a git log or unauthorized access.

A pre-commit hook that scans for token patterns (ghp_, sk-, Bearer ) before each commit is a simple additional protection to put in place.

CLAUDE_CODE_SUBPROCESS_ENV_SCRUB (v2.1.78+): environment variable that forces Claude Code to strip sensitive variables (*_KEY, *_TOKEN, *_SECRET) before passing them to subprocesses and MCP servers. Enable in production to minimize exposure surface.

Enter your email to read the full card and get the complete PDF bundle.

All content is free and open-source. We just ask for your email.

PDF: