Secret Handling For MCP Servers And Agent Tools
A practical guide for handling secrets when connecting MCP servers and authoring Agent SDK tools in Claude Code: env expansion in .mcp.json, OAuth scope pins, keychain storage, local scope, and redaction before tool arguments reach the model.
Open the source and read safety notes before installing.
Safety notes
- Stdio MCP servers inherit environment variables you pass via --env or .mcp.json env blocks; treat that as handing the server your credentials.
- HTTP MCP headers and OAuth tokens authenticate outbound calls; a compromised server or overly broad scope can exfiltrate data through tool results.
- Agent SDK tool descriptions, inputs, and outputs enter model context each turn—never embed live secrets in schemas or sample responses.
- Project-scoped .mcp.json is designed for version control; use ${VAR} expansion and local scope for machine-specific secrets instead of committing raw keys.
Privacy notes
- MCP tool arguments, resource contents, and error messages can contain API keys, JWTs, customer IDs, and internal URLs that flow into session transcripts.
- OAuth access tokens for remote MCP servers are stored in the macOS Keychain or a credentials file; revoke with Clear authentication in /mcp when offboarding.
- Agent SDK handlers that call external APIs may log request metadata; redact at the handler boundary before traces or support exports leave your environment.
- Shared .mcp.json templates should name required variables (for example API_KEY) without example values that look like real credentials.
Prerequisites
- Inventory of MCP servers (stdio, HTTP, or plugin) and any Agent SDK custom tools in your project.
- Access to .mcp.json, user settings, and environment variables on developer machines.
- Team policy for secret stores, rotation, and what may appear in version control.
- Ability to test MCP connections in a non-production profile before granting production credentials.
Schema details
- Install type
- copy
- Reading time
- 9 min
- Difficulty score
- 62
- Troubleshooting
- Yes
- Breaking changes
- No
Full copyable content
Before connecting MCP servers or shipping Agent SDK tools, map every credential path, use env expansion instead of committed secrets, pin OAuth scopes, store tokens in the system keychain, and redact values before they enter tool schemas or model context.About this resource
TL;DR
MCP servers and Agent SDK tools are secret touchpoints: credentials arrive through environment variables, HTTP headers, OAuth flows, and handler code. Keep committed configs free of raw secrets, pin OAuth scopes, prefer local scope for personal tokens, and assume tool arguments and results will reach the model unless you redact them first.
Prerequisites & Requirements
- {"task": "Credential inventory", "description": "Every MCP server and custom tool lists which secrets it reads, stores, or forwards"}
- {"task": "Config review", "description": ".mcp.json, plugin MCP entries, and SDK mcpServers blocks are scanned for hardcoded tokens"}
- {"task": "Scope policy", "description": "OAuth scopes and API tokens are narrowed to the minimum tools each workflow needs"}
- {"task": "Rotation path", "description": "Owners know how to revoke OAuth tokens, rotate env vars, and remove servers"}
- {"task": "Redaction rules", "description": "Prompts and tool outputs forbid pasting live secrets into issues, PRs, or logs"}
Core Concepts Explained
Three secret paths in MCP configs
Claude Code MCP documentation describes credentials flowing through:
- Stdio
envblocks and--envflags — values are injected into the server process environment. - HTTP
headersand Bearer tokens — often expanded from${VAR}in.mcp.json. - OAuth tokens — obtained via
/mcp, stored in the system keychain (macOS) or a credentials file, and refreshed automatically.
Each path needs different rotation and sharing rules.
Env expansion keeps secrets out of git
.mcp.json supports ${VAR} and ${VAR:-default} in command, args, env,
url, and headers. Teams can commit structure while developers export secrets
locally. If a required variable has no default and is unset, Claude Code fails to
parse the config—an intentional fail-closed behavior.
Local scope isolates personal credentials
Local-scoped servers live in ~/.claude.json under the project path and do not
sync to teammates. Use local scope for experimental servers or credentials that
must not enter version control, while project scope carries shared non-secret
structure.
OAuth scopes are a supported least-privilege pin
MCP documentation describes oauth.scopes as a space-separated string that pins
requested scopes when the authorization server advertises more than you want to
grant. Widen scopes only when a tool returns insufficient_scope.
Agent SDK tools multiply context exposure
Custom Agent SDK tools document that descriptions, validated arguments, and
handler content arrays are visible to the model each turn. Secrets placed in
schemas, descriptions, or sample tool results become session data—not just env
vars on disk.
Step-by-Step Implementation Guide
Inventory servers and tools. List each MCP server transport, each custom SDK tool, and every secret name (API keys, PATs, OAuth clients, DB URLs).
Replace committed secrets with placeholders. Move raw values to env vars or secret stores; reference them with
${VAR}in.mcp.jsonheaders andenvblocks.Choose scope deliberately. Put shared structure in project
.mcp.json; keep personal tokens in local scope or user settings.Pin OAuth scopes. Add
oauth.scopesfor remote servers that need only a subset of advertised permissions.Validate Agent SDK handlers. Ensure handlers read secrets from process env or secure stores—not from prompts—and return redacted errors via
isError.Test in a sandbox profile. Connect servers with synthetic credentials before granting production access.
Document rotation. Record which store holds each secret, who rotates it, and how to revoke OAuth via
/mcpClear authentication.Audit transcripts and exports. Scan session logs and MCP tool output for accidental secret paste before sharing externally.
Configuration Patterns
HTTP header from environment (committed template)
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}
Export API_KEY locally; never commit the value.
Stdio server with scoped env
claude mcp add --env AIRTABLE_API_KEY --transport stdio airtable -- \
npx -y airtable-mcp-server
Place --env before the server name per CLI rules; pass secrets only from your shell or secret store.
OAuth scope pin
{
"mcpServers": {
"slack": {
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": {
"scopes": "channels:read chat:write search:read"
}
}
}
}
Agent SDK Tool Rules
- Read credentials inside handlers from environment variables or your vault SDK.
- Keep tool descriptions operational, not credential-bearing.
- Return
{ isError: true, content: [...] }with redacted messages instead of echoing upstream API errors that include tokens. - Cap
allowedToolsto namedmcp__server__toolentries rather than wildcards when tools can reach sensitive systems.
Troubleshooting
Config fails to parse at startup
Confirm every ${VAR} without a default is exported in the shell that launches
Claude Code.
OAuth works locally but not for teammates
OAuth client secrets belong in keychain/credentials storage or CI secrets—not in
shared .mcp.json. Each developer completes /mcp auth or uses managed CI tokens.
Tool output triggers secret scanner alerts
Redact handler responses; avoid returning full upstream JSON that includes auth headers or session cookies.
Secrets appeared in a committed file
Rotate immediately, purge from git history per your policy, and switch the config
to ${VAR} expansion.
Source Verification Notes
Verified against Claude Code MCP and security documentation on 2026-06-16:
- MCP docs describe
${VAR}expansion in.mcp.json,--envfor stdio servers, OAuth token storage in keychain/credentials files, andoauth.scopespinning. - Security docs describe secure credential storage in macOS Keychain and file permissions on other platforms, plus trust verification for new MCP servers.
- Agent SDK custom-tools docs describe tool schemas and
contentresults entering model context and recommendisErrorinstead of throwing on failures.
Duplicate Check
This guide complements threat-model-mcp-servers-before-installation (pre-install
trust review), mcp-server-auth-least-privilege (building servers with auth
boundaries), and auditing-mcp-client-configuration-before-team-rollout (config
audits). Those entries do not provide a unified secret-handling workflow spanning
MCP connection configs and Agent SDK custom tools. Rules in
ai-assistant-secret-handling-rules target general coding assistants, not MCP/OAuth
operational patterns.
References
- Claude Code MCP - https://code.claude.com/docs/en/mcp
- Claude Code security - https://code.claude.com/docs/en/security
- Agent SDK custom tools - https://code.claude.com/docs/en/agent-sdk/custom-tools
Source citations
Add this badge to your README
Show that Secret Handling For MCP Servers And Agent Tools is listed on HeyClaude. Paste this Markdown into your README — it renders the badge and links back to this page.
[](https://heyclau.de/entry/guides/secret-handling-for-mcp-servers-and-agent-tools)How it compares
Secret Handling For MCP Servers And Agent Tools side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
| Field | Secret Handling For MCP Servers And Agent Tools A practical guide for handling secrets when connecting MCP servers and authoring Agent SDK tools in Claude Code: env expansion in .mcp.json, OAuth scope pins, keychain storage, local scope, and redaction before tool arguments reach the model. Open dossier | OAuth Patterns For MCP Server Authentication Implement OAuth patterns for MCP servers in Claude Code: Dynamic Client Registration, pre-configured client IDs, oauth.scopes pins, authServerMetadataUrl overrides, and keychain token storage from official MCP documentation. Open dossier | Remote MCP Server Security Review Checklist Checklist for reviewing remote MCP servers before team rollout: OAuth scopes, transport security, tool surface, registry provenance, and rollback. Open dossier | Auditing MCP Client Configuration Before Team Rollout Source-backed checklist for reviewing Claude Code MCP client configuration before a team rollout, covering scopes, transports, commands, secrets, allowlists, denylists, approvals, and rollback. Open dossier |
|---|---|---|---|---|
| Trust | ||||
| Install risk | Review first | Review first | Review first | Review first |
| Notes | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ |
| Category | guides | guides | guides | guides |
| Source | source-backed | source-backed | source-backed | source-backed |
| Author | kiannidev | kiannidev | kiannidev | YB0y |
| Added | 2026-06-16 | 2026-06-16 | 2026-06-14 | 2026-06-10 |
| Platforms | Claude Code | Claude Code | Claude Code | Claude Code |
| Source repo | — | — | — | — |
| Safety notes | ✓Stdio MCP servers inherit environment variables you pass via --env or .mcp.json env blocks; treat that as handing the server your credentials. HTTP MCP headers and OAuth tokens authenticate outbound calls; a compromised server or overly broad scope can exfiltrate data through tool results. Agent SDK tool descriptions, inputs, and outputs enter model context each turn—never embed live secrets in schemas or sample responses. Project-scoped .mcp.json is designed for version control; use ${VAR} expansion and local scope for machine-specific secrets instead of committing raw keys. | ✓Pin oauth.scopes to least privilege; widen only when tools return insufficient_scope. Client secrets belong in keychain/credentials storage—not committed .mcp.json. Static Authorization headers bypass OAuth discovery—verify tokens separately. | ✓Remote MCP servers expose model-callable tools over the network; treat write tools, shell proxies, and broad API scopes as production-risk actions until explicitly approved. Verify transport uses HTTPS with valid certificates and that OAuth tokens are scoped to the minimum tenant, project, or account needed for the workflow. Do not approve registry entries or remote URLs that cannot be tied to an identifiable maintainer, version history, and update channel. | ✓Local stdio MCP servers execute commands with the user's privileges, so review the exact command, arguments, package runner, file paths, and network behavior before sharing a config. Remote MCP servers can expose model-controlled tools for production systems; require least-privilege scopes, explicit approval for write tools, and a rollback path before team rollout. Do not rely on server names alone for enforcement because names are user-assigned labels; use command or URL allowlist entries when policy must control what actually runs. |
| Privacy notes | ✓MCP tool arguments, resource contents, and error messages can contain API keys, JWTs, customer IDs, and internal URLs that flow into session transcripts. OAuth access tokens for remote MCP servers are stored in the macOS Keychain or a credentials file; revoke with Clear authentication in /mcp when offboarding. Agent SDK handlers that call external APIs may log request metadata; redact at the handler boundary before traces or support exports leave your environment. Shared .mcp.json templates should name required variables (for example API_KEY) without example values that look like real credentials. | ✓OAuth tokens in keychain still grant server access—revoke via /mcp Clear authentication. Redirect URIs must match registered localhost callback ports exactly. | ✓Remote MCP traffic can include prompts, tool arguments, tool outputs, OAuth metadata, tenant IDs, and resource identifiers visible to the server operator. Review whether the remote server logs, caches, or forwards tool inputs to third-party observability or analytics systems. Revoke OAuth grants and delete local MCP configuration when uninstalling a remote server that accessed private repositories, tickets, or customer data. | ✓MCP client configuration can reveal server URLs, internal hostnames, command paths, environment-variable names, header names, OAuth client IDs, and tool availability. Do not store API keys, bearer tokens, client secrets, tenant IDs, or personal credentials in shared `.mcp.json`, managed-mcp.json, PR bodies, issue comments, logs, or screenshots. Tool arguments, tool results, resources, prompts, logs, traces, and OAuth metadata can expose private repositories, tickets, databases, user identities, and workspace data. |
| Prerequisites |
|
|
|
|
| Install | — | — | — | — |
| Config | — | — | — | — |
| Citations | ||||
| Claim | Unclaimed | Unclaimed | Unclaimed | Unclaimed |
Signals
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.