New PolicyLayer is now the system of record for AI agent authority. Never answer your agent twice
Home / Integrations / Claude Code

Claude Code MCP config: the complete reference

Where Claude Code’s MCP config lives, how the three scopes resolve, the full claude mcp add syntax, and how to fix the common failures — plus how to put a policy gate in front of every tool call.

QUICK ANSWERQuick answer: project-shared servers go in .mcp.json at the project root; personal servers live in ~/.claude.json. Top-level key is mcpServers.

Where Claude Code keeps its MCP config.

ScopePathNotes
Local (default) ~/.claude.json Private to you, loads in the current project only. Nested under projects → <path> → mcpServers.
Project .mcp.json In the project root. Commit it to share servers with the team. Requires one-time approval per user.
User ~/.claude.json Private to you, loads in every project.

Precedence when names collide: local > project > user — entries are not merged; the highest-precedence server wins. Older docs called local “project” and user “global”.

The config format, key by key.

All scopes use the same shape: a top-level mcpServers object, one entry per server. Local servers declare a command; remote servers declare a type and url.

KeyWhat it does
type stdio, http (alias streamable-http), sse (deprecated), or ws.
command Executable for a stdio server. Use a full path if it isn’t on PATH.
args Array of arguments passed to the command.
env Environment variables for the server process.
url Endpoint for an HTTP, SSE or WebSocket server.
headers HTTP headers sent with every request — where static auth tokens go.
oauth OAuth client config: clientId, clientSecret, callbackPort, scopes.
timeout Per-tool-call limit in milliseconds.
.mcp.json
{
  "mcpServers": {
    "airtable": {
      "command": "npx",
      "args": ["-y", "airtable-mcp-server"],
      "env": {
        "AIRTABLE_API_KEY": "${AIRTABLE_API_KEY}"
      }
    }
  }
}

REMOTE SERVER (HTTP):

.mcp.json
{
  "mcpServers": {
    "stripe": {
      "type": "http",
      "url": "https://mcp.stripe.com",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

.mcp.json supports env-var expansion — ${VAR} and ${VAR:-default} — in command, args, env, url and headers. A missing variable with no default fails the whole config parse.

What Claude Code speaks.

TransportStatusHow to declare it
stdio Supported Declare command + args, or --transport stdio on the CLI. Local child process.
Streamable HTTP Supported "type": "http" or --transport http. Recommended for remote servers; supports OAuth and auto-reconnects.
SSE Deprecated "type": "sse" still works but use HTTP instead.
WebSocket Supported "type": "ws" — JSON config only, header auth, no OAuth.

Adding a server, three ways.

01 CLI — claude mcp add

Flags (--transport, --env, --scope, --header) come before the server name; -- separates the name from a stdio command.

TERMINAL
# Remote HTTP server, available in all your projects
claude mcp add --transport http --scope user stripe https://mcp.stripe.com \
  --header "Authorization: Bearer <token>"

# Local stdio server with an env var
claude mcp add --transport stdio --env AIRTABLE_API_KEY=<key> airtable \
  -- npx -y airtable-mcp-server
02 Edit the config file

Add an entry under mcpServers in .mcp.json (shared with the team) or ~/.claude.json (personal). claude mcp add-json <name> '<json>' does the same from the command line.

03 Import from Claude Desktop

claude mcp add-from-claude-desktop imports servers interactively (macOS and WSL). Manage everything with claude mcp list, claude mcp get <name> and claude mcp remove <name>.

Check it's actually connected.

  1. Run /mcp inside Claude Code — it shows each server’s connection status and tool count, and flags servers exposing zero tools. It is also where OAuth logins are triggered.
  2. Run claude mcp list from the shell — project-scoped servers awaiting approval show ⏸ Pending approval.
  3. Ask Claude to call one of the server’s tools; the first call confirms the round trip end to end.

When it doesn't work.

Server never connects — command not found

The command must be a full path if it isn’t on PATH. which npx gives you the absolute path to use.

Project .mcp.json servers not loading

Servers from a committed .mcp.json need one-time approval per user. If you rejected the prompt, reset with claude mcp reset-project-choices.

Config parse failure after adding a server

A ${VAR} reference with no value and no default fails the parse. Set the variable or use ${VAR:-default}.

Slow server times out on startup

Raise the startup limit with the MCP_TIMEOUT env var (e.g. MCP_TIMEOUT=10000 claude). The per-server timeout field governs individual tool calls.

Authentication keeps failing on a remote server

If a static headers.Authorization token is rejected, Claude Code reports failure without falling back to OAuth — fix or remove the token. “Does not support dynamic client registration” means you need to supply --client-id and --client-secret.

Put a policy gate in front of it.

A standard MCP server in your Claude Code config. Every tool call hits the upstream directly, with no policy gate.

.mcp.json
{
  "mcpServers": {
    "stripe": {
      "command": "npx",
      "args": ["-y", "@stripe/mcp-server"],
      "env": {
        "STRIPE_SECRET_KEY": "sk_live_..."
      }
    }
  }
}

Register the server in PolicyLayer, mint a grant, point Claude Code at the proxy URL. PolicyLayer evaluates every call against the grant’s attached policy before it reaches Stripe — and the live key leaves your config.

.mcp.json
{
  "mcpServers": {
    "stripe": {
      "type": "http",
      "url": "https://proxy.policylayer.com/mcp/<server-uuid>/",
      "headers": {
        "Authorization": "Bearer <grant-token>"
      }
    }
  }
}

CLI ALTERNATIVE:

TERMINAL
claude mcp add --transport http stripe \
  https://proxy.policylayer.com/mcp/<server-uuid>/ \
  --header "Authorization: Bearer <grant-token>"

The <server-uuid> appears on each server's detail page. The <grant-token> shows once at mint time. See the Quick start for the full setup walk-through — and if you operate under SOC 2, HIPAA, GDPR or similar, the compliance hub maps how gateway-mediated MCP traffic evidences each framework.

What the gateway adds.

Rate limits
Cap tool calls per minute, hour, or day, per grant or shared across the team.
Access controls
Allow, deny, or conditionally gate any tool against the call's arguments.
Spend caps
Increment a counter by the call's amount; deny when the daily total exceeds your budget.
Audit logs
Every call records the grant, tool, argument keys, and the rule that decided.

A policy in practice.

Allow list_customers. Allow create_charge, but deny any charge over 50000 cents. Deny everything else.

policy.json
{
  "version": "1",
  "default": "deny",
  "tools": {
    "list_customers": {},
    "create_charge": {
      "deny_if": [
        {
          "conditions": [
            { "path": "args.amount", "op": "gt", "value": 50000 }
          ]
        }
      ]
    }
  }
}

See Writing policies for the policy format, operators, and quota shapes.

Claude Code MCP questions.

Where is the Claude Code MCP config file?+

Team-shared servers go in .mcp.json at the project root. Personal servers (local and user scope) live in ~/.claude.json. The claude mcp add command writes to these files for you — use --scope to pick which.

What is the difference between local, project and user scope?+

Local (the default) is private to you and loads in the current project only. Project scope lives in .mcp.json and is shared with everyone who clones the repo. User scope is private to you but loads in every project. On a name collision, local beats project beats user.

How do I add a remote MCP server to Claude Code?+

Run claude mcp add --transport http <name> <url>, with --header for token auth. Streamable HTTP is the recommended remote transport; SSE is deprecated. OAuth-protected servers complete login via the /mcp command.

How do I check whether an MCP server is connected?+

Type /mcp inside Claude Code. It lists every configured server with its connection status and tool count, and lets you authenticate OAuth servers. From the shell, claude mcp list shows the same inventory.

Can I restrict which MCP tools Claude Code can call?+

Claude Code prompts for approval, and enterprise deployments can pin allowed servers via managed settings. For deterministic per-tool rules — argument conditions, rate limits, spend caps, audit logs — route the server through a policy gateway like PolicyLayer.

Take your agents live. Without losing control.

Route your MCP traffic through PolicyLayer. Every tool call is checked against your policy before it runs: allow, deny, or require approval. Per-identity grants. Full audit log. Live in minutes.

Instant setup, no code required.

46,500+ MCP servers and 515,000+ tools scanned and risk-classified.

// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.