Skip to main content
guidesSource-backedReview first Safety Privacy

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.

by kiannidev·added 2026-06-16·
HarnessClaude Code
Review first review before installing

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:

  1. Stdio env blocks and --env flags — values are injected into the server process environment.
  2. HTTP headers and Bearer tokens — often expanded from ${VAR} in .mcp.json.
  3. 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

  1. Inventory servers and tools. List each MCP server transport, each custom SDK tool, and every secret name (API keys, PATs, OAuth clients, DB URLs).

  2. Replace committed secrets with placeholders. Move raw values to env vars or secret stores; reference them with ${VAR} in .mcp.json headers and env blocks.

  3. Choose scope deliberately. Put shared structure in project .mcp.json; keep personal tokens in local scope or user settings.

  4. Pin OAuth scopes. Add oauth.scopes for remote servers that need only a subset of advertised permissions.

  5. Validate Agent SDK handlers. Ensure handlers read secrets from process env or secure stores—not from prompts—and return redacted errors via isError.

  6. Test in a sandbox profile. Connect servers with synthetic credentials before granting production access.

  7. Document rotation. Record which store holds each secret, who rotates it, and how to revoke OAuth via /mcp Clear authentication.

  8. 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 allowedTools to named mcp__server__tool entries 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, --env for stdio servers, OAuth token storage in keychain/credentials files, and oauth.scopes pinning.
  • 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 content results entering model context and recommend isError instead 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

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.

Listed on HeyClaude
[![Listed on HeyClaude](https://heyclau.de/badge/guides/secret-handling-for-mcp-servers-and-agent-tools.svg)](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.

FieldSecret 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 riskReview firstReview firstReview firstReview first
Notes Safety Privacy Safety Privacy Safety Privacy Safety Privacy
Categoryguidesguidesguidesguides
Sourcesource-backedsource-backedsource-backedsource-backed
AuthorkiannidevkiannidevkiannidevYB0y
Added2026-06-162026-06-162026-06-142026-06-10
Platforms
Claude Code
Claude Code
Claude Code
Claude Code
Source repo
Safety notesStdio 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 notesMCP 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
  • 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.
  • Remote HTTP MCP server requiring OAuth per server documentation.
  • Developer portal access to register OAuth apps when DCR is unsupported.
  • Team policy for scope pins and credential storage.
  • The remote MCP server URL, registry listing or package source, documentation, and declared tool list.
  • The OAuth client configuration, redirect URIs, requested scopes, token storage behavior, and identity provider policy.
  • A test Claude Code profile where the remote server can be connected with non-production credentials.
  • A named approver who can block the server, revoke tokens, and publish managed MCP policy if the review fails.
  • A draft `.mcp.json`, `~/.claude.json` entry, plugin-provided MCP server, claude.ai connector plan, or managed-mcp.json deployment to review.
  • The server documentation, package or repository source, expected transport, command or URL, environment variables, headers, OAuth behavior, and tool list.
  • A test machine or disposable Claude Code profile where the configuration can be loaded with non-production data.
  • A named owner who can approve the rollout, publish the final configuration, and revoke credentials or block servers if the rollout fails.
Install
Config
Citations
ClaimUnclaimedUnclaimedUnclaimedUnclaimed

Signals

Loading live community signals…

More like this, weekly

A short, calm digest of reviewed Claude resources. Unsubscribe any time.