MCP Integration
Connect Claude Code to tools and resources through Model Context Protocol servers.
Key takeaways
- MCP is an open standard that lets Claude Code act as a client connecting to multiple servers that expose tools, resources, and prompts.
- Add servers with
claude mcp addover HTTP (recommended; SSE is deprecated) or stdio, placing all options before the server name and--before a stdio command. - Choose a scope deliberately:
local(default, private per project),project(shared via.mcp.jsonin version control), oruser(all your projects). - Classify each server's trust level before enabling it, since servers fetching external content carry prompt-injection risk; prefer read-only tools plus human approval for writes.
- Tool search (default on, via
ENABLE_TOOL_SEARCH) defers tool definitions to keep context low; MCP output is capped at 25,000 tokens (MAX_MCP_OUTPUT_TOKENS), and long calls should setCLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT.
The Model Context Protocol (MCP) is an open standard that connects Claude Code to external tools, databases, and APIs. Claude Code acts as an MCP client and can connect to multiple servers at once; each server can expose tools, resources, and prompts. Use it when the agent needs repeatable access to systems that should not be pasted into prompts.
Common Uses
- Internal documentation search.
- Browser or design inspection tools.
- Issue trackers and pull request metadata.
- Database schema discovery.
- Product analytics or operational dashboards.
The value is strongest when the server returns structured, narrow data instead of a large dump.
Trust Boundary
Every MCP server expands what the agent can see or do, and servers that fetch external content can expose you to prompt-injection risk. Classify each server before enabling it:
- Read-only context.
- Read-write project automation.
- External network access.
- Sensitive data access.
- Production-impacting operations.
For sensitive systems, prefer read-only tools plus explicit human approval for writes.
Adding Servers
claude mcp add supports three transports. The official docs recommend HTTP for remote servers; the
SSE transport is deprecated, so prefer HTTP where available. All options (--transport, --env,
--scope, --header) must come before the server name, and -- separates the name from the
command and arguments passed to a stdio server.
# HTTP remote server (recommended)
claude mcp add --transport http notion https://mcp.notion.com/mcp
# With a Bearer-token header
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_PAT"
# Local stdio server
claude mcp add --transport stdio --env AIRTABLE_API_KEY=KEY airtable \
-- npx -y airtable-mcp-serverYou can also add a server from a JSON string with claude mcp add-json, or import existing servers
from Claude Desktop (macOS and WSL only) with claude mcp add-from-claude-desktop.
Configuration Pattern
Keep team-approved servers in shared project configuration and personal experiments in local or user
configuration. Name servers by purpose, not by implementation detail. The mcpServers schema used in
.mcp.json and add-json accepts a type of stdio, http, or sse; in JSON, streamable-http
is accepted as an alias for http. When command is present, the type defaults to stdio.
{
"mcpServers": {
"docs-search": {
"type": "stdio",
"command": "node",
"args": ["./tools/mcp/docs-search.js"],
"env": {}
}
}
}Scopes and file locations
MCP servers are stored at one of three scopes, selected with --scope. The scope controls which
projects load the server and whether it is shared with your team.
| Scope | Loads in | Shared with team | Stored in |
|---|---|---|---|
local (default) | Current project only | No | ~/.claude.json (per project) |
project | Current project only | Yes, via version control | .mcp.json in project root |
user | All your projects | No | ~/.claude.json |
Scope renaming
Older versions named these scopes differently: the current local was project, and the current
user was global. The default is now local. Note that "local scope" for MCP servers (stored in
~/.claude.json) is unrelated to general local settings in .claude/settings.local.json.
Project-scoped servers from .mcp.json prompt for approval before first use. To reset those approval
choices, run claude mcp reset-project-choices. When the same server is defined in more than one
place, Claude Code uses a single definition from the highest-precedence source without merging
fields. Precedence is: local, then project, then user, then plugin-provided servers, then claude.ai
connectors. The three scopes match duplicates by name; plugins and connectors match by endpoint.
Reserved server name
workspace is reserved for internal use. A server defined with that name is skipped at load time
with a warning asking you to rename it.
Environment variable expansion
.mcp.json supports ${VAR} (value substitution) and ${VAR:-default} (with a default). Expansion
is allowed in command, args, env, url, and headers. If a required variable has no value and
no default, the config fails to parse.
For stdio servers, Claude Code injects the project root as CLAUDE_PROJECT_DIR into the spawned
server's environment, so the server can resolve project-relative paths. Because this variable lives in
the server's environment (not Claude Code's own), referencing it via ${CLAUDE_PROJECT_DIR} in a
project- or user-scoped command/args needs a default such as ${CLAUDE_PROJECT_DIR:-.}.
Plugin-provided configurations substitute ${CLAUDE_PROJECT_DIR} directly.
Authentication
Many remote servers require OAuth 2.0. When a server responds with 401 Unauthorized or 403 Forbidden, Claude Code flags it as needing authentication; run /mcp to complete the browser login
flow. Tokens are stored securely and refreshed automatically, and you can revoke access with "Clear
authentication" in the /mcp menu.
Current CLI builds also expose claude mcp login <server> and claude mcp logout <server> for
explicit remote-server authentication flows outside the interactive /mcp panel. In team bootstrap
docs, keep configuration checks (list/get) separate from the browser-auth step so operators do
not mistake a configured server for an authenticated one.
For servers that do not support Dynamic Client Registration (DCR), supply pre-registered OAuth
credentials. The --client-secret flag takes no value: it prompts for the secret with masked input,
and in CI you can supply it via the MCP_CLIENT_SECRET environment variable. Use --callback-port to
fix the OAuth callback to a pre-registered http://localhost:PORT/callback redirect URI (usable on
its own with DCR, or together with --client-id). These flags apply only to HTTP and SSE transports.
# Fixed callback port + pre-registered client-id (secret via masked prompt)
claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcpFor non-OAuth schemes (Kerberos, short-lived tokens, internal SSO), set headersHelper in the
server's config. The command must write a JSON object of string key-value pairs to stdout, runs with a
10-second timeout on each connection (no caching), and overrides any static headers with the same
name. The helper receives CLAUDE_CODE_MCP_SERVER_NAME and CLAUDE_CODE_MCP_SERVER_URL.
Trust check
headersHelper runs arbitrary shell commands. When defined at project or local scope, it only runs
after you accept the workspace trust dialog.
You can also override OAuth metadata discovery with oauth.authServerMetadataUrl (requires v2.1.64
or later) and pin requested scopes with oauth.scopes (a single space-separated string), both set in
the server's oauth object in .mcp.json.
Managing Servers
claude mcp list # list configured servers
claude mcp get github # show one server's details
claude mcp remove github # remove a server
claude mcp serve # run Claude Code itself as a stdio MCP server
/mcp # (inside Claude Code) check status and authenticateclaude mcp list and get show pending project-scoped servers as ⏸ Pending approval and rejected
ones as ✗ Rejected. The /mcp panel shows each connected server's tool count and flags servers that
advertise the tools capability but expose none.
Recent v2.1.181~v2.1.190 releases reduced misleading MCP status reports, but incident response should still
check claude mcp get <server>, server logs, HTTP status, and OAuth token state instead of relying
only on the interactive status view.
If an HTTP or SSE server disconnects mid-session, Claude Code reconnects with exponential backoff (up
to five attempts, starting at one second and doubling). As of v2.1.121, the initial connection is
retried up to three times on transient errors (5xx, connection refused, timeout); authentication and
not-found errors are not retried. Stdio servers are local processes and are not reconnected
automatically. Servers can also send MCP list_changed notifications to refresh their tools, prompts,
and resources without a reconnect.
Scaling with Tool Search
Tool search keeps context usage low by deferring tool definitions until Claude needs them, so adding
more servers has minimal impact on the context window. It is enabled by default. Control it with the
ENABLE_TOOL_SEARCH environment variable:
| Value | Behavior |
|---|---|
| (unset) | All MCP tools deferred and loaded on demand; falls back to loading upfront on Vertex AI or a non-first-party ANTHROPIC_BASE_URL. |
true | All tools deferred; the beta header is sent even on Vertex AI and through proxies (fails on unsupported models or proxies). |
auto | Loads tools upfront if they fit within 10% of the context window, defers the overflow. |
auto:N | Threshold mode with a custom percentage (0-100), e.g. auto:5. |
false | All tools loaded upfront, no deferral. |
Tool search requires a model that supports tool_reference blocks (Sonnet 4 / Opus 4 or later; not
Haiku). To exempt a server so its tools always load at session start, set "alwaysLoad": true in that
server's config (available on all server types, requires v2.1.121 or later); an individual tool can
opt in with "anthropic/alwaysLoad": true in its _meta. You can disable the search tool itself with
a permission rule, "deny": ["ToolSearch"].
Output Limits and Timeouts
MCP tool output triggers a warning above 10,000 tokens and is capped by default at 25,000 tokens.
Adjust the cap with MAX_MCP_OUTPUT_TOKENS (e.g. MAX_MCP_OUTPUT_TOKENS=50000); it applies to tools
that do not declare their own limit. A server can raise a specific tool's persist-to-disk threshold up
to 500,000 characters by setting _meta["anthropic/maxResultSizeChars"] in its tools/list entry.
Relevant timeouts: MCP_TIMEOUT sets the server startup timeout (e.g. MCP_TIMEOUT=10000 for ten
seconds). A per-server timeout field (milliseconds) in .mcp.json is a hard per-tool-call limit and
overrides the MCP_TOOL_TIMEOUT environment variable for that server; values below 1000 are floored
to one second.
For long-running MCP tools, set CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT deliberately. Use it when a tool
streams sparse progress or waits on a remote service, and keep the value low enough that CI can still
fail stuck jobs promptly.
Resources and Prompts
Servers can expose resources referenced with @, like files. Type @ to see available resources in
autocomplete, then use @server:protocol://resource/path:
Analyze @github:issue://123 and suggest a fix.
Compare @postgres:schema://users with @docs:file://database/user-model.Servers can also expose prompts as slash commands in the form /mcp__servername__promptname, with
arguments passed space-separated after the command:
/mcp__github__pr_review 456
/mcp__jira__create_issue "Bug in login flow" highHooks and Permissions
MCP tools are named mcp__<server>__<tool>. Use that pattern in hook matchers and permission rules.
A rule like "deny": ["mcp__servername"] blocks every tool from one server. For organization-wide
control, see managed MCP configuration, which deploys a
fixed server set via managed-mcp.json and restricts connections with allowedMcpServers and
deniedMcpServers.
Operational Checklist
- The server has a narrow purpose.
- Tool names are understandable from the prompt alone.
- Result sizes are capped.
- Authentication is not committed to the repository.
- Write tools have explicit approval boundaries.
- Failure messages tell the agent what to try next.
References
- MCP overview and configuration: https://code.claude.com/docs/en/mcp
- Managed MCP configuration: https://code.claude.com/docs/en/managed-mcp
- Environment variables: https://code.claude.com/docs/en/env-vars