[FEATURE] OS Keychain/Credential Manager Support for MCP Configuration
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Add support for MCP server configuration to reference credentials stored in OS keychain/credential managers (macOS Keychain, Windows Credential Manager, Linux pass) rather than requiring environment variables or plaintext configuration.
Currently, Claude Code's MCP configuration supports environment variables for sensitive values like API keys:
{
"mcp_servers": {
"my_service": {
"command": "my-mcp-server",
"args": [],
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}
This approach has several issues:
Security concerns:
- Environment variables are visible in process listings (
ps auxon Unix systems shows all env vars) .envfiles stored in plaintext on disk- Shell history may contain export commands with credentials
- Difficult to rotate keys without manual intervention
- No encryption at rest
Team development problems:
- Config files must be git-ignored if they contain secrets
- Developers either manage secrets separately (friction) or store them in plaintext profiles
- No standard practice for credential sharing across teams
Operational challenges:
- No audit trail of who accessed credentials
- Credentials scattered across system environment, shell configs, and dotfiles
- No easy way to revoke or rotate credentials across machines
Proposed Solution
Support credential lookup syntax in MCP configuration to reference OS credential stores. When Claude Code reads the configuration, it would resolve these special URIs to fetch actual credentials from the OS's encrypted credential store.
Syntax by platform:
{
"mcp_servers": {
"database": {
"command": "db-mcp-server",
"env": {
"API_KEY": "keychain://service_name"
}
},
"analytics": {
"command": "analytics-mcp",
"env": {
"TOKEN": "credential://service_name"
}
},
"reporting": {
"command": "reporting-mcp",
"env": {
"SECRET": "pass://path/to/secret"
}
}
}
}
Supported credential stores:
| Platform | Syntax | Tool/API | Lookup Command |
|----------|--------|----------|---|
| macOS | keychain://service_name | Keychain | security find-generic-password -w -s "service_name" |
| Windows | credential://target_name | Credential Manager | Win32 CredRead API or cmdkey /query |
| Linux | pass://path/to/secret | pass utility | pass show path/to/secret |
Fallback and error handling:
- If credential not found, fall back to environment variable with a warning
- Support optional fallback syntax:
"keychain://key_name|${ENV_VAR_FALLBACK}" - Log warning (never the credential value):
"Credential lookup failed for API_KEY, falling back to environment variable" - Graceful degradation if OS credential tool unavailable
Acceptance Criteria
- [ ] macOS Keychain lookup implemented and tested
- [ ] Windows Credential Manager lookup implemented and tested
- [ ] Linux
passutility lookup implemented and tested - [ ] Fallback to environment variables implemented
- [ ] Credentials never logged in plaintext (only URIs and status)
- [ ] Documentation with setup examples for each platform
- [ ] Configuration validation with helpful error messages
- [ ] Graceful handling when credential not found
- [ ] Support for optional fallback syntax (
keychain://key|${ENV_VAR}) - [ ] No breaking changes to existing MCP configurations
Alternative Solutions
1. Client-side secret management tools (1Password CLI, AWS Vault, etc.)
Users could integrate third-party secret management tools:
{
"env": {
"API_KEY": "$(op read op://vault/secret/field)"
}
}
Drawbacks:
- Requires users to install and configure separate tools
- Not standardized across team members
- Higher barrier to entry
- No built-in support needed, users already do this
Why proposed solution is better:
- Uses OS-native credential stores (already available, no extra tools)
- Zero friction for users (Keychain already on macOS, Credential Manager on Windows)
- Standardized approach across all platforms
- Better UX (no shell command substitution syntax)
2. Store credentials in a remote secret manager (Vault, AWS Secrets Manager, etc.)
MCP configuration could support remote credential fetching:
{
"env": {
"API_KEY": "vault://secret/mcp/api_key"
}
}
Drawbacks:
- Requires network access on startup
- Adds complexity for local development
- Needs authentication to the secret manager itself
- Overkill for personal development credentials
Why proposed solution is better:
- Local, no network required
- Simple and lightweight
- Works offline
- Can be upgraded to remote secrets later
3. Standalone credential storage format (cqlai-specific or generic)
Each MCP server could implement its own credential storage/lookup:
Drawbacks:
- Duplicated effort across MCP projects
- No standardization
- Users must learn each MCP's credential management approach
- Not a Claude Code feature (out of scope for MCP integration)
Why proposed solution is better:
- Single standard approach in Claude Code
- Works for all MCP servers
- Consistent UX across projects
Priority
Medium - Would be very helpful
Feature Category
MCP server integration
Use Case Example
Scenario: Team Development with Shared Configuration
A development team uses multiple MCP servers for databases, analytics, and reporting. They want to:
- Share MCP configuration across team members via git
- Each developer uses their own credentials
- Credentials stored securely, encrypted at rest
- Works across macOS, Windows, and Linux
Traditional approach (problematic):
{
"mcp_servers": {
"database": {
"command": "db-mcp",
"env": {
"DB_API_KEY": "${DB_API_KEY}"
}
}
}
}
- Config must be git-ignored if DB_API_KEY is in it
- Each developer manually sets environment variables
- No standard way to share the setup instructions
- Keys visible in shell history
With proposed feature (improved):
{
"mcp_servers": {
"database": {
"command": "db-mcp",
"env": {
"DB_API_KEY": "keychain://team_db_api_key"
}
},
"analytics": {
"command": "analytics-mcp",
"env": {
"ANALYTICS_TOKEN": "credential://team_analytics_token"
}
}
}
}
Setup instructions for each developer:
macOS:
security add-generic-password -s "team_db_api_key" -a "$(whoami)" -w "your_api_key_here"
security add-generic-password -s "team_analytics_token" -a "$(whoami)" -w "your_token_here"
Windows:
cmdkey /generic:team_db_api_key /user:YourUsername /pass:your_api_key_here
cmdkey /generic:team_analytics_token /user:YourUsername /pass:your_token_here
Linux:
pass insert team/db_api_key
pass insert team/analytics_token
Benefits:
- Config can be committed to git (no secrets in it)
- Each developer stores their own credentials in OS keychain
- Credentials encrypted by OS
- Clear setup instructions (one-time per machine)
- No manual environment variable management
Additional Context
Security Properties
At rest: Credentials stored encrypted by OS keychain/credential manager. Encryption key typically protected by:
- Keychain password (macOS)
- User account login (Windows Credential Manager)
- User's GPG key (Linux pass)
In transit: Credentials only exist in:
- OS credential store (encrypted)
- Claude Code process memory (duration: startup only)
- MCP server process memory (standard operation)
Visibility: Credentials are:
- ✅ Not in environment variables (invisible to
ps, shell inspection) - ✅ Not in plaintext config files
- ✅ Not in shell history
- ✅ Never logged by Claude Code (only lookup paths)
Implementation Notes
- Minimal performance impact: credential lookup happens once at Claude Code startup, before MCP server spawns
- Platform detection already available in Node.js/Electron
- Optional implementation: if credential tool unavailable on a platform, graceful fallback to env var
- Security: Never log actual credential values, only log lookup URIs and success/failure
Enterprise Considerations
This feature supports:
- Organization credential management policies
- IT-managed credential stores (with proper OS integration)
- Audit trails of credential access (OS-provided)
- Credential rotation without config changes
Related Discussions
This improves security posture for all MCP server configurations requiring sensitive values:
- API keys and authentication tokens
- Database credentials
- Cloud provider credentials
- Service account tokens
- OAuth refresh tokens
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗