Learn how to connect Claude Code to your tools with the Model Context Protocol.
Claude Code can connect to hundreds of external tools and data sources through the Model Context Protocol (MCP), an open source standard for AI-tool integrations. MCP servers give Claude Code access to your tools, databases, and APIs.Connect a server when you find yourself copying data into chat from another tool, like an issue tracker or a monitoring dashboard. Once connected, Claude can read and act on that system directly instead of working from what you paste.If you’re connecting your first server, start with the MCP quickstart for a step-by-step walkthrough. This page is the full reference.
With MCP servers connected, you can ask Claude Code to:
Implement features from issue trackers: “Add the feature described in JIRA issue ENG-4521 and create a PR on GitHub.”
Analyze monitoring data: “Check Sentry and Statsig to check the usage of the feature described in ENG-4521.”
Query databases: “Find emails of 10 random users who used feature ENG-4521, based on our PostgreSQL database.”
Integrate designs: “Update our standard email template based on the new Figma designs that were posted in Slack”
Automate workflows: “Create Gmail drafts inviting these 10 users to a feedback session about the new feature.”
React to external events: an MCP server can also act as a channel that pushes messages into your session, so Claude reacts to Telegram messages, Discord chats, or webhook events while you’re away.
Browse reviewed connectors in the Anthropic Directory. Directory connectors use the same MCP infrastructure as Claude Code, so you can add any remote server listed there with claude mcp add.
Verify you trust each server before connecting it. Servers that fetch external content can expose you to prompt injection risk.
In the VS Code extension or the desktop app, follow Install a plugin instead of this step. In a terminal, start Claude Code by running claude, then enter this at its prompt:
If the install fails, match the message Claude Code reports:
Marketplace "claude-plugins-official" not found: add the marketplace with /plugin marketplace add anthropics/claude-plugins-official, then retry the install.
Plugin "<name>" not found in marketplace "claude-plugins-official": your local copy of the marketplace catalog may be out of date. Refresh it with /plugin marketplace update claude-plugins-official, then retry the install. If the retry prints the same message, see Plugin not found in marketplace.
If the install summary reports Run /reload-plugins to apply., Claude Code then runs that reload for you. If the reload warns that your next message would re-read the conversation, run /reload-plugins --force.
2
Run the build skill
/mcp-server-dev:build-mcp-server
Claude asks about your use case and scaffolds a remote HTTP or local stdio server.
HTTP servers are the recommended option for connecting to remote MCP servers. This is the most widely supported transport for cloud-based services.
# Basic syntaxclaude mcp add --transport http <name> <url># Real example: Connect to Notionclaude mcp add --transport http notion https://mcp.notion.com/mcp# Example with Bearer tokenclaude mcp add --transport http secure-api https://api.example.com/mcp \ --header "Authorization: Bearer your-token"
When configuring MCP servers via JSON in .mcp.json, ~/.claude.json, or claude mcp add-json, the type field accepts streamable-http as an alias for http. The MCP specification uses the name streamable-http for this transport, so configurations copied from server documentation work without modification.A JSON entry that has a url but no type is a configuration error, because Claude Code reads an entry with no type as a stdio server. Claude Code skips that server and reports MCP server "<name>" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entry.Only an SDK host application, such as an Agent SDK application or the desktop app, can register an in-process "type": "sdk" server. Claude Code skips a "type": "sdk" entry in .mcp.json, ~/.claude.json, or settings and reports Skipped — MCP server "<name>" declares type "sdk", which only an SDK host application can register.
In --output-format stream-json runs, Claude Code also reports a skipped --mcp-config entry in the system/init event’s mcp_server_errors field, so scripts can detect that the server never loaded.
The SSE (Server-Sent Events) transport is deprecated. Use HTTP servers instead, where available.
Some services still expose only an SSE endpoint. Add these with the same claude mcp add --transport http <name> <url> command as an HTTP server. Claude Code tries the HTTP transport first and switches to SSE when the server doesn’t accept it. The automatic switch requires Claude Code v2.1.265 or later.On an earlier version, or to connect over SSE directly, pass --transport sse instead:
# Basic syntaxclaude mcp add --transport sse <name> <url># Real example: Connect to Asanaclaude mcp add --transport sse asana https://mcp.asana.com/sse# Example with authentication headerclaude mcp add --transport sse private-api https://api.company.com/sse \ --header "X-API-Key: your-key-here"
Stdio servers run as local processes on your machine. They’re ideal for tools that need direct system access or custom scripts.Claude Code sets CLAUDE_PROJECT_DIR in the spawned server’s environment to the project root, so your server can resolve project-relative paths without depending on the working directory. This is the same directory hooks receive in their CLAUDE_PROJECT_DIR variable. Read it from inside your server process, for example process.env.CLAUDE_PROJECT_DIR in Node or os.environ["CLAUDE_PROJECT_DIR"] in Python.CLAUDE_PROJECT_DIR is the stable project root and doesn’t change when you add or remove working directories mid-session. A server that limits its own filesystem access to a set of allowed directories should implement the MCP roots/list request instead. Claude Code answers roots/list with the session’s launch directory plus every additional working directory you’ve granted with --add-dir, /add-dir, or the additionalDirectories setting. Claude Code sends notifications/roots/list_changed when that set changes.This variable is set in the server’s environment, not in Claude Code’s own environment, so referencing it via ${VAR} expansion in the command or args of a project-scoped .mcp.json entry or a local- or user-scoped server entry in ~/.claude.json requires a default such as ${CLAUDE_PROJECT_DIR:-.}. Plugin-provided MCP configurations substitute ${CLAUDE_PROJECT_DIR} directly and don’t need the default.
For stdio servers, the -- (double dash) separates Claude’s own options, such as --transport, --env, and --scope, from the command and arguments that run the server. Everything after -- is passed to the server untouched.For example:
claude mcp add --transport stdio myserver -- npx server → runs npx server
claude mcp add --env KEY=value --transport stdio myserver -- python server.py --port 8080 → runs python server.py --port 8080 with KEY=value in environment
Without --, Claude Code would try to parse the server’s flags, like --port above, as its own options.--env accepts multiple KEY=value pairs. If the server name comes directly after --env, the CLI reads the name as another pair and rejects it, so place at least one other option, such as --transport stdio, between --env and the server name.
When Claude Code disconnects a stdio server, for example when your session ends, it signals the server process and waits briefly for it to exit before forcing it to stop. If your server saves state or removes lock files at shutdown, handle the signal for your platform and finish within that time:
On macOS and Linux: Claude Code sends SIGINT, then SIGTERM if the process is still running 100 milliseconds later, then SIGKILL after a further 400 milliseconds.
On Windows: Claude Code closes the server’s stdin, then ends the server’s process tree if the process is still running 300 milliseconds later.
Before v2.1.296, Claude Code on Windows ended the server’s process tree at once, without closing stdin first or waiting.
WebSocket servers hold a persistent bidirectional connection, which suits remote MCP servers that push events to Claude unprompted. Use HTTP instead when your server only responds to requests, since HTTP supports OAuth and the claude mcp add --transport flag, while WebSocket supports neither.Configure WebSocket servers in .mcp.json or with claude mcp add-json:
claude mcp add-json events-server \ '{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer YOUR_TOKEN"}}'
The type: "ws" entry accepts the same url, headers, headersHelper, timeout, and alwaysLoad fields as http. Authentication is header-only, so pass a static token in headers or generate one at connect time with headersHelper. The claude mcp add --transport flag doesn’t accept ws.
Add a server from setup instructions written for another client
MCP servers aren’t specific to Claude Code, so a server’s setup instructions may be written for Claude Desktop, Cursor, or another MCP client and give no claude mcp add command. To add the server anyway, look in those instructions for a URL, a launch command, or a JSON block:
A URL such as https://mcp.example.com/mcp: the server is remote.
A launch command such as npx -y @example/mcp-server: the server runs on your machine.
An mcpServers JSON block: configuration written for another client’s settings file.
Each is one of the inputs the four options in Installing MCP servers take. Find the shape you have below to turn it into the command Claude Code accepts. Each command writes to local scope unless you add --scope project or --scope user.
A URL means the server is remote. For an https:// endpoint, add it with --transport http, or follow Option 2 when the instructions say the endpoint uses SSE. For a wss:// endpoint, use Option 4 instead, since --transport doesn’t accept ws:
claude mcp add --transport http example https://mcp.example.com/mcp
If the instructions also give an API key or token header, pass it with --header as shown in Option 1.
A launch command means the server runs as a local stdio process. Put the whole command after --, so Claude Code passes flags such as -y to the command that starts the server instead of reading them as its own options. Pass any environment variables the instructions ask for with --env, after the server name and before --:
claude mcp add example --env API_KEY=your-key -- npx -y @example/mcp-server
An mcpServers block written for another MCP client, such as Claude Desktop, uses the wrapper key and entry shape Claude Code reads. Pass claude mcp add-json the object inside mcpServers, not the wrapper. Two entries need a repair first:
A url with no type: add "type": "http", "type": "sse", or "type": "ws" to match the endpoint. Claude Code reads an entry with no type as a stdio server, so a url entry without a type fails.
A key with characters other than letters, numbers, hyphens, and underscores: pick a server name that uses only those characters. Otherwise the key is the server name.
claude mcp add-json example '{"command":"npx","args":["-y","@example/mcp-server"]}'
Add MCP servers from JSON configuration covers shell escaping and the --scope flag for add-json. To share the server with your team instead, add --scope project, or add the entry under mcpServers in .mcp.json at your project root and commit it. Project scope covers how Claude Code loads and approves that file.Each claude mcp add and claude mcp add-json command prints an Added ... line on success. To check that Claude Code connected, run claude mcp get <name>; Server status covers the statuses it shows and the approval step for .mcp.json servers.
Once configured, you can manage your MCP servers with these commands:
# List all configured serversclaude mcp list# Get details for a specific serverclaude mcp get notion# Remove a serverclaude mcp remove notion# (within Claude Code) Check server status/mcp
When you remove a remote server, Claude Code also deletes the OAuth tokens and client registration it stored for that server. Claude Code doesn’t revoke the tokens at the authorization server that issued them. To revoke the tokens where the authorization server supports revocation, run claude mcp logout <name> in your shell before claude mcp remove <name>.
claude mcp add confirms a successful add by printing an Added ... line, which means the configuration was written. If the command prints a was not saved message instead, see MCP server was not saved or removed; for a may not have been saved message, see MCP server may not have been saved or removed.claude mcp list shows a health status next to each server it lists, such as ✔ Connected, ! Needs authentication, or ✘ Failed to connect. A failure status means Claude Code couldn’t connect to that server, not that the list command failed.The statuses in this list report a configuration decision rather than a connection attempt, so Claude Code prints them without connecting to the server:
⏸ Pending approval (run `claude` to approve): a project-scoped server from .mcp.json that you haven’t approved yet. Claude Code shows it in both claude mcp list and claude mcp get <name>. Run claude interactively to review and approve it.
✘ Rejected (see disabledMcpjsonServers in settings): a .mcp.json server that a disabledMcpjsonServers entry rejects. Claude Code shows it only in claude mcp get <name>.
⊘ Disabled for this project (re-enable via /mcp): a server that the project’s disabledMcpServers list names. Claude Code shows it in both claude mcp list and claude mcp get <name>. Turn the server back on from the /mcp panel.
✘ Blocked by enterprise managed policy: a server that one of your organization’s policies refuses. Claude Code shows it in both claude mcp list and claude mcp get <name>. A server blocked by an allowlist, a denylist, or another restriction in managed MCP configuration is hidden from both commands rather than shown with this status. Ask your administrator which policy blocks the server.
claude mcp list and claude mcp get read .mcp.json approvals only from settings files that aren’t checked into the repository until you trust the workspace by running claude in it and accepting the workspace trust dialog. A cloned repository can’t approve its own servers: enableAllProjectMcpServers or enabledMcpjsonServers committed to the project’s .claude/settings.json is ignored in an untrusted folder, and the server stays at ⏸ Pending approval instead of being connected and health-checked.Approvals from these sources still apply in an untrusted folder:
your user ~/.claude/settings.json
managed settings
settings passed with --settings
Claude Code also applies approvals from an untracked .claude/settings.local.json, but it runs git to check whether the file is tracked, and it runs that check only in a trusted folder. In a folder you’ve never trusted, Claude Code waits for the trust dialog before applying the file’s approvals, unless the folder is your own configuration home: your home directory, or a directory whose .claude you’ve set as CLAUDE_CONFIG_DIR. Before v2.1.207, Claude Code applied approvals from an untracked .claude/settings.local.json even in a folder you’d never trusted.A disabledMcpjsonServers entry in any settings file still rejects the server.
In /mcp, including a server’s menu there, and in the /plugin manager, a remote HTTP or SSE server you’ve used before can show a cached status such as cached 2h ago · connects on first use · 5 tools. Claude Code loaded the server’s tool list from its discovery cache, saved in a previous session, instead of connecting at startup, and Claude Code connects the server the first time Claude calls one of the server’s tools. The tools are available from your first message, so you don’t need to do anything. The discovery cache and its cached status require Claude Code v2.1.221 or later.The discovery cache is off by default unless a gradual rollout has enabled it for your account. Set MCP_DISCOVERY_CACHE=1 to turn it on, or 0 to keep it off even when the rollout has enabled it. Before v2.1.238, the cache was on by default.When you select Disable or Clear authentication from a server’s menu in /mcp, Claude Code also discards that server’s cache entry. Reconnect discards it too on a connected or failed server; on a cached server, Reconnect connects the server now and keeps the entry. The next time Claude Code connects to the server after discarding the entry, it fetches the tool list from the server instead of from the cache.
Connection failures and unconfigured servers
When a server’s status is ✘ Failed to connect, claude mcp list appends the failure detail to that status line, and claude mcp get <name> shows it on an Issue: line. The detail is the HTTP status or error code, plus any error text the server returned. The server’s detail view in /mcp includes the same server-reported text in its Issue: row.Claude Code redacts credential-like text from this detail and never includes the expanded server URL, which can carry secrets. Claude Code appends no detail to a ✘ Connection error status, because the exception text it would print there can embed that URL.When you complete authentication from /mcp and the connection still fails with an HTTP status or a transport error code, Claude Code adds that code and the origin of the server’s URL to the message it prints after the attempt. The origin is the scheme and host, plus the port when the URL names one, such as https://mcp.example.com.
The path and query never appear in that message.
For a server in the local, project, or user scope or in managed MCP configuration, the origin shows the host as written in that configuration, so a ${VAR} reference in the host isn’t expanded in the message.
For a failure with no status or error code, Claude Code shows the error text without the origin.
A remote server whose configuration has an empty url shows as not configured in /mcp, in claude mcp list, and in the /plugin manager, and Claude Code doesn’t attempt to connect to it. A plugin can include a placeholder entry like this for a connector you configure later, so Claude Code doesn’t report it as an error or a setup issue. The server’s detail view in /mcp reads No URL configured for this server; set the entry’s url to connect it.
Claude Code warns about the configuration problems below. Each entry says what Claude Code checks and how to clear the warning:
Hidden whitespace: Claude Code warns when an MCP config value carries hidden leading or trailing whitespace, which often comes from pasting a token with a trailing newline. Claude Code checks command, url, each args entry, and the values and key names under env and headers. Claude Code shows the warning in claude mcp list output and in /mcp, naming the affected fields without echoing their values, for example Leading or trailing whitespace in: headers.Authorization. Claude Code doesn’t trim the whitespace and uses the values exactly as written, so edit the configuration to remove it.
Same name in more than one scope: if you define the same server name in more than one scope with different endpoints, Claude Code warns about the conflict in claude mcp list output and in /mcp. Claude Code stores OAuth sign-ins per endpoint, so when you authenticate the definition that loads in one project, you still need to sign in separately in a project where a different definition loads. Keep the endpoint you want and remove the others with claude mcp remove <name> --scope <scope>. In the warning, Claude Code quotes each scope’s endpoint as written in your configuration, with ${VAR} references unexpanded, so it never shows a resolved value such as an API key.
Reserved names: Claude Code reserves the names of its built-in servers, including workspace, claude-in-chrome, computer-use, Claude Preview, and Claude Browser. If your configuration defines a server with a reserved name, Claude Code skips it at load time and shows a warning asking you to rename it. claude mcp add rejects a reserved name with an error. Claude Preview and Claude Browser both name the built-in server that the Claude Code desktop app’s preview pane uses.
Missing environment variable: if a ${VAR} reference in a server’s configuration names a variable that isn’t set and has no :-default, Claude Code warns in claude mcp list output and in /mcp, naming the variable, and still loads the server with the ${VAR} text unexpanded. Set the variable or add a ${VAR:-default} fallback. In a remote server’s url and headers, some credential variables read as empty instead, with no warning.
The /mcp panel shows the tool count next to each connected server and flags servers that advertise the tools capability but expose no tools.If your request needs tools from a server that is still connecting in the background, Claude waits for that server before continuing. How the wait happens depends on your configuration:
With tool search, the default: the wait happens inside the ToolSearch call.
Without tool search: Claude uses the WaitForMcpServers tool instead. Configurations without tool search include ENABLE_TOOL_SEARCH=false and a model earlier than Claude Opus 4.5, Claude Sonnet 4.5, and Claude Haiku 4.5 on Google Cloud’s Agent Platform. For an ANTHROPIC_BASE_URL gateway, see Tool search through an LLM gateway.
On a Microsoft Foundry deployment hosted on Azure: Claude starts on the tool-search path rather than with WaitForMcpServers, since Claude Code discovers the deployment’s server-side rejection only from the API. After Claude Code switches that deployment to upfront loading, tools from a server that finishes connecting become available on Claude’s next request.
With tool search enabled, when a server finishes connecting while Claude is working, Claude Code lists the server’s tool names to Claude on its next request in the same turn. Claude can then search for and call those tools without waiting for your next message.After you resume a session, Claude can call a tool from the saved conversation while the tool’s MCP server is still connecting. While the server is on its first connection attempt, Claude Code holds the call for up to 10 seconds and runs it once the tool is available. If the server doesn’t connect in time, or it is already retrying after a failed attempt, the call fails with the No such tool availabletool error.
Toggle a server off in the /mcp panel to stop Claude Code from connecting to it without losing its configuration. Claude Code still lists the server in /mcp, marked as disabled.When you toggle a server, Claude Code records your choice per project in ~/.claude.json, in one of two lists that cover disjoint sets of servers:
disabledMcpServers: an opt-out list for user-configured servers, plugin servers, servers your organization provides through managed settings, the claude.ai connectors Claude Code fetches itself, and built-in servers that default to on. Claude Code doesn’t connect to a server you list here. When you disable a claude.ai connector with the per-project /mcp toggle described in Disable claude.ai connectors, Claude Code writes it to this list under its display name, for example claude.ai Slack.
enabledMcpServers: an opt-in list for built-in servers that default to off, such as computer-use. Claude Code connects to a default-off server only when you list it here.
Claude Code consults exactly one of the two lists for each server, so neither list overrides the other. If you add a regular server to enabledMcpServers, or a default-off built-in server to disabledMcpServers, Claude Code ignores the entry.disabledMcpServers and enabledMcpServers are unrelated to enabledMcpjsonServers and disabledMcpjsonServers, which control approval of servers defined in a project’s .mcp.json file.
Claude Code connects to MCP servers through one of two client runtimes. The v1 runtime is built on MCP TypeScript SDK 1.x. The v2 runtime is the same code on MCP TypeScript SDK 2.0, which adds MCP protocol revision 2026-07-28. The rest of this page applies to both runtimes, except where a section names the v2 runtime.Claude Code picks a runtime each time you start it and keeps it until you exit. In sessions where it fetches feature flags, it uses the v2 runtime on Claude Code v2.1.232 or later.In the sessions where it doesn’t fetch feature flags, Claude Code uses the v2 runtime by default on Claude Code v2.1.274 or later:
Sessions on Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry, unless a host platform that embeds Claude Code sets CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST
Sessions where you turn off telemetry or feature-flag fetching, for example with DISABLE_TELEMETRY
On v2, Claude Code also:
Asks HTTP, stdio, and claude.ai connector servers whether they support the newer revision and uses it with those that do. That includes the connectors of cloud and Remote Control sessions. Claude Code connects to every other server as v1 does.
Receives list_changed notifications from servers on the newer revision over a stream it holds open.
Doesn’t register a channel server that connects on the newer revision, because that revision can’t carry channel messages.
Fails an MCP OAuth sign-in whose authorization response names an unexpected issuer.
Sends MCP OAuth credentials only to a token endpoint served over HTTPS or at localhost, 127.0.0.1, or ::1. Sign-in fails for a server whose token endpoint is plain http:// anywhere else, such as a device on your local network. See Refusing to send credentials to non-https token endpoint.
Anthropic can keep a specific server on the earlier protocol, or off that stream, with a feature flag Claude Code fetches.To pick the runtime yourself, set MCP_SDK_GENERATION to v1 or v2. To decide whether Claude Code asks, set MCP_PROTOCOL_NEGOTIATION to auto or legacy.
On the v2 runtime, Claude Code receives list_changed notifications from a server on the newer protocol revision over a stream it holds open. When the stream closes, Claude Code reopens it, with two limits:
The stream closes again within 10 seconds: Claude Code reopens it up to three times, then stops for that connection.
The stream stays open longer than 10 seconds, then closes, as streams to serverless hosts commonly do: after five reopens in an hour, Claude Code waits about six hours before the next one.
Until the stream reopens, you keep the server’s last fetched tools, prompts, and resources. To pick up its changes sooner, reconnect the server from /mcp.
Claude Code reconnects a remote server that drops mid-session and retries an HTTP or SSE server’s first connection after a transient error. For a stdio server, see Stdio servers that exit or fail to start.
Claude Code first tries to reconnect a dropped remote server up to five times with exponential backoff, starting at a one-second delay and doubling it each time:
In an interactive session: /mcp shows the server as pending while Claude Code reconnects. After five failed attempts, Claude Code marks the server as failed, or as needing authentication when the server needs authorizing again. When it marks the server as failed, you see an MCP server "<name>" disconnected · open /mcp to reconnect notification. You can retry manually from /mcp.
In claude -p runs and Agent SDK sessions: Claude Code makes the same five attempts, with no /mcp panel to show them. If all five fail, the run continues without the server’s tools:
After a transient error, such as a 5xx response or a timeout: Claude Code keeps retrying an HTTP or SSE server in the background. Retries last up to about half an hour, and the server’s tools become available again when one connects. Until then, an Agent SDK session reports the statusfailed, and your code can reconnect the server. To reconnect it in claude -p, start the run again.
When an HTTP or SSE server’s first connection fails with a transient error, such as a 5xx response, a connection refused, or a timeout, Claude Code retries up to three times. If the connection still fails, Claude Code marks the server as failed.Those retries don’t apply in these cases:
A WebSocket server’s first connection. To try it again in an interactive terminal session, select Reconnect from the server’s menu in /mcp
An authentication or not-found error, because it requires a configuration change to resolve. When a headersHelper is the server’s only source of the Authorization header, Claude Code retries an authentication error anyway, because it re-runs the helper on each attempt and can pick up a fresh credential
To start a stdio server again, read the column that matches what happened to it. Find your row by how you run Claude Code: an interactive session, a claude -p run, or an Agent SDK session.
How you run Claude Code
The server’s process exits mid-session
The server’s first connection fails
Interactive session
Claude Code marks the server as failed. To start it again, select Reconnect from the server’s menu in /mcp
Claude Code marks the server as failed. To start it again, select Reconnect from the server’s menu in /mcp
claude -p run
Claude Code starts the server again the next time Claude calls one of the server’s tools, and the call runs once the server connects
The run continues without the server’s tools. To have Claude Code try the connection again, start the run again. When a plugin provides the server, new runs skip the connection for 15 minutes after a failure, so wait that long first or retry sooner
Agent SDK session
Claude Code starts the server again the next time Claude calls one of the server’s tools, and the call runs once the server connects
The session continues without the server’s tools. Your code can reconnect the server
After a server connects, Claude Code sends it capability discovery requests such as tools/list, prompts/list, and resources/list. Claude Code retries those requests up to three times with short backoff after a transient network or server error. It doesn’t retry authentication errors, 4xx responses, or request timeouts.
To retry every server that failed or needs authentication, run /mcp reconnect all at the Claude Code prompt in an interactive terminal session. This requires Claude Code v2.1.284 or later. Earlier versions print MCP server "all" not found.
Whether Claude Code tells Claude about a configured server that failed to connect depends on tool search, which is on by default:
With tool search, Claude Code tells Claude which server failed and its connection error, so Claude reports the connection failure in its response. Claude Code includes the same information in ToolSearch results that find no matching tool.
An MCP server can also push messages directly into your session so Claude can react to external events like CI results, monitoring alerts, or chat messages. To enable this, your server declares the claude/channel capability and you opt it in with the --channels flag at startup. See Channels to use an officially supported channel, or Channels reference to build your own.On the v2 runtime, a channel server that negotiates MCP protocol revision 2026-07-28 can’t deliver channel messages, so Claude Code doesn’t register it as a channel. A channel server that doesn’t support that revision connects on the earlier handshake and registers as before.Claude Code asks stdio servers for that revision by default. To keep a stdio channel server on the earlier handshake, set MCP_PROTOCOL_NEGOTIATION to legacy, which keeps every server on it.
Tips:
Use the -s or --scope flag to specify where the configuration is stored:
local (default): available only to you in the current project
project: shared with everyone in the project via the .mcp.json file
user: available to you across all projects
Set environment variables with -e or --env flags (for example, -e KEY=value)
The --transport and --header flags also accept -t and -H short forms
Configure MCP server startup timeout using the MCP_TIMEOUT environment variable (for example, MCP_TIMEOUT=10000 claude sets a 10-second timeout)
Set a per-server tool execution timeout by adding a timeout field in milliseconds to that server’s .mcp.json entry, for example "timeout": 600000 for ten minutes. This overrides the MCP_TOOL_TIMEOUT environment variable for that server only
Claude Code displays a warning when MCP tool output exceeds 10,000 tokens and limits output to 25,000 tokens by default. To change the token limit, set the MAX_MCP_OUTPUT_TOKENS environment variable, for example MAX_MCP_OUTPUT_TOKENS=50000. The warning threshold is fixed. Unless the server raises a tool’s own limit, successful text results longer than 50,000 characters are saved to a file regardless of this variable. See MCP output limits and warnings
Use /mcp to authenticate with remote servers that require OAuth 2.0 authentication
The per-server timeout is a hard wall-clock limit per tool call, and progress notifications from the server don’t extend it. Values below 1000 are ignored and fall through to MCP_TOOL_TIMEOUT, or to its default of about 28 hours when that variable is unset. For an HTTP, SSE, or claude.ai connector server there is also a second, per-request timer that covers each request through to the server’s first response byte. Claude Code sets that timer to the greatest of three values: 60 seconds, the tool timeout that applies to the server, and MCP_TIMEOUT. The 28-hour default of an unset MCP_TOOL_TIMEOUT doesn’t enter that comparison, and a value below 60 seconds doesn’t shorten the timer. Stdio and WebSocket servers have no per-request timer.A per-server timeout of at least 1000 also acts as a floor on the idle timeout described below: Claude Code never aborts that server’s tool calls for idleness sooner than the per-server timeout.A tool call to an MCP server that sends no response and no progress notification for the idle window aborts with an error instead of waiting for the wall-clock limit. The idle timeout applies to every server type except IDE servers and SDK in-process servers. The idle window defaults to five minutes for HTTP, SSE, WebSocket, and claude.ai connector servers, and to 30 minutes for stdio servers.Set the CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT environment variable in milliseconds to change the idle window, or set it to 0 to disable the check.These timeouts bound how long a call can run, not always how long it blocks the session: a main-conversation call that runs past two minutes moves to a background task first. See Automatic backgrounding of long tool calls.
If a background call’s detail view in /tasks shows runs on the server; survives exiting this session, see MCP tasks that run on the server.An MCP tool call in the main conversation that is still running after two minutes moves to a background task instead of blocking the session. Claude receives the task ID immediately and keeps working, and the result arrives as a task notification when the call settles.The task appears in /tasks, where you can also stop it, and it doesn’t survive exiting the session. The task’s entry shows the latest progress the server has reported. If you stop the task, Claude Code cancels the call and tells Claude that no result is coming. Stopping doesn’t guarantee the server stops: it may already have done some of the work, or may still finish it.The per-call limits still apply while the call runs in the background: the wall-clock limit set by the per-server timeout or MCP_TOOL_TIMEOUT, and the idle timeout set by CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT.To change or turn off automatic backgrounding:
Set the CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS environment variable in milliseconds to change the threshold, or set it to 0 to turn automatic backgrounding off. With 0, Claude also waits for MCP tasks in an interactive session
Calls from subagents; Claude Code backgrounds only main-conversation calls
Calls to IDE servers
Calls in non-interactive mode, unless CLAUDE_AUTO_BACKGROUND_TASKS is set to 1, since a one-shot run can end before the result arrives
A call waiting on an open elicitation dialog isn’t backgrounded while the dialog is open; the server is blocked on your input, not slow, so Claude Code defers the move until the dialog closes.
An MCP task is a long job, such as a report export or a build, that an MCP server runs itself using the MCP tasks extension. Claude’s tool call returns once the server accepts the job, so Claude keeps working unless you make Claude wait. When the job ends, the transcript says so and Claude gets the result. Ask Claude for it.Meanwhile, the footer shows a count such as 1 MCP task, and Claude Code follows the task by checking its status with the server. A task on a remote server keeps running after you exit. To follow it again, resume the same session.
MCP tasks are in public beta in the Claude Code CLI and require Claude Code v2.1.304 or later. What a call needs to become an MCP task lists the sessions and servers that get them.
To stop a running task, select it in /tasks and press x, or ask Claude to. Claude Code stops following the task and asks the server to cancel it, though the server may still finish it. Reconnect a disconnected server from /mcp first, or no cancel request goes out and Claude Code forgets the task and can’t follow it again. Pressing Esc doesn’t stop a background task.When the task ends, a line such as this one appears in the transcript:
A running task can open an elicitation dialog to ask you for input. While /tasks is open, the dialog stays hidden, so close /tasks to answer. Declining or pressing Esc is an answer to the server, which then decides whether the task goes on.In a non-interactive session, Claude Code asks the server to cancel a task that requests input, without running your Elicitation hooks or calling the Agent SDK’s onElicitation callback.
A task on a remote server keeps running after you exit. A stdio server’s process stops when Claude Code exits, though its tasks show runs on the server; survives exiting this session in /tasks. Unless that server’s documentation says the work outlives the process, let those tasks finish or stop them in /tasks first.
Situation
What happens to the task
What you can do
You run /clear or /branch, or /resume another session
While Claude Code stays open, the result arrives in your current conversation
After an exit, claude --resume the session the task started in
You exit Claude Code
No exit option cancels a remote server’s task, even when the exit dialog lists it under The following will stop when you exit:
Stop it in /tasks first, or resume the same session later
You return to the task’s session interactively: claude --resume, claude --continue, or /resume
Once the server connects, Claude Code follows the task again, and Claude gets the result if it finished meanwhile and the server still knows it
Keep the server’s name and connection settings unchanged
You resume the task’s session with --resume or --continue in a one-shot claude -p "<prompt>" run
That run doesn’t follow the task
Resume interactively, or with --input-format stream-json
The session fetches feature flags, so not on a third-party provider such as Amazon Bedrock, and not with telemetry or flag fetching turned off
Anthropic has turned MCP tasks on for your kind of session. On v2.1.304 or later that covers terminal CLI sessions, Agent SDK sessions, and GitHub Actions runs. Other surfaces, such as the VS Code extension and the desktop app, don’t have MCP tasks
The call comes from the main conversation, not from a subagent
Either the session is interactive, or an Agent SDK session or a claude -p run reading --input-format stream-json has:
Any other call is a plain tool call, and Automatic backgrounding of long tool calls says which of those move to the background.Keep an Agent SDK or stream-json session’s input open, because the run doesn’t wait for MCP tasks after input closes. A one-shot claude -p "<prompt>" run doesn’t get MCP tasks.
These messages, in a task’s /tasks entry or its closing transcript line, mean Claude Code can’t reach the server or the task. While one shows in /tasks, the job may still be running: Claude Code leaves it alone and keeps checking. The 300s and configuration messages stay on the entry even after contact returns.
Message
What is happening
What you can do
reconnecting…
The server hasn’t answered since a resume, or status checks get no answer
If it stays, reconnect from /mcp
needs a sign-in to <server>
The server refused a status check
Sign in from /mcp
status requests come back with errors; retrying…
The server, or a proxy in front of it, answers status checks with errors
Wait while Claude Code retries
server '<name>' did not reconnect within 300s
No answered check for five minutes, for example with the connection down or the server disabled
Reconnect from /mcp
server '<name>' asked for a sign-in, and none was accepted within 300s
After five minutes the server still wants a sign-in
Sign in from /mcp
status requests to server '<name>' came back with errors, and none succeeded in 300s
Five minutes of error answers
Check the server’s own health or logs
server '<name>' is not configured in this session; the task may still be running on it
The session has no server by that name, for example it was removed, renamed, or left out of --mcp-config, or a claude.ai connector is still loading
Restore the server under the same name, then resume the session again. For a loading connector, nothing: Claude Code follows the task once it appears
A message beginning server '<name>' was reconfigured to a different transport since this task was created
A server by that name exists with connection settings that changed since the task started, such as its URL, command, args, env, headers, or timeout
Restore the earlier settings, then resume the session again
the server rejected this task's id; asking again…
The server says it doesn’t know the task ID. Claude Code keeps asking for up to five minutes
Wait: the message clears if the server recognizes the ID again, or the outcome unknown. line follows
A transcript line ending outcome unknown., in one form expired on the server: outcome unknown.
The server rejected the ID or refused with another permanent error, and Claude Code stopped following the task
A second call may repeat the work. Before calling the tool again, find out from the server what was done, for example by asking Claude to use the server’s other tools
By default, a task in the background has no Claude Code time limit. The tool call time limits, including the wall-clock limit and the idle timeout, apply until the server answers the call with the task. If you make Claude wait, they apply for the whole task. Answered status checks count as activity for the idle timeout.
To make Claude wait for a task’s result in an interactive session, set one of two environment variables, for example in the env block of settings.json:
CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND set to 1: Claude waits for a task’s result. While automatic backgrounding is on, it moves the call after two minutes by default, so short tasks finish in place and long ones don’t block you. The moved call is a plain background call rather than an MCP task. It doesn’t survive exiting the session
While Claude waits, pressing Esc or reaching the wall-clock limit or idle timeout ends the call, and Claude Code asks the server to cancel the task.If you set CLAUDE_CODE_DISABLE_BACKGROUND_TASKS to 1 or start in bare mode, that alone doesn’t make Claude wait for MCP tasks. This example sets CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS to 0, so Claude waits for every MCP tool call:
If you build an MCP server, you can answer a long-running tools/call with a task. The MCP tasks extension defines the messages you send. On a protocol revision 2026-07-28 connection, each request carries Claude Code’s client capabilities at params._meta["io.modelcontextprotocol/clientCapabilities"], with "io.modelcontextprotocol/tasks": {} under extensions. A tools/call request that can’t become a task omits that extension.
Answer with a task only when the request carries the extension, or Claude gets the tool error Unsupported result type 'task' for tools/call. Claude gets the same error when taskId, status, createdAt, lastUpdatedAt, or ttlMs is missing. The task object is the JSON-RPC result of your tools/call response, needs no content array, and here includes the optional statusMessage and pollIntervalMs:
Set it to "task" to mark the reply as a task. Without it, Claude Code reads the reply as a plain result
taskId
Required. At most 128 printable ASCII characters with no spaces, or Claude gets a tool error beginning MCP server "<name>" returned a malformed task handle for tool "<tool>". Keep the ID answerable across connections, because after a resume Claude Code asks about it on a new connection
status
Required. One of working, input_required, completed, failed, or cancelled. Another value gives the Unsupported result type error
createdAt, lastUpdatedAt, ttlMs
Required, and ttlMs may be null. Claude Code doesn’t drop a task because its ttlMs has passed
pollIntervalMs
Optional, but not null. Milliseconds between tasks/get requests, clamped to between 250 and 30000. Claude Code uses 2000 when the field is absent, and reads the value again from each tasks/get response
statusMessage
Optional. /tasks shows the value from your latest tasks/get response, not this first one, and a response that omits the field clears it. A status message from Claude Code can take its place
On an HTTP or claude.ai connector server, the task answer has to start within the per-request timer, so accept the job and answer first, then do the work.
Right after the task answer, Claude Code sends tasks/get with { "taskId": ... }, then repeats it once per poll interval. The tasks extension requires your response to carry "resultType": "complete" along with taskId, status, createdAt, lastUpdatedAt, and ttlMs. ttlMs may be null, and statusMessage and pollIntervalMs are optional. This example reports the build as done:
Gives Claude the normal tools/call result in the top-level result object. isError: true in it is reported as a failure
failed
Tells Claude the message of the top-level error object { code, message, data }, which the tasks extension requires on a failed task. Without that message, Claude gets statusMessage instead, or else Task failed
cancelled
Tells Claude statusMessage, or else Task was cancelled by the server
input_required
Reads inputRequests, an object that maps a key you choose to { method, params }. Claude Code answers each key once through tasks/update with { taskId, inputResponses }, where inputResponses maps the same key to that request’s result. Keys beyond 16 per task are ignored
Methods in inputRequests
elicitation/create is served only in interactive terminal sessions, and roots/list everywhere. When Claude Code can’t serve a request, it asks the server to cancel the task
Another status value
Claude Code asks the server to cancel the task and reports it to Claude as failed
JSON-RPC error -32602
Read as an unknown task ID. For a task in the background, Claude Code keeps asking for up to five minutes, then reports the outcome to Claude as unknown
tasks/cancel
Sent, for example, when Claude or the person stops the task while the server is connected. Not sent on exit
tasks/result, tasks/list, notifications/tasks
Not used, so put the outcome in your tasks/get responses
You add and remove plugin servers by installing or uninstalling the plugin, not with /mcp commands. You can still toggle an installed plugin server off in /mcp, which stops Claude Code from connecting to it without removing the plugin
Example plugin MCP configuration:In .mcp.json at plugin root:
Automatic lifecycle: servers connect and disconnect at these points:
At session startup, Claude Code connects the servers for enabled plugins automatically. In /mcp, a remote (HTTP or SSE) plugin server you’ve used before can show the cached status instead; Claude Code connects it when Claude first calls one of its tools. When a stdio plugin server’s connection failed less than 15 minutes earlier, Claude Code skips the connection
If you enable or disable a plugin during a session, Claude Code connects or disconnects its MCP servers when the change applies. Apply plugin changes without restarting describes when that is. In a session without an interactive terminal, /reload-plugins doesn’t connect or disconnect plugin MCP servers; those changes take effect in your next session
When you reload, Claude Code keeps the live connections of plugin servers whose configuration is unchanged, and does the same when you replace the session’s MCP server list from the Agent SDK without naming them
When you move the session with /cd on v2.1.246 or later, Claude Code connects the servers of plugins the new directory’s settings enable and disconnects the servers of plugins that are no longer enabled, so you don’t need to run /reload-plugins after the move
In cloud sessions, an MCP call to a plugin server that isn’t connected yet, such as right after an idle session wakes, starts the server on demand and waits for it to connect
Path placeholders: ${CLAUDE_PLUGIN_ROOT} resolves to the plugin’s installation directory, ${CLAUDE_PLUGIN_DATA} to its persistent state directory, and ${CLAUDE_PROJECT_DIR} to the stable project root. Substitution applies to:
stdio servers: command, args, env
http, sse, and ws servers: url, headers, and headersHelper
User environment access: access to the same environment variables as manually configured servers
Multiple transport types: support for stdio, SSE, HTTP, and WebSocket transports, though transport support may vary by server
Plugin servers appear in /mcp with indicators showing they come from plugins.claude mcp get hides the values configured for a plugin’s stdio or WebSocket server, because they can carry credentials:
stdio server: it prints Command: stdio, an empty Args: line, and each environment variable as NAME=[REDACTED]
WebSocket server: it prints URL: ws and each header as <name>: [REDACTED], and claude mcp list shows ws in place of the URL
To see what the plugin configured, find the plugin on disk and read its .mcp.json or plugin.json.Plugin MCP tool names:Tools from a plugin-bundled MCP server include both the plugin name and the server key in their callable name. The full form is mcp__plugin_<plugin-name>_<server-name>__<tool-name>, where any character outside A-Z, a-z, 0-9, _, and - is replaced with _. For the database-tools server bundled in a plugin named my-plugin, a query tool is callable as:
mcp__plugin_my-plugin_database-tools__query
Use this full name when referencing the tool in permission rules, a skill’s allowed-tools list, a subagent’s tools field, or a hook matcher. A hook matcher written against the bare server key, such as mcp__database-tools__.*, never fires for a plugin-bundled server.The server itself registers under the scoped name plugin:<plugin-name>:<server-name>, such as plugin:my-plugin:database-tools. Use that name where a configured server name is expected, such as an mcp_tool hook’s server field.See the plugin components reference for details on bundling MCP servers with plugins.
MCP servers can be configured at three scopes. The scope you choose controls which projects the server loads in and whether the configuration is shared with your team. Administrators can also deploy or provide servers for every user via managed configuration.
Local scope is the default. A local-scoped server loads only in the project where you added it and stays private to you. Claude Code stores it in ~/.claude.json under that project’s path, so the same server won’t appear in your other projects. Use local scope for personal development servers, experimental configurations, or servers with credentials you don’t want in version control.
The term “local scope” for MCP servers differs from general local settings. MCP local-scoped servers are stored in ~/.claude.json (your home directory), while general local settings use .claude/settings.local.json (in the project directory). See Settings for details on settings file locations.
# Add a local-scoped server (default)claude mcp add --transport http stripe https://mcp.stripe.com# Explicitly specify local scopeclaude mcp add --transport http stripe --scope local https://mcp.stripe.com
The command writes the server into the entry for your current project inside ~/.claude.json. The example below shows the result when you run it from /path/to/your/project:
Project-scoped servers enable team collaboration by storing configurations in a .mcp.json file at your project’s root directory. When you add a project-scoped server, Claude Code automatically creates or updates this file with the appropriate configuration structure. Check .mcp.json into version control so everyone on your team gets the same MCP tools and services.
For security reasons, Claude Code prompts for approval in interactive sessions before using project-scoped servers from .mcp.json files. To reset those approval choices, run claude mcp reset-project-choices.In claude -p runs, Agent SDK sessions, and cloud sessions outside a project’s threads, Claude Code can’t show that prompt: it loads project-scoped servers without asking. Claude Code also skips the prompt in a session you start in bypassPermissions mode with skipDangerousModePermissionPrompt set in your user settings or in managed settings. To keep a server out anyway:
Exclude project settings entirely with --setting-sources or the SDK’s settingSources option.
Start the session with --strict-mcp-config. Claude Code then uses only the MCP servers you pass with --mcp-config. Skipping the approval prompt for the project-scoped servers Claude Code isn’t loading requires Claude Code v2.1.246 or later; before v2.1.246, a strict session still waited on approval for them, which left background sessions waiting at startup. See Exclusive control with managed-mcp.json for what the flag does under a managed MCP file.
User-scoped servers are stored in ~/.claude.json and provide cross-project accessibility, making them available across all projects on your machine while remaining private to your user account. This scope works well for personal utility servers, development tools, or services you frequently use across different projects.
# Add a user serverclaude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic
When the same server is defined in more than one place, Claude Code connects to it once, using the definition from the highest-precedence source. The entire server entry from that source is used; fields are not merged across scopes.
Claude Code matches duplicates across the three scopes by name. It matches plugins and connectors by endpoint, so one that points at the same URL or command as an enabled server above counts as a duplicate.Two URL spellings count as the same endpoint when they differ only in the letter case of the scheme or host, the scheme’s default port, such as :443 on https, or a trailing slash. A different path, query string, userinfo, or non-default port makes two servers.A server your organization provides through the managedMcpServers managed setting ranks above all of these, so when one of them duplicates it, Claude Code connects the organization’s definition. Requires Claude Code v2.1.259 or later.If you open a local session in the Desktop app’s Code tab with the same stdio server name at the top level of ~/.claude.json (user scope) and in .mcp.json, the Code tab uses the ~/.claude.json definition.
Claude Code supports environment variable expansion in .mcp.json files, allowing teams to share configurations while maintaining flexibility for machine-specific paths and sensitive values like API keys.You can reference an environment variable in a server’s command, args, env, url, or headers value, in either of two forms:
${VAR}: expands to the value of environment variable VAR
${VAR:-default}: expands to the value of VAR if VAR is set, or to default if it is unset
In this server entry, the URL is the value of API_BASE_URL followed by /mcp, with https://api.example.com as the default, and the API key comes from API_KEY:
If a referenced environment variable isn’t set and has no default value, the config still loads: Claude Code reports a missing-variable warning for that server in claude mcp list output and uses the unexpanded ${VAR} text as-is. Set the variable or add a :-default fallback so the server starts with the value you intend. In a remote server’s url and headers, some credential variables read as empty instead, with no warning.
If you set a variable to an empty string, it counts as set, so a ${VAR:-default} reference expands to the empty string rather than to default. With the example server, if you set API_BASE_URL to an empty string, its url becomes /mcp and claude mcp list reports 'url' is not a valid URL. To use the default, unset the variable rather than setting it to an empty string.
In a remote server’s url and headers, Claude Code reads credential variables from your environment as empty rather than expanding them. This keeps a project’s .mcp.json or a plugin from sending your Claude Code or cloud provider credentials to a server it names. If you write Bearer ${ANTHROPIC_AUTH_TOKEN}, the server receives Bearer with no credential and rejects the request, usually with a 401. Claude Code reports that as a failed connection.The covered names are:
Claude Code’s own credentials, such as ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN
Your cloud provider’s credentials, such as AWS_BEARER_TOKEN_BEDROCK
Other credentials your environment carries, such as HTTPS_PROXY and NPM_TOKEN
A covered name reads as empty whether or not you have set the variable, and a :-default fallback on it is ignored. A provider base URL such as ANTHROPIC_BASE_URL still expands, so "url": "${ANTHROPIC_BASE_URL}/mcp" works, unless the URL’s value itself embeds a credential such as a username and password.A name outside this set, such as API_KEY, expands as written. To give the server one of the covered credentials, copy it into a variable with a name of your own and reference that name instead.When a remote server’s url or headers references a covered variable you have set, Claude Code names it in a debug-log line. To read the line, run claude --debug-file /tmp/claude-debug.log and search that file for never expanded toward a remote server.
For a server in the local, project, or user scope, the following surfaces show a ${VAR} reference by name rather than as its resolved value:
The URL or command line in a server’s /mcp detail view
claude mcp list and claude mcp get output
The /mcp detail view shows references this way in Claude Code v2.1.268 or later.For a server your organization provides through the managedMcpServers setting, these surfaces show the URL’s host only.To check what claude mcp list, claude mcp get, and /mcp show when a connection fails, see Server status detail.
GitHub’s remote MCP server authenticates with a GitHub personal access token passed as a header. To get one, open your GitHub token settings, generate a new fine-grained token with access to the repositories you want Claude to work with, then add the server:
Replace YOUR_GITHUB_PAT with your personal access token. The claude mcp add command saves the configuration without validating credentials, so a placeholder value is accepted here but the server fails to connect later. To verify the connection, run /mcp and check that the server’s row shows a checkmark. A server with bad credentials shows an ✘ instead, and its failure detail includes the HTTP status the server returned, such as a 401.Then work with GitHub:
DBHub, the @bytebase/dbhub package, is an MCP server that connects Claude to a relational database through the connection string you pass in --dsn. Use a read-only database user in the connection string so the queries Claude runs can’t modify data:
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \ --dsn "postgresql://readonly:pass@prod.db.com:5432/analytics"
To confirm the server starts, run /mcp and check that the db row shows a checkmark.Then query your database naturally:
What's our total revenue this month?
Show me the schema for the orders table
Find customers who haven't made a purchase in 90 days
Many cloud-based MCP servers require authentication. Claude Code supports OAuth 2.0 for secure connections.Claude Code marks a remote server as needing authentication when the server responds with 401 Unauthorized or 403 Forbidden. What Claude Code shows depends on the server:
For a server you haven’t signed in to, either status code flags it in /mcp so you can complete the OAuth flow.
For a claude.ai connector, a 401 caused by claude.ai rejecting your session token doesn’t flag the connector, because re-authorizing the connector can’t fix your login. Claude Code shows the session-token-rejected state instead.
For a server whose Authorization header you configured, in headers or through a headersHelper, a 401 or 403 while connecting doesn’t flag the server, because the credential to fix is the one you configured. Claude Code reports the connection as failed instead. If you set that header from a ${VAR} reference, check whether that variable is one Claude Code reads as empty.
For a connector delivered to a cloud session, Claude Code doesn’t run a sign-in flow, because the session’s proxy authenticates to the connector with the authorization you granted in claude.ai. When a connector there needs authorizing again, reconnect it at claude.ai/customize/connectors rather than from the session.
When an OAuth server you already signed in to rejects your stored token with 401 Unauthorized, Claude Code refreshes the token, reconnects, and retries the request once. It flags the server in /mcp only if that retry also fails. In a claude -p or Agent SDK run on macOS, a request that Claude Code sent while it couldn’t read your stored token fails with a stored-credentials error instead.When the server rejects the stored refresh token, Claude Code immediately shows a notice pointing at /mcp. Open /mcp and select Re-authenticate on the server to sign in again before the next tool call fails.A custom server that returns a WWW-Authenticate header pointing to its authorization server gets the same automatic discovery as any other remote server.Claude Code also shows a startup notice when one or more configured servers need authentication, so you don’t have to open /mcp to discover which servers need sign-in. The notice counts only servers you can sign in to from Claude Code. Before v2.1.218, it also counted claude.ai connectors that weren’t connected in claude.ai, which you can connect only from claude.ai settings.The notice announces each server once and leaves it out of the count at later launches until that server has connected and needs sign-in again. /mcp still lists every server that needs sign-in.A claude -p or Agent SDK run has no /mcp panel, so Claude Code can’t run the OAuth flow there. To use a server that needs authentication, complete the sign-in from an interactive session first: run /mcp in the session, or claude mcp login <name> in your shell. When a configured server needs authentication during a claude -p or Agent SDK run with tool search enabled, Claude Code tells Claude that the server’s tools are unavailable until you authorize it.If you configured headers.Authorization for the server and the server rejects that header, Claude Code reports the connection as failed instead of falling back to OAuth. Check that the token is valid for the MCP endpoint, or remove the header to use the OAuth flow.
1
Add the server that requires authentication
If you already added the sentry server in the MCP quickstart, skip this step: running claude mcp add again with the same server name at the same scope fails with MCP server sentry already exists in local config. Otherwise, run:
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
2
Use the /mcp command within Claude Code
In Claude Code, use the command:
/mcp
Then follow the steps in your browser to log in.
Tips:
Authentication tokens are stored securely and refreshed automatically
Use “Clear authentication” in the /mcp menu to revoke access
If your browser doesn’t open automatically, copy the provided URL and open it manually
If the browser redirect fails with a connection error after authenticating, paste the full callback URL from your browser’s address bar into the URL prompt that appears in Claude Code
The claude mcp login <name> command runs a configured server’s OAuth flow directly from your shell, so you don’t need to open the /mcp panel inside a session. For a claude.ai connector, follow Authorize a connector again from your shell.
claude mcp login sentry
To clear stored credentials later, run claude mcp logout <name>.claude mcp login detects when no local browser is available, such as during an SSH session or on Linux without a display server, and prints the authorization URL instead of trying to open a browser. Open the URL on your local machine, then paste the full redirect URL from your browser’s address bar back at the prompt. The command needs an interactive terminal for the paste step, so connect with ssh -t. Pass --no-browser to force the URL prompt even when a local browser is detected.
Some MCP servers require a specific redirect URI registered in advance. By default, Claude Code picks a random available port for the OAuth callback. Use --callback-port to fix the port so it matches a pre-registered redirect URI of the form http://localhost:PORT/callback. If sign-in on Claude Code v2.1.229 fails with a redirect URI mismatch, see the version note under Use pre-configured OAuth credentials.You can use --callback-port on its own (with dynamic client registration) or together with --client-id (with pre-configured credentials).
# Fixed callback port with dynamic client registrationclaude mcp add --transport http \ --callback-port 8080 \ my-server https://mcp.example.com/mcp
Some MCP servers don’t support automatic OAuth setup via Dynamic Client Registration. If you see an error like “Incompatible auth server: does not support dynamic client registration,” the server requires pre-configured credentials. Claude Code also supports servers that use a Client ID Metadata Document (CIMD) instead of Dynamic Client Registration, and discovers these automatically. If automatic discovery fails, register an OAuth app through the server’s developer portal first, then provide the credentials when adding the server.
1
Register an OAuth app with the server
Create an app through the server’s developer portal and note your client ID and client secret.If the registration form asks for a redirect URI, pick any available port and enter http://localhost:PORT/callback with that port. You’ll use the same port in the next step.In v2.1.229, Claude Code sent http://127.0.0.1:PORT/callback instead, and servers that exact-match the registered redirect URI rejected the sign-in with a redirect URI mismatch. Claude Code v2.1.231 restored the localhost form. To recover on v2.1.229, upgrade Claude Code, or temporarily add the http://127.0.0.1:PORT/callback form to the server’s registered redirect URIs.
2
Add the server with your credentials
The tabs cover both commands: claude mcp add takes your client ID and callback port as flags, and claude mcp add-json takes them in an oauth object. If you registered a redirect URI, set the callback port to the port in that URI.
claude mcp add
claude mcp add-json
claude mcp add-json (callback port only)
CI / env var
Use --client-id to pass your app’s client ID. The --client-secret flag prompts for the secret with masked input:
Run /mcp in Claude Code and follow the browser login flow.
Tips:
The client secret is stored securely in your system keychain (macOS) or a credentials file, not in your config
You can set the client secret only when you add the server. When you authenticate with claude mcp login or from /mcp, Claude Code uses the stored secret and doesn’t prompt for one or read MCP_CLIENT_SECRET
To add or change the secret later, remove the server with claude mcp remove <name>, then add it again with --client-secret and the same --scope
If the server uses a public OAuth client with no secret, use only --client-id without --client-secret
These flags only apply to HTTP and SSE transports. They have no effect on stdio servers
Use claude mcp get <name> to verify that OAuth credentials are configured for a server
Point Claude Code at a specific OAuth authorization server metadata URL to bypass the default discovery chain. Set authServerMetadataUrl when the MCP server’s standard endpoints error, or when you want to route discovery through an internal proxy. By default, Claude Code first checks RFC 9728 Protected Resource Metadata at /.well-known/oauth-protected-resource, then falls back to RFC 8414 authorization server metadata at /.well-known/oauth-authorization-server.Set authServerMetadataUrl in the oauth object of your server’s config in .mcp.json:
Set oauth.scopes to pin the scopes Claude Code requests during the authorization flow. This is the supported way to restrict an MCP server to a security-team-approved subset when the upstream authorization server advertises more scopes than you want to grant. The value is a single space-separated string, matching the scope parameter format in RFC 6749 §3.3.
oauth.scopes takes precedence over both authServerMetadataUrl and the scopes the server discovers at /.well-known. Leave it unset to let the MCP server determine the requested scope set.When oauth.scopes isn’t set, Claude Code doesn’t request the full scopes_supported catalog from automatically discovered authorization server metadata. Metadata fetched from a configured authServerMetadataUrl still supplies its scopes_supported as the requested scopes.If the authorization server advertises offline_access in scopes_supported, Claude Code appends it to the pinned scopes so the access token can be refreshed without a new browser sign-in.If the server later returns a 403 insufficient_scope for a tool call, the call fails with a needs additional permissions message that names the scope the server asks for. The server shows as needing authentication in /mcp.If that scope isn’t in your pinned oauth.scopes, add it, then run /mcp and authenticate the server again. Claude Code requests the pinned scopes rather than the scope the server named, so if you authenticate again without adding it, the token you get still lacks it.
Use OAuth with a server behind an authenticating proxy
If your MCP server uses OAuth behind a proxy or gateway that checks a header of its own, sign-in fails when the OAuth requests arrive without that header. Signing in through the proxy requires Claude Code v2.1.299 or later, with the header and the sign-in both configured:
The proxy’s header: pass it with --header, the headers field, or a headersHelper, under the name the proxy reads
The OAuth sign-in: keep Authorization out of the configured headers, then sign in with claude mcp login <name> in your shell. If you configure an Authorization header, Claude Code uses it as the server’s credential and doesn’t fall back to OAuth for that server.
When authentication such as Kerberos, short-lived tokens, or internal SSO needs headers generated at connection time, set the server’s headersHelper to a command. Claude Code runs it when connecting and merges its output into the headers it sends. This example uses a script:
The command must write a JSON object of string key-value pairs to stdout
Claude Code runs the command in a shell and gives up on it after 10 seconds
Claude Code picks the command’s working directory by where you configured the server, so give the script as an absolute path or put it on PATH
Dynamic headers override any static headers with the same name
Claude Code runs the helper fresh on each connection, at session start and on reconnect, once the trust rule for project and local-scope servers lets it run. It doesn’t cache the result, so your script is responsible for any token reuse.If a tool call returns 401 Unauthorized or 403 Forbidden, Claude Code automatically re-runs the helper under the same rule, reconnects with the fresh headers, and retries the call once. Claude Code marks the server as needing authentication in /mcp only if that retry also fails.When the helper’s output includes an Authorization header, Claude Code uses that credential as the server’s authentication and doesn’t fall back to OAuth for the server.If the server rejects the helper’s credential while connecting, Claude Code reports the connection as failed rather than marking the server as needing authentication. Fix the credential your helper returns, then reconnect from /mcp to re-run the helper.Claude Code sets these environment variables when executing the helper:
Variable
Value
CLAUDE_CODE_MCP_SERVER_NAME
the name of the MCP server
CLAUDE_CODE_MCP_SERVER_URL
the URL of the MCP server
CLAUDE_PLUGIN_ROOT
the plugin’s root directory. Set only when a plugin provides the server
Use these to write a single helper script that serves multiple MCP servers.A plugin-provided headersHelper can’t reference the plugin’s ${user_config.*} values, because the command runs through a shell. Claude Code reports the server as misconfigured with an error and doesn’t substitute the value. Put ${user_config.KEY} in the server’s headers field instead, which isn’t shell-parsed, or have the helper script read the value from a config file. Before v2.1.207, headersHelper substituted ${user_config.*} values.
Claude Code picks the headersHelper command’s working directory from the configuration that declares the server. A cd that Claude runs in Bash doesn’t move it, and /cd moves it only for servers that run from the session’s primary working directory. Each row below gives the directory that a relative path in your headersHelper command resolves against.
Your configuration directory, ~/.claude unless you set CLAUDE_CONFIG_DIR
Before v2.1.238, Claude Code also ran the helpers of user-scope, managed, and claude.ai connector servers, and of agent files from outside your project, from the directory you started it in.
A headersHelper that a repository or plugin supplies is a command you didn’t write, so Claude Code runs it without the credential variables from your environment, such as ANTHROPIC_API_KEY. Where you configured the server decides whether this applies:
Removed: a server in a project .mcp.json or in a plugin, and an inline server in an agent file from your project or from an --add-dir directory
Not removed: a server at user or local scope, in managed MCP, from a claude.ai connector, or supplied by the SDK or --mcp-config, and an inline server in an agent file from ~/.claude/agents/, from managed settings, or passed with --agents
Apart from Git’s GIT_CONFIG_KEY_<n> variables, Claude Code removes every variable from your environment whose name looks like a credential, such as a name with TOKEN, SECRET, PASSWORD, KEY, or AUTH in it in either letter case, so ANTHROPIC_API_KEY and MY_REGISTRY_TOKEN are both removed. Claude Code also removes a fixed list of credential variables whose names don’t follow that pattern, such as ANTHROPIC_CUSTOM_HEADERS.When this applies to your helper, have the script read its credential from a file or a credential store. If the server’s urlcarries the live value of one of these variables, such as MY_REGISTRY_TOKEN, the CLAUDE_CODE_MCP_SERVER_URL value the helper receives has that part replaced with REDACTED as well.
Claude Code executes a headersHelper as an arbitrary shell command. For a server in a project .mcp.json or at local scope, it runs the helper only after you accept the trust dialog for the project directory the server is declared in. Before v2.1.238, a claude -p or SDK session ran these helpers without checking trust, and an interactive session ran them once you had trusted a parent folder.
Trust that doesn’t count: a parent folder’s trust, and the automatic trust a claude -p or SDK session gets for hooks in settings files
Until you trust the folder: Claude Code connects the server with its static headers alone. In a claude -p or SDK session it also prints one headersHelper not run line per server to stderr, telling you how to grant the trust.
Trust without a dialog: set projects["<path>"].hasTrustDialogAccepted to true in ~/.claude.json. <path> is the folder Project allow rules and workspace trust says Claude Code keys the trust on.
Claude Code applies the same rule to a server declared inline in an agent file, checking where that agent file came from: your project, for a file in its .claude/agents/ directory, or an --add-dir directory. Until you trust that project or directory itself, Claude Code doesn’t load the server at all, so its helper never runs either.
Sign in to an MCP server behind a gateway that requires a header
OAuth sign-in to an MCP server fails when a gateway requires a header, such as X-API-Key, and Claude Code doesn’t send it. To have Claude Code send that header, add it to the server’s configuration and use Claude Code v2.1.299 or later:
A server that managed MCP or a plugin supplies: ask your administrator or the plugin’s author to add the header to the server’s entry
Claude Code then adds the configured headers except Authorization to the sign-in, token refresh, and token revocation requests it sends to the server’s origin. The server’s origin is the scheme, host, and port in its url. A gateway that requires the header can still stop sign-in at the authorization page or at an authorization server on another origin:
The authorization page: you sign in on this page in your browser, which doesn’t send the configured headers. If your browser gets the gateway’s error instead of the page, ask whoever runs the gateway to let the page through without the header.
An authorization server on another origin: if a gateway in front of that server requires the header too, sign-in fails there. Ask whoever runs that gateway to let OAuth requests through without the header.
If you’ve already configured MCP servers in Claude Desktop, you can import them:
1
Import servers from Claude Desktop
# Basic syntaxclaude mcp add-from-claude-desktop
2
Select which servers to import
After running the command, you’ll see an interactive dialog that allows you to select which servers you want to import.
3
Verify the servers were imported
claude mcp list
Server names added through claude mcp commands can contain only letters, numbers, hyphens, and underscores. Claude Desktop doesn’t apply that restriction, so a Claude Desktop server whose name contains any other character, such as a space, can’t be imported. The import reports each name it rejects and still imports the other servers you selected.
Tips:
This feature only works on macOS and Windows Subsystem for Linux (WSL)
It reads the Claude Desktop configuration file from its standard location on those platforms
Use the --scope user flag to add servers to your user configuration
Imported servers keep the same names as in Claude Desktop when the name contains only letters, numbers, hyphens, and underscores. Claude Code reports a server whose name contains any other character and skips it
If servers with the same names already exist, they get a numerical suffix (for example, server_1)
If you’ve logged into Claude Code with a claude.ai account, MCP servers you’ve added in claude.ai, known as connectors, are automatically available in Claude Code:
Complete any required authentication steps in claude.ai.
3
View and manage servers in Claude Code
In Claude Code, use the command:
/mcp
Servers from claude.ai appear in the list with indicators showing they come from claude.ai.
Anthropic also provides some connectors itself, without you or an admin adding them. On accounts where Claude Docs is available, /mcp lists claude.ai Claude Docs with no setup, and Claude uses it when you ask for a document meant for other people. To turn off only this connector, see Disable claude.ai connectors.Claude Code marks a connector managed in /mcp and in the /plugin manager when your organization manages its authentication in claude.ai. Managed status doesn’t change how Claude Code connects to the connector or applies your organization’s tool controls.Connectors you have never signed in to are collapsed behind a Show unused connectors row at the end of the claude.ai section, so an organization-provisioned list doesn’t fill the panel. Select the row to expand them. A connector you signed in to before stays visible even when it currently needs re-authentication.Connectors from claude.ai are fetched only when your active authentication method is a claude.ai subscription login. They aren’t loaded, even if you previously ran /login, when:
ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or apiKeyHelper is active
A third-party provider such as Amazon Bedrock or Google Cloud’s Agent Platform is active
ANTHROPIC_PROFILE, the federation variables, or an active Anthropic profile supplies the credential
CLAUDE_CODE_OAUTH_TOKEN holds a token from claude setup-token, which can only make model requests
If /mcp doesn’t list a connector you added, run /status to confirm which authentication method is active. Unset that environment variable, remove the apiKeyHelper setting, or switch off the profile, then run /login to select your claude.ai account.If a temporary network problem keeps the connector list from loading when your session starts, Claude Code retries the fetch up to three times in the background, and the connectors appear once a retry succeeds. If they still haven’t appeared, restart Claude Code to fetch the list again.If /mcp shows a connector as session token rejected, or its detail view shows claude.ai rejected the session token, claude.ai rejected the token from your Claude Code login. Authorizing the connector again doesn’t clear this state, because the connector’s own authorization in claude.ai isn’t what was rejected. To clear it:
Run /login to sign in again.
Reconnect the connector from /mcp.
Before v2.1.222, Claude Code marked connectors as needing authentication instead, and authorizing them didn’t resolve it.A server you’ve added in Claude Code takes precedence over a claude.ai connector that points at the same URL. When this happens, /mcp lists the connector as hidden and shows how to remove the duplicate if you’d rather use the connector.Some Anthropic-hosted connectors, such as Microsoft 365, Gmail, and Google Calendar, don’t support local OAuth from Claude Code because the upstream identity provider only accepts the redirect URL that claude.ai registered. When a server you added with claude mcp add or in .mcp.json points at one of these hosts and you sign in to it from /mcp or with claude mcp login, Claude Code shows is Anthropic-hosted and doesn't support local OAuth, directing you to connect the service at claude.ai/customize/connectors instead.After you remove your entry with claude mcp remove <name> and connect the service on claude.ai, the connector appears in Claude Code automatically.
Which settings govern a claude.ai connector depends on where your session runs, because only some sessions fetch connectors from claude.ai themselves. Each row below names how connectors arrive in one kind of session and what controls them there. The desktop app’s WSL sessions have no row because connectors are still rolling out to them.
Your claude.ai organization settings, plus the allowlist and denylist settings that reach the session and any managed-mcp.json on the host that runs it
disableClaudeAiConnectors, ENABLE_CLAUDEAI_MCP_SERVERS, and allowAllClaudeAiMcps act only on the first row, the connectors Claude Code fetches itself. The other two rows differ from it in these ways:
Cloud sessions: allowedMcpServers and deniedMcpServers entries that reach the session, for example through server-managed settings, filter the delivered connectors too. The session’s proxy rewrites each connector’s URL, so a serverUrl pattern written for the connector’s own URL doesn’t match it. To admit delivered connectors alongside a URL allowlist in a self-hosted environment, add the serverUrl entries listed under Connector traffic leaves your network. Claude Code drops the delivered connectors when a managed-mcp.json is present on the host that runs the session, such as a self-hosted runner host, whether or not you set allowAllClaudeAiMcps.
Desktop app local and SSH sessions: the desktop app registers the connectors as in-process type: "sdk" servers, and no MCP setting or managed-mcp.json reaches them. A user keeps a connector out of their own sessions by disconnecting it at claude.ai/customize/connectors. An organization blocks a connector’s tools or turns off Claude Code in the desktop app entirely.
Your organization can set per-tool controls on claude.ai connectors. Claude Code reads these settings at startup and enforces them locally, except in the desktop app’s local and SSH sessions. There, the desktop app withholds blocked tools before it delivers a connector, and the ask setting doesn’t reach Claude Code, so it applies the session’s ordinary permission rules to those tools instead of prompting on every call. In sessions where Claude Code fetches connectors itself, run /mcp to see which setting applies to each tool on a connector.
Tool set to ask: Claude Code prompts on every call with the reason Your organization requires approval for this tool. The prompt appears even in acceptEdits, auto, and bypassPermissionspermission modes. In the terminal, the prompt has no option to remember your choice. Allow rules that match the tool don’t skip the prompt either. In dontAsk mode, which never prompts, Claude Code denies the call instead.
Tool set to blocked: Claude Code filters the tool out before Claude sees it, so it never appears in Claude’s tool list. In sessions where Claude Code fetches connectors itself, the /mcp tool list still shows the tool, marked disabled by your organization.
The desktop app and claude.ai chat apply the same blocked setting, so Claude can’t use a blocked tool there either, and you can’t withhold a tool from the desktop app’s sessions while keeping it available in chat. The desktop app skips a connector whose tools are all blocked.
Claude Code applies disableClaudeAiConnectors only to the connectors it fetches itself, not to the connectors a cloud host or the desktop app delivers. To turn off the connectors it fetches, set the setting to true in any settings scope:
{ "disableClaudeAiConnectors": true}
This setting uses any-source-true semantics: true in any settings source takes precedence. A checked-in project .claude/settings.json can opt a repository out of the connectors Claude Code fetches itself, but a project-level false can’t re-enable connectors that a user- or policy-level true has disabled. Servers passed explicitly via --mcp-config are unaffected.You can also set the ENABLE_CLAUDEAI_MCP_SERVERS environment variable to false, which has the same effect for the current shell session:
ENABLE_CLAUDEAI_MCP_SERVERS=false claude
To block individual claude.ai connectors instead of all of them, add them to deniedMcpServers by name or by URL pattern. For example, a serverName entry of "claude.ai Slack" blocks the Slack connector. You can also run /mcp to toggle any connector Claude Code fetches on or off for the current project only.
You can use Claude Code itself as an MCP server that other applications can connect to:
# Start Claude as a stdio MCP serverclaude mcp serve
The command prints nothing when it starts. A stdio MCP server communicates over stdin and stdout, so a silent, blocked terminal means the server is running and waiting for a client to connect.You can use this in Claude Desktop by adding this configuration to claude_desktop_config.json:
Configuring the executable path: the command field must reference the Claude Code executable. If the claude command is not in your system’s PATH, you’ll need to specify the full path to the executable.To find the full path:
Without the correct executable path, you’ll encounter errors like spawn claude ENOENT.
Tips:
In Claude Desktop, try asking Claude to read files in a directory, make edits, and more.
This MCP server only exposes Claude Code’s tools to your MCP client, so your own client is responsible for implementing user confirmation for individual tool calls.
Read a background command’s output as an MCP client
A backgroundOutputPath field in a Bash or PowerShell result from claude mcp serve means the call left its command running in the background. A command runs in the background when your client sets run_in_background: true on the call. A foreground command can also move to the background when it reaches its timeout.The field is in the result’s JSON text and holds the path of the command’s output file.
To read the output so far: open the file at that path from your client, or pass the path as file_path to the server’s Read tool
To tell when the command has finished: append an echo of a fixed string to the command value, as in npm test; echo DONE. The command has finished once that string appears in the file. Without the string, nothing marks the end, because Claude Code adds no closing line to the file and doesn’t notify your client.
To read the end of long output: Read with only file_path returns the first page, or fails when the file exceeds the size limit. Pass offset and limit as well, which works at any file size:
Call Read with offset and limit both set to 1, and take totalLines from the result
Call Read again with offset set to totalLines minus nine and limit set to 10
Look for your echo string in the last ten lines, which the second call returns
The backgroundOutputPath field requires Claude Code v2.1.295 or later.
When MCP tools produce large outputs, Claude Code helps manage the token usage to prevent overwhelming your conversation context:
Output warning threshold: Claude Code displays a warning when any MCP tool output exceeds 10,000 tokens
Configurable limit: you can adjust the maximum allowed MCP output tokens using the MAX_MCP_OUTPUT_TOKENS environment variable
Default limit: the default maximum is 25,000 tokens
Scope: the environment variable applies to tools that don’t declare their own limit. Tools that set anthropic/maxResultSizeChars use that value instead for text content, regardless of what MAX_MCP_OUTPUT_TOKENS is set to. Tools that return image data are still subject to MAX_MCP_OUTPUT_TOKENS
Over the limit: when a successful result with no image content exceeds the token limit, Claude Code saves it to a file and replaces it in the conversation with a message that names the file path, so Claude reads the file when it needs the content. The file goes in the session’s tool-results directory under ~/.claude/projects/.
Response size from HTTP and SSE servers: when a response from an HTTP or SSE server passes 16 MiB, Claude Code stops reading it and the request fails. The limit applies after decompression to one JSON response body or one event of an event stream. If you maintain the server, return less data per response to stay under the limit, for example by paginating results
Message size from WebSocket servers: when a WebSocket server sends one message over 16 MiB, Claude Code closes the connection, and calls in progress on that server fail. If you maintain the server, return less data per message to stay under the limit
A call that Claude Code has moved to a background task reports its result through the task notification. Two more limits apply to a call that completes in the foreground:
Character limit for text results: for a tool that doesn’t declare anthropic/maxResultSizeChars, Claude Code saves a successful result with no image content to a file once it’s longer than 50,000 characters, whatever its token count. Setting MAX_MCP_OUTPUT_TOKENS doesn’t change this threshold
Error results: when a tool returns a result marked isError: true, Claude receives the result’s text as the tool’s error message. Error text longer than about 11,000 characters keeps only its first 5,000 and last 5,000 characters, with a marker between them that says how many characters were removed
To change the token limit, set MAX_MCP_OUTPUT_TOKENS in your shell before starting Claude Code:
If you’re building an MCP server, you can allow individual tools to return results larger than the default persist-to-disk threshold of 50,000 characters by setting _meta["anthropic/maxResultSizeChars"] in the tool’s tools/list response entry. Claude Code raises that tool’s threshold to the annotated value, up to a hard ceiling of 500,000 characters.This is useful for tools that return inherently large but necessary outputs, such as database schemas or full file trees. Without the annotation, successful results that exceed the default threshold are persisted to disk and replaced with a file reference in the conversation.
{ "name": "get_schema", "description": "Returns the full database schema", "_meta": { "anthropic/maxResultSizeChars": 200000 }}
The annotation applies independently of MAX_MCP_OUTPUT_TOKENS for text content, so users don’t need to raise the environment variable for tools that declare it. Tools that return image data are still subject to the token limit.
When an MCP tool returns a PNG, JPEG, GIF, or WebP image, Claude sees the image inline in the conversation. The inline copy may be scaled down or compressed to fit the model’s image size limits. Claude Code also saves the original bytes to a file in the session’s tool-results directory under ~/.claude/projects/ and gives Claude the path. Claude can then crop, convert, or reuse the full-resolution file with tools such as Bash.If you disable session persistence with --no-session-persistence or CLAUDE_CODE_SKIP_PROMPT_HISTORY, Claude Code writes no image file and Claude receives only the inline copy.Saving MCP image results to a file requires Claude Code v2.1.283 or later.
Some MCP servers declare a tool’s input schema as a JSON Schema union, with anyOf, oneOf, or allOf at the top level of the schema. The Claude API doesn’t accept those keywords at the schema root. It does accept combinators nested inside properties, which Claude Code sends unchanged.Tools with a root-level combinator stay available. Before sending the tool to the API, Claude Code flattens the schema into a single object and prepends a sentence to the tool’s description that tells Claude which parameter groups belong together:
allOf: properties from every branch are merged, and each branch’s required list still applies
anyOf and oneOf: properties from every branch are merged, and each branch’s required list is described in the tool description instead of enforced by the schema
Your server receives whichever arguments Claude chose, so keep validating the combination server-side.When Claude Code can’t produce a schema the API accepts, or on a deployment that doesn’t receive the remote configuration that enables the rewrite, it skips that one tool, records the reason in the server’s log, and leaves the server’s other tools available.
If your session fails with a 400 error that names a tool by its position, follow the steps in Tool input schema is invalid.
If one of your MCP server’s tools has an input schema that breaks either of two rules the API enforces, Claude Code excludes that tool. The server’s other tools are unaffected. Claude Code checks both rules as it loads the server’s tools:
Top-level property names must be 1 to 64 characters long and use only ASCII letters and digits, _, ., and -
The schema must be valid against the JSON Schema draft 2020-12 meta-schema. Claude Code applies this check to schemas that declare no $schema and schemas that declare draft 2020-12. A schema that declares any other dialect skips this check, though the property-name check above still applies
When Claude Code excludes a tool, it records the reason in the server’s log and tells Claude which tools it excluded and why, so you can ask Claude why a tool is missing. If you fix the schema on the server, the tool comes back the next time Claude Code loads the server’s tools.When feature flag fetching is off or the flags have never arrived, as on an air-gapped machine, a tool that breaks a rule isn’t excluded:
Claude gets the tool unchanged, and the server’s log records input schema would be rejected by the Anthropic API for it
Before v2.1.216, no deployment ran these checks.The root-level combinator handling is separate and keeps its own behavior when flag fetching is off or the flags have never arrived.
If a line in the debug log contains the API refused this tool's input schema, it names a tool whose schema the API rejected in a request. Claude Code resends that request with the tool declared without parameters.
If your session fails with a 400 error that names a tool by its position: follow the steps in Tool input schema is invalid
If you use the server: you don’t need to do anything. Claude can still call the tool, but doesn’t see its parameters
If you maintain the server: fix the tool’s input schema on the server. The log line ends with The API said: and the API’s reason for rejecting the schema. Validate the arguments the server receives, because Claude calls the tool without seeing its parameters
If /mcp lists a tool that Claude can’t call, check whether the tool’s full name is longer than 128 characters. Run /mcp in your session and select the tool to see its full name, such as mcp__<server>__<tool>. Claude Code leaves an MCP tool out of the tools it sends to Claude when its full name is over 128 characters. The Claude API rejects a request that includes such a tool, so leaving the tool out keeps the server’s other tools working.For the message that names the tool and the ways to shorten its full name, see MCP tool name over 128 characters.
If you’re building an MCP server, you can mark a tool as requiring explicit approval on every call by setting _meta["anthropic/requiresUserInteraction"] to true in the tool’s tools/list response entry. The value must be the JSON Boolean true; any other value is ignored.Claude Code shows that tool’s permission prompt on every call, even in acceptEdits, auto, and bypassPermissionspermission modes, and doesn’t offer a “don’t ask again” option for it. Allow rules that match the tool don’t skip the prompt either. In dontAsk mode, which never prompts, Claude Code denies the call instead.The prompt has to reach a person. In non-interactive mode with --permission-prompt-tool, an allow result from the prompt tool for a flagged tool is converted to a deny with the message MCP tool requires user interaction; not supported via --permission-prompt-tool. The Agent SDK’s canUseTool callback does receive these calls and can approve them, because your SDK application is expected to show them to a user.Use this for tools whose permission prompt is itself the point, such as a consent or access-grant step where auto-approval would mean no human ever agreed. Other tools from the same server keep their normal permission behavior.The following tools/list entry marks one tool as always requiring approval.
{ "name": "grant_access", "description": "Requests access to a protected resource", "_meta": { "anthropic/requiresUserInteraction": true }}
Some surfaces, such as Remote Control and applications built on the Agent SDK, normally let you approve tool calls with one tap. For a tool marked with this annotation, Claude Code withholds the one-tap action and shows the tool’s full permission prompt instead, so approval still comes from a person answering the prompt rather than a tap.Claude Code withholds one-tap approval the same way for any permission request that only the terminal dialog can render in full, such as one that carries a safety warning or an always-allow option the remote surface can’t show. You answer that request in the terminal dialog rather than from Remote Control.
If you build an MCP server, mark the tools that are safe to call twice so Claude Code can repeat a call that was pending when a connection closed. Claude Code can repeat such a call to an HTTP server or a claude.ai connector once, on a new connection. A call Claude Code doesn’t repeat can fail with connection closed before the tool call was answered.To mark a tool, set one of these annotations to true in its tools/list entry:
idempotentHint: the tool can change something, and calling it again with the same arguments is safe
readOnlyHint: the tool changes nothing. Claude Code also runs the tool’s calls in parallel with other read-only calls.
For example, these fields in a tools/list entry mark the set_issue_status tool as safe to repeat:
MCP servers can request structured input from you mid-task using elicitation. When a server needs information it can’t get on its own, Claude Code displays an interactive dialog and passes your response back to the server. No configuration is required on your side: elicitation dialogs appear automatically when a server requests them.Servers can request input in two ways:
Form mode: Claude Code shows a dialog with form fields defined by the server (for example, a username and password prompt). Fill in the fields and submit.
URL mode: Claude Code asks whether to open a link in your browser. Servers use this mode for a flow that finishes outside the terminal, such as sign-in.
In URL mode, Claude Code passes the URL as a command-line argument to your system’s URL handler, and caps how long that argument can be. When the URL, once escaped for the command line, is over that cap, you can only decline the request. Every character that needs escaping, such as % or &, counts four times toward the cap: its own character plus three escape characters. A URL with none of them reaches the cap at about 8,000 characters. A URL built largely of percent-escapes, where every third character is a %, reaches it at roughly 4,000.To auto-respond to elicitation requests without showing a dialog, use the Elicitation hook.If you’re building an MCP server that uses elicitation, see the MCP elicitation specification for protocol details and schema examples.
If you build an MCP server, the client capabilities Claude Code sends when it connects tell your server which elicitation modes it can request. Claude Code declares elicitation: {form: {}, url: {}} on the following connections, so a server on any of them can request both modes:
Connections on the earlier protocol revisions, 2025-11-25 and older, to the stdio, sse, http, and ws servers in a user’s Claude Code MCP configuration. Requires Claude Code v2.1.287 or later
On its other connections on the earlier revisions, such as to claude.ai connectors, Claude Code declares the bare elicitation: {}, which permits elicitation requests in form mode only.A server built on Java MCP SDK 0.17.0 or earlier can refuse a declaration that has form and url in it. See MCP server rejected the elicitation capability.
Type @ in your prompt to see available resources from all connected MCP servers. Resources appear alongside files in the autocomplete menu.
2
Reference a specific resource
Use the format @server:protocol://resource/path to reference a resource:
Can you analyze @github:issue://123 and suggest a fix?
Please review the API documentation at @docs:file://api/authentication
3
Multiple resource references
You can reference multiple resources in a single prompt:
Compare @postgres:schema://users with @docs:file://database/user-model
Tips:
Resources are automatically fetched and included as attachments when referenced
Resource paths are fuzzy-searchable in the @ mention autocomplete
Claude Code automatically provides tools to list and read MCP resources when servers support them
Resources can contain any type of content that the MCP server provides (text, JSON, structured data, etc.)
MCP Apps UI resources are entries with a ui:// URI or the text/html;profile=mcp-app media type: pages for a host application to render rather than content for Claude to read. They don’t appear in the @ suggestions or in the resource list tool’s results, and a server that offers only UI resources shows an empty resource list. Reading a UI resource by its URI still works.
Tool search keeps MCP context usage low by deferring tool definitions until Claude needs them. Only tool names and server instructions load at session start, so adding more MCP servers has minimal impact on your context window. Claude Code doesn’t impose a fixed per-server tool cap; the practical limit is your context window budget.
Tool search isn’t supported on Microsoft Foundry deployments hosted on Azure, which reject it server-side: Claude Code detects the rejection and loads MCP tools upfront for that deployment instead. ENABLE_TOOL_SEARCH can’t override this, since the rejection comes from the deployment itself.
If you’re building an MCP server, the server instructions field becomes more useful with tool search enabled. Server instructions help Claude understand when to search for your tools, similar to how skills work.Add clear, descriptive server instructions that explain:
What category of tasks your tools handle
When Claude should search for your tools
Key capabilities your server provides
Claude Code cuts a tool description or server instructions that run past these default limits, and Claude sees only the text before the cut:
Server instructions, and the description of a tool that loads upfront: 4,096 characters
The description of a tool that Claude loads through tool search: 16,384 characters
Keep descriptions and instructions concise, and put critical details near the start. When tool search matches Claude’s query against a tool’s description, it reads only the part within the shorter limit, so put the words Claude would search for near the start too. A tool loads upfront and keeps the shorter limit whenever it isn’t deferred, for example when tool search is off, when the tool is marked to load upfront, or when its server is exempt from deferral.Before v2.1.296, the shorter limit was 2,048 characters, and before v2.1.295 it applied to every tool description, including one loaded through tool search.
To change the default limits of 4,096 and 16,384 characters for the MCP servers in your session, set CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH to a number of characters. Claude Code uses that number for both limits. With 8192, for example, you raise the 4,096-character limit on server instructions and tool descriptions loaded upfront, and lower the 16,384-character limit on tool descriptions loaded through tool search. This variable requires Claude Code v2.1.280 or later.Descriptions and instructions from some of the MCP servers that Anthropic hosts at api.anthropic.com reach Claude in full, and setting this variable doesn’t cut them.
To control how one of your server’s tools loads, set "anthropic/alwaysLoad" in that tool’s _meta object. The person who adds your server to Claude Code can also set alwaysLoad for the whole server in their configuration, and their setting can override yours:
Your tool’s value
What happens
true
The tool loads upfront. Startup doesn’t wait for your server because of this value. The person configuring your server can still defer all of its tools
false
The tool stays deferred when their configuration sets "alwaysLoad": true. This applies when your server is passed with --mcp-config, supplied by an Agent SDK application, or provided by a plugin. On other servers the tool loads upfront. Requires Claude Code v2.1.285 or later
The following tools/list entry asks for one tool to load upfront:
{ "name": "search_tickets", "description": "Searches the ticket tracker by keyword", "_meta": { "anthropic/alwaysLoad": true }}
Tool search is enabled by default: MCP tools are deferred and discovered on demand.Setting CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS keeps tool search off. You can’t override it by setting ENABLE_TOOL_SEARCH yourself. On Claude Code v2.1.227 or later, your organization can keep tool search on under this variable through managed settings. In a session that gets the HIPAA configuration, tool search is off, and neither ENABLE_TOOL_SEARCH nor managed settings turns it back on. Disable pre-release capabilities covers where the override applies and what the variable strips.Claude Code uses tool search on Claude Opus 4, Claude Sonnet 4, Claude Haiku 4.5, and later models, or Opus 4.5, Sonnet 4.5, Haiku 4.5, and later models on Google Cloud’s Agent Platform. On earlier models, Claude Code loads all MCP tools upfront, and ENABLE_TOOL_SEARCH=true doesn’t override this.On Google Cloud’s Agent Platform, Claude Code decides by model generation:
Claude Opus 4.5, Sonnet 4.5, Haiku 4.5, and later: tool search is on by default, the same as on the Anthropic API.
Earlier Agent Platform models: Claude Code loads all MCP tools upfront, because their serving stacks reject the required beta header. ENABLE_TOOL_SEARCH=true doesn’t override this.
Before v2.1.221, Claude Code disabled tool search for all models on Google Cloud’s Agent Platform unless you set ENABLE_TOOL_SEARCH=true.Control tool search behavior with the ENABLE_TOOL_SEARCH environment variable:
Value
Behavior
(unset)
All MCP tools deferred and loaded on demand. Loaded upfront on models earlier than Opus 4 and Sonnet 4, on the earlier Agent Platform models, and on Microsoft Foundry deployments hosted on Azure
true
MCP tools deferred, with the same fallbacks as (unset)
auto
Threshold mode. Tools that would otherwise be deferred load upfront while their definitions total under 10% of the context window. At 10% or more, tool search turns on, and those tools can stay deferred even if the total falls under 10%
auto:N
Threshold mode with a custom percentage, where N is 0-100. For example, auto:5 for 5%
false
All MCP tools loaded upfront, no deferral
# Use a custom 5% thresholdENABLE_TOOL_SEARCH=auto:5 claude# Disable tool search entirelyENABLE_TOOL_SEARCH=false claude
Or set the value in your settings.json env field.You can also disable the ToolSearch tool specifically:
{ "permissions": { "deny": ["ToolSearch"] }}
If you deny ToolSearch or leave it out of --tools, MCP tools load upfront instead, but a request can still carry a placeholder defer_loading entry. If a gateway rejects that entry, see Tool search through an LLM gateway.
When ANTHROPIC_BASE_URL points to a gateway, tool search is on by default, so requests include defer_loading tool fields and tool_reference blocks for the gateway to forward. While tool search is on, MCP tools are deferred. To load every tool upfront instead, set ENABLE_TOOL_SEARCH=false in your shell or your settings env. Before v2.1.304, tool search was off behind a gateway unless ENABLE_TOOL_SEARCH was true, auto, or auto:N.On v2.1.305 or later, Claude Code can retry a request without tool search after a 400 or 422 whose cause it doesn’t recognize. When the retry works, nothing shows on screen and you don’t need to do anything: MCP tools load upfront instead. Claude Code tries tool search again later, at the cost of another rejected request. To skip those requests, set ENABLE_TOOL_SEARCH=false.
Tools that stay deferred below the ENABLE_TOOL_SEARCH=auto threshold
If /context labels tools (deferred) or (loaded on-demand) though their definitions total under the auto threshold, tool search was already on in this conversation and stayed on. The total can drop later, for example while MCP servers reconnect after you resume a session. You don’t need to do anything: Claude loads each of those tools when a task needs it.
If a server’s tools should always be visible to Claude without a search step, set alwaysLoad to true in that server’s configuration. The server’s tools then load into context regardless of the ENABLE_TOOL_SEARCH setting. Use this for a small number of tools that Claude needs on every turn, since each upfront tool consumes context that would otherwise be available for your conversation.The following .mcp.json entry exempts one HTTP server while leaving other servers deferred:
The alwaysLoad field is available on all server types.Setting alwaysLoad: true also makes startup wait for the server’s tools, capped at the standard 5-second connect timeout, since they must be present when the first prompt is built. A remote server with a valid cached entry supplies its tools from the cache without connecting, so it doesn’t hold startup. Other servers connect in the background by default; set MCP_CONNECTION_NONBLOCKING=0 to make startup wait for them too.
To keep all of a server’s tools behind tool search, set "alwaysLoad": false in that server’s entry in your MCP configuration. That includes tools that the server’s author has marked to load upfront. If you leave alwaysLoad out, those marked tools load upfront. Requires Claude Code v2.1.287 or later.
MCP servers can expose prompts that become available as commands in Claude Code.Prompts from a server named anthropic-skills don’t appear, because Claude Code reserves that name for skills synced from claude.ai. The server’s tools still work. Rename the server in your MCP configuration to list its prompts.
Type / to see the commands available to you, including those from MCP servers. Claude Code lists each MCP prompt as /servername:promptname (MCP). Typing /mcp__servername__promptname also runs it.
2
Execute a prompt without arguments
/mcp__github__list_prs
3
Execute a prompt with arguments
Many prompts accept arguments. Pass them space-separated after the command. Claude Code splits the arguments on whitespace, so each argument is a single token:
/mcp__github__pr_review 456
/mcp__jira__create_issue login-bug high
Tips:
MCP prompts are dynamically discovered from connected servers
Arguments are parsed based on the prompt’s defined parameters
Prompt results are injected directly into the conversation
In the /mcp__servername__promptname form, Claude Code replaces any character in the server name outside A-Z, a-z, 0-9, _, and - with _, and uses the prompt name as the server declares it
For organizations that need centralized control over which MCP servers users can connect to, see Managed MCP configuration. It covers deploying a fixed server set with managed-mcp.json, providing servers to every user with managedMcpServers, restricting servers with allowedMcpServers and deniedMcpServers, and what users see when a server is blocked.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Claude Code Docs","description":"Official documentation for Claude Code, Anthropic's agentic coding tool available in the terminal, IDE, desktop app, and browser. Covers installation, configuration, skills, subagents, hooks, MCP, the Agent SDK, and reference material.","colors":{"primary":"#0E0E0E","light":"#D4A27F","dark":"#0E0E0E"},"logo":{"light":"https://mintcdn.com/claude-code/c5r9_6tjPMzFdDDT/logo/light.svg?fit=max\u0026auto=format\u0026n=c5r9_6tjPMzFdDDT\u0026q=85\u0026s=78fd01ff4f4340295a4f66e2ea54903c","dark":"https://mintcdn.com/claude-code/c5r9_6tjPMzFdDDT/logo/dark.svg?fit=max\u0026auto=format\u0026n=c5r9_6tjPMzFdDDT\u0026q=85\u0026s=1298a0c3b3a1da603b190d0de0e31712"},"favicon":"https://mintcdn.com/claude-code/T2WlxklWBkR5Y1mJ/favicon.ico?fit=max\u0026auto=format\u0026n=T2WlxklWBkR5Y1mJ\u0026q=85\u0026s=346a85952ae08d5ee90e3c34d4423930","appearance":{"default":"system"},"background":{"color":{"light":"#FDFDF7","dark":"#09090B"}},"navbar":{"links":[{"href":"https://platform.claude.com/","label":"Claude Developer Platform"}],"primary":{"type":"button","label":"Open Claude Code","href":"https://claude.ai/code"}},"footer":{"socials":{"x":"https://x.com/AnthropicAI","linkedin":"https://www.linkedin.com/company/anthropicresearch"},"links":[{"header":"Company","items":[{"label":"Anthropic","href":"https://www.anthropic.com/company"},{"label":"Careers","href":"https://www.anthropic.com/careers"},{"label":"Economic Futures","href":"https://www.anthropic.com/economic-futures"},{"label":"Research","href":"https://www.anthropic.com/research"},{"label":"News","href":"https://www.anthropic.com/news"},{"label":"Trust center","href":"https://trust.anthropic.com/"},{"label":"Transparency","href":"https://www.anthropic.com/transparency"}]},{"header":"Help and security","items":[{"label":"Availability","href":"https://www.anthropic.com/supported-countries"},{"label":"Status","href":"https://status.anthropic.com/"},{"label":"Support center","href":"https://support.claude.com/"}]},{"header":"Learn","items":[{"label":"Courses","href":"https://academy.claude.com/"},{"label":"MCP connectors","href":"https://claude.com/partners/mcp"},{"label":"Customer stories","href":"https://www.claude.com/customers"},{"label":"Engineering blog","href":"https://www.anthropic.com/engineering"},{"label":"Events","href":"https://www.anthropic.com/events"},{"label":"Powered by Claude","href":"https://claude.com/partners/powered-by-claude"},{"label":"Service partners","href":"https://claude.com/partners/services"},{"label":"Startups program","href":"https://claude.com/programs/startups"}]},{"header":"Terms and policies","items":[{"label":"Privacy choices","href":"https://www.anthropic.com/legal/privacy"},{"label":"Privacy policy","href":"https://www.anthropic.com/legal/privacy"},{"label":"Disclosure policy","href":"https://www.anthropic.com/responsible-disclosure-policy"},{"label":"Usage policy","href":"https://www.anthropic.com/legal/aup"},{"label":"Commercial terms","href":"https://www.anthropic.com/legal/commercial-terms"},{"label":"Consumer terms","href":"https://www.anthropic.com/legal/consumer-terms"}]}]},"seo":{"metatags":{"canonical":"https://code.claude.com/docs"}},"fonts":{"family":"Anthropic Sans"},"contextual":{"options":["copy","view","claude"],"display":"header"},"styling":{"latex":true},"navigation":{"languages":[{"language":"en","href":"en/overview"},{"language":"fr","href":"fr/overview"},{"language":"de","href":"de/overview"},{"language":"it","href":"it/overview"},{"language":"jp","href":"ja/overview"},{"language":"es","href":"es/overview"},{"language":"ko","href":"ko/overview"},{"language":"zh-CN","href":"zh-CN/overview"},{"language":"zh-TW","href":"zh-TW/overview"},{"language":"ru","href":"ru/overview"},{"language":"id","href":"id/overview"},{"language":"pt-BR","href":"pt/overview"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"claude-code","hasAudioNarration":false,"actualSubdomain":"claude-code","customDomains":["code.claude.com"],"gitSource":{"type":"github","owner":"anthropics","repo":"claude-code-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae3ae50b1cb4571d5d954f5","collectionId":"5571174e-1260-45b3-92f4-fe87338846f4","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae3ae50b1cb4571d5d954f5"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED","enabled":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED","enabled":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae3b137ba1169b26ccae6a4","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"en","tag":"Agent SDK","count":60},{"language":"en","tag":"Plugins","count":56},{"language":"de","tag":"Neuigkeiten","count":50},{"language":"en","tag":"What's New","count":50},{"language":"es","tag":"Novedades","count":50},{"language":"fr","tag":"Nouveautés","count":50},{"language":"it","tag":"Novità","count":50},{"language":"ko","tag":"새로운 기능","count":50},{"language":"pt-BR","tag":"Novidades","count":50},{"language":"ru","tag":"Что нового","count":50},{"language":"zh-TW","tag":"最新消息","count":50},{"language":"de","tag":"Erste Schritte","count":49},{"language":"es","tag":"Primeros pasos","count":49},{"language":"fr","tag":"Premiers pas","count":49},{"language":"id","tag":"Memulai","count":49},{"language":"it","tag":"Per iniziare","count":49},{"language":"jp","tag":"はじめに","count":49},{"language":"ko","tag":"시작하기","count":49},{"language":"pt-BR","tag":"Primeiros passos","count":49},{"language":"ru","tag":"Начало работы","count":49},{"language":"zh-TW","tag":"快速入門","count":49},{"language":"en","tag":"Getting started","count":48},{"language":"zh-CN","tag":"快速入门","count":46},{"language":"en","tag":"Overview","count":41},{"language":"de","tag":"Agent SDK","count":36},{"language":"en","tag":"Setup and access","count":36},{"language":"es","tag":"Agent SDK","count":36},{"language":"id","tag":"Agent SDK","count":36},{"language":"it","tag":"Agent SDK","count":36},{"language":"jp","tag":"Agent SDK","count":36},{"language":"pt-BR","tag":"Agent SDK","count":36},{"language":"ru","tag":"Agent SDK","count":36},{"language":"zh-CN","tag":"Agent SDK","count":36},{"language":"zh-TW","tag":"Agent SDK","count":36},{"language":"de","tag":"Administration","count":34},{"language":"en","tag":"Administration","count":34},{"language":"es","tag":"Administración","count":34},{"language":"fr","tag":"Administration","count":34},{"language":"id","tag":"Administrasi","count":34},{"language":"it","tag":"Amministrazione","count":34},{"language":"jp","tag":"管理","count":34},{"language":"ko","tag":"관리","count":34},{"language":"pt-BR","tag":"Administração","count":34},{"language":"ru","tag":"Администрирование","count":34},{"language":"zh-CN","tag":"管理","count":34},{"language":"zh-TW","tag":"管理","count":34},{"language":"de","tag":"Plugins","count":32},{"language":"es","tag":"Plugins","count":32},{"language":"fr","tag":"SDK Agent","count":32},{"language":"fr","tag":"Plugins","count":32},{"language":"id","tag":"Plugin","count":32},{"language":"it","tag":"Plugin","count":32},{"language":"jp","tag":"プラグイン","count":32},{"language":"ko","tag":"Agent SDK","count":32},{"language":"ko","tag":"플러그인","count":32},{"language":"pt-BR","tag":"Plugins","count":32},{"language":"ru","tag":"Плагины","count":32},{"language":"zh-CN","tag":"插件","count":32},{"language":"zh-TW","tag":"外掛","count":32},{"language":"en","tag":"Reference","count":28},{"language":"es","tag":"Configuración","count":28},{"language":"jp","tag":"設定","count":28},{"language":"zh-TW","tag":"設定","count":28},{"language":"de","tag":"Konfiguration","count":25},{"language":"en","tag":"Configuration","count":25},{"language":"fr","tag":"Configuration","count":25},{"language":"id","tag":"Konfigurasi","count":25},{"language":"id","tag":"Apa yang Baru","count":25},{"language":"id","tag":"Yang Baru","count":25},{"language":"it","tag":"Configurazione","count":25},{"language":"jp","tag":"新機能","count":25},{"language":"jp","tag":"最新情報","count":25},{"language":"ko","tag":"구성","count":25},{"language":"pt-BR","tag":"Configuração","count":25},{"language":"ru","tag":"Конфигурация","count":25},{"language":"zh-CN","tag":"配置","count":25},{"language":"zh-CN","tag":"新功能","count":25},{"language":"zh-CN","tag":"最新动态","count":25},{"language":"en","tag":"Settings","count":24},{"language":"de","tag":"Mit Claude Code entwickeln","count":22},{"language":"es","tag":"Crea con Claude Code","count":22},{"language":"fr","tag":"Développer avec Claude Code","count":22},{"language":"id","tag":"Membangun dengan Claude Code","count":22},{"language":"it","tag":"Crea con Claude Code","count":22},{"language":"jp","tag":"Claude Code で構築","count":22},{"language":"ko","tag":"Claude Code로 만들기","count":22},{"language":"pt-BR","tag":"Desenvolva com Claude Code","count":22},{"language":"ru","tag":"Разработка с Claude Code","count":22},{"language":"zh-CN","tag":"使用 Claude Code 构建","count":22},{"language":"zh-TW","tag":"使用 Claude Code 打造","count":22},{"language":"de","tag":"Referenz","count":20},{"language":"es","tag":"Referencia","count":20},{"language":"fr","tag":"Référence","count":20},{"language":"id","tag":"Referensi","count":20},{"language":"it","tag":"Riferimento","count":20},{"language":"jp","tag":"リファレンス","count":20},{"language":"ko","tag":"레퍼런스","count":20},{"language":"pt-BR","tag":"Referência","count":20},{"language":"ru","tag":"Справочник","count":20},{"language":"zh-CN","tag":"参考","count":20},{"language":"de","tag":"Plattformen und Integrationen","count":19},{"language":"es","tag":"Plataformas e integraciones","count":19},{"language":"fr","tag":"Plateformes et intégrations","count":19},{"language":"id","tag":"Platform dan integrasi","count":19},{"language":"it","tag":"Piattaforme e integrazioni","count":19},{"language":"jp","tag":"プラットフォームと連携","count":19},{"language":"ko","tag":"플랫폼 및 통합","count":19},{"language":"pt-BR","tag":"Plataformas e integrações","count":19},{"language":"ru","tag":"Платформы и интеграции","count":19},{"language":"zh-CN","tag":"平台与集成","count":19},{"language":"zh-TW","tag":"平台與整合","count":19},{"language":"de","tag":"Code-Review und Pull Requests","count":14},{"language":"es","tag":"Revisión de código y pull requests","count":14},{"language":"fr","tag":"Revue de code et pull requests","count":14},{"language":"it","tag":"Code review e pull request","count":14},{"language":"ko","tag":"코드 리뷰 및 풀 리퀘스트","count":14},{"language":"pt-BR","tag":"Revisão de código e pull requests","count":14},{"language":"ru","tag":"Код-ревью и pull request","count":14},{"language":"zh-TW","tag":"程式碼審查與 pull request","count":14},{"language":"zh-TW","tag":"部署","count":11}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"/docs","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-bash","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"chat-bucketing-batched","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"button.css","content":".btn{position:relative;display:inline-flex;gap:.5rem;align-items:center;justify-content:center;flex-shrink:0;min-width:5rem;height:2.25rem;padding:.5rem 1rem;white-space:nowrap;font-family:Styrene;font-weight:600;border-radius:.5rem}"},{"filePath":"style.css","content":"@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-Regular-Static.otf) format(\"opentype\");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-RegularItalic-Static.otf) format(\"opentype\");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-Medium-Static.otf) format(\"opentype\");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-MediumItalic-Static.otf) format(\"opentype\");font-weight:500;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-Semibold-Static.otf) format(\"opentype\");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-SemiboldItalic-Static.otf) format(\"opentype\");font-weight:600;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-Bold-Static.otf) format(\"opentype\");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Sans\";src:url(https://assets.claude.ai/Fonts/AnthropicSans-Text-BoldItalic-Static.otf) format(\"opentype\");font-weight:700;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Serif Display\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Display-Regular-Static.otf) format(\"opentype\");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif Display\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Display-RegularItalic-Static.otf) format(\"opentype\");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Serif Display\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Display-Medium-Static.otf) format(\"opentype\");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif Display\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Display-Semibold-Static.otf) format(\"opentype\");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif Display\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Display-Bold-Static.otf) format(\"opentype\");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-Regular-Static.otf) format(\"opentype\");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-RegularItalic-Static.otf) format(\"opentype\");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-Medium-Static.otf) format(\"opentype\");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-MediumItalic-Static.otf) format(\"opentype\");font-weight:500;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-Semibold-Static.otf) format(\"opentype\");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-SemiboldItalic-Static.otf) format(\"opentype\");font-weight:600;font-style:italic;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-Bold-Static.otf) format(\"opentype\");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:\"Anthropic Serif\";src:url(https://assets.claude.ai/Fonts/AnthropicSerif-Text-BoldItalic-Static.otf) format(\"opentype\");font-weight:700;font-style:italic;font-display:swap}:root{--always-white:0 0% 100%;--always-black:0 0% 0%;--constant-book-cloth:15 55% 80%;--constant-clay:15 60% 85%;--constant-kraft:25 40% 83%;--constant-manilla:40 20% 92%;--constant-slate-000:0 0% 100%;--constant-slate-050:48 33.3% 97.1%;--constant-slate-100:53 28.6% 94.5%;--constant-slate-150:48 25% 92.2%;--constant-slate-200:50 20.7% 88.6%;--constant-slate-250:51 16.5% 84.5%;--constant-slate-300:50 11.5% 79.6%;--constant-slate-350:50 9% 73.7%;--constant-slate-400:49 6.5% 66.9%;--constant-slate-450:48 4.8% 59.2%;--constant-slate-500:53 3.2% 51.4%;--constant-slate-550:51 3.1% 43.7%;--constant-slate-600:48 2.7% 35.9%;--constant-slate-650:48 3.4% 29.2%;--constant-slate-700:60 2.5% 23.3%;--constant-slate-750:60 2.1% 18.4%;--constant-slate-800:60 2.7% 14.5%;--constant-slate-850:30 3.3% 11.8%;--constant-slate-900:30 4% 9.8%;--constant-slate-950:60 2.6% 7.6%;--constant-slate-1000:60 3.4% 5.7%}:root:not(.dark){--accent-brand:15 63.1% 59.6%;--accent-main-000:15 55.6% 52.4%;--accent-main-100:15 55.6% 52.4%;--accent-main-200:15 63.1% 59.6%;--accent-main-900:0 0% 0%;--accent-pro-000:251 34.2% 33.3%;--accent-pro-100:251 40% 45.1%;--accent-pro-200:251 61% 72.2%;--accent-pro-900:253 33.3% 91.8%;--accent-secondary-000:210 73.7% 40.2%;--accent-secondary-100:210 70.9% 51.6%;--accent-secondary-200:210 70.9% 51.6%;--accent-secondary-900:211 72% 90%;--bg-000:0 0% 100%;--bg-100:48 33.3% 97.1%;--bg-200:53 28.6% 94.5%;--bg-300:48 25% 92.2%;--bg-400:50 20.7% 88.6%;--bg-500:50 20.7% 88.6%;--border-100:30 3.3% 11.8%;--border-200:30 3.3% 11.8%;--border-300:30 3.3% 11.8%;--border-400:30 3.3% 11.8%;--danger-000:0 61.4% 22.4%;--danger-100:0 58.6% 34.1%;--danger-200:0 58.6% 34.1%;--danger-900:0 50% 95%;--oncolor-100:0 0% 100%;--oncolor-200:60 6.7% 97.1%;--oncolor-300:60 6.7% 97.1%;--text-000:60 2.6% 7.6%;--text-100:60 2.6% 7.6%;--text-200:60 2.5% 23.3%;--text-300:60 2.5% 23.3%;--text-400:51 3.1% 43.7%;--text-500:51 3.1% 43.7%}:root.dark{--accent-brand:15 63.1% 59.6%;--accent-main-000:15 55.6% 52.4%;--accent-main-100:15 63.1% 59.6%;--accent-main-200:15 63.1% 59.6%;--accent-main-900:0 0% 0%;--accent-pro-000:251 84.6% 74.5%;--accent-pro-100:251 40.2% 54.1%;--accent-pro-200:251 40% 45.1%;--accent-pro-900:250 25.3% 19.4%;--accent-secondary-000:210 71.1% 62%;--accent-secondary-100:210 70.9% 51.6%;--accent-secondary-200:210 70.9% 51.6%;--accent-secondary-900:210 55.9% 24.6%;--bg-000:60 2.1% 18.4%;--bg-100:60 2.7% 14.5%;--bg-200:30 3.3% 11.8%;--bg-300:60 2.6% 7.6%;--bg-400:60 3.4% 5.7%;--bg-500:60 3.4% 5.7%;--border-100:51 16.5% 84.5%;--border-200:51 16.5% 84.5%;--border-300:51 16.5% 84.5%;--border-400:51 16.5% 84.5%;--danger-000:0 73.1% 66.5%;--danger-100:0 58.6% 34.1%;--danger-200:0 58.6% 34.1%;--danger-900:0 23% 15.6%;--oncolor-100:0 0% 100%;--oncolor-200:60 6.7% 97.1%;--oncolor-300:60 6.7% 97.1%;--text-000:48 33.3% 97.1%;--text-100:48 33.3% 97.1%;--text-200:50 9% 73.7%;--text-300:50 9% 73.7%;--text-400:48 4.8% 59.2%;--text-500:48 4.8% 59.2%}#home-header{font-family:\"Anthropic Sans\",system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-weight:400!important;font-size:50px;line-height:1.2;margin-bottom:1rem;color:--text-000;display:flex;align-items:baseline;justify-content:center;flex-wrap:nowrap}#localization-select-trigger>:has(img[src*=flags]),div[id^=localization-select-item]>:has(img[src*=flags]){display:none}@media (min-width:768px){#home-header{justify-content:center}}.build-with{font-family:\"Anthropic Sans\",system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;letter-spacing:-.02em}.claude-wordmark-wrapper{display:inline-flex;align-items:baseline;margin-left:10px}.claude-wordmark{height:40px;width:auto;position:relative}.dark #home-header,.dark .description-text{color:#fff}.description-text{color:#000}.dark .claude-wordmark{filter:invert(1)}:root{--bg-color:#f0efea}.dark{--bg-color:#2b2b2b}#category-select,#content-container,#table-of-contents,.dropdown-item,.eyebrow,body,input{font-family:\"Anthropic Sans\",system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif}.eyebrow{text-transform:uppercase;letter-spacing:.02rem}#content-container h1,#content-container h2,#content-container h3,#content-container h4,#content-container h5,#content-container h6{font-family:\"Anthropic Serif Display\",Georgia,\"Times New Roman\",Times,serif;font-weight:400;letter-spacing:0;word-spacing:.1em}#content-container p{font-size:1rem;line-height:1.65rem}.font-extrabold{font-weight:600!important}.wide-table{width:100%;overflow-x:auto}.wide-table table{width:175%;margin-bottom:0}#prompt-library-container{margin:4rem auto;max-width:48rem;padding-left:1.25rem;padding-right:1.25rem}.prompt-library-title{font-size:24px;text-align:center;font-weight:700;color:#1f2937}.dark .prompt-library-title{color:#e5e7eb}.prompt-library-description{margin-top:1rem;text-align:center}.main-content{margin-bottom:10rem;max-width:64rem;margin-left:auto;margin-right:auto;padding-left:1.25rem;padding-right:1.25rem}.prompt-controllers{display:flex;gap:.5rem}.prompt-search-container{position:relative;flex:1 1 0%}.prompt-search-icon-container{display:flex;position:absolute;top:0;bottom:0;left:0;align-items:center;padding-left:.75rem}.prompt-search-icon{margin-left:.25rem;margin-right:.75rem;flex:none;width:1rem;height:1rem;background-color:#6b7280;mask-image:url(https://mintlify.b-cdn.net/v6.5.1/solid/magnifying-glass.svg);mask-repeat:no-repeat;mask-position:center center}input.prompt-search-bar{display:block;height:2.5rem;padding-left:2.5rem;border-radius:.75rem;border-width:1px;background-color:#fff;width:100%;color:#111827;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.dark input.prompt-search-bar{color:#fff;background-color:rgb(var(--background-dark));border-color:#d1d5db1a}input.prompt-search-bar:focus{outline-color:rgb(var(--primary))}.dark input.prompt-search-bar:focus{outline-color:rgb(var(--primary-light))}.dark .dropdown-icon,.dark .prompt-search-icon{background-color:#ffffff80}#category-select{padding-left:1rem;padding-right:2.5rem;height:2.5rem;display:flex;align-items:center;border-radius:.75rem;border-width:1px;color:#111827;background-color:#fff;cursor:pointer;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);white-space:nowrap}.dark #category-select{background-color:rgb(var(--background-dark));border-color:#d1d5db1a;color:#fff}#category-select:hover,.dropdown-item:hover{background-color:#f9fafb}.dark #category-select:hover,.dark .dropdown-item:hover{background-color:#ffffff0d}#category-select:focus{outline-color:rgb(var(--primary))}.dark #category-select:focus{outline-color:rgb(var(--primary-light))}#categories-dropdown{top:calc(100% + 4px);padding:.5rem;display:none;position:absolute;z-index:10;border-radius:.75rem;border-width:1px;width:100%;color:#111827;background-color:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.dark #categories-dropdown{background-color:rgb(var(--background-dark));border-color:#d1d5db1a;color:#fff}#categories-dropdown-clickout{position:fixed;top:0;right:0;bottom:0;left:0;z-index:0}.dropdown-icon-container{display:flex;position:absolute;top:0;bottom:0;right:0;align-items:center;padding-right:.25rem}.dropdown-icon{margin-left:.25rem;margin-right:.75rem;flex:none;width:.75rem;height:.75rem;background-color:#6b7280;mask-image:url(https://mintlify.b-cdn.net/v6.5.1/solid/caret-down.svg);mask-repeat:no-repeat;mask-position:center center}#prompts-container{grid-template-columns:repeat(1,minmax(0,1fr));gap:2rem;display:grid;margin-top:2.5rem}.dropdown-item{padding:.25rem .5rem;border-radius:.375rem;display:flex;align-items:center;cursor:pointer}.check-icon{mask-image:url(https://mintlify.b-cdn.net/v6.5.1/solid/check.svg);height:.875rem;width:1rem;background-color:rgb(var(--primary-light));mask-repeat:no-repeat;mask-position:center center}.prompt-card{margin:-.75rem;padding:.75rem;display:flex;border-radius:1rem}.prompt-card:hover{background-color:#03071208}.dark .prompt-card:hover{background-color:#ffffff08}.prompt-icon-container{display:flex;flex:none;align-items:center;justify-content:center;margin-right:1.5rem;border-radius:.75rem;height:4rem;width:4rem;background-color:#cb785c1a}.prompt-icon{height:1.5rem;width:1.5rem;background-color:rgb(var(--primary-light));mask-repeat:no-repeat;mask-position:center center}.prompt-title{color:rgb(31 41 55);font-weight:600}.dark .prompt-title{color:rgb(229 231 235)}.prompt-description{margin-top:.25rem}@media (min-width:640px){#category-select{width:16rem}}@media (min-width:1024px){#prompts-container{grid-template-columns:repeat(2,minmax(0,1fr))}}.home-cards-custom{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,auto);gap:1.5rem}.home-cards-custom .card{background:0 0;border:.5px solid hsl(var(--border-300));border-radius:12px;padding:.25rem}@media (max-width:1024px){.home-cards-custom{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,auto)}}@media (max-width:768px){.home-cards-custom{grid-template-columns:1fr;grid-template-rows:repeat(6,auto)}}.relative{position:relative}.flex-1{flex:1 1 0%}.mermaid{position:relative;background-color:#fdfdfb;background-image:linear-gradient(rgba(235,219,188,.25) 1px,transparent 1px),linear-gradient(90deg,rgba(235,219,188,.25) 1px,transparent 1px),linear-gradient(rgba(235,219,188,.1) 1px,transparent 1px),linear-gradient(90deg,rgba(235,219,188,.1) 1px,transparent 1px);background-size:20px 20px,20px 20px,4px 4px,4px 4px;background-position:-1px -1px,-1px -1px,-1px -1px,-1px -1px;padding:20px;border-radius:8px;border:1px solid rgba(235,219,188,.4);box-shadow:0 2px 4px rgba(64,64,62,.08)}.dark .mermaid{background-color:#1a1918;background-image:linear-gradient(rgba(212,162,127,.15) 1px,transparent 1px),linear-gradient(90deg,rgba(212,162,127,.15) 1px,transparent 1px),linear-gradient(rgba(212,162,127,.08) 1px,transparent 1px),linear-gradient(90deg,rgba(212,162,127,.08) 1px,transparent 1px);border:1px solid rgba(102,102,99,.5);box-shadow:0 2px 4px rgba(0,0,0,.2)}.digest-meta{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem 1rem;padding:.75rem 1rem;margin:1.5rem 0 2.5rem;border:1px solid hsl(var(--border-300)/.15);background:hsl(var(--bg-200));font-variant-numeric:tabular-nums;font-size:.875rem;color:hsl(var(--text-400))}#content-container .digest-meta a{color:hsl(var(--accent-main-100));font-weight:500;text-decoration:none;border-bottom:none}#content-container .digest-meta a:hover{text-decoration:underline}.digest-feature{position:relative;margin:2.5rem 0;padding:1.875rem 1.875rem 1.625rem;background:radial-gradient(circle,hsl(var(--text-000)/.025) 1px,transparent 1px) 0 0/18px 18px,linear-gradient(180deg,hsl(var(--constant-manilla)/.55),hsl(var(--constant-manilla)/.38));border:1px solid hsl(var(--border-300)/.12);box-shadow:inset 0 1px 0 hsl(var(--text-000)/.04),0 1px 2px hsl(var(--always-black)/.04)}.digest-feature::before{content:\"\";position:absolute;inset:0 auto 0 0;width:4px;background:hsl(var(--accent-brand))}.dark .digest-feature{background:radial-gradient(circle,hsl(var(--text-000)/.02) 1px,transparent 1px) 0 0/18px 18px,linear-gradient(180deg,hsl(var(--bg-000)/.75),hsl(var(--bg-000)/.5));border-color:hsl(var(--border-300)/.1);box-shadow:inset 0 1px 0 hsl(var(--text-000)/.03),0 1px 2px hsl(var(--always-black)/.25)}.digest-feature>:first-child{margin-top:0}.digest-feature>:last-child{margin-bottom:0}.digest-feature-header{display:flex;align-items:center;flex-wrap:wrap;gap:.625rem;margin:0 0 .75rem}#content-container .digest-feature-title{font-family:\"Anthropic Serif Display\",Georgia,serif;font-size:1.75rem;line-height:1.15;font-weight:500;letter-spacing:-.015em;color:hsl(var(--text-000));margin:0}#content-container .digest-feature-pill{font-family:ui-monospace,\"SF Mono\",Menlo,Consolas,monospace;font-size:.75rem;line-height:1;letter-spacing:.01em;padding:.3rem .6rem;border-radius:999px;background:hsl(var(--accent-brand)/.12);color:hsl(var(--accent-main-000));border:1px solid hsl(var(--accent-brand)/.25);white-space:nowrap;transform:translateY(1px)}#content-container .digest-feature-lede{font-size:1.0625rem;line-height:1.65;color:hsl(var(--text-100));margin:0 0 1.25rem;max-width:none}#content-container .digest-feature-lede code{font-size:.875em;padding:.1em .35em}#content-container .digest-feature-try{font-size:.875rem;color:hsl(var(--text-400));margin:1.25rem 0 .5rem}#content-container .digest-feature .frame{margin:1rem 0;border-radius:0;padding:0}#content-container .digest-feature .frame>*,#content-container .digest-feature [class*=CodeBlock],#content-container .digest-feature pre{border-radius:0}#content-container .digest-feature-link{display:inline-flex;align-items:center;gap:.35rem;font-size:.875rem;font-weight:500;color:hsl(var(--accent-main-100));text-decoration:none;border-bottom:none;margin-top:.75rem}#content-container .digest-feature-link::after{content:\"→\";transition:transform 120ms ease-out}#content-container .digest-feature-link:hover::after{transform:translateX(3px)}.digest-wins{margin:2.5rem 0;padding:1.5rem 1.75rem 1.25rem;background:hsl(var(--bg-200));border:1px solid hsl(var(--border-300)/.1)}.dark .digest-wins{background:hsl(var(--bg-200)/.6)}#content-container .digest-wins-title{font-family:\"Anthropic Serif Display\",Georgia,serif;font-size:1.25rem;font-weight:500;color:hsl(var(--text-000));margin:0 0 .75rem}.digest-wins-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));column-gap:2rem}#content-container .digest-wins-grid>div{position:relative;font-size:.875rem;line-height:1.5;color:hsl(var(--text-300));padding:.5rem 0 .5rem 1.125rem;border-top:1px solid hsl(var(--border-300)/.06);margin:0}#content-container .digest-wins-grid>div::before{content:\"+\";position:absolute;left:0;top:.5rem;font-family:ui-monospace,\"SF Mono\",Menlo,Consolas,monospace;font-size:.8125rem;font-weight:600;color:hsl(var(--accent-brand))}#content-container .digest-wins-grid>div:first-child,#content-container .digest-wins-grid>div:nth-child(2){border-top:none;padding-top:0}#content-container .digest-wins-grid>div:first-child::before,#content-container .digest-wins-grid>div:nth-child(2)::before{top:0}#content-container .digest-wins-grid code{font-size:.8125rem;padding:.1em .3em}:root{--toc-wrapper-max:92rem;--toc-wrapper-pad:2rem;--toc-col:19rem;--toc-side:28rem;--toc-btn-size:1.75rem}#toc-collapse-toggle{display:none;align-items:center;justify-content:center;position:fixed;top:10rem;right:calc(max((100% - var(--toc-wrapper-max))/2,0px) + var(--toc-wrapper-pad) + var(--toc-col) - var(--toc-btn-size) - .35rem);transition:right 200ms ease-out;z-index:30;width:var(--toc-btn-size);height:var(--toc-btn-size);border-radius:9999px;border:1px solid hsl(var(--border-300)/.15);background:hsl(var(--bg-100));color:hsl(var(--text-400));cursor:pointer}#toc-collapse-toggle:hover{background:hsl(var(--bg-300));color:hsl(var(--text-100))}#toc-collapse-toggle svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}#toc-collapse-toggle .toc-glyph{display:none;stroke-width:2}@media print{#toc-collapse-toggle{display:none!important}}@media (prefers-reduced-motion:reduce){#toc-collapse-toggle{transition:none}}@media (min-width:1280px){html:has(#table-of-contents-layout) #toc-collapse-toggle{display:flex}html.toc-collapsed #toc-collapse-toggle .toc-chevron{transform:rotate(180deg)}html.toc-collapsed #toc-collapse-toggle{right:.5rem;width:auto;padding:0 .5rem;gap:.25rem}html.toc-collapsed #toc-collapse-toggle .toc-glyph{display:block}html.toc-collapsed #table-of-contents-layout{display:none!important}html.toc-collapsed #content-side-layout:has(#table-of-contents-layout){display:none!important}html.toc-collapsed #content-container:has(#table-of-contents-layout) #content-area{width:100%!important}html.toc-collapsed #content-container:has(#table-of-contents-layout) #content-area>*{max-width:calc(var(--toc-wrapper-max) - var(--toc-side))}}@media (max-width:640px){.digest-feature{margin:1.5rem 0}#content-container .digest-feature-title{font-size:1.375rem}.digest-feature,.digest-wins{padding:1.25rem 1rem 1rem}.digest-wins-grid{grid-template-columns:1fr}#content-container .digest-wins-grid>div:nth-child(2){border-top:1px solid hsl(var(--border-300)/.06);padding-top:.5rem}#content-container .digest-wins-grid>div:nth-child(2)::before{top:.5rem}}[role=menu]:has(>.nav-dropdown-item){width:340px;max-width:calc(100vw - 32px);max-height:min(680px,calc(100vh - 130px));padding:8px;border-radius:16px}[role=menu]:has(>.nav-dropdown-item:nth-child(5)){width:640px;display:grid;grid-template-columns:1fr 1fr;column-gap:8px;align-content:start}.nav-dropdown-item{padding:9px 12px}.nav-dropdown-item span.text-sm{font-size:14.5px;font-weight:600;color:#141413}.nav-dropdown-item span.text-xs{font-size:13.5px;line-height:1.4;color:#73726c}.dark .nav-dropdown-item span.text-sm{color:#faf9f5}.dark .nav-dropdown-item span.text-xs{color:#97958c}@media (max-width:700px){[role=menu]:has(>.nav-dropdown-item:nth-child(5)){width:340px;display:block}}.nav-tabs .nav-tabs-item:focus-visible{outline:2px solid currentColor;outline-offset:-4px;border-radius:8px}#navigation-items button[aria-haspopup=menu]:not(#localization-select-trigger)~button[aria-haspopup=menu]{display:none}[data-base-ui-portal]:has(.nav-dropdown-item):has(~[data-base-ui-portal] .nav-dropdown-item){visibility:hidden;pointer-events:none}"}],"page":{"pagePath":"en/mcp","slug":"/en/mcp","pageMetadata":{"sidebarTitle":"Reference","title":"Connect Claude Code to tools via MCP","description":"Learn how to connect Claude Code to your tools with the Model Context Protocol.","keywords":["mcp","model context protocol","mcp server",".mcp.json","figma","linear"],"href":"/en/mcp"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Learn how to connect Claude Code to your tools with the Model Context Protocol.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,h5:`h5`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Note,Step,Steps,Tab,Table,Tabs,Tip,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Claude Code can connect to hundreds of external tools and data sources through the `,_jsx(_components.a,{href:`https://modelcontextprotocol.io/introduction`,children:`Model Context Protocol (MCP)`}),`, an open source standard for AI-tool integrations. MCP servers give Claude Code access to your tools, databases, and APIs.`]}),`\n`,_jsx(_components.p,{children:`Connect a server when you find yourself copying data into chat from another tool, like an issue tracker or a monitoring dashboard. Once connected, Claude can read and act on that system directly instead of working from what you paste.`}),`\n`,_jsxs(_components.p,{children:[`If you’re connecting your first server, start with the `,_jsx(_components.a,{href:`/en/mcp-quickstart`,children:`MCP quickstart`}),` for a step-by-step walkthrough. This page is the full reference.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-you-can-do-with-mcp`,children:`What you can do with MCP`}),`\n`,_jsx(_components.p,{children:`With MCP servers connected, you can ask Claude Code to:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Implement features from issue trackers`}),`: “Add the feature described in JIRA issue ENG-4521 and create a PR on GitHub.”`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Analyze monitoring data`}),`: “Check Sentry and Statsig to check the usage of the feature described in ENG-4521.”`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Query databases`}),`: “Find emails of 10 random users who used feature ENG-4521, based on our PostgreSQL database.”`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Integrate designs`}),`: “Update our standard email template based on the new Figma designs that were posted in Slack”`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Automate workflows`}),`: “Create Gmail drafts inviting these 10 users to a feedback session about the new feature.”`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`React to external events`}),`: an MCP server can also act as a `,_jsx(_components.a,{href:`/en/channels`,children:`channel`}),` that pushes messages into your session, so Claude reacts to Telegram messages, Discord chats, or webhook events while you’re away.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`find-and-build-mcp-servers`,children:`Find and build MCP servers`}),`\n`,_jsxs(_components.p,{children:[`Browse reviewed connectors in the `,_jsx(_components.a,{href:`https://claude.ai/directory`,children:`Anthropic Directory`}),`. Directory connectors use the same MCP infrastructure as Claude Code, so you can add any remote server listed there with `,_jsx(_components.code,{children:`claude mcp add`}),`.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Verify you trust each server before connecting it. Servers that fetch external content can expose you to `,_jsx(_components.a,{href:`/en/security#protect-against-prompt-injection`,children:`prompt injection risk`}),`.`]})}),`\n`,_jsxs(_components.p,{children:[`To build your own server, see the `,_jsx(_components.a,{href:`https://modelcontextprotocol.io/docs/develop/build-server`,children:`MCP server guide`}),` for protocol fundamentals and the `,_jsx(_components.a,{href:`https://claude.com/docs/connectors/building`,children:`Claude connector building docs`}),` for authentication, testing, and Directory submission.`]}),`\n`,_jsxs(_components.p,{children:[`You can also have Claude scaffold a server for you with the official `,_jsxs(_components.a,{href:`https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev`,children:[_jsx(_components.code,{children:`mcp-server-dev`}),` plugin`]}),`.`]}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Install the plugin`,children:[_jsxs(_components.p,{children:[`In the VS Code extension or the desktop app, follow `,_jsx(_components.a,{href:`/en/plugins/install#install-a-plugin`,children:`Install a plugin`}),` instead of this step. In a terminal, start Claude Code by running `,_jsx(_components.code,{children:`claude`}),`, then enter this at its prompt:`]}),_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/plugin install mcp-server-dev@claude-plugins-official`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(_components.p,{children:`If the install fails, match the message Claude Code reports:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`Marketplace \"claude-plugins-official\" not found`}),`: add the marketplace with `,_jsx(_components.code,{children:`/plugin marketplace add anthropics/claude-plugins-official`}),`, then retry the install.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`Plugin \"\u003cname>\" not found in marketplace \"claude-plugins-official\"`}),`: your local copy of the marketplace catalog may be out of date. Refresh it with `,_jsx(_components.code,{children:`/plugin marketplace update claude-plugins-official`}),`, then retry the install. If the retry prints the same message, see `,_jsx(_components.a,{href:`/en/plugins/troubleshooting#plugin-not-found-in-marketplace`,children:`Plugin not found in marketplace`}),`.`]}),`\n`]}),_jsxs(_components.p,{children:[`If the install summary reports `,_jsx(_components.code,{children:`Run /reload-plugins to apply.`}),`, Claude Code then runs that reload for you. If the reload warns that your next message would re-read the conversation, run `,_jsx(_components.code,{children:`/reload-plugins --force`}),`.`]})]}),_jsxs(Step,{title:`Run the build skill`,children:[_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp-server-dev:build-mcp-server`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(_components.p,{children:`Claude asks about your use case and scaffolds a remote HTTP or local stdio server.`})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`installing-mcp-servers`,children:`Installing MCP servers`}),`\n`,_jsx(_components.p,{children:`MCP servers can be configured in several ways depending on your needs:`}),`\n`,_jsx(Heading,{level:`3`,id:`option-1-add-a-remote-http-server`,children:`Option 1: Add a remote HTTP server`}),`\n`,_jsx(_components.p,{children:`HTTP servers are the recommended option for connecting to remote MCP servers. This is the most widely supported transport for cloud-based services.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Basic syntax`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`nam`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`e`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`ur`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`l`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Real example: Connect to Notion`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` notion`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.notion.com/mcp`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Example with Bearer token`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` secure-api`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.example.com/mcp`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --header`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer your-token\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`When configuring MCP servers via JSON in `,_jsx(_components.code,{children:`.mcp.json`}),`, `,_jsx(_components.code,{children:`~/.claude.json`}),`, or `,_jsx(_components.code,{children:`claude mcp add-json`}),`, the `,_jsx(_components.code,{children:`type`}),` field accepts `,_jsx(_components.code,{children:`streamable-http`}),` as an alias for `,_jsx(_components.code,{children:`http`}),`. The MCP specification uses the name `,_jsx(_components.code,{children:`streamable-http`}),` for this transport, so configurations copied from server documentation work without modification.`]}),`\n`,_jsxs(_components.p,{children:[`A JSON entry that has a `,_jsx(_components.code,{children:`url`}),` but no `,_jsx(_components.code,{children:`type`}),` is a configuration error, because Claude Code reads an entry with no `,_jsx(_components.code,{children:`type`}),` as a stdio server. Claude Code skips that server and reports `,_jsx(_components.code,{children:`MCP server \"\u003cname>\" has a \"url\" but no \"type\"; add \"type\": \"http\" (or \"sse\" / \"ws\") to this entry`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Only an SDK host application, such as an `,_jsx(_components.a,{href:`/en/agent-sdk/mcp`,children:`Agent SDK`}),` application or the `,_jsx(_components.a,{href:`/en/desktop`,children:`desktop app`}),`, can register an in-process `,_jsx(_components.code,{children:`\"type\": \"sdk\"`}),` server. Claude Code skips a `,_jsx(_components.code,{children:`\"type\": \"sdk\"`}),` entry in `,_jsx(_components.code,{children:`.mcp.json`}),`, `,_jsx(_components.code,{children:`~/.claude.json`}),`, or settings and reports `,_jsx(_components.code,{children:`Skipped — MCP server \"\u003cname>\" declares type \"sdk\", which only an SDK host application can register`}),`.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`In `,_jsx(_components.code,{children:`--output-format stream-json`}),` runs, Claude Code also reports a skipped `,_jsx(_components.code,{children:`--mcp-config`}),` entry in the `,_jsx(_components.code,{children:`system/init`}),` event’s `,_jsxs(_components.a,{href:`/en/headless#stream-responses`,children:[_jsx(_components.code,{children:`mcp_server_errors`}),` field`]}),`, so scripts can detect that the server never loaded.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`option-2-add-a-remote-sse-server`,children:`Option 2: Add a remote SSE server`}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`The SSE (Server-Sent Events) transport is deprecated. Use HTTP servers instead, where available.`})}),`\n`,_jsxs(_components.p,{children:[`Some services still expose only an SSE endpoint. Add these with the same `,_jsx(_components.code,{children:`claude mcp add --transport http \u003cname> \u003curl>`}),` command as `,_jsx(_components.a,{href:`#option-1-add-a-remote-http-server`,children:`an HTTP server`}),`. Claude Code tries the HTTP transport first and switches to SSE when the server doesn’t accept it. The automatic switch requires Claude Code v2.1.265 or later.`]}),`\n`,_jsxs(_components.p,{children:[`On an earlier version, or to connect over SSE directly, pass `,_jsx(_components.code,{children:`--transport sse`}),` instead:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Basic syntax`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sse`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`nam`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`e`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`ur`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`l`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Real example: Connect to Asana`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sse`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` asana`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.asana.com/sse`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Example with authentication header`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sse`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` private-api`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.company.com/sse`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --header`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"X-API-Key: your-key-here\"`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`option-3-add-a-local-stdio-server`,children:`Option 3: Add a local stdio server`}),`\n`,_jsx(_components.p,{children:`Stdio servers run as local processes on your machine. They’re ideal for tools that need direct system access or custom scripts.`}),`\n`,_jsxs(_components.p,{children:[`Claude Code sets `,_jsx(_components.code,{children:`CLAUDE_PROJECT_DIR`}),` in the spawned server’s environment to the project root, so your server can resolve project-relative paths without depending on the working directory. This is the same directory hooks receive in their `,_jsx(_components.code,{children:`CLAUDE_PROJECT_DIR`}),` variable. Read it from inside your server process, for example `,_jsx(_components.code,{children:`process.env.CLAUDE_PROJECT_DIR`}),` in Node or `,_jsx(_components.code,{children:`os.environ[\"CLAUDE_PROJECT_DIR\"]`}),` in Python.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`CLAUDE_PROJECT_DIR`}),` is the stable project root and doesn’t change when you add or remove working directories mid-session. A server that limits its own filesystem access to a set of allowed directories should implement the MCP `,_jsx(_components.code,{children:`roots/list`}),` request instead. Claude Code answers `,_jsx(_components.code,{children:`roots/list`}),` with the session’s launch directory plus every `,_jsx(_components.a,{href:`/en/permissions#working-directories`,children:`additional working directory`}),` you’ve granted with `,_jsx(_components.code,{children:`--add-dir`}),`, `,_jsx(_components.code,{children:`/add-dir`}),`, or the `,_jsx(_components.code,{children:`additionalDirectories`}),` setting. Claude Code sends `,_jsx(_components.code,{children:`notifications/roots/list_changed`}),` when that set changes.`]}),`\n`,_jsxs(_components.p,{children:[`This variable is set in the server’s environment, not in Claude Code’s own environment, so referencing it via `,_jsx(_components.code,{children:\"${VAR}\"}),` expansion in the `,_jsx(_components.code,{children:`command`}),` or `,_jsx(_components.code,{children:`args`}),` of a project-scoped `,_jsx(_components.code,{children:`.mcp.json`}),` entry or a local- or user-scoped server entry in `,_jsx(_components.code,{children:`~/.claude.json`}),` requires a default such as `,_jsx(_components.code,{children:\"${CLAUDE_PROJECT_DIR:-.}\"}),`. Plugin-provided MCP configurations substitute `,_jsx(_components.code,{children:\"${CLAUDE_PROJECT_DIR}\"}),` directly and don’t need the default.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Basic syntax`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [options] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` -- `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`command`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [args...]`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Real example: Add Airtable server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --env`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` AIRTABLE_API_KEY=YOUR_KEY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` stdio`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` airtable`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` npx`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` airtable-mcp-server`})]}),`\n`]})})}),`\n`,_jsxs(Note,{children:[_jsxs(_components.p,{children:[`For stdio servers, the `,_jsx(_components.code,{children:`--`}),` (double dash) separates Claude’s own options, such as `,_jsx(_components.code,{children:`--transport`}),`, `,_jsx(_components.code,{children:`--env`}),`, and `,_jsx(_components.code,{children:`--scope`}),`, from the command and arguments that run the server. Everything after `,_jsx(_components.code,{children:`--`}),` is passed to the server untouched.`]}),_jsx(_components.p,{children:`For example:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`claude mcp add --transport stdio myserver -- npx server`}),` → runs `,_jsx(_components.code,{children:`npx server`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`claude mcp add --env KEY=value --transport stdio myserver -- python server.py --port 8080`}),` → runs `,_jsx(_components.code,{children:`python server.py --port 8080`}),` with `,_jsx(_components.code,{children:`KEY=value`}),` in environment`]}),`\n`]}),_jsxs(_components.p,{children:[`Without `,_jsx(_components.code,{children:`--`}),`, Claude Code would try to parse the server’s flags, like `,_jsx(_components.code,{children:`--port`}),` above, as its own options.`]}),_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--env`}),` accepts multiple `,_jsx(_components.code,{children:`KEY=value`}),` pairs. If the server name comes directly after `,_jsx(_components.code,{children:`--env`}),`, the CLI reads the name as another pair and rejects it, so place at least one other option, such as `,_jsx(_components.code,{children:`--transport stdio`}),`, between `,_jsx(_components.code,{children:`--env`}),` and the server name.`]})]}),`\n`,_jsx(Heading,{level:`4`,id:`how-claude-code-stops-a-stdio-server`,children:`How Claude Code stops a stdio server`}),`\n`,_jsx(_components.p,{children:`When Claude Code disconnects a stdio server, for example when your session ends, it signals the server process and waits briefly for it to exit before forcing it to stop. If your server saves state or removes lock files at shutdown, handle the signal for your platform and finish within that time:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`On macOS and Linux`}),`: Claude Code sends `,_jsx(_components.code,{children:`SIGINT`}),`, then `,_jsx(_components.code,{children:`SIGTERM`}),` if the process is still running 100 milliseconds later, then `,_jsx(_components.code,{children:`SIGKILL`}),` after a further 400 milliseconds.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`On Windows`}),`: Claude Code closes the server’s stdin, then ends the server’s process tree if the process is still running 300 milliseconds later.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Before v2.1.296, Claude Code on Windows ended the server’s process tree at once, without closing stdin first or waiting.`}),`\n`,_jsx(Heading,{level:`3`,id:`option-4-add-a-remote-websocket-server`,children:`Option 4: Add a remote WebSocket server`}),`\n`,_jsxs(_components.p,{children:[`WebSocket servers hold a persistent bidirectional connection, which suits remote MCP servers that push events to Claude unprompted. Use HTTP instead when your server only responds to requests, since HTTP supports OAuth and the `,_jsx(_components.code,{children:`claude mcp add --transport`}),` flag, while WebSocket supports neither.`]}),`\n`,_jsxs(_components.p,{children:[`Configure WebSocket servers in `,_jsx(_components.code,{children:`.mcp.json`}),` or with `,_jsx(_components.code,{children:`claude mcp add-json`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` events-server`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"ws\",\"url\":\"wss://mcp.example.com/socket\",\"headers\":{\"Authorization\":\"Bearer YOUR_TOKEN\"}}'`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`type: \"ws\"`}),` entry accepts the same `,_jsx(_components.code,{children:`url`}),`, `,_jsx(_components.code,{children:`headers`}),`, `,_jsx(_components.code,{children:`headersHelper`}),`, `,_jsx(_components.code,{children:`timeout`}),`, and `,_jsx(_components.code,{children:`alwaysLoad`}),` fields as `,_jsx(_components.code,{children:`http`}),`. Authentication is header-only, so pass a static token in `,_jsx(_components.code,{children:`headers`}),` or generate one at connect time with `,_jsx(_components.a,{href:`#use-dynamic-headers-for-custom-authentication`,children:_jsx(_components.code,{children:`headersHelper`})}),`. The `,_jsx(_components.code,{children:`claude mcp add --transport`}),` flag doesn’t accept `,_jsx(_components.code,{children:`ws`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`add-a-server-from-setup-instructions-written-for-another-client`,children:`Add a server from setup instructions written for another client`}),`\n`,_jsxs(_components.p,{children:[`MCP servers aren’t specific to Claude Code, so a server’s setup instructions may be written for Claude Desktop, Cursor, or another MCP client and give no `,_jsx(_components.code,{children:`claude mcp add`}),` command. To add the server anyway, look in those instructions for a URL, a launch command, or a JSON block:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A URL`}),` such as `,_jsx(_components.code,{children:`https://mcp.example.com/mcp`}),`: the server is remote.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A launch command`}),` such as `,_jsx(_components.code,{children:`npx -y @example/mcp-server`}),`: the server runs on your machine.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`An `,_jsx(_components.code,{children:`mcpServers`}),` JSON block`]}),`: configuration written for another client’s settings file.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Each is one of the inputs the four options in `,_jsx(_components.a,{href:`#installing-mcp-servers`,children:`Installing MCP servers`}),` take. Find the shape you have below to turn it into the command Claude Code accepts. Each command writes to `,_jsx(_components.a,{href:`#local-scope`,children:`local scope`}),` unless you add `,_jsx(_components.code,{children:`--scope project`}),` or `,_jsx(_components.code,{children:`--scope user`}),`.`]}),`\n`,_jsx(`span`,{id:`from-a-url`}),`\n`,_jsx(Heading,{level:`4`,id:`add-a-server-from-a-url`,children:`Add a server from a URL`}),`\n`,_jsxs(_components.p,{children:[`A URL means the server is remote. For an `,_jsx(_components.code,{children:`https://`}),` endpoint, add it with `,_jsx(_components.code,{children:`--transport http`}),`, or follow `,_jsx(_components.a,{href:`#option-2-add-a-remote-sse-server`,children:`Option 2`}),` when the instructions say the endpoint uses SSE. For a `,_jsx(_components.code,{children:`wss://`}),` endpoint, use `,_jsx(_components.a,{href:`#option-4-add-a-remote-websocket-server`,children:`Option 4`}),` instead, since `,_jsx(_components.code,{children:`--transport`}),` doesn’t accept `,_jsx(_components.code,{children:`ws`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` example`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.example.com/mcp`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`If the instructions also give an API key or token header, pass it with `,_jsx(_components.code,{children:`--header`}),` as shown in `,_jsx(_components.a,{href:`#option-1-add-a-remote-http-server`,children:`Option 1`}),`.`]}),`\n`,_jsx(`span`,{id:`from-an-npx-uvx-or-binary-command`}),`\n`,_jsxs(Heading,{level:`4`,id:`add-a-server-from-an-npx-uvx-or-binary-command`,children:[`Add a server from an `,_jsx(_components.code,{children:`npx`}),`, `,_jsx(_components.code,{children:`uvx`}),`, or binary command`]}),`\n`,_jsxs(_components.p,{children:[`A launch command means the server runs as a local stdio process. Put the whole command after `,_jsx(_components.code,{children:`--`}),`, so Claude Code passes flags such as `,_jsx(_components.code,{children:`-y`}),` to the command that starts the server instead of reading them as its own options. Pass any environment variables the instructions ask for with `,_jsx(_components.code,{children:`--env`}),`, after the server name and before `,_jsx(_components.code,{children:`--`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` example`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --env`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` API_KEY=your-key`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` npx`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @example/mcp-server`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`#option-3-add-a-local-stdio-server`,children:`Option 3`}),` covers the `,_jsx(_components.code,{children:`--`}),` separator in full.`]}),`\n`,_jsx(`span`,{id:`from-an-mcpservers-json-block`}),`\n`,_jsxs(Heading,{level:`4`,id:`add-a-server-from-an-mcpservers-json-block`,children:[`Add a server from an `,_jsx(_components.code,{children:`mcpServers`}),` JSON block`]}),`\n`,_jsxs(_components.p,{children:[`An `,_jsx(_components.code,{children:`mcpServers`}),` block written for another MCP client, such as Claude Desktop, uses the wrapper key and entry shape Claude Code reads. Pass `,_jsx(_components.code,{children:`claude mcp add-json`}),` the object inside `,_jsx(_components.code,{children:`mcpServers`}),`, not the wrapper. Two entries need a repair first:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`A `,_jsx(_components.code,{children:`url`}),` with no `,_jsx(_components.code,{children:`type`})]}),`: add `,_jsx(_components.code,{children:`\"type\": \"http\"`}),`, `,_jsx(_components.code,{children:`\"type\": \"sse\"`}),`, or `,_jsx(_components.code,{children:`\"type\": \"ws\"`}),` to match the endpoint. Claude Code reads an entry with no `,_jsx(_components.code,{children:`type`}),` as a stdio server, so a `,_jsx(_components.code,{children:`url`}),` entry without a `,_jsx(_components.code,{children:`type`}),` fails.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A key with characters other than letters, numbers, hyphens, and underscores`}),`: pick a server name that uses only those characters. Otherwise the key is the server name.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`For example, this block:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"example\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"npx\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"-y\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"@example/mcp-server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`becomes this command:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` example`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"command\":\"npx\",\"args\":[\"-y\",\"@example/mcp-server\"]}'`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`#add-mcp-servers-from-json-configuration`,children:`Add MCP servers from JSON configuration`}),` covers shell escaping and the `,_jsx(_components.code,{children:`--scope`}),` flag for `,_jsx(_components.code,{children:`add-json`}),`. To share the server with your team instead, add `,_jsx(_components.code,{children:`--scope project`}),`, or add the entry under `,_jsx(_components.code,{children:`mcpServers`}),` in `,_jsx(_components.code,{children:`.mcp.json`}),` at your project root and commit it. `,_jsx(_components.a,{href:`#project-scope`,children:`Project scope`}),` covers how Claude Code loads and approves that file.`]}),`\n`,_jsxs(_components.p,{children:[`Each `,_jsx(_components.code,{children:`claude mcp add`}),` and `,_jsx(_components.code,{children:`claude mcp add-json`}),` command prints an `,_jsx(_components.code,{children:`Added ...`}),` line on success. To check that Claude Code connected, run `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),`; `,_jsx(_components.a,{href:`#server-status`,children:`Server status`}),` covers the statuses it shows and the approval step for `,_jsx(_components.code,{children:`.mcp.json`}),` servers.`]}),`\n`,_jsx(Heading,{level:`3`,id:`managing-your-servers`,children:`Managing your servers`}),`\n`,_jsx(_components.p,{children:`Once configured, you can manage your MCP servers with these commands:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# List all configured servers`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` list`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Get details for a specific server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` get`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` notion`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Remove a server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` remove`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` notion`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# (within Claude Code) Check server status`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`/mcp`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`When you remove a remote server, Claude Code also deletes the OAuth tokens and client registration it stored for that server. Claude Code doesn’t revoke the tokens at the authorization server that issued them. To revoke the tokens where the authorization server supports revocation, run `,_jsx(_components.a,{href:`#authenticate-from-the-command-line`,children:_jsx(_components.code,{children:`claude mcp logout \u003cname>`})}),` in your shell before `,_jsx(_components.code,{children:`claude mcp remove \u003cname>`}),`.`]}),`\n`,_jsx(Heading,{level:`4`,id:`server-status`,children:`Server status`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`claude mcp add`}),` confirms a successful add by printing an `,_jsx(_components.code,{children:`Added ...`}),` line, which means the configuration was written. If the command prints a `,_jsx(_components.code,{children:`was not saved`}),` message instead, see `,_jsx(_components.a,{href:`/en/errors#mcp-server-was-not-saved-or-removed`,children:`MCP server was not saved or removed`}),`; for a `,_jsx(_components.code,{children:`may not have been saved`}),` message, see `,_jsx(_components.a,{href:`/en/errors#mcp-server-may-not-have-been-saved-or-removed`,children:`MCP server may not have been saved or removed`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`claude mcp list`}),` shows a health status next to each server it lists, such as `,_jsx(_components.code,{children:`✔ Connected`}),`, `,_jsx(_components.code,{children:`! Needs authentication`}),`, or `,_jsx(_components.code,{children:`✘ Failed to connect`}),`. A failure status means Claude Code couldn’t connect to that server, not that the list command failed.`]}),`\n`,_jsx(_components.p,{children:`The statuses in this list report a configuration decision rather than a connection attempt, so Claude Code prints them without connecting to the server:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:\"⏸ Pending approval (run `claude` to approve)\"}),`: a project-scoped server from `,_jsx(_components.code,{children:`.mcp.json`}),` that you haven’t approved yet. Claude Code shows it in both `,_jsx(_components.code,{children:`claude mcp list`}),` and `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),`. Run `,_jsx(_components.code,{children:`claude`}),` interactively to review and approve it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`✘ Rejected (see disabledMcpjsonServers in settings)`}),`: a `,_jsx(_components.code,{children:`.mcp.json`}),` server that a `,_jsx(_components.a,{href:`/en/settings-reference#disabledmcpjsonservers`,children:_jsx(_components.code,{children:`disabledMcpjsonServers`})}),` entry rejects. Claude Code shows it only in `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`⊘ Disabled for this project (re-enable via /mcp)`}),`: a server that the project’s `,_jsx(_components.a,{href:`#disable-a-server-without-removing-it`,children:_jsx(_components.code,{children:`disabledMcpServers`})}),` list names. Claude Code shows it in both `,_jsx(_components.code,{children:`claude mcp list`}),` and `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),`. Turn the server back on from the `,_jsx(_components.code,{children:`/mcp`}),` panel.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`✘ Blocked by enterprise managed policy`}),`: a server that one of your organization’s policies refuses. Claude Code shows it in both `,_jsx(_components.code,{children:`claude mcp list`}),` and `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),`. A server blocked by an allowlist, a denylist, or another restriction in `,_jsx(_components.a,{href:`/en/managed-mcp#how-restrictions-appear-to-users`,children:`managed MCP configuration`}),` is hidden from both commands rather than shown with this status. Ask your administrator which policy blocks the server.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`project-server-approvals-and-workspace-trust`,children:`Project server approvals and workspace trust`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`claude mcp list`}),` and `,_jsx(_components.code,{children:`claude mcp get`}),` read `,_jsx(_components.code,{children:`.mcp.json`}),` approvals only from settings files that aren’t checked into the repository until you trust the workspace by running `,_jsx(_components.code,{children:`claude`}),` in it and accepting the workspace trust dialog. A cloned repository can’t approve its own servers: `,_jsx(_components.a,{href:`/en/settings-reference#enableallprojectmcpservers`,children:_jsx(_components.code,{children:`enableAllProjectMcpServers`})}),` or `,_jsx(_components.a,{href:`/en/settings-reference#enabledmcpjsonservers`,children:_jsx(_components.code,{children:`enabledMcpjsonServers`})}),` committed to the project’s `,_jsx(_components.code,{children:`.claude/settings.json`}),` is ignored in an untrusted folder, and the server stays at `,_jsx(_components.code,{children:`⏸ Pending approval`}),` instead of being connected and health-checked.`]}),`\n`,_jsx(_components.p,{children:`Approvals from these sources still apply in an untrusted folder:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`your user `,_jsx(_components.code,{children:`~/.claude/settings.json`})]}),`\n`,_jsx(_components.li,{children:`managed settings`}),`\n`,_jsxs(_components.li,{children:[`settings passed with `,_jsx(_components.code,{children:`--settings`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code also applies approvals from an untracked `,_jsx(_components.code,{children:`.claude/settings.local.json`}),`, but it runs git to check whether the file is tracked, and it runs that check only in a `,_jsx(_components.a,{href:`/en/permissions#project-allow-rules-and-workspace-trust`,children:`trusted folder`}),`. In a folder you’ve never trusted, Claude Code waits for the trust dialog before applying the file’s approvals, unless the folder is your own configuration home: your home directory, or a directory whose `,_jsx(_components.code,{children:`.claude`}),` you’ve set as `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CONFIG_DIR`})}),`. Before v2.1.207, Claude Code applied approvals from an untracked `,_jsx(_components.code,{children:`.claude/settings.local.json`}),` even in a folder you’d never trusted.`]}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`disabledMcpjsonServers`}),` entry in any settings file still rejects the server.`]}),`\n`,_jsx(Heading,{level:`4`,id:`server-status-detail`,children:`Server status detail`}),`\n`,_jsxs(_components.p,{children:[`In `,_jsx(_components.code,{children:`/mcp`}),`, including a server’s menu there, and in the `,_jsx(_components.a,{href:`/en/plugins/install`,children:_jsx(_components.code,{children:`/plugin`})}),` manager, a remote HTTP or SSE server you’ve used before can show a `,_jsx(_components.code,{children:`cached`}),` status such as `,_jsx(_components.code,{children:`cached 2h ago · connects on first use · 5 tools`}),`. Claude Code loaded the server’s tool list from its discovery cache, saved in a previous session, instead of connecting at startup, and Claude Code connects the server the first time Claude calls one of the server’s tools. The tools are available from your first message, so you don’t need to do anything. The discovery cache and its `,_jsx(_components.code,{children:`cached`}),` status require Claude Code v2.1.221 or later.`]}),`\n`,_jsxs(_components.p,{children:[`The discovery cache is off by default unless a gradual rollout has enabled it for your account. Set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_DISCOVERY_CACHE=1`})}),` to turn it on, or `,_jsx(_components.code,{children:`0`}),` to keep it off even when the rollout has enabled it. Before v2.1.238, the cache was on by default.`]}),`\n`,_jsxs(_components.p,{children:[`When you select `,_jsx(_components.strong,{children:`Disable`}),` or `,_jsx(_components.strong,{children:`Clear authentication`}),` from a server’s menu in `,_jsx(_components.code,{children:`/mcp`}),`, Claude Code also discards that server’s cache entry. `,_jsx(_components.strong,{children:`Reconnect`}),` discards it too on a connected or failed server; on a `,_jsx(_components.code,{children:`cached`}),` server, `,_jsx(_components.strong,{children:`Reconnect`}),` connects the server now and keeps the entry. The next time Claude Code connects to the server after discarding the entry, it fetches the tool list from the server instead of from the cache.`]}),`\n`,_jsx(_components.h5,{children:`Connection failures and unconfigured servers`}),`\n`,_jsxs(_components.p,{children:[`When a server’s status is `,_jsx(_components.code,{children:`✘ Failed to connect`}),`, `,_jsx(_components.code,{children:`claude mcp list`}),` appends the failure detail to that status line, and `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),` shows it on an `,_jsx(_components.code,{children:`Issue:`}),` line. The detail is the HTTP status or error code, plus any error text the server returned. The server’s detail view in `,_jsx(_components.code,{children:`/mcp`}),` includes the same server-reported text in its `,_jsx(_components.code,{children:`Issue:`}),` row.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code redacts credential-like text from this detail and never includes the expanded server URL, which can carry secrets. Claude Code appends no detail to a `,_jsx(_components.code,{children:`✘ Connection error`}),` status, because the exception text it would print there can embed that URL.`]}),`\n`,_jsxs(_components.p,{children:[`When you complete authentication from `,_jsx(_components.code,{children:`/mcp`}),` and the connection still fails with an HTTP status or a transport error code, Claude Code adds that code and the origin of the server’s URL to the message it prints after the attempt. The origin is the scheme and host, plus the port when the URL names one, such as `,_jsx(_components.code,{children:`https://mcp.example.com`}),`.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The path and query never appear in that message.`}),`\n`,_jsxs(_components.li,{children:[`For a server in the local, project, or user `,_jsx(_components.a,{href:`#mcp-installation-scopes`,children:`scope`}),` or in managed MCP configuration, the origin shows the host as written in that configuration, so a `,_jsx(_components.code,{children:\"${VAR}\"}),` reference in the host isn’t expanded in the message.`]}),`\n`,_jsx(_components.li,{children:`For a failure with no status or error code, Claude Code shows the error text without the origin.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`A remote server whose configuration has an empty `,_jsx(_components.code,{children:`url`}),` shows as `,_jsx(_components.code,{children:`not configured`}),` in `,_jsx(_components.code,{children:`/mcp`}),`, in `,_jsx(_components.code,{children:`claude mcp list`}),`, and in the `,_jsx(_components.a,{href:`/en/plugins/install`,children:_jsx(_components.code,{children:`/plugin`})}),` manager, and Claude Code doesn’t attempt to connect to it. A plugin can include a placeholder entry like this for a connector you configure later, so Claude Code doesn’t report it as an error or a setup issue. The server’s detail view in `,_jsx(_components.code,{children:`/mcp`}),` reads `,_jsx(_components.code,{children:`No URL configured for this server`}),`; set the entry’s `,_jsx(_components.code,{children:`url`}),` to connect it.`]}),`\n`,_jsx(Heading,{level:`4`,id:`configuration-warnings`,children:`Configuration warnings`}),`\n`,_jsx(_components.p,{children:`Claude Code warns about the configuration problems below. Each entry says what Claude Code checks and how to clear the warning:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Hidden whitespace`}),`: Claude Code warns when an MCP config value carries hidden leading or trailing whitespace, which often comes from pasting a token with a trailing newline. Claude Code checks `,_jsx(_components.code,{children:`command`}),`, `,_jsx(_components.code,{children:`url`}),`, each `,_jsx(_components.code,{children:`args`}),` entry, and the values and key names under `,_jsx(_components.code,{children:`env`}),` and `,_jsx(_components.code,{children:`headers`}),`. Claude Code shows the warning in `,_jsx(_components.code,{children:`claude mcp list`}),` output and in `,_jsx(_components.code,{children:`/mcp`}),`, naming the affected fields without echoing their values, for example `,_jsx(_components.code,{children:`Leading or trailing whitespace in: headers.Authorization`}),`. Claude Code doesn’t trim the whitespace and uses the values exactly as written, so edit the configuration to remove it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Same name in more than one scope`}),`: if you define the same server name in more than one `,_jsx(_components.a,{href:`#mcp-installation-scopes`,children:`scope`}),` with different endpoints, Claude Code warns about the conflict in `,_jsx(_components.code,{children:`claude mcp list`}),` output and in `,_jsx(_components.code,{children:`/mcp`}),`. Claude Code stores OAuth sign-ins per endpoint, so when you authenticate the definition that loads in one project, you still need to sign in separately in a project where a different definition loads. Keep the endpoint you want and remove the others with `,_jsx(_components.code,{children:`claude mcp remove \u003cname> --scope \u003cscope>`}),`. In the warning, Claude Code quotes each scope’s endpoint as written in your configuration, with `,_jsxs(_components.a,{href:`#environment-variable-expansion-in-mcp-json`,children:[_jsx(_components.code,{children:\"${VAR}\"}),` references`]}),` unexpanded, so it never shows a resolved value such as an API key.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Reserved names`}),`: Claude Code reserves the names of its built-in servers, including `,_jsx(_components.code,{children:`workspace`}),`, `,_jsx(_components.code,{children:`claude-in-chrome`}),`, `,_jsx(_components.code,{children:`computer-use`}),`, `,_jsx(_components.code,{children:`Claude Preview`}),`, and `,_jsx(_components.code,{children:`Claude Browser`}),`. If your configuration defines a server with a reserved name, Claude Code skips it at load time and shows a warning asking you to rename it. `,_jsx(_components.code,{children:`claude mcp add`}),` rejects a reserved name with an error. `,_jsx(_components.code,{children:`Claude Preview`}),` and `,_jsx(_components.code,{children:`Claude Browser`}),` both name the built-in server that the `,_jsx(_components.a,{href:`/en/desktop#preview-your-app`,children:`Claude Code desktop app’s preview pane`}),` uses.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Missing environment variable`}),`: if a `,_jsxs(_components.a,{href:`#environment-variable-expansion-in-mcp-json`,children:[_jsx(_components.code,{children:\"${VAR}\"}),` reference`]}),` in a server’s configuration names a variable that isn’t set and has no `,_jsx(_components.code,{children:`:-default`}),`, Claude Code warns in `,_jsx(_components.code,{children:`claude mcp list`}),` output and in `,_jsx(_components.code,{children:`/mcp`}),`, naming the variable, and still loads the server with the `,_jsx(_components.code,{children:\"${VAR}\"}),` text unexpanded. Set the variable or add a `,_jsx(_components.code,{children:\"${VAR:-default}\"}),` fallback. In a remote server’s `,_jsx(_components.code,{children:`url`}),` and `,_jsx(_components.code,{children:`headers`}),`, some credential variables `,_jsx(_components.a,{href:`#credential-variables-that-read-as-empty`,children:`read as empty`}),` instead, with no warning.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`tool-availability`,children:`Tool availability`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`/mcp`}),` panel shows the tool count next to each connected server and flags servers that advertise the tools capability but expose no tools.`]}),`\n`,_jsx(_components.p,{children:`If your request needs tools from a server that is still connecting in the background, Claude waits for that server before continuing. How the wait happens depends on your configuration:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`With `,_jsx(_components.a,{href:`#scale-with-mcp-tool-search`,children:`tool search`}),`, the default`]}),`: the wait happens inside the `,_jsx(_components.code,{children:`ToolSearch`}),` call.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Without tool search`}),`: Claude uses the `,_jsx(_components.code,{children:`WaitForMcpServers`}),` tool instead. Configurations without tool search include `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=false`}),` and a model earlier than Claude Opus 4.5, Claude Sonnet 4.5, and Claude Haiku 4.5 on Google Cloud’s Agent Platform. For an `,_jsx(_components.code,{children:`ANTHROPIC_BASE_URL`}),` gateway, see `,_jsx(_components.a,{href:`#tool-search-through-a-gateway`,children:`Tool search through an LLM gateway`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`On a Microsoft Foundry `,_jsx(_components.a,{href:`https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry#hosting-options`,children:`deployment hosted on Azure`})]}),`: Claude starts on the tool-search path rather than with `,_jsx(_components.code,{children:`WaitForMcpServers`}),`, since Claude Code discovers the deployment’s server-side rejection only from the API. After Claude Code switches that deployment to `,_jsx(_components.a,{href:`#scale-with-mcp-tool-search`,children:`upfront loading`}),`, tools from a server that finishes connecting become available on Claude’s next request.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`With tool search enabled, when a server finishes connecting while Claude is working, Claude Code lists the server’s tool names to Claude on its next request in the same turn. Claude can then search for and call those tools without waiting for your next message.`}),`\n`,_jsxs(_components.p,{children:[`After you resume a session, Claude can call a tool from the saved conversation while the tool’s MCP server is still connecting. While the server is on its first connection attempt, Claude Code holds the call for up to 10 seconds and runs it once the tool is available. If the server doesn’t connect in time, or it is already `,_jsx(_components.a,{href:`#automatic-reconnection`,children:`retrying after a failed attempt`}),`, the call fails with the `,_jsx(_components.code,{children:`No such tool available`}),` `,_jsx(_components.a,{href:`/en/errors#no-such-tool-available`,children:`tool error`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`disable-a-server-without-removing-it`,children:`Disable a server without removing it`}),`\n`,_jsxs(_components.p,{children:[`Toggle a server off in the `,_jsx(_components.code,{children:`/mcp`}),` panel to stop Claude Code from connecting to it without losing its configuration. Claude Code still lists the server in `,_jsx(_components.code,{children:`/mcp`}),`, marked as disabled.`]}),`\n`,_jsxs(_components.p,{children:[`When you toggle a server, Claude Code records your choice per project in `,_jsx(_components.code,{children:`~/.claude.json`}),`, in one of two lists that cover disjoint sets of servers:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`disabledMcpServers`}),`: an opt-out list for user-configured servers, plugin servers, servers your organization `,_jsx(_components.a,{href:`/en/managed-mcp#provide-servers-through-managed-settings`,children:`provides through managed settings`}),`, the claude.ai connectors Claude Code `,_jsx(_components.a,{href:`#how-connectors-reach-claude-code`,children:`fetches itself`}),`, and built-in servers that default to on. Claude Code doesn’t connect to a server you list here. When you disable a claude.ai connector with the per-project `,_jsx(_components.code,{children:`/mcp`}),` toggle described in `,_jsx(_components.a,{href:`#disable-claude-ai-connectors`,children:`Disable claude.ai connectors`}),`, Claude Code writes it to this list under its display name, for example `,_jsx(_components.code,{children:`claude.ai Slack`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`enabledMcpServers`}),`: an opt-in list for built-in servers that default to off, such as `,_jsx(_components.code,{children:`computer-use`}),`. Claude Code connects to a default-off server only when you list it here.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code consults exactly one of the two lists for each server, so neither list overrides the other. If you add a regular server to `,_jsx(_components.code,{children:`enabledMcpServers`}),`, or a default-off built-in server to `,_jsx(_components.code,{children:`disabledMcpServers`}),`, Claude Code ignores the entry.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`disabledMcpServers`}),` and `,_jsx(_components.code,{children:`enabledMcpServers`}),` are unrelated to `,_jsx(_components.a,{href:`/en/settings-reference#enabledmcpjsonservers`,children:_jsx(_components.code,{children:`enabledMcpjsonServers`})}),` and `,_jsx(_components.a,{href:`/en/settings-reference#disabledmcpjsonservers`,children:_jsx(_components.code,{children:`disabledMcpjsonServers`})}),`, which control approval of servers defined in a project’s `,_jsx(_components.code,{children:`.mcp.json`}),` file.`]}),`\n`,_jsx(Heading,{level:`3`,id:`mcp-client-runtimes`,children:`MCP client runtimes`}),`\n`,_jsxs(_components.p,{children:[`Claude Code connects to MCP servers through one of two client runtimes. The v1 runtime is built on MCP TypeScript SDK 1.x. The v2 runtime is the same code on `,_jsx(_components.a,{href:`https://ts.sdk.modelcontextprotocol.io/v2/`,children:`MCP TypeScript SDK 2.0`}),`, which adds MCP protocol revision 2026-07-28. The rest of this page applies to both runtimes, except where a section names the v2 runtime.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code picks a runtime each time you start it and keeps it until you exit. In sessions where it `,_jsx(_components.a,{href:`/en/env-vars#features-that-need-feature-flag-fetching`,children:`fetches feature flags`}),`, it uses the v2 runtime on Claude Code v2.1.232 or later.`]}),`\n`,_jsx(_components.p,{children:`In the sessions where it doesn’t fetch feature flags, Claude Code uses the v2 runtime by default on Claude Code v2.1.274 or later:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Sessions on Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry, unless a host platform that embeds Claude Code sets `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`})})]}),`\n`,_jsxs(_components.li,{children:[`Sessions signed in through a `,_jsx(_components.a,{href:`/en/claude-apps-gateway`,children:`Claude apps gateway`})]}),`\n`,_jsxs(_components.li,{children:[`Sessions where you turn off telemetry or feature-flag fetching, for example with `,_jsx(_components.code,{children:`DISABLE_TELEMETRY`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`On v2, Claude Code also:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Asks HTTP, stdio, and claude.ai connector servers whether they support the newer revision and uses it with those that do. That includes the connectors of cloud and `,_jsx(_components.a,{href:`/en/remote-control`,children:`Remote Control`}),` sessions. Claude Code connects to every other server as v1 does.`]}),`\n`,_jsxs(_components.li,{children:[`Receives `,_jsx(_components.code,{children:`list_changed`}),` notifications from servers on the newer revision over a `,_jsx(_components.a,{href:`#notification-streams-on-the-v2-runtime`,children:`stream it holds open`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Doesn’t register a `,_jsx(_components.a,{href:`#push-messages-with-channels`,children:`channel`}),` server that connects on the newer revision, because that revision can’t carry channel messages.`]}),`\n`,_jsxs(_components.li,{children:[`Fails an `,_jsx(_components.a,{href:`#authenticate-with-remote-mcp-servers`,children:`MCP OAuth sign-in`}),` whose authorization response names an unexpected issuer.`]}),`\n`,_jsxs(_components.li,{children:[`Sends `,_jsx(_components.a,{href:`#authenticate-with-remote-mcp-servers`,children:`MCP OAuth`}),` credentials only to a token endpoint served over HTTPS or at `,_jsx(_components.code,{children:`localhost`}),`, `,_jsx(_components.code,{children:`127.0.0.1`}),`, or `,_jsx(_components.code,{children:`::1`}),`. Sign-in fails for a server whose token endpoint is plain `,_jsx(_components.code,{children:`http://`}),` anywhere else, such as a device on your local network. See `,_jsx(_components.a,{href:`/en/errors#refusing-to-send-credentials-to-non-https-token-endpoint`,children:`Refusing to send credentials to non-https token endpoint`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Anthropic can keep a specific server on the earlier protocol, or off that stream, with a feature flag Claude Code fetches.`}),`\n`,_jsxs(_components.p,{children:[`To pick the runtime yourself, set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_SDK_GENERATION`})}),` to `,_jsx(_components.code,{children:`v1`}),` or `,_jsx(_components.code,{children:`v2`}),`. To decide whether Claude Code asks, set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_PROTOCOL_NEGOTIATION`})}),` to `,_jsx(_components.code,{children:`auto`}),` or `,_jsx(_components.code,{children:`legacy`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`dynamic-tool-updates`,children:`Dynamic tool updates`}),`\n`,_jsxs(_components.p,{children:[`An MCP server can change the tools, prompts, or resources it offers while connected and send a `,_jsx(_components.code,{children:`list_changed`}),` notification. When one arrives:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`In an interactive terminal session`}),`, Claude Code fetches the updated list from that server, so you don’t need to reconnect it.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`In `,_jsx(_components.a,{href:`/en/headless`,children:`non-interactive mode`}),` with the `,_jsx(_components.code,{children:`-p`}),` flag and in the `,_jsx(_components.a,{href:`/en/agent-sdk/overview`,children:`Agent SDK`})]}),`, Claude Code refreshes only the tool list on these notifications.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`If a refresh request fails, Claude Code keeps the server’s previously discovered tools, prompts, and resources until a later refresh succeeds.`}),`\n`,_jsx(Heading,{level:`4`,id:`notification-streams-on-the-v2-runtime`,children:`Notification streams on the v2 runtime`}),`\n`,_jsxs(_components.p,{children:[`On the `,_jsx(_components.a,{href:`#mcp-client-runtimes`,children:`v2 runtime`}),`, Claude Code receives `,_jsx(_components.code,{children:`list_changed`}),` notifications from a server on the newer protocol revision over a stream it holds open. When the stream closes, Claude Code reopens it, with two limits:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The stream closes again within 10 seconds`}),`: Claude Code reopens it up to three times, then stops for that connection.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The stream stays open longer than 10 seconds, then closes`}),`, as streams to serverless hosts commonly do: after five reopens in an hour, Claude Code waits about six hours before the next one.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Until the stream reopens, you keep the server’s last fetched tools, prompts, and resources. To pick up its changes sooner, reconnect the server from `,_jsx(_components.code,{children:`/mcp`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`automatic-reconnection`,children:`Automatic reconnection`}),`\n`,_jsxs(_components.p,{children:[`Claude Code reconnects a remote server that drops mid-session and retries an HTTP or SSE server’s first connection after a transient error. For a stdio server, see `,_jsx(_components.a,{href:`#stdio-servers-that-exit-or-fail-to-start`,children:`Stdio servers that exit or fail to start`}),`.`]}),`\n`,_jsx(Heading,{level:`4`,id:`mid-session-drops-of-a-remote-server`,children:`Mid-session drops of a remote server`}),`\n`,_jsx(_components.p,{children:`Claude Code first tries to reconnect a dropped remote server up to five times with exponential backoff, starting at a one-second delay and doubling it each time:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`In an interactive session`}),`: `,_jsx(_components.code,{children:`/mcp`}),` shows the server as pending while Claude Code reconnects. After five failed attempts, Claude Code marks the server as failed, or as needing authentication when the server needs authorizing again. When it marks the server as failed, you see an `,_jsx(_components.code,{children:`MCP server \"\u003cname>\" disconnected · open /mcp to reconnect`}),` notification. You can retry manually from `,_jsx(_components.code,{children:`/mcp`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`In `,_jsx(_components.a,{href:`/en/headless`,children:_jsx(_components.code,{children:`claude -p`})}),` runs and `,_jsx(_components.a,{href:`/en/agent-sdk/overview`,children:`Agent SDK`}),` sessions`]}),`: Claude Code makes the same five attempts, with no `,_jsx(_components.code,{children:`/mcp`}),` panel to show them. If all five fail, the run continues without the server’s tools:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`After a transient error, such as a 5xx response or a timeout`}),`: Claude Code keeps retrying an HTTP or SSE server in the background. Retries last up to about half an hour, and the server’s tools become available again when one connects. Until then, an Agent SDK session reports the `,_jsx(_components.a,{href:`/en/agent-sdk/mcp#error-handling`,children:`status`}),` `,_jsx(_components.code,{children:`failed`}),`, and your code can `,_jsx(_components.a,{href:`/en/agent-sdk/mcp#error-handling`,children:`reconnect the server`}),`. To reconnect it in `,_jsx(_components.code,{children:`claude -p`}),`, start the run again.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`When the server `,_jsx(_components.a,{href:`#authenticate-with-remote-mcp-servers`,children:`needs you to sign in again`})]}),`: Claude Code stops retrying, and an Agent SDK session reports the server’s status as `,_jsx(_components.code,{children:`needs-auth`}),`. Sign in with `,_jsx(_components.a,{href:`#authenticate-from-the-command-line`,children:_jsx(_components.code,{children:`claude mcp login \u003cname>`})}),` in your shell. Then start the run again or, in an Agent SDK session, `,_jsx(_components.a,{href:`/en/agent-sdk/mcp#error-handling`,children:`reconnect the server`}),` instead.`]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`failed-first-connections`,children:`Failed first connections`}),`\n`,_jsx(_components.p,{children:`When an HTTP or SSE server’s first connection fails with a transient error, such as a 5xx response, a connection refused, or a timeout, Claude Code retries up to three times. If the connection still fails, Claude Code marks the server as failed.`}),`\n`,_jsx(_components.p,{children:`Those retries don’t apply in these cases:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A stdio server’s first connection. To try it again, see `,_jsx(_components.a,{href:`#stdio-servers-that-exit-or-fail-to-start`,children:`Stdio servers that exit or fail to start`})]}),`\n`,_jsxs(_components.li,{children:[`A WebSocket server’s first connection. To try it again in an interactive terminal session, select `,_jsx(_components.strong,{children:`Reconnect`}),` from the server’s menu in `,_jsx(_components.code,{children:`/mcp`})]}),`\n`,_jsxs(_components.li,{children:[`An authentication or not-found error, because it requires a configuration change to resolve. When a `,_jsx(_components.a,{href:`#use-dynamic-headers-for-custom-authentication`,children:_jsx(_components.code,{children:`headersHelper`})}),` is the server’s only source of the `,_jsx(_components.code,{children:`Authorization`}),` header, Claude Code retries an authentication error anyway, because it re-runs the helper on each attempt and can pick up a fresh credential`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`stdio-servers-that-exit-or-fail-to-start`,children:`Stdio servers that exit or fail to start`}),`\n`,_jsxs(_components.p,{children:[`To start a stdio server again, read the column that matches what happened to it. Find your row by how you run Claude Code: an interactive session, a `,_jsx(_components.code,{children:`claude -p`}),` run, or an Agent SDK session.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`How you run Claude Code`}),_jsx(_components.th,{children:`The server’s process exits mid-session`}),_jsx(_components.th,{children:`The server’s first connection fails`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Interactive session`}),_jsxs(_components.td,{children:[`Claude Code marks the server as failed. To start it again, select `,_jsx(_components.strong,{children:`Reconnect`}),` from the server’s menu in `,_jsx(_components.code,{children:`/mcp`})]}),_jsxs(_components.td,{children:[`Claude Code marks the server as failed. To start it again, select `,_jsx(_components.strong,{children:`Reconnect`}),` from the server’s menu in `,_jsx(_components.code,{children:`/mcp`})]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`claude -p`}),` run`]}),_jsx(_components.td,{children:`Claude Code starts the server again the next time Claude calls one of the server’s tools, and the call runs once the server connects`}),_jsxs(_components.td,{children:[`The run continues without the server’s tools. To have Claude Code try the connection again, start the run again. When a plugin provides the server, new runs skip the connection for 15 minutes after a failure, so wait that long first or `,_jsx(_components.a,{href:`/en/errors#skipping-connection-recent-failure-cached`,children:`retry sooner`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Agent SDK session`}),_jsx(_components.td,{children:`Claude Code starts the server again the next time Claude calls one of the server’s tools, and the call runs once the server connects`}),_jsxs(_components.td,{children:[`The session continues without the server’s tools. Your code can `,_jsx(_components.a,{href:`/en/agent-sdk/mcp#error-handling`,children:`reconnect the server`})]})]})]})]}),`\n`,_jsx(Heading,{level:`4`,id:`failed-discovery-requests`,children:`Failed discovery requests`}),`\n`,_jsxs(_components.p,{children:[`After a server connects, Claude Code sends it capability discovery requests such as `,_jsx(_components.code,{children:`tools/list`}),`, `,_jsx(_components.code,{children:`prompts/list`}),`, and `,_jsx(_components.code,{children:`resources/list`}),`. Claude Code retries those requests up to three times with short backoff after a transient network or server error. It doesn’t retry authentication errors, 4xx responses, or request timeouts.`]}),`\n`,_jsx(Heading,{level:`4`,id:`retry-failed-servers-yourself`,children:`Retry failed servers yourself`}),`\n`,_jsxs(_components.p,{children:[`To retry every server that failed or needs authentication, run `,_jsx(_components.code,{children:`/mcp reconnect all`}),` at the Claude Code prompt in an interactive terminal session. This requires Claude Code v2.1.284 or later. Earlier versions print `,_jsx(_components.code,{children:`MCP server \"all\" not found`}),`.`]}),`\n`,_jsx(Heading,{level:`4`,id:`how-claude-learns-that-a-server-failed`,children:`How Claude learns that a server failed`}),`\n`,_jsxs(_components.p,{children:[`Whether Claude Code tells Claude about a configured server that failed to connect depends on `,_jsx(_components.a,{href:`#scale-with-mcp-tool-search`,children:`tool search`}),`, which is on by default:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`With tool search, Claude Code tells Claude which server failed and its connection error, so Claude reports the connection failure in its response. Claude Code includes the same information in `,_jsx(_components.code,{children:`ToolSearch`}),` results that find no matching tool.`]}),`\n`,_jsxs(_components.li,{children:[`In any `,_jsx(_components.a,{href:`#configure-tool-search`,children:`configuration without tool search`}),`, Claude Code doesn’t report failed server connections to Claude.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`push-messages-with-channels`,children:`Push messages with channels`}),`\n`,_jsxs(_components.p,{children:[`An MCP server can also push messages directly into your session so Claude can react to external events like CI results, monitoring alerts, or chat messages. To enable this, your server declares the `,_jsx(_components.code,{children:`claude/channel`}),` capability and you opt it in with the `,_jsx(_components.code,{children:`--channels`}),` flag at startup. See `,_jsx(_components.a,{href:`/en/channels`,children:`Channels`}),` to use an officially supported channel, or `,_jsx(_components.a,{href:`/en/channels-reference`,children:`Channels reference`}),` to build your own.`]}),`\n`,_jsxs(_components.p,{children:[`On the `,_jsx(_components.a,{href:`#mcp-client-runtimes`,children:`v2 runtime`}),`, a channel server that negotiates MCP protocol revision 2026-07-28 can’t deliver channel messages, so Claude Code doesn’t register it as a channel. A channel server that doesn’t support that revision connects on the earlier handshake and registers as before.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code asks stdio servers for that revision by default. To keep a stdio channel server on the earlier handshake, set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_PROTOCOL_NEGOTIATION`})}),` to `,_jsx(_components.code,{children:`legacy`}),`, which keeps every server on it.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Use the `,_jsx(_components.code,{children:`-s`}),` or `,_jsx(_components.code,{children:`--scope`}),` flag to specify where the configuration is stored:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`local`}),` (default): available only to you in the current project`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`project`}),`: shared with everyone in the project via the `,_jsx(_components.code,{children:`.mcp.json`}),` file`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`user`}),`: available to you across all projects`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Set environment variables with `,_jsx(_components.code,{children:`-e`}),` or `,_jsx(_components.code,{children:`--env`}),` flags (for example, `,_jsx(_components.code,{children:`-e KEY=value`}),`)`]}),`\n`,_jsxs(_components.li,{children:[`The `,_jsx(_components.code,{children:`--transport`}),` and `,_jsx(_components.code,{children:`--header`}),` flags also accept `,_jsx(_components.code,{children:`-t`}),` and `,_jsx(_components.code,{children:`-H`}),` short forms`]}),`\n`,_jsxs(_components.li,{children:[`Configure MCP server startup timeout using the `,_jsx(_components.code,{children:`MCP_TIMEOUT`}),` environment variable (for example, `,_jsx(_components.code,{children:`MCP_TIMEOUT=10000 claude`}),` sets a 10-second timeout)`]}),`\n`,_jsxs(_components.li,{children:[`Set a per-server tool execution timeout by adding a `,_jsx(_components.code,{children:`timeout`}),` field in milliseconds to that server’s `,_jsx(_components.code,{children:`.mcp.json`}),` entry, for example `,_jsx(_components.code,{children:`\"timeout\": 600000`}),` for ten minutes. This overrides the `,_jsx(_components.code,{children:`MCP_TOOL_TIMEOUT`}),` environment variable for that server only`]}),`\n`,_jsxs(_components.li,{children:[`Claude Code displays a warning when MCP tool output exceeds 10,000 tokens and limits output to 25,000 tokens by default. To change the token limit, set the `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` environment variable, for example `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS=50000`}),`. The warning threshold is fixed. Unless the server raises a tool’s own limit, successful text results longer than 50,000 characters are saved to a file regardless of this variable. See `,_jsx(_components.a,{href:`#mcp-output-limits-and-warnings`,children:`MCP output limits and warnings`})]}),`\n`,_jsxs(_components.li,{children:[`Use `,_jsx(_components.code,{children:`/mcp`}),` to authenticate with remote servers that require OAuth 2.0 authentication`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`3`,id:`time-limits-on-mcp-tool-calls`,children:`Time limits on MCP tool calls`}),`\n`,_jsx(_components.p,{children:`To limit how long an MCP tool call can run:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Per server`}),`: add a `,_jsx(_components.code,{children:`timeout`}),` field in milliseconds to that server’s configuration entry`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Across servers`}),`: set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_TOOL_TIMEOUT`})})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The per-server `,_jsx(_components.code,{children:`timeout`}),` is a hard wall-clock limit per tool call, and progress notifications from the server don’t extend it. Values below 1000 are ignored and fall through to `,_jsx(_components.code,{children:`MCP_TOOL_TIMEOUT`}),`, or to its default of about 28 hours when that variable is unset. For an HTTP, SSE, or `,_jsx(_components.a,{href:`/en/mcp#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),` server there is also a second, per-request timer that covers each request through to the server’s first response byte. Claude Code sets that timer to the greatest of three values: 60 seconds, the tool timeout that applies to the server, and `,_jsx(_components.code,{children:`MCP_TIMEOUT`}),`. The 28-hour default of an unset `,_jsx(_components.code,{children:`MCP_TOOL_TIMEOUT`}),` doesn’t enter that comparison, and a value below 60 seconds doesn’t shorten the timer. Stdio and WebSocket servers have no per-request timer.`]}),`\n`,_jsxs(_components.p,{children:[`A per-server `,_jsx(_components.code,{children:`timeout`}),` of at least 1000 also acts as a floor on the idle timeout described below: Claude Code never aborts that server’s tool calls for idleness sooner than the per-server `,_jsx(_components.code,{children:`timeout`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`A tool call to an MCP server that sends no response and no progress notification for the idle window aborts with an error instead of waiting for the wall-clock limit. The idle timeout applies to every server type except IDE servers and SDK in-process servers. The idle window defaults to five minutes for HTTP, SSE, WebSocket, and `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),` servers, and to 30 minutes for stdio servers.`]}),`\n`,_jsxs(_components.p,{children:[`Set the `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`})}),` environment variable in milliseconds to change the idle window, or set it to `,_jsx(_components.code,{children:`0`}),` to disable the check.`]}),`\n`,_jsxs(_components.p,{children:[`These timeouts bound how long a call can run, not always how long it blocks the session: a main-conversation call that runs past two minutes moves to a background task first. See `,_jsx(_components.a,{href:`#automatic-backgrounding-of-long-tool-calls`,children:`Automatic backgrounding of long tool calls`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`automatic-backgrounding-of-long-tool-calls`,children:`Automatic backgrounding of long tool calls`}),`\n`,_jsxs(_components.p,{children:[`If a background call’s detail view in `,_jsx(_components.a,{href:`/en/commands#all-commands`,children:_jsx(_components.code,{children:`/tasks`})}),` shows `,_jsx(_components.code,{children:`runs on the server; survives exiting this session`}),`, see `,_jsx(_components.a,{href:`#mcp-tasks-that-run-on-the-server`,children:`MCP tasks that run on the server`}),`.`]}),`\n`,_jsx(_components.p,{children:`An MCP tool call in the main conversation that is still running after two minutes moves to a background task instead of blocking the session. Claude receives the task ID immediately and keeps working, and the result arrives as a task notification when the call settles.`}),`\n`,_jsxs(_components.p,{children:[`The task appears in `,_jsx(_components.a,{href:`/en/commands#all-commands`,children:_jsx(_components.code,{children:`/tasks`})}),`, where you can also stop it, and it doesn’t survive exiting the session. The task’s entry shows the latest progress the server has reported. If you stop the task, Claude Code cancels the call and tells Claude that no result is coming. Stopping doesn’t guarantee the server stops: it may already have done some of the work, or may still finish it.`]}),`\n`,_jsxs(_components.p,{children:[`The per-call limits still apply while the call runs in the background: the wall-clock limit set by the per-server `,_jsx(_components.code,{children:`timeout`}),` or `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_TOOL_TIMEOUT`})}),`, and the idle timeout set by `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`})}),`.`]}),`\n`,_jsx(_components.p,{children:`To change or turn off automatic backgrounding:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Set the `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`})}),` environment variable in milliseconds to change the threshold, or set it to `,_jsx(_components.code,{children:`0`}),` to turn automatic backgrounding off. With `,_jsx(_components.code,{children:`0`}),`, Claude also `,_jsx(_components.a,{href:`#make-claude-wait-for-the-result-of-an-mcp-task`,children:`waits for MCP tasks`}),` in an interactive session`]}),`\n`,_jsxs(_components.li,{children:[`Set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`})}),` to `,_jsx(_components.code,{children:`1`}),` to turn off automatic backgrounding and `,_jsx(_components.a,{href:`/en/tools-reference#background-commands`,children:`background commands`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Some calls never move to the background:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Calls from `,_jsx(_components.a,{href:`/en/sub-agents`,children:`subagents`}),`; Claude Code backgrounds only main-conversation calls`]}),`\n`,_jsx(_components.li,{children:`Calls to IDE servers`}),`\n`,_jsxs(_components.li,{children:[`Calls in `,_jsx(_components.a,{href:`/en/headless`,children:`non-interactive mode`}),`, unless `,_jsx(_components.code,{children:`CLAUDE_AUTO_BACKGROUND_TASKS`}),` is set to `,_jsx(_components.code,{children:`1`}),`, since a one-shot run can end before the result arrives`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`A call waiting on an open `,_jsx(_components.a,{href:`#respond-to-mcp-elicitation-requests`,children:`elicitation dialog`}),` isn’t backgrounded while the dialog is open; the server is blocked on your input, not slow, so Claude Code defers the move until the dialog closes.`]}),`\n`,_jsx(Heading,{level:`3`,id:`mcp-tasks-that-run-on-the-server`,children:`MCP tasks that run on the server`}),`\n`,_jsxs(_components.p,{children:[`An MCP task is a long job, such as a report export or a build, that an MCP server runs itself using the `,_jsx(_components.a,{href:`https://modelcontextprotocol.io/extensions/tasks/overview`,children:`MCP tasks extension`}),`. Claude’s tool call returns once the server accepts the job, so Claude keeps working unless you `,_jsx(_components.a,{href:`#make-claude-wait-for-the-result-of-an-mcp-task`,children:`make Claude wait`}),`. When the job ends, the transcript says so and Claude gets the result. Ask Claude for it.`]}),`\n`,_jsxs(_components.p,{children:[`Meanwhile, the footer shows a count such as `,_jsx(_components.code,{children:`1 MCP task`}),`, and Claude Code follows the task by checking its status with the server. A task on a remote server keeps running after you exit. To follow it again, `,_jsx(_components.a,{href:`#exit-clear-or-resume-while-an-mcp-task-runs`,children:`resume the same session`}),`.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`MCP tasks are in public beta in the Claude Code CLI and require Claude Code v2.1.304 or later. `,_jsx(_components.a,{href:`#requirements-for-mcp-tasks`,children:`What a call needs to become an MCP task`}),` lists the sessions and servers that get them.`]})}),`\n`,_jsx(Heading,{level:`4`,id:`stop-an-mcp-task-or-get-its-result`,children:`Stop an MCP task or get its result`}),`\n`,_jsxs(_components.p,{children:[`To stop a running task, select it in `,_jsx(_components.a,{href:`/en/commands#all-commands`,children:_jsx(_components.code,{children:`/tasks`})}),` and press `,_jsx(_components.code,{children:`x`}),`, or ask Claude to. Claude Code stops following the task and asks the server to cancel it, though the server may still finish it. Reconnect a disconnected server from `,_jsx(_components.code,{children:`/mcp`}),` first, or no cancel request goes out and Claude Code forgets the task and can’t follow it again. Pressing `,_jsx(_components.code,{children:`Esc`}),` doesn’t stop a background task.`]}),`\n`,_jsx(_components.p,{children:`When the task ends, a line such as this one appears in the transcript:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`MCP task \u003cserver task id> (\u003cserver>/\u003ctool>) completed.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`The result goes to Claude, not into the transcript, so ask Claude for it. If Claude is idle when the result arrives, Claude starts on it unprompted.`}),`\n`,_jsx(Heading,{level:`4`,id:`answer-a-question-from-an-mcp-task`,children:`Answer a question from an MCP task`}),`\n`,_jsxs(_components.p,{children:[`A running task can open an `,_jsx(_components.a,{href:`#respond-to-mcp-elicitation-requests`,children:`elicitation dialog`}),` to ask you for input. While `,_jsx(_components.code,{children:`/tasks`}),` is open, the dialog stays hidden, so close `,_jsx(_components.code,{children:`/tasks`}),` to answer. Declining or pressing `,_jsx(_components.code,{children:`Esc`}),` is an answer to the server, which then decides whether the task goes on.`]}),`\n`,_jsxs(_components.p,{children:[`In a `,_jsx(_components.a,{href:`/en/headless`,children:`non-interactive`}),` session, Claude Code asks the server to cancel a task that requests input, without running your `,_jsxs(_components.a,{href:`/en/hooks#elicitation`,children:[_jsx(_components.code,{children:`Elicitation`}),` hooks`]}),` or calling the Agent SDK’s `,_jsx(_components.code,{children:`onElicitation`}),` callback.`]}),`\n`,_jsx(Heading,{level:`4`,id:`exit-clear-or-resume-while-an-mcp-task-runs`,children:`Exit, clear, or resume while an MCP task runs`}),`\n`,_jsxs(_components.p,{children:[`A task on a remote server keeps running after you exit. A stdio server’s process stops when Claude Code exits, though its tasks show `,_jsx(_components.code,{children:`runs on the server; survives exiting this session`}),` in `,_jsx(_components.code,{children:`/tasks`}),`. Unless that server’s documentation says the work outlives the process, let those tasks finish or stop them in `,_jsx(_components.code,{children:`/tasks`}),` first.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Situation`}),_jsx(_components.th,{children:`What happens to the task`}),_jsx(_components.th,{children:`What you can do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`You run `,_jsx(_components.code,{children:`/clear`}),` or `,_jsx(_components.code,{children:`/branch`}),`, or `,_jsx(_components.code,{children:`/resume`}),` another session`]}),_jsx(_components.td,{children:`While Claude Code stays open, the result arrives in your current conversation`}),_jsxs(_components.td,{children:[`After an exit, `,_jsx(_components.code,{children:`claude --resume`}),` the session the task started in`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`You exit Claude Code`}),_jsxs(_components.td,{children:[`No exit option cancels a remote server’s task, even when the exit dialog lists it under `,_jsx(_components.code,{children:`The following will stop when you exit:`})]}),_jsxs(_components.td,{children:[`Stop it in `,_jsx(_components.code,{children:`/tasks`}),` first, or resume the same session later`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`You return to the task’s session interactively: `,_jsx(_components.code,{children:`claude --resume`}),`, `,_jsx(_components.code,{children:`claude --continue`}),`, or `,_jsx(_components.code,{children:`/resume`})]}),_jsx(_components.td,{children:`Once the server connects, Claude Code follows the task again, and Claude gets the result if it finished meanwhile and the server still knows it`}),_jsx(_components.td,{children:`Keep the server’s name and connection settings unchanged`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`You resume the task’s session with `,_jsx(_components.code,{children:`--resume`}),` or `,_jsx(_components.code,{children:`--continue`}),` in a one-shot `,_jsx(_components.code,{children:`claude -p \"\u003cprompt>\"`}),` run`]}),_jsx(_components.td,{children:`That run doesn’t follow the task`}),_jsxs(_components.td,{children:[`Resume interactively, or with `,_jsx(_components.code,{children:`--input-format stream-json`})]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`You start a new session or use `,_jsx(_components.code,{children:`--fork-session`})]}),_jsx(_components.td,{children:`The new session doesn’t follow the task`}),_jsx(_components.td,{children:`Resume the session that started it`})]})]})]}),`\n`,_jsx(Heading,{level:`4`,id:`requirements-for-mcp-tasks`,children:`What a call needs to become an MCP task`}),`\n`,_jsx(_components.p,{children:`A tool call becomes an MCP task only when all of these conditions hold:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The server supports tasks`}),`\n`,_jsxs(_components.li,{children:[`The server is an HTTP, stdio, or claude.ai connector server connected on `,_jsx(_components.a,{href:`#mcp-client-runtimes`,children:`protocol revision 2026-07-28`}),`. Setting `,_jsxs(_components.a,{href:`/en/env-vars`,children:[_jsx(_components.code,{children:`MCP_SDK_GENERATION=v1`}),` or `,_jsx(_components.code,{children:`MCP_PROTOCOL_NEGOTIATION=legacy`})]}),` rules that out`]}),`\n`,_jsxs(_components.li,{children:[`The session `,_jsx(_components.a,{href:`/en/env-vars#features-that-need-feature-flag-fetching`,children:`fetches feature flags`}),`, so not on a third-party provider such as Amazon Bedrock, and not with telemetry or flag fetching turned off`]}),`\n`,_jsxs(_components.li,{children:[`Anthropic has turned MCP tasks on for your kind of session. On v2.1.304 or later that covers terminal CLI sessions, `,_jsx(_components.a,{href:`/en/agent-sdk/overview`,children:`Agent SDK`}),` sessions, and `,_jsx(_components.a,{href:`/en/github-actions`,children:`GitHub Actions`}),` runs. Other surfaces, such as the `,_jsx(_components.a,{href:`/en/vs-code`,children:`VS Code extension`}),` and the `,_jsx(_components.a,{href:`/en/desktop`,children:`desktop app`}),`, don’t have MCP tasks`]}),`\n`,_jsxs(_components.li,{children:[`The call comes from the main conversation, not from a `,_jsx(_components.a,{href:`/en/sub-agents`,children:`subagent`})]}),`\n`,_jsxs(_components.li,{children:[`Either the session is interactive, or an `,_jsx(_components.a,{href:`/en/agent-sdk/overview`,children:`Agent SDK`}),` session or a `,_jsx(_components.code,{children:`claude -p`}),` run reading `,_jsx(_components.code,{children:`--input-format stream-json`}),` has:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_AUTO_BACKGROUND_TASKS`})}),` at `,_jsx(_components.code,{children:`1`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND`}),` not `,_jsx(_components.code,{children:`1`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`}),` not `,_jsx(_components.code,{children:`0`})]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Any other call is a plain tool call, and `,_jsx(_components.a,{href:`#automatic-backgrounding-of-long-tool-calls`,children:`Automatic backgrounding of long tool calls`}),` says which of those move to the background.`]}),`\n`,_jsxs(_components.p,{children:[`Keep an Agent SDK or stream-json session’s input open, because the run `,_jsx(_components.a,{href:`/en/headless#mcp-work-when-a-non-interactive-run-ends`,children:`doesn’t wait for MCP tasks`}),` after input closes. A one-shot `,_jsx(_components.code,{children:`claude -p \"\u003cprompt>\"`}),` run doesn’t get MCP tasks.`]}),`\n`,_jsx(Heading,{level:`4`,id:`status-messages-on-an-mcp-task`,children:`Status messages on an MCP task`}),`\n`,_jsxs(_components.p,{children:[`These messages, in a task’s `,_jsx(_components.code,{children:`/tasks`}),` entry or its closing transcript line, mean Claude Code can’t reach the server or the task. While one shows in `,_jsx(_components.code,{children:`/tasks`}),`, the job may still be running: Claude Code leaves it alone and keeps checking. The `,_jsx(_components.code,{children:`300s`}),` and configuration messages stay on the entry even after contact returns.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Message`}),_jsx(_components.th,{children:`What is happening`}),_jsx(_components.th,{children:`What you can do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`reconnecting…`})}),_jsx(_components.td,{children:`The server hasn’t answered since a resume, or status checks get no answer`}),_jsxs(_components.td,{children:[`If it stays, reconnect from `,_jsx(_components.code,{children:`/mcp`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`needs a sign-in to \u003cserver>`})}),_jsx(_components.td,{children:`The server refused a status check`}),_jsxs(_components.td,{children:[`Sign in from `,_jsx(_components.code,{children:`/mcp`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`status requests come back with errors; retrying…`})}),_jsx(_components.td,{children:`The server, or a proxy in front of it, answers status checks with errors`}),_jsx(_components.td,{children:`Wait while Claude Code retries`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`server '\u003cname>' did not reconnect within 300s`})}),_jsx(_components.td,{children:`No answered check for five minutes, for example with the connection down or the server disabled`}),_jsxs(_components.td,{children:[`Reconnect from `,_jsx(_components.code,{children:`/mcp`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`server '\u003cname>' asked for a sign-in, and none was accepted within 300s`})}),_jsx(_components.td,{children:`After five minutes the server still wants a sign-in`}),_jsxs(_components.td,{children:[`Sign in from `,_jsx(_components.code,{children:`/mcp`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`status requests to server '\u003cname>' came back with errors, and none succeeded in 300s`})}),_jsx(_components.td,{children:`Five minutes of error answers`}),_jsx(_components.td,{children:`Check the server’s own health or logs`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`server '\u003cname>' is not configured in this session; the task may still be running on it`})}),_jsxs(_components.td,{children:[`The session has no server by that name, for example it was removed, renamed, or left out of `,_jsx(_components.code,{children:`--mcp-config`}),`, or a claude.ai connector is still loading`]}),_jsx(_components.td,{children:`Restore the server under the same name, then resume the session again. For a loading connector, nothing: Claude Code follows the task once it appears`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`A message beginning `,_jsx(_components.code,{children:`server '\u003cname>' was reconfigured to a different transport since this task was created`})]}),_jsx(_components.td,{children:`A server by that name exists with connection settings that changed since the task started, such as its URL, command, args, env, headers, or timeout`}),_jsx(_components.td,{children:`Restore the earlier settings, then resume the session again`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`the server rejected this task's id; asking again…`})}),_jsx(_components.td,{children:`The server says it doesn’t know the task ID. Claude Code keeps asking for up to five minutes`}),_jsxs(_components.td,{children:[`Wait: the message clears if the server recognizes the ID again, or the `,_jsx(_components.code,{children:`outcome unknown.`}),` line follows`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`A transcript line ending `,_jsx(_components.code,{children:`outcome unknown.`}),`, in one form `,_jsx(_components.code,{children:`expired on the server: outcome unknown.`})]}),_jsx(_components.td,{children:`The server rejected the ID or refused with another permanent error, and Claude Code stopped following the task`}),_jsx(_components.td,{children:`A second call may repeat the work. Before calling the tool again, find out from the server what was done, for example by asking Claude to use the server’s other tools`})]})]})]}),`\n`,_jsx(Heading,{level:`4`,id:`time-limits-on-mcp-tasks`,children:`Time limits on MCP tasks`}),`\n`,_jsxs(_components.p,{children:[`By default, a task in the background has no Claude Code time limit. The `,_jsx(_components.a,{href:`#time-limits-on-mcp-tool-calls`,children:`tool call time limits`}),`, including the wall-clock limit and the idle timeout, apply until the server answers the call with the task. If you `,_jsx(_components.a,{href:`#make-claude-wait-for-the-result-of-an-mcp-task`,children:`make Claude wait`}),`, they apply for the whole task. Answered status checks count as activity for the idle timeout.`]}),`\n`,_jsx(Heading,{level:`4`,id:`make-claude-wait-for-the-result-of-an-mcp-task`,children:`Make Claude wait for the result of an MCP task`}),`\n`,_jsxs(_components.p,{children:[`To make Claude wait for a task’s result in an interactive session, set one of two environment variables, for example in the `,_jsx(_components.code,{children:`env`}),` block of `,_jsx(_components.a,{href:`/en/settings`,children:_jsx(_components.code,{children:`settings.json`})}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`})}),` set to `,_jsx(_components.code,{children:`0`})]}),`: Claude waits for every MCP tool call until the call ends`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND`})}),` set to `,_jsx(_components.code,{children:`1`})]}),`: Claude waits for a task’s result. While `,_jsx(_components.a,{href:`#automatic-backgrounding-of-long-tool-calls`,children:`automatic backgrounding`}),` is on, it moves the call after two minutes by default, so short tasks finish in place and long ones don’t block you. The moved call is a plain background call rather than an MCP task. It doesn’t survive exiting the session`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`While Claude waits, pressing `,_jsx(_components.code,{children:`Esc`}),` or reaching the `,_jsx(_components.a,{href:`#time-limits-on-mcp-tasks`,children:`wall-clock limit or idle timeout`}),` ends the call, and Claude Code asks the server to cancel the task.`]}),`\n`,_jsxs(_components.p,{children:[`If you set `,_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`}),` to `,_jsx(_components.code,{children:`1`}),` or start in `,_jsx(_components.a,{href:`/en/headless#start-faster-with-bare-mode`,children:`bare mode`}),`, that alone doesn’t make Claude wait for MCP tasks. This example sets `,_jsx(_components.code,{children:`CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`}),` to `,_jsx(_components.code,{children:`0`}),`, so Claude waits for every MCP tool call:`]}),`\n`,_jsx(CodeBlock,{filename:`settings.json`,numberOfLines:`5`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"env\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"0\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`mcp-tasks-for-server-authors`,children:`MCP tasks for server authors`}),`\n`,_jsxs(_components.p,{children:[`If you build an MCP server, you can answer a long-running `,_jsx(_components.code,{children:`tools/call`}),` with a task. The `,_jsx(_components.a,{href:`https://modelcontextprotocol.io/extensions/tasks/overview`,children:`MCP tasks extension`}),` defines the messages you send. On a `,_jsx(_components.a,{href:`#mcp-client-runtimes`,children:`protocol revision 2026-07-28`}),` connection, each request carries Claude Code’s client capabilities at `,_jsx(_components.code,{children:`params._meta[\"io.modelcontextprotocol/clientCapabilities\"]`}),`, with `,_jsx(_components.code,{children:`\"io.modelcontextprotocol/tasks\": {}`}),` under `,_jsx(_components.code,{children:`extensions`}),`. A `,_jsx(_components.code,{children:`tools/call`}),` request that `,_jsx(_components.a,{href:`#requirements-for-mcp-tasks`,children:`can’t become a task`}),` omits that extension.`]}),`\n`,_jsx(Heading,{level:`4`,id:`answer-the-call-with-a-task`,children:`Answer the call with a task`}),`\n`,_jsxs(_components.p,{children:[`Answer with a task only when the request carries the extension, or Claude gets the tool error `,_jsx(_components.code,{children:`Unsupported result type 'task' for tools/call`}),`. Claude gets the same error when `,_jsx(_components.code,{children:`taskId`}),`, `,_jsx(_components.code,{children:`status`}),`, `,_jsx(_components.code,{children:`createdAt`}),`, `,_jsx(_components.code,{children:`lastUpdatedAt`}),`, or `,_jsx(_components.code,{children:`ttlMs`}),` is missing. The task object is the JSON-RPC `,_jsx(_components.code,{children:`result`}),` of your `,_jsx(_components.code,{children:`tools/call`}),` response, needs no `,_jsx(_components.code,{children:`content`}),` array, and here includes the optional `,_jsx(_components.code,{children:`statusMessage`}),` and `,_jsx(_components.code,{children:`pollIntervalMs`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`10`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"resultType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"task\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"taskId\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"build-7f3a9c2e\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"working\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"statusMessage\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Compiling, 40 of 212 files done\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"createdAt\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-10-22T14:03:07Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"lastUpdatedAt\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-10-22T14:03:07Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"ttlMs\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"pollIntervalMs\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`5000`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`How Claude Code handles it`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`resultType`})}),_jsxs(_components.td,{children:[`Set it to `,_jsx(_components.code,{children:`\"task\"`}),` to mark the reply as a task. Without it, Claude Code reads the reply as a plain result`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`taskId`})}),_jsxs(_components.td,{children:[`Required. At most 128 printable ASCII characters with no spaces, or Claude gets a tool error beginning `,_jsx(_components.code,{children:`MCP server \"\u003cname>\" returned a malformed task handle for tool \"\u003ctool>\"`}),`. Keep the ID answerable across connections, because after a resume Claude Code asks about it on a new connection`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`status`})}),_jsxs(_components.td,{children:[`Required. One of `,_jsx(_components.code,{children:`working`}),`, `,_jsx(_components.code,{children:`input_required`}),`, `,_jsx(_components.code,{children:`completed`}),`, `,_jsx(_components.code,{children:`failed`}),`, or `,_jsx(_components.code,{children:`cancelled`}),`. Another value gives the `,_jsx(_components.code,{children:`Unsupported result type`}),` error`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`createdAt`}),`, `,_jsx(_components.code,{children:`lastUpdatedAt`}),`, `,_jsx(_components.code,{children:`ttlMs`})]}),_jsxs(_components.td,{children:[`Required, and `,_jsx(_components.code,{children:`ttlMs`}),` may be `,_jsx(_components.code,{children:`null`}),`. Claude Code doesn’t drop a task because its `,_jsx(_components.code,{children:`ttlMs`}),` has passed`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`pollIntervalMs`})}),_jsxs(_components.td,{children:[`Optional, but not `,_jsx(_components.code,{children:`null`}),`. Milliseconds between `,_jsx(_components.code,{children:`tasks/get`}),` requests, clamped to between 250 and 30000. Claude Code uses 2000 when the field is absent, and reads the value again from each `,_jsx(_components.code,{children:`tasks/get`}),` response`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`statusMessage`})}),_jsxs(_components.td,{children:[`Optional. `,_jsx(_components.code,{children:`/tasks`}),` shows the value from your latest `,_jsx(_components.code,{children:`tasks/get`}),` response, not this first one, and a response that omits the field clears it. A `,_jsx(_components.a,{href:`#status-messages-on-an-mcp-task`,children:`status message from Claude Code`}),` can take its place`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`On an HTTP or claude.ai connector server, the task answer has to start within the `,_jsx(_components.a,{href:`#time-limits-on-mcp-tool-calls`,children:`per-request timer`}),`, so accept the job and answer first, then do the work.`]}),`\n`,_jsx(Heading,{level:`4`,id:`report-status-results-and-questions`,children:`Report status, results, and questions`}),`\n`,_jsxs(_components.p,{children:[`Right after the task answer, Claude Code sends `,_jsx(_components.code,{children:`tasks/get`}),` with `,_jsx(_components.code,{children:`{ \"taskId\": ... }`}),`, then repeats it once per poll interval. The tasks extension requires your response to carry `,_jsx(_components.code,{children:`\"resultType\": \"complete\"`}),` along with `,_jsx(_components.code,{children:`taskId`}),`, `,_jsx(_components.code,{children:`status`}),`, `,_jsx(_components.code,{children:`createdAt`}),`, `,_jsx(_components.code,{children:`lastUpdatedAt`}),`, and `,_jsx(_components.code,{children:`ttlMs`}),`. `,_jsx(_components.code,{children:`ttlMs`}),` may be `,_jsx(_components.code,{children:`null`}),`, and `,_jsx(_components.code,{children:`statusMessage`}),` and `,_jsx(_components.code,{children:`pollIntervalMs`}),` are optional. This example reports the build as done:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"resultType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"complete\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"taskId\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"build-7f3a9c2e\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"completed\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"createdAt\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-10-22T14:03:07Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"lastUpdatedAt\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-10-22T14:09:41Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"ttlMs\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"result\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"content\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"text\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"text\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Build succeeded: 212 files, 0 warnings\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Status, method, or response`}),_jsx(_components.th,{children:`How Claude Code handles it`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`working`})}),_jsx(_components.td,{children:`Keeps polling`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`completed`})}),_jsxs(_components.td,{children:[`Gives Claude the normal `,_jsx(_components.code,{children:`tools/call`}),` result in the top-level `,_jsx(_components.code,{children:`result`}),` object. `,_jsx(_components.code,{children:`isError: true`}),` in it is reported as a failure`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`failed`})}),_jsxs(_components.td,{children:[`Tells Claude the `,_jsx(_components.code,{children:`message`}),` of the top-level `,_jsx(_components.code,{children:`error`}),` object `,_jsx(_components.code,{children:`{ code, message, data }`}),`, which the tasks extension requires on a failed task. Without that `,_jsx(_components.code,{children:`message`}),`, Claude gets `,_jsx(_components.code,{children:`statusMessage`}),` instead, or else `,_jsx(_components.code,{children:`Task failed`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`cancelled`})}),_jsxs(_components.td,{children:[`Tells Claude `,_jsx(_components.code,{children:`statusMessage`}),`, or else `,_jsx(_components.code,{children:`Task was cancelled by the server`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`input_required`})}),_jsxs(_components.td,{children:[`Reads `,_jsx(_components.code,{children:`inputRequests`}),`, an object that maps a key you choose to `,_jsx(_components.code,{children:`{ method, params }`}),`. Claude Code answers each key once through `,_jsx(_components.code,{children:`tasks/update`}),` with `,_jsx(_components.code,{children:`{ taskId, inputResponses }`}),`, where `,_jsx(_components.code,{children:`inputResponses`}),` maps the same key to that request’s result. Keys beyond 16 per task are ignored`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`Methods in `,_jsx(_components.code,{children:`inputRequests`})]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`elicitation/create`}),` is served only in interactive terminal sessions, and `,_jsx(_components.code,{children:`roots/list`}),` everywhere. When Claude Code can’t serve a request, it asks the server to cancel the task`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`Another `,_jsx(_components.code,{children:`status`}),` value`]}),_jsx(_components.td,{children:`Claude Code asks the server to cancel the task and reports it to Claude as failed`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`JSON-RPC error `,_jsx(_components.code,{children:`-32602`})]}),_jsx(_components.td,{children:`Read as an unknown task ID. For a task in the background, Claude Code keeps asking for up to five minutes, then reports the outcome to Claude as unknown`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`tasks/cancel`})}),_jsx(_components.td,{children:`Sent, for example, when Claude or the person stops the task while the server is connected. Not sent on exit`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`tasks/result`}),`, `,_jsx(_components.code,{children:`tasks/list`}),`, `,_jsx(_components.code,{children:`notifications/tasks`})]}),_jsxs(_components.td,{children:[`Not used, so put the outcome in your `,_jsx(_components.code,{children:`tasks/get`}),` responses`]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`plugin-provided-mcp-servers`,children:`Plugin-provided MCP servers`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`/en/plugins/overview`,children:`Plugins`}),` can bundle MCP servers that provide tools and integrations when you enable the plugin.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`How plugin MCP servers work`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Plugins define MCP servers in `,_jsx(_components.code,{children:`.mcp.json`}),` at the plugin root or inline in `,_jsx(_components.code,{children:`plugin.json`})]}),`\n`,_jsx(_components.li,{children:`When you enable a plugin, Claude Code starts its MCP servers automatically`}),`\n`,_jsx(_components.li,{children:`Claude Code offers plugin MCP tools alongside manually configured MCP tools`}),`\n`,_jsxs(_components.li,{children:[`You add and remove plugin servers by installing or uninstalling the plugin, not with `,_jsx(_components.code,{children:`/mcp`}),` commands. You can still `,_jsx(_components.a,{href:`#disable-a-server-without-removing-it`,children:`toggle an installed plugin server off`}),` in `,_jsx(_components.code,{children:`/mcp`}),`, which stops Claude Code from connecting to it without removing the plugin`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Example plugin MCP configuration`}),`:`]}),`\n`,_jsxs(_components.p,{children:[`In `,_jsx(_components.code,{children:`.mcp.json`}),` at plugin root:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"database-tools\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"${CLAUDE_PLUGIN_ROOT}/servers/db-server\"'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"--config\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"${CLAUDE_PLUGIN_ROOT}/config.json\"'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"env\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"DB_URL\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"${DB_URL}\"'})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Or inline in `,_jsx(_components.code,{children:`plugin.json`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"my-plugin\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"plugin-api\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"${CLAUDE_PLUGIN_ROOT}/servers/api-server\"'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"--port\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"8080\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Plugin MCP features`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Automatic lifecycle`}),`: servers connect and disconnect at these points:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`At session startup, Claude Code connects the servers for enabled plugins automatically. In `,_jsx(_components.code,{children:`/mcp`}),`, a remote (HTTP or SSE) plugin server you’ve used before can show the `,_jsxs(_components.a,{href:`#server-status-detail`,children:[_jsx(_components.code,{children:`cached`}),` status`]}),` instead; Claude Code connects it when Claude first calls one of its tools. When a stdio plugin server’s connection failed less than 15 minutes earlier, Claude Code `,_jsx(_components.a,{href:`/en/errors#skipping-connection-recent-failure-cached`,children:`skips the connection`})]}),`\n`,_jsxs(_components.li,{children:[`If you enable or disable a plugin during a session, Claude Code connects or disconnects its MCP servers when the change applies. `,_jsx(_components.a,{href:`/en/plugins/cli-reference#reload-plugins`,children:`Apply plugin changes without restarting`}),` describes when that is. In a session without an interactive terminal, `,_jsx(_components.code,{children:`/reload-plugins`}),` doesn’t connect or disconnect plugin MCP servers; those changes take effect in your next session`]}),`\n`,_jsxs(_components.li,{children:[`When you reload, Claude Code keeps the live connections of plugin servers whose configuration is unchanged, and does the same when you `,_jsx(_components.a,{href:`/en/agent-sdk/typescript#mcpsetserversresult`,children:`replace the session’s MCP server list`}),` from the Agent SDK without naming them`]}),`\n`,_jsxs(_components.li,{children:[`When you `,_jsxs(_components.a,{href:`/en/permissions#move-the-session-to-another-directory`,children:[`move the session with `,_jsx(_components.code,{children:`/cd`})]}),` on v2.1.246 or later, Claude Code connects the servers of plugins the new directory’s settings enable and disconnects the servers of plugins that are no longer enabled, so you don’t need to run `,_jsx(_components.code,{children:`/reload-plugins`}),` after the move`]}),`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.a,{href:`/en/claude-code-on-the-web`,children:`cloud sessions`}),`, an MCP call to a plugin server that isn’t connected yet, such as right after an idle session wakes, starts the server on demand and waits for it to connect`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Path placeholders`}),`: `,_jsx(_components.code,{children:\"${CLAUDE_PLUGIN_ROOT}\"}),` resolves to the plugin’s installation directory, `,_jsx(_components.code,{children:\"${CLAUDE_PLUGIN_DATA}\"}),` to its `,_jsx(_components.a,{href:`/en/plugins/components#path-variables-and-persistent-data`,children:`persistent state`}),` directory, and `,_jsx(_components.code,{children:\"${CLAUDE_PROJECT_DIR}\"}),` to the stable project root. Substitution applies to:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`stdio`}),` servers: `,_jsx(_components.code,{children:`command`}),`, `,_jsx(_components.code,{children:`args`}),`, `,_jsx(_components.code,{children:`env`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`http`}),`, `,_jsx(_components.code,{children:`sse`}),`, and `,_jsx(_components.code,{children:`ws`}),` servers: `,_jsx(_components.code,{children:`url`}),`, `,_jsx(_components.code,{children:`headers`}),`, and `,_jsx(_components.code,{children:`headersHelper`})]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`User environment access`}),`: access to the same environment variables as manually configured servers`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Multiple transport types`}),`: support for stdio, SSE, HTTP, and WebSocket transports, though transport support may vary by server`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Plugin servers appear in `,_jsx(_components.code,{children:`/mcp`}),` with indicators showing they come from plugins.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`claude mcp get`}),` hides the values configured for a plugin’s stdio or WebSocket server, because they can carry credentials:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`stdio server`}),`: it prints `,_jsx(_components.code,{children:`Command: stdio`}),`, an empty `,_jsx(_components.code,{children:`Args:`}),` line, and each environment variable as `,_jsx(_components.code,{children:`NAME=[REDACTED]`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`WebSocket server`}),`: it prints `,_jsx(_components.code,{children:`URL: ws`}),` and each header as `,_jsx(_components.code,{children:`\u003cname>: [REDACTED]`}),`, and `,_jsx(_components.code,{children:`claude mcp list`}),` shows `,_jsx(_components.code,{children:`ws`}),` in place of the URL`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`To see what the plugin configured, `,_jsx(_components.a,{href:`/en/plugins/loading#find-plugins-on-disk`,children:`find the plugin on disk`}),` and read its `,_jsx(_components.code,{children:`.mcp.json`}),` or `,_jsx(_components.code,{children:`plugin.json`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Plugin MCP tool names`}),`:`]}),`\n`,_jsxs(_components.p,{children:[`Tools from a plugin-bundled MCP server include both the plugin name and the server key in their callable name. The full form is `,_jsx(_components.code,{children:`mcp__plugin_\u003cplugin-name>_\u003cserver-name>__\u003ctool-name>`}),`, where any character outside `,_jsx(_components.code,{children:`A-Z`}),`, `,_jsx(_components.code,{children:`a-z`}),`, `,_jsx(_components.code,{children:`0-9`}),`, `,_jsx(_components.code,{children:`_`}),`, and `,_jsx(_components.code,{children:`-`}),` is replaced with `,_jsx(_components.code,{children:`_`}),`. For the `,_jsx(_components.code,{children:`database-tools`}),` server bundled in a plugin named `,_jsx(_components.code,{children:`my-plugin`}),`, a `,_jsx(_components.code,{children:`query`}),` tool is callable as:`]}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`mcp__plugin_my-plugin_database-tools__query`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Use this full name when referencing the tool in `,_jsx(_components.a,{href:`/en/permissions`,children:`permission rules`}),`, a skill’s `,_jsx(_components.code,{children:`allowed-tools`}),` list, a `,_jsxs(_components.a,{href:`/en/sub-agents#available-tools`,children:[`subagent’s `,_jsx(_components.code,{children:`tools`}),` field`]}),`, or a `,_jsx(_components.a,{href:`/en/hooks#match-mcp-tools`,children:`hook matcher`}),`. A hook matcher written against the bare server key, such as `,_jsx(_components.code,{children:`mcp__database-tools__.*`}),`, never fires for a plugin-bundled server.`]}),`\n`,_jsxs(_components.p,{children:[`The server itself registers under the scoped name `,_jsx(_components.code,{children:`plugin:\u003cplugin-name>:\u003cserver-name>`}),`, such as `,_jsx(_components.code,{children:`plugin:my-plugin:database-tools`}),`. Use that name where a configured server name is expected, such as an `,_jsxs(_components.a,{href:`/en/hooks#mcp-tool-hook-fields`,children:[_jsx(_components.code,{children:`mcp_tool`}),` hook’s `,_jsx(_components.code,{children:`server`}),` field`]}),`.`]}),`\n`,_jsxs(_components.p,{children:[`See the `,_jsx(_components.a,{href:`/en/plugins/components#mcp-servers`,children:`plugin components reference`}),` for details on bundling MCP servers with plugins.`]}),`\n`,_jsx(Heading,{level:`2`,id:`mcp-installation-scopes`,children:`MCP installation scopes`}),`\n`,_jsxs(_components.p,{children:[`MCP servers can be configured at three scopes. The scope you choose controls which projects the server loads in and whether the configuration is shared with your team. Administrators can also deploy or provide servers for every user via `,_jsx(_components.a,{href:`#managed-mcp-configuration`,children:`managed configuration`}),`.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Scope`}),_jsx(_components.th,{children:`Loads in`}),_jsx(_components.th,{children:`Shared with team`}),_jsx(_components.th,{children:`Stored in`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#local-scope`,children:`Local`})}),_jsx(_components.td,{children:`Current project only`}),_jsx(_components.td,{children:`No`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`~/.claude.json`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#project-scope`,children:`Project`})}),_jsx(_components.td,{children:`Current project only`}),_jsx(_components.td,{children:`Yes, via version control`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`.mcp.json`}),` in project root`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#user-scope`,children:`User`})}),_jsx(_components.td,{children:`All your projects`}),_jsx(_components.td,{children:`No`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`~/.claude.json`})})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`local-scope`,children:`Local scope`}),`\n`,_jsxs(_components.p,{children:[`Local scope is the default. A local-scoped server loads only in the project where you added it and stays private to you. Claude Code stores it in `,_jsx(_components.code,{children:`~/.claude.json`}),` under that project’s path, so the same server won’t appear in your other projects. Use local scope for personal development servers, experimental configurations, or servers with credentials you don’t want in version control.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`The term “local scope” for MCP servers differs from general local settings. MCP local-scoped servers are stored in `,_jsx(_components.code,{children:`~/.claude.json`}),` (your home directory), while general local settings use `,_jsx(_components.code,{children:`.claude/settings.local.json`}),` (in the project directory). See `,_jsx(_components.a,{href:`/en/settings#where-settings-live`,children:`Settings`}),` for details on settings file locations.`]})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Add a local-scoped server (default)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` stripe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.stripe.com`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Explicitly specify local scope`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` stripe`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --scope`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` local`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.stripe.com`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The command writes the server into the entry for your current project inside `,_jsx(_components.code,{children:`~/.claude.json`}),`. The example below shows the result when you run it from `,_jsx(_components.code,{children:`/path/to/your/project`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`12`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"projects\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"/path/to/your/project\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"stripe\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.stripe.com\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`project-scope`,children:`Project scope`}),`\n`,_jsxs(_components.p,{children:[`Project-scoped servers enable team collaboration by storing configurations in a `,_jsx(_components.code,{children:`.mcp.json`}),` file at your project’s root directory. When you add a project-scoped server, Claude Code automatically creates or updates this file with the appropriate configuration structure. Check `,_jsx(_components.code,{children:`.mcp.json`}),` into version control so everyone on your team gets the same MCP tools and services.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Add a project-scoped server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` shared-server`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --scope`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` project`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://example.com/mcp`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The resulting `,_jsx(_components.code,{children:`.mcp.json`}),` file follows a standardized format:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"shared-server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://example.com/mcp\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`For security reasons, Claude Code prompts for approval in interactive sessions before using project-scoped servers from `,_jsx(_components.code,{children:`.mcp.json`}),` files. To reset those approval choices, run `,_jsx(_components.code,{children:`claude mcp reset-project-choices`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`In `,_jsx(_components.code,{children:`claude -p`}),` runs, `,_jsx(_components.a,{href:`/en/headless`,children:`Agent SDK`}),` sessions, and `,_jsx(_components.a,{href:`/en/claude-code-on-the-web`,children:`cloud sessions`}),` outside a `,_jsx(_components.a,{href:`/en/claude-projects#what-threads-pick-up-from-your-repositories`,children:`project`}),`’s threads, Claude Code can’t show that prompt: it loads project-scoped servers without asking. Claude Code also skips the prompt in a session you start in `,_jsx(_components.code,{children:`bypassPermissions`}),` mode with `,_jsx(_components.a,{href:`/en/settings-reference#skipdangerousmodepermissionprompt`,children:_jsx(_components.code,{children:`skipDangerousModePermissionPrompt`})}),` set in your user settings or in managed settings. To keep a server out anyway:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Add it to `,_jsx(_components.a,{href:`/en/settings-reference#disabledmcpjsonservers`,children:_jsx(_components.code,{children:`disabledMcpjsonServers`})}),`, which blocks it in every permission mode.`]}),`\n`,_jsxs(_components.li,{children:[`Exclude project settings entirely with `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--setting-sources`})}),` or the SDK’s `,_jsx(_components.code,{children:`settingSources`}),` option.`]}),`\n`,_jsxs(_components.li,{children:[`Start the session with `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--strict-mcp-config`})}),`. Claude Code then uses only the MCP servers you pass with `,_jsx(_components.code,{children:`--mcp-config`}),`. Skipping the approval prompt for the project-scoped servers Claude Code isn’t loading requires Claude Code v2.1.246 or later; before v2.1.246, a strict session still waited on approval for them, which left background sessions waiting at startup. See `,_jsx(_components.a,{href:`/en/managed-mcp#exclusive-control-with-managed-mcp-json`,children:`Exclusive control with managed-mcp.json`}),` for what the flag does under a managed MCP file.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`#project-server-approvals-and-workspace-trust`,children:`Project server approvals and workspace trust`}),` covers how approvals committed to the repository interact with workspace trust.`]}),`\n`,_jsx(Heading,{level:`3`,id:`user-scope`,children:`User scope`}),`\n`,_jsxs(_components.p,{children:[`User-scoped servers are stored in `,_jsx(_components.code,{children:`~/.claude.json`}),` and provide cross-project accessibility, making them available across all projects on your machine while remaining private to your user account. This scope works well for personal utility servers, development tools, or services you frequently use across different projects.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Add a user server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` hubspot`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --scope`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` user`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.hubspot.com/anthropic`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`scope-hierarchy-and-precedence`,children:`Scope hierarchy and precedence`}),`\n`,_jsx(_components.p,{children:`When the same server is defined in more than one place, Claude Code connects to it once, using the definition from the highest-precedence source. The entire server entry from that source is used; fields are not merged across scopes.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Local scope`}),`\n`,_jsx(_components.li,{children:`Project scope`}),`\n`,_jsx(_components.li,{children:`User scope`}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/en/plugins/components#mcp-servers`,children:`Plugin-provided servers`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connectors`})}),`\n`]}),`\n`,_jsx(_components.p,{children:`Claude Code matches duplicates across the three scopes by name. It matches plugins and connectors by endpoint, so one that points at the same URL or command as an enabled server above counts as a duplicate.`}),`\n`,_jsxs(_components.p,{children:[`Two URL spellings count as the same endpoint when they differ only in the letter case of the scheme or host, the scheme’s default port, such as `,_jsx(_components.code,{children:`:443`}),` on `,_jsx(_components.code,{children:`https`}),`, or a trailing slash. A different path, query string, userinfo, or non-default port makes two servers.`]}),`\n`,_jsxs(_components.p,{children:[`A server your organization provides through the `,_jsx(_components.a,{href:`/en/managed-mcp#provide-servers-through-managed-settings`,children:_jsx(_components.code,{children:`managedMcpServers`})}),` managed setting ranks above all of these, so when one of them duplicates it, Claude Code connects the organization’s definition. Requires Claude Code v2.1.259 or later.`]}),`\n`,_jsxs(_components.p,{children:[`If you open a local session in the `,_jsx(_components.a,{href:`/en/desktop#mcp-servers-from-the-claude-desktop-chat-app`,children:`Desktop app’s Code tab`}),` with the same stdio server name at the top level of `,_jsx(_components.code,{children:`~/.claude.json`}),` (user scope) and in `,_jsx(_components.code,{children:`.mcp.json`}),`, the Code tab uses the `,_jsx(_components.code,{children:`~/.claude.json`}),` definition.`]}),`\n`,_jsxs(Heading,{level:`3`,id:`environment-variable-expansion-in-mcp-json`,children:[`Environment variable expansion in `,_jsx(_components.code,{children:`.mcp.json`})]}),`\n`,_jsxs(_components.p,{children:[`Claude Code supports environment variable expansion in `,_jsx(_components.code,{children:`.mcp.json`}),` files, allowing teams to share configurations while maintaining flexibility for machine-specific paths and sensitive values like API keys.`]}),`\n`,_jsxs(_components.p,{children:[`You can reference an environment variable in a server’s `,_jsx(_components.code,{children:`command`}),`, `,_jsx(_components.code,{children:`args`}),`, `,_jsx(_components.code,{children:`env`}),`, `,_jsx(_components.code,{children:`url`}),`, or `,_jsx(_components.code,{children:`headers`}),` value, in either of two forms:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:\"${VAR}\"}),`: expands to the value of environment variable `,_jsx(_components.code,{children:`VAR`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:\"${VAR:-default}\"}),`: expands to the value of `,_jsx(_components.code,{children:`VAR`}),` if `,_jsx(_components.code,{children:`VAR`}),` is set, or to `,_jsx(_components.code,{children:`default`}),` if it is unset`]}),`\n`]}),`\n`,_jsx(Heading,{level:`4`,id:`example-with-variable-expansion`,children:`Example with variable expansion`}),`\n`,_jsxs(_components.p,{children:[`In this server entry, the URL is the value of `,_jsx(_components.code,{children:`API_BASE_URL`}),` followed by `,_jsx(_components.code,{children:`/mcp`}),`, with `,_jsx(_components.code,{children:`https://api.example.com`}),` as the default, and the API key comes from `,_jsx(_components.code,{children:`API_KEY`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"api-server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"${API_BASE_URL:-https://api.example.com}/mcp\"'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"headers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Authorization\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'\"Bearer ${API_KEY}\"'})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`4`,id:`unset-variables-without-a-default`,children:`Unset variables without a default`}),`\n`,_jsxs(_components.p,{children:[`If a referenced environment variable isn’t set and has no default value, the config still loads: Claude Code reports a missing-variable warning for that server in `,_jsx(_components.code,{children:`claude mcp list`}),` output and uses the unexpanded `,_jsx(_components.code,{children:\"${VAR}\"}),` text as-is. Set the variable or add a `,_jsx(_components.code,{children:`:-default`}),` fallback so the server starts with the value you intend. In a remote server’s `,_jsx(_components.code,{children:`url`}),` and `,_jsx(_components.code,{children:`headers`}),`, some credential variables `,_jsx(_components.a,{href:`#credential-variables-that-read-as-empty`,children:`read as empty`}),` instead, with no warning.`]}),`\n`,_jsx(Heading,{level:`4`,id:`variables-set-to-an-empty-string`,children:`Variables set to an empty string`}),`\n`,_jsxs(_components.p,{children:[`If you set a variable to an empty string, it counts as set, so a `,_jsx(_components.code,{children:\"${VAR:-default}\"}),` reference expands to the empty string rather than to `,_jsx(_components.code,{children:`default`}),`. With the `,_jsx(_components.a,{href:`#example-with-variable-expansion`,children:`example server`}),`, if you set `,_jsx(_components.code,{children:`API_BASE_URL`}),` to an empty string, its `,_jsx(_components.code,{children:`url`}),` becomes `,_jsx(_components.code,{children:`/mcp`}),` and `,_jsx(_components.code,{children:`claude mcp list`}),` reports `,_jsx(_components.code,{children:`'url' is not a valid URL`}),`. To use the default, unset the variable rather than setting it to an empty string.`]}),`\n`,_jsx(Heading,{level:`4`,id:`credential-variables-that-read-as-empty`,children:`Credential variables that read as empty`}),`\n`,_jsxs(_components.p,{children:[`In a remote server’s `,_jsx(_components.code,{children:`url`}),` and `,_jsx(_components.code,{children:`headers`}),`, Claude Code reads credential variables from your environment as empty rather than expanding them. This keeps a project’s `,_jsx(_components.code,{children:`.mcp.json`}),` or a plugin from sending your Claude Code or cloud provider credentials to a server it names. If you write `,_jsx(_components.code,{children:\"Bearer ${ANTHROPIC_AUTH_TOKEN}\"}),`, the server receives `,_jsx(_components.code,{children:`Bearer `}),` with no credential and rejects the request, usually with a `,_jsx(_components.code,{children:`401`}),`. Claude Code reports that as a failed connection.`]}),`\n`,_jsx(_components.p,{children:`The covered names are:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Claude Code’s own credentials, such as `,_jsx(_components.code,{children:`ANTHROPIC_API_KEY`}),` and `,_jsx(_components.code,{children:`ANTHROPIC_AUTH_TOKEN`})]}),`\n`,_jsxs(_components.li,{children:[`Your cloud provider’s credentials, such as `,_jsx(_components.code,{children:`AWS_BEARER_TOKEN_BEDROCK`})]}),`\n`,_jsxs(_components.li,{children:[`Other credentials your environment carries, such as `,_jsx(_components.code,{children:`HTTPS_PROXY`}),` and `,_jsx(_components.code,{children:`NPM_TOKEN`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`A covered name reads as empty whether or not you have set the variable, and a `,_jsx(_components.code,{children:`:-default`}),` fallback on it is ignored. A provider base URL such as `,_jsx(_components.code,{children:`ANTHROPIC_BASE_URL`}),` still expands, so `,_jsx(_components.code,{children:'\"url\": \"${ANTHROPIC_BASE_URL}/mcp\"'}),` works, unless the URL’s value itself embeds a credential such as a username and password.`]}),`\n`,_jsxs(_components.p,{children:[`A name outside this set, such as `,_jsx(_components.code,{children:`API_KEY`}),`, expands as written. To give the server one of the covered credentials, copy it into a variable with a name of your own and reference that name instead.`]}),`\n`,_jsxs(_components.p,{children:[`When a remote server’s `,_jsx(_components.code,{children:`url`}),` or `,_jsx(_components.code,{children:`headers`}),` references a covered variable you have set, Claude Code names it in a debug-log line. To read the line, run `,_jsx(_components.code,{children:`claude --debug-file /tmp/claude-debug.log`}),` and search that file for `,_jsx(_components.code,{children:`never expanded toward a remote server`}),`.`]}),`\n`,_jsxs(Heading,{level:`4`,id:`how-references-appear-in-/mcp-and-cli-output`,children:[`How references appear in `,_jsx(_components.code,{children:`/mcp`}),` and CLI output`]}),`\n`,_jsxs(_components.p,{children:[`For a server in the local, project, or user `,_jsx(_components.a,{href:`#mcp-installation-scopes`,children:`scope`}),`, the following surfaces show a `,_jsx(_components.code,{children:\"${VAR}\"}),` reference by name rather than as its resolved value:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The URL or command line in a server’s `,_jsx(_components.code,{children:`/mcp`}),` detail view`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`claude mcp list`}),` and `,_jsx(_components.code,{children:`claude mcp get`}),` output`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`/mcp`}),` detail view shows references this way in Claude Code v2.1.268 or later.`]}),`\n`,_jsxs(_components.p,{children:[`For a server your organization provides through the `,_jsx(_components.code,{children:`managedMcpServers`}),` setting, these surfaces show `,_jsx(_components.a,{href:`/en/managed-mcp#what-users-can-see-and-change`,children:`the URL’s host only`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`To check what `,_jsx(_components.code,{children:`claude mcp list`}),`, `,_jsx(_components.code,{children:`claude mcp get`}),`, and `,_jsx(_components.code,{children:`/mcp`}),` show when a connection fails, see `,_jsx(_components.a,{href:`#server-status-detail`,children:`Server status detail`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`practical-examples`,children:`Practical examples`}),`\n`,_jsx(Heading,{level:`3`,id:`example-connect-to-github-for-code-reviews`,children:`Example: Connect to GitHub for code reviews`}),`\n`,_jsxs(_components.p,{children:[`GitHub’s remote MCP server authenticates with a GitHub personal access token passed as a header. To get one, open your `,_jsx(_components.a,{href:`https://github.com/settings/personal-access-tokens`,children:`GitHub token settings`}),`, generate a new fine-grained token with access to the repositories you want Claude to work with, then add the server:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` github`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.githubcopilot.com/mcp/`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --header`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer YOUR_GITHUB_PAT\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Replace `,_jsx(_components.code,{children:`YOUR_GITHUB_PAT`}),` with your personal access token. The `,_jsx(_components.code,{children:`claude mcp add`}),` command saves the configuration without validating credentials, so a placeholder value is accepted here but the server fails to connect later. To verify the connection, run `,_jsx(_components.code,{children:`/mcp`}),` and check that the server’s row shows a checkmark. A server with bad credentials shows an ✘ instead, and its `,_jsx(_components.a,{href:`#server-status-detail`,children:`failure detail`}),` includes the HTTP status the server returned, such as a 401.`]}),`\n`,_jsx(_components.p,{children:`Then work with GitHub:`}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Review PR #456 and suggest improvements`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Create a new issue for the bug we just found`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Show me all open PRs assigned to me`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`3`,id:`example-query-your-postgresql-database`,children:`Example: Query your PostgreSQL database`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`https://github.com/bytebase/dbhub`,children:`DBHub`}),`, the `,_jsx(_components.code,{children:`@bytebase/dbhub`}),` package, is an MCP server that connects Claude to a relational database through the connection string you pass in `,_jsx(_components.code,{children:`--dsn`}),`. Use a read-only database user in the connection string so the queries Claude runs can’t modify data:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` stdio`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` db`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` npx`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @bytebase/dbhub`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --dsn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"postgresql://readonly:pass@prod.db.com:5432/analytics\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`To confirm the server starts, run `,_jsx(_components.code,{children:`/mcp`}),` and check that the `,_jsx(_components.code,{children:`db`}),` row shows a checkmark.`]}),`\n`,_jsx(_components.p,{children:`Then query your database naturally:`}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`What's our total revenue this month?`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Show me the schema for the orders table`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Find customers who haven't made a purchase in 90 days`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`authenticate-with-remote-mcp-servers`,children:`Authenticate with remote MCP servers`}),`\n`,_jsx(_components.p,{children:`Many cloud-based MCP servers require authentication. Claude Code supports OAuth 2.0 for secure connections.`}),`\n`,_jsxs(_components.p,{children:[`Claude Code marks a remote server as needing authentication when the server responds with `,_jsx(_components.code,{children:`401 Unauthorized`}),` or `,_jsx(_components.code,{children:`403 Forbidden`}),`. What Claude Code shows depends on the server:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`For a server you haven’t signed in to, either status code flags it in `,_jsx(_components.code,{children:`/mcp`}),` so you can complete the OAuth flow.`]}),`\n`,_jsxs(_components.li,{children:[`For a `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),`, a `,_jsx(_components.code,{children:`401`}),` caused by claude.ai rejecting your session token doesn’t flag the connector, because re-authorizing the connector can’t fix your login. Claude Code shows the `,_jsx(_components.a,{href:`/en/errors#claude-ai-rejected-the-session-token`,children:`session-token-rejected state`}),` instead.`]}),`\n`,_jsxs(_components.li,{children:[`For a server whose `,_jsx(_components.code,{children:`Authorization`}),` header you configured, in `,_jsx(_components.code,{children:`headers`}),` or through a `,_jsx(_components.a,{href:`#use-dynamic-headers-for-custom-authentication`,children:_jsx(_components.code,{children:`headersHelper`})}),`, a `,_jsx(_components.code,{children:`401`}),` or `,_jsx(_components.code,{children:`403`}),` while connecting doesn’t flag the server, because the credential to fix is the one you configured. Claude Code reports the connection as failed instead. If you set that header from a `,_jsx(_components.code,{children:\"${VAR}\"}),` reference, check whether that variable is one Claude Code `,_jsx(_components.a,{href:`#credential-variables-that-read-as-empty`,children:`reads as empty`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`For a connector `,_jsx(_components.a,{href:`#how-connectors-reach-claude-code`,children:`delivered to a cloud session`}),`, Claude Code doesn’t run a sign-in flow, because the session’s proxy authenticates to the connector with the authorization you granted in claude.ai. When a connector there needs authorizing again, reconnect it at `,_jsx(_components.a,{href:`https://claude.ai/customize/connectors`,children:`claude.ai/customize/connectors`}),` rather than from the session.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`When an OAuth server you already signed in to rejects your stored token with `,_jsx(_components.code,{children:`401 Unauthorized`}),`, Claude Code refreshes the token, reconnects, and retries the request once. It flags the server in `,_jsx(_components.code,{children:`/mcp`}),` only if that retry also fails. In a `,_jsx(_components.code,{children:`claude -p`}),` or Agent SDK run on macOS, a request that Claude Code sent while it couldn’t read your stored token fails with a `,_jsx(_components.a,{href:`/en/errors#couldnt-read-the-stored-credentials-for-mcp-server`,children:`stored-credentials error`}),` instead.`]}),`\n`,_jsxs(_components.p,{children:[`When the server rejects the stored refresh token, Claude Code immediately shows a notice pointing at `,_jsx(_components.code,{children:`/mcp`}),`. Open `,_jsx(_components.code,{children:`/mcp`}),` and select `,_jsx(_components.strong,{children:`Re-authenticate`}),` on the server to sign in again before the next tool call fails.`]}),`\n`,_jsxs(_components.p,{children:[`A custom server that returns a `,_jsx(_components.code,{children:`WWW-Authenticate`}),` header pointing to its authorization server gets the same automatic discovery as any other remote server.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code also shows a startup notice when one or more configured servers need authentication, so you don’t have to open `,_jsx(_components.code,{children:`/mcp`}),` to discover which servers need sign-in. The notice counts only servers you can sign in to from Claude Code. Before v2.1.218, it also counted `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connectors`}),` that weren’t connected in claude.ai, which you can connect only from claude.ai settings.`]}),`\n`,_jsxs(_components.p,{children:[`The notice announces each server once and leaves it out of the count at later launches until that server has connected and needs sign-in again. `,_jsx(_components.code,{children:`/mcp`}),` still lists every server that needs sign-in.`]}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`claude -p`}),` or Agent SDK run has no `,_jsx(_components.code,{children:`/mcp`}),` panel, so Claude Code can’t run the OAuth flow there. To use a server that needs authentication, complete the sign-in from an interactive session first: run `,_jsx(_components.code,{children:`/mcp`}),` in the session, or `,_jsx(_components.code,{children:`claude mcp login \u003cname>`}),` in your shell. When a configured server needs authentication during a `,_jsx(_components.code,{children:`claude -p`}),` or Agent SDK run with `,_jsx(_components.a,{href:`#scale-with-mcp-tool-search`,children:`tool search`}),` enabled, Claude Code tells Claude that the server’s tools are unavailable until you authorize it.`]}),`\n`,_jsxs(_components.p,{children:[`If you configured `,_jsx(_components.code,{children:`headers.Authorization`}),` for the server and the server rejects that header, Claude Code reports the connection as failed instead of falling back to OAuth. Check that the token is valid for the MCP endpoint, or remove the header to use the OAuth flow.`]}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Add the server that requires authentication`,children:[_jsxs(_components.p,{children:[`If you already added the `,_jsx(_components.code,{children:`sentry`}),` server in the `,_jsx(_components.a,{href:`/en/mcp-quickstart#connect-a-server-that-requires-sign-in`,children:`MCP quickstart`}),`, skip this step: running `,_jsx(_components.code,{children:`claude mcp add`}),` again with the same server name at the same scope fails with `,_jsx(_components.code,{children:`MCP server sentry already exists in local config`}),`. Otherwise, run:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sentry`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.sentry.dev/mcp`})]}),`\n`]})})})]}),_jsxs(Step,{title:`Use the /mcp command within Claude Code`,children:[_jsx(_components.p,{children:`In Claude Code, use the command:`}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(_components.p,{children:`Then follow the steps in your browser to log in.`})]})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Authentication tokens are stored securely and refreshed automatically`}),`\n`,_jsxs(_components.li,{children:[`Use “Clear authentication” in the `,_jsx(_components.code,{children:`/mcp`}),` menu to revoke access`]}),`\n`,_jsx(_components.li,{children:`If your browser doesn’t open automatically, copy the provided URL and open it manually`}),`\n`,_jsx(_components.li,{children:`If the browser redirect fails with a connection error after authenticating, paste the full callback URL from your browser’s address bar into the URL prompt that appears in Claude Code`}),`\n`,_jsx(_components.li,{children:`OAuth authentication works with HTTP servers`}),`\n`]})]}),`\n`,_jsx(Heading,{level:`3`,id:`authenticate-from-the-command-line`,children:`Authenticate from the command line`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`claude mcp login \u003cname>`}),` command runs a configured server’s OAuth flow directly from your shell, so you don’t need to open the `,_jsx(_components.code,{children:`/mcp`}),` panel inside a session. For a claude.ai connector, follow `,_jsx(_components.a,{href:`/en/remote-control#authorize-a-connector-again-from-your-shell`,children:`Authorize a connector again from your shell`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` login`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sentry`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`To clear stored credentials later, run `,_jsx(_components.code,{children:`claude mcp logout \u003cname>`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`claude mcp login`}),` detects when no local browser is available, such as during an SSH session or on Linux without a display server, and prints the authorization URL instead of trying to open a browser. Open the URL on your local machine, then paste the full redirect URL from your browser’s address bar back at the prompt. The command needs an interactive terminal for the paste step, so connect with `,_jsx(_components.code,{children:`ssh -t`}),`. Pass `,_jsx(_components.code,{children:`--no-browser`}),` to force the URL prompt even when a local browser is detected.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` login`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sentry`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --no-browser`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`use-a-fixed-oauth-callback-port`,children:`Use a fixed OAuth callback port`}),`\n`,_jsxs(_components.p,{children:[`Some MCP servers require a specific redirect URI registered in advance. By default, Claude Code picks a random available port for the OAuth callback. Use `,_jsx(_components.code,{children:`--callback-port`}),` to fix the port so it matches a pre-registered redirect URI of the form `,_jsx(_components.code,{children:`http://localhost:PORT/callback`}),`. If sign-in on Claude Code v2.1.229 fails with a redirect URI mismatch, see the version note under `,_jsx(_components.a,{href:`#use-pre-configured-oauth-credentials`,children:`Use pre-configured OAuth credentials`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`You can use `,_jsx(_components.code,{children:`--callback-port`}),` on its own (with dynamic client registration) or together with `,_jsx(_components.code,{children:`--client-id`}),` (with pre-configured credentials).`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Fixed callback port with dynamic client registration`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --callback-port`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 8080`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.example.com/mcp`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`use-pre-configured-oauth-credentials`,children:`Use pre-configured OAuth credentials`}),`\n`,_jsx(_components.p,{children:`Some MCP servers don’t support automatic OAuth setup via Dynamic Client Registration. If you see an error like “Incompatible auth server: does not support dynamic client registration,” the server requires pre-configured credentials. Claude Code also supports servers that use a Client ID Metadata Document (CIMD) instead of Dynamic Client Registration, and discovers these automatically. If automatic discovery fails, register an OAuth app through the server’s developer portal first, then provide the credentials when adding the server.`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Register an OAuth app with the server`,children:[_jsx(_components.p,{children:`Create an app through the server’s developer portal and note your client ID and client secret.`}),_jsxs(_components.p,{children:[`If the registration form asks for a redirect URI, pick any available port and enter `,_jsx(_components.code,{children:`http://localhost:PORT/callback`}),` with that port. You’ll use the same port in the next step.`]}),_jsxs(_components.p,{children:[`In v2.1.229, Claude Code sent `,_jsx(_components.code,{children:`http://127.0.0.1:PORT/callback`}),` instead, and servers that exact-match the registered redirect URI rejected the sign-in with a redirect URI mismatch. Claude Code v2.1.231 restored the `,_jsx(_components.code,{children:`localhost`}),` form. To recover on v2.1.229, upgrade Claude Code, or temporarily add the `,_jsx(_components.code,{children:`http://127.0.0.1:PORT/callback`}),` form to the server’s registered redirect URIs.`]})]}),_jsxs(Step,{title:`Add the server with your credentials`,children:[_jsxs(_components.p,{children:[`The tabs cover both commands: `,_jsx(_components.code,{children:`claude mcp add`}),` takes your client ID and callback port as flags, and `,_jsx(_components.code,{children:`claude mcp add-json`}),` takes them in an `,_jsx(_components.code,{children:`oauth`}),` object. If you registered a redirect URI, set the callback port to the port in that URI.`]}),_jsxs(Tabs,{children:[_jsxs(Tab,{title:`claude mcp add`,id:`claude-mcp-add`,children:[_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`--client-id`}),` to pass your app’s client ID. The `,_jsx(_components.code,{children:`--client-secret`}),` flag prompts for the secret with masked input:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-id`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` your-client-id`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-secret`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --callback-port`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 8080`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.example.com/mcp`})]}),`\n`]})})})]}),_jsxs(Tab,{title:`claude mcp add-json`,id:`claude-mcp-add-json`,children:[_jsxs(_components.p,{children:[`Include the `,_jsx(_components.code,{children:`oauth`}),` object in the JSON config and pass `,_jsx(_components.code,{children:`--client-secret`}),` as a separate flag:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"http\",\"url\":\"https://mcp.example.com/mcp\",\"oauth\":{\"clientId\":\"your-client-id\",\"callbackPort\":8080}}'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-secret`})}),`\n`]})})})]}),_jsxs(Tab,{title:`claude mcp add-json (callback port only)`,id:`claude-mcp-add-json-callback-port-only`,children:[_jsxs(_components.p,{children:[`To fix only the callback port and let Claude Code register the client automatically, set `,_jsx(_components.code,{children:`callbackPort`}),` on its own:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"http\",\"url\":\"https://mcp.example.com/mcp\",\"oauth\":{\"callbackPort\":8080}}'`})}),`\n`]})})})]}),_jsxs(Tab,{title:`CI / env var`,id:`ci-%2F-env-var`,children:[_jsx(_components.p,{children:`Set the secret via environment variable to skip the interactive prompt:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`MCP_CLIENT_SECRET`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your-secret`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --transport`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-id`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` your-client-id`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-secret`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --callback-port`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 8080`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://mcp.example.com/mcp`})]}),`\n`]})})})]})]})]}),_jsx(Step,{title:`Authenticate in Claude Code`,children:_jsxs(_components.p,{children:[`Run `,_jsx(_components.code,{children:`/mcp`}),` in Claude Code and follow the browser login flow.`]})})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The client secret is stored securely in your system keychain (macOS) or a credentials file, not in your config`}),`\n`,_jsxs(_components.li,{children:[`You can set the client secret only when you add the server. When you authenticate with `,_jsx(_components.code,{children:`claude mcp login`}),` or from `,_jsx(_components.code,{children:`/mcp`}),`, Claude Code uses the stored secret and doesn’t prompt for one or read `,_jsx(_components.code,{children:`MCP_CLIENT_SECRET`})]}),`\n`,_jsxs(_components.li,{children:[`To add or change the secret later, remove the server with `,_jsx(_components.code,{children:`claude mcp remove \u003cname>`}),`, then add it again with `,_jsx(_components.code,{children:`--client-secret`}),` and the same `,_jsx(_components.code,{children:`--scope`})]}),`\n`,_jsxs(_components.li,{children:[`If the server uses a public OAuth client with no secret, use only `,_jsx(_components.code,{children:`--client-id`}),` without `,_jsx(_components.code,{children:`--client-secret`})]}),`\n`,_jsx(_components.li,{children:`These flags only apply to HTTP and SSE transports. They have no effect on stdio servers`}),`\n`,_jsxs(_components.li,{children:[`Use `,_jsx(_components.code,{children:`claude mcp get \u003cname>`}),` to verify that OAuth credentials are configured for a server`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`3`,id:`override-oauth-metadata-discovery`,children:`Override OAuth metadata discovery`}),`\n`,_jsxs(_components.p,{children:[`Point Claude Code at a specific OAuth authorization server metadata URL to bypass the default discovery chain. Set `,_jsx(_components.code,{children:`authServerMetadataUrl`}),` when the MCP server’s standard endpoints error, or when you want to route discovery through an internal proxy. By default, Claude Code first checks RFC 9728 Protected Resource Metadata at `,_jsx(_components.code,{children:`/.well-known/oauth-protected-resource`}),`, then falls back to RFC 8414 authorization server metadata at `,_jsx(_components.code,{children:`/.well-known/oauth-authorization-server`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Set `,_jsx(_components.code,{children:`authServerMetadataUrl`}),` in the `,_jsx(_components.code,{children:`oauth`}),` object of your server’s config in `,_jsx(_components.code,{children:`.mcp.json`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"my-server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.example.com/mcp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"oauth\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"authServerMetadataUrl\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://auth.example.com/.well-known/openid-configuration\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The URL must use `,_jsx(_components.code,{children:`https://`}),`. The metadata URL’s `,_jsx(_components.code,{children:`scopes_supported`}),` overrides the scopes the upstream server advertises.`]}),`\n`,_jsx(Heading,{level:`3`,id:`restrict-oauth-scopes`,children:`Restrict OAuth scopes`}),`\n`,_jsxs(_components.p,{children:[`Set `,_jsx(_components.code,{children:`oauth.scopes`}),` to pin the scopes Claude Code requests during the authorization flow. This is the supported way to restrict an MCP server to a security-team-approved subset when the upstream authorization server advertises more scopes than you want to grant. The value is a single space-separated string, matching the `,_jsx(_components.code,{children:`scope`}),` parameter format in RFC 6749 §3.3.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"slack\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.slack.com/mcp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"oauth\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"scopes\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"channels:read chat:write search:read\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`oauth.scopes`}),` takes precedence over both `,_jsx(_components.code,{children:`authServerMetadataUrl`}),` and the scopes the server discovers at `,_jsx(_components.code,{children:`/.well-known`}),`. Leave it unset to let the MCP server determine the requested scope set.`]}),`\n`,_jsxs(_components.p,{children:[`When `,_jsx(_components.code,{children:`oauth.scopes`}),` isn’t set, Claude Code doesn’t request the full `,_jsx(_components.code,{children:`scopes_supported`}),` catalog from automatically discovered authorization server metadata. Metadata fetched from a configured `,_jsx(_components.code,{children:`authServerMetadataUrl`}),` still supplies its `,_jsx(_components.code,{children:`scopes_supported`}),` as the requested scopes.`]}),`\n`,_jsxs(_components.p,{children:[`If the authorization server advertises `,_jsx(_components.code,{children:`offline_access`}),` in `,_jsx(_components.code,{children:`scopes_supported`}),`, Claude Code appends it to the pinned scopes so the access token can be refreshed without a new browser sign-in.`]}),`\n`,_jsxs(_components.p,{children:[`If the server later returns a 403 `,_jsx(_components.code,{children:`insufficient_scope`}),` for a tool call, the call fails with a `,_jsx(_components.a,{href:`/en/errors#mcp-server-needs-you-to-sign-in-again`,children:_jsx(_components.code,{children:`needs additional permissions`})}),` message that names the scope the server asks for. The server shows as needing authentication in `,_jsx(_components.code,{children:`/mcp`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`If that scope isn’t in your pinned `,_jsx(_components.code,{children:`oauth.scopes`}),`, add it, then run `,_jsx(_components.code,{children:`/mcp`}),` and authenticate the server again. Claude Code requests the pinned scopes rather than the scope the server named, so if you authenticate again without adding it, the token you get still lacks it.`]}),`\n`,_jsx(Heading,{level:`3`,id:`use-oauth-with-a-server-behind-an-authenticating-proxy`,children:`Use OAuth with a server behind an authenticating proxy`}),`\n`,_jsx(_components.p,{children:`If your MCP server uses OAuth behind a proxy or gateway that checks a header of its own, sign-in fails when the OAuth requests arrive without that header. Signing in through the proxy requires Claude Code v2.1.299 or later, with the header and the sign-in both configured:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The proxy’s header`}),`: pass it with `,_jsx(_components.a,{href:`#option-1-add-a-remote-http-server`,children:_jsx(_components.code,{children:`--header`})}),`, the `,_jsx(_components.code,{children:`headers`}),` field, or a `,_jsx(_components.a,{href:`#use-dynamic-headers-for-custom-authentication`,children:_jsx(_components.code,{children:`headersHelper`})}),`, under the name the proxy reads`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The OAuth sign-in`}),`: keep `,_jsx(_components.code,{children:`Authorization`}),` out of the configured headers, then sign in with `,_jsx(_components.code,{children:`claude mcp login \u003cname>`}),` in your shell. If you configure an `,_jsx(_components.code,{children:`Authorization`}),` header, Claude Code uses it as the server’s credential and doesn’t fall back to OAuth for that server.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`use-dynamic-headers-for-custom-authentication`,children:`Use dynamic headers for custom authentication`}),`\n`,_jsxs(_components.p,{children:[`When authentication such as Kerberos, short-lived tokens, or internal SSO needs headers generated at connection time, set the server’s `,_jsx(_components.code,{children:`headersHelper`}),` to a command. Claude Code runs it when connecting and merges its output into the headers it sends. This example uses a script:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"internal-api\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.internal.example.com\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"headersHelper\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/opt/bin/get-mcp-auth-headers.sh\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The command can also be inline:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"internal-api\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.internal.example.com\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"headersHelper\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"echo '{`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`Authorization`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`: `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`Bearer '`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`$(get-token)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\\"`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`}'\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Requirements:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The command must write a JSON object of string key-value pairs to stdout`}),`\n`,_jsx(_components.li,{children:`Claude Code runs the command in a shell and gives up on it after 10 seconds`}),`\n`,_jsxs(_components.li,{children:[`Claude Code picks the command’s working directory by `,_jsx(_components.a,{href:`#where-the-helper-runs`,children:`where you configured the server`}),`, so give the script as an absolute path or put it on `,_jsx(_components.code,{children:`PATH`})]}),`\n`,_jsxs(_components.li,{children:[`Dynamic headers override any static `,_jsx(_components.code,{children:`headers`}),` with the same name`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code runs the helper fresh on each connection, at session start and on reconnect, once the `,_jsx(_components.a,{href:`#trust-a-folder-before-its-headershelper-runs`,children:`trust rule for project and local-scope servers`}),` lets it run. It doesn’t cache the result, so your script is responsible for any token reuse.`]}),`\n`,_jsxs(_components.p,{children:[`If a tool call returns `,_jsx(_components.code,{children:`401 Unauthorized`}),` or `,_jsx(_components.code,{children:`403 Forbidden`}),`, Claude Code automatically re-runs the helper under the same rule, reconnects with the fresh headers, and retries the call once. Claude Code marks the server as needing authentication in `,_jsx(_components.code,{children:`/mcp`}),` only if that retry also fails.`]}),`\n`,_jsxs(_components.p,{children:[`When the helper’s output includes an `,_jsx(_components.code,{children:`Authorization`}),` header, Claude Code uses that credential as the server’s authentication and doesn’t fall back to OAuth for the server.`]}),`\n`,_jsxs(_components.p,{children:[`If the server rejects the helper’s credential while connecting, Claude Code reports the connection as failed rather than marking the server as needing authentication. Fix the credential your helper returns, then reconnect from `,_jsx(_components.code,{children:`/mcp`}),` to re-run the helper.`]}),`\n`,_jsx(_components.p,{children:`Claude Code sets these environment variables when executing the helper:`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Variable`}),_jsx(_components.th,{style:{textAlign:`left`},children:`Value`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_SERVER_NAME`})}),_jsx(_components.td,{style:{textAlign:`left`},children:`the name of the MCP server`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`CLAUDE_CODE_MCP_SERVER_URL`})}),_jsx(_components.td,{style:{textAlign:`left`},children:`the URL of the MCP server`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`CLAUDE_PLUGIN_ROOT`})}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`the plugin’s root directory. Set only when a `,_jsx(_components.a,{href:`/en/plugins/components#mcp-servers`,children:`plugin`}),` provides the server`]})]})]})]}),`\n`,_jsx(_components.p,{children:`Use these to write a single helper script that serves multiple MCP servers.`}),`\n`,_jsxs(_components.p,{children:[`A plugin-provided `,_jsx(_components.code,{children:`headersHelper`}),` can’t reference the plugin’s `,_jsx(_components.a,{href:`/en/plugins/manifest-reference#user-configuration`,children:_jsx(_components.code,{children:\"${user_config.*}\"})}),` values, because the command runs through a shell. Claude Code reports the server as misconfigured with an `,_jsx(_components.a,{href:`/en/errors#plugin-command-references-user-config`,children:`error`}),` and doesn’t substitute the value. Put `,_jsx(_components.code,{children:\"${user_config.KEY}\"}),` in the server’s `,_jsx(_components.code,{children:`headers`}),` field instead, which isn’t shell-parsed, or have the helper script read the value from a config file. Before v2.1.207, `,_jsx(_components.code,{children:`headersHelper`}),` substituted `,_jsx(_components.code,{children:\"${user_config.*}\"}),` values.`]}),`\n`,_jsx(Heading,{level:`4`,id:`where-the-helper-runs`,children:`Where the helper runs`}),`\n`,_jsxs(_components.p,{children:[`Claude Code picks the `,_jsx(_components.code,{children:`headersHelper`}),` command’s working directory from the configuration that declares the server. A `,_jsx(_components.code,{children:`cd`}),` that Claude runs in Bash doesn’t move it, and `,_jsx(_components.a,{href:`/en/permissions#move-the-session-to-another-directory`,children:_jsx(_components.code,{children:`/cd`})}),` moves it only for servers that run from the session’s primary working directory. Each row below gives the directory that a relative path in your `,_jsx(_components.code,{children:`headersHelper`}),` command resolves against.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Where you configured the server`}),_jsx(_components.th,{style:{textAlign:`left`},children:`Working directory`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[`A `,_jsx(_components.a,{href:`/en/plugins/components#mcp-servers`,children:`plugin`})]}),_jsx(_components.td,{style:{textAlign:`left`},children:`The plugin’s root directory`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[`A project `,_jsx(_components.code,{children:`.mcp.json`}),` or a `,_jsx(_components.a,{href:`#local-scope`,children:`local-scope`}),` server`]}),_jsx(_components.td,{style:{textAlign:`left`},children:`The project directory the server is declared in`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[`An agent file in your project, a server from the SDK’s `,_jsx(_components.code,{children:`mcpServers`}),` option or `,_jsx(_components.code,{children:`setMcpServers()`}),` method, or `,_jsx(_components.a,{href:`/en/cli-reference`,children:_jsx(_components.code,{children:`--mcp-config`})})]}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`The session’s `,_jsx(_components.a,{href:`/en/permissions#working-directories`,children:`primary working directory`})]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[_jsx(_components.a,{href:`#user-scope`,children:`User scope`}),`, `,_jsx(_components.a,{href:`/en/managed-mcp`,children:`managed MCP`}),`, a `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),`, or an agent file from outside your project, including one from an `,_jsx(_components.code,{children:`--add-dir`}),` directory`]}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`Your configuration directory, `,_jsx(_components.code,{children:`~/.claude`}),` unless you set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CONFIG_DIR`})})]})]})]})]}),`\n`,_jsx(_components.p,{children:`Before v2.1.238, Claude Code also ran the helpers of user-scope, managed, and claude.ai connector servers, and of agent files from outside your project, from the directory you started it in.`}),`\n`,_jsx(Heading,{level:`4`,id:`which-variables-a-helper-can-read`,children:`Which variables a helper can read`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`headersHelper`}),` that a repository or plugin supplies is a command you didn’t write, so Claude Code runs it without the credential variables from your environment, such as `,_jsx(_components.code,{children:`ANTHROPIC_API_KEY`}),`. Where you configured the server decides whether this applies:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Removed`}),`: a server in a project `,_jsx(_components.code,{children:`.mcp.json`}),` or in a plugin, and an inline server in an agent file from your project or from an `,_jsx(_components.code,{children:`--add-dir`}),` directory`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Not removed`}),`: a server at `,_jsx(_components.a,{href:`#user-scope`,children:`user`}),` or `,_jsx(_components.a,{href:`#local-scope`,children:`local scope`}),`, in `,_jsx(_components.a,{href:`/en/managed-mcp`,children:`managed MCP`}),`, from a `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),`, or supplied by the SDK or `,_jsx(_components.a,{href:`/en/cli-reference`,children:_jsx(_components.code,{children:`--mcp-config`})}),`, and an inline server in an agent file from `,_jsx(_components.code,{children:`~/.claude/agents/`}),`, from managed settings, or passed with `,_jsx(_components.code,{children:`--agents`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Apart from Git’s `,_jsx(_components.code,{children:`GIT_CONFIG_KEY_\u003cn>`}),` variables, Claude Code removes every variable from your environment whose name looks like a credential, such as a name with `,_jsx(_components.code,{children:`TOKEN`}),`, `,_jsx(_components.code,{children:`SECRET`}),`, `,_jsx(_components.code,{children:`PASSWORD`}),`, `,_jsx(_components.code,{children:`KEY`}),`, or `,_jsx(_components.code,{children:`AUTH`}),` in it in either letter case, so `,_jsx(_components.code,{children:`ANTHROPIC_API_KEY`}),` and `,_jsx(_components.code,{children:`MY_REGISTRY_TOKEN`}),` are both removed. Claude Code also removes a fixed list of credential variables whose names don’t follow that pattern, such as `,_jsx(_components.code,{children:`ANTHROPIC_CUSTOM_HEADERS`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`When this applies to your helper, have the script read its credential from a file or a credential store. If the server’s `,_jsx(_components.code,{children:`url`}),` `,_jsx(_components.a,{href:`#environment-variable-expansion-in-mcp-json`,children:`carries the live value of one of these variables`}),`, such as `,_jsx(_components.code,{children:`MY_REGISTRY_TOKEN`}),`, the `,_jsx(_components.code,{children:`CLAUDE_CODE_MCP_SERVER_URL`}),` value the helper receives has that part replaced with `,_jsx(_components.code,{children:`REDACTED`}),` as well.`]}),`\n`,_jsx(Heading,{level:`4`,id:`trust-a-folder-before-its-headershelper-runs`,children:`Trust a folder before its headersHelper runs`}),`\n`,_jsxs(_components.p,{children:[`Claude Code executes a `,_jsx(_components.code,{children:`headersHelper`}),` as an arbitrary shell command. For a server in a project `,_jsx(_components.code,{children:`.mcp.json`}),` or at `,_jsx(_components.a,{href:`#local-scope`,children:`local scope`}),`, it runs the helper only after you accept the `,_jsx(_components.a,{href:`/en/permissions#project-allow-rules-and-workspace-trust`,children:`trust dialog`}),` for the project directory the server is declared in. Before v2.1.238, a `,_jsx(_components.code,{children:`claude -p`}),` or SDK session ran these helpers without checking trust, and an interactive session ran them once you had trusted a parent folder.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Trust that doesn’t count`}),`: a parent folder’s trust, and the automatic trust a `,_jsx(_components.code,{children:`claude -p`}),` or SDK session gets for `,_jsx(_components.a,{href:`/en/permissions#what-runs-before-you-trust-a-folder`,children:`hooks in settings files`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Until you trust the folder`}),`: Claude Code connects the server with its static `,_jsx(_components.code,{children:`headers`}),` alone. In a `,_jsx(_components.code,{children:`claude -p`}),` or SDK session it also prints one `,_jsx(_components.a,{href:`/en/errors#headershelper-not-run`,children:_jsx(_components.code,{children:`headersHelper not run`})}),` line per server to stderr, telling you how to grant the trust.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Trust without a dialog`}),`: set `,_jsx(_components.code,{children:`projects[\"\u003cpath>\"].hasTrustDialogAccepted`}),` to `,_jsx(_components.code,{children:`true`}),` in `,_jsx(_components.code,{children:`~/.claude.json`}),`. `,_jsx(_components.code,{children:`\u003cpath>`}),` is the folder `,_jsx(_components.a,{href:`/en/permissions#project-allow-rules-and-workspace-trust`,children:`Project allow rules and workspace trust`}),` says Claude Code keys the trust on.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code applies the same rule to a server declared inline in an `,_jsx(_components.a,{href:`/en/sub-agents#scope-mcp-servers-to-a-subagent`,children:`agent file`}),`, checking where that agent file came from: your project, for a file in its `,_jsx(_components.code,{children:`.claude/agents/`}),` directory, or an `,_jsx(_components.code,{children:`--add-dir`}),` directory. Until you `,_jsx(_components.a,{href:`/en/permissions#what-runs-before-you-trust-a-folder`,children:`trust that project or directory itself`}),`, Claude Code doesn’t load the server at all, so its helper never runs either.`]}),`\n`,_jsx(Heading,{level:`3`,id:`sign-in-to-an-mcp-server-behind-a-gateway-that-requires-a-header`,children:`Sign in to an MCP server behind a gateway that requires a header`}),`\n`,_jsxs(_components.p,{children:[`OAuth sign-in to an MCP server fails when a gateway requires a header, such as `,_jsx(_components.code,{children:`X-API-Key`}),`, and Claude Code doesn’t send it. To have Claude Code send that header, add it to the server’s configuration and use Claude Code v2.1.299 or later:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`A server whose `,_jsx(_components.a,{href:`#mcp-installation-scopes`,children:`configuration`}),` you can edit`]}),`: set it in `,_jsx(_components.a,{href:`#example-with-variable-expansion`,children:_jsx(_components.code,{children:`headers`})}),` or return it from a `,_jsx(_components.a,{href:`#use-dynamic-headers-for-custom-authentication`,children:_jsx(_components.code,{children:`headersHelper`})})]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`A server that `,_jsx(_components.a,{href:`/en/managed-mcp`,children:`managed MCP`}),` or a `,_jsx(_components.a,{href:`#plugin-provided-mcp-servers`,children:`plugin`}),` supplies`]}),`: ask your administrator or the plugin’s author to add the header to the server’s entry`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code then adds the configured headers except `,_jsx(_components.code,{children:`Authorization`}),` to the sign-in, token refresh, and token revocation requests it sends to the server’s origin. The server’s origin is the scheme, host, and port in its `,_jsx(_components.code,{children:`url`}),`. A gateway that requires the header can still stop sign-in at the authorization page or at an authorization server on another origin:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The authorization page`}),`: you sign in on this page in your browser, which doesn’t send the configured headers. If your browser gets the gateway’s error instead of the page, ask whoever runs the gateway to let the page through without the header.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`An authorization server on another origin`}),`: if a gateway in front of that server requires the header too, sign-in fails there. Ask whoever runs that gateway to let OAuth requests through without the header.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`add-mcp-servers-from-json-configuration`,children:`Add MCP servers from JSON configuration`}),`\n`,_jsx(_components.p,{children:`If you have a JSON configuration for an MCP server, you can add it directly:`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Add an MCP server from JSON`,children:_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Basic syntax`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`nam`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`e`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '\u003cjson>'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Example: Adding an HTTP server with JSON configuration`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` weather-api`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"http\",\"url\":\"https://api.weather.com/mcp\",\"headers\":{\"Authorization\":\"Bearer token\"}}'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Example: Adding a stdio server with JSON configuration`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` local-weather`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"stdio\",\"command\":\"/path/to/weather-cli\",\"args\":[\"--api-key\",\"abc123\"],\"env\":{\"CACHE_DIR\":\"/tmp\"}}'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Example: Adding an HTTP server with pre-configured OAuth credentials`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-json`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` my-server`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"type\":\"http\",\"url\":\"https://mcp.example.com/mcp\",\"oauth\":{\"clientId\":\"your-client-id\",\"callbackPort\":8080}}'`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --client-secret`})]}),`\n`]})})})}),_jsx(Step,{title:`Verify the server was added`,children:_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` get`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` weather-api`})]}),`\n`]})})})})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Make sure the JSON is properly escaped in your shell`}),`\n`,_jsx(_components.li,{children:`The JSON must conform to the MCP server configuration schema`}),`\n`,_jsxs(_components.li,{children:[`You can use `,_jsx(_components.code,{children:`--scope user`}),` to add the server to your user configuration instead of the project-specific one`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`import-mcp-servers-from-claude-desktop`,children:`Import MCP servers from Claude Desktop`}),`\n`,_jsx(_components.p,{children:`If you’ve already configured MCP servers in Claude Desktop, you can import them:`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Import servers from Claude Desktop`,children:_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Basic syntax`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add-from-claude-desktop`})]}),`\n`]})})})}),_jsx(Step,{title:`Select which servers to import`,children:_jsx(_components.p,{children:`After running the command, you’ll see an interactive dialog that allows you to select which servers you want to import.`})}),_jsx(Step,{title:`Verify the servers were imported`,children:_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` list`})]}),`\n`]})})})})]}),`\n`,_jsxs(_components.p,{children:[`Server names added through `,_jsx(_components.code,{children:`claude mcp`}),` commands can contain only letters, numbers, hyphens, and underscores. Claude Desktop doesn’t apply that restriction, so a Claude Desktop server whose name contains any other character, such as a space, can’t be imported. The import reports each name it rejects and still imports the other servers you selected.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`This feature only works on macOS and Windows Subsystem for Linux (WSL)`}),`\n`,_jsx(_components.li,{children:`It reads the Claude Desktop configuration file from its standard location on those platforms`}),`\n`,_jsxs(_components.li,{children:[`Use the `,_jsx(_components.code,{children:`--scope user`}),` flag to add servers to your user configuration`]}),`\n`,_jsx(_components.li,{children:`Imported servers keep the same names as in Claude Desktop when the name contains only letters, numbers, hyphens, and underscores. Claude Code reports a server whose name contains any other character and skips it`}),`\n`,_jsxs(_components.li,{children:[`If servers with the same names already exist, they get a numerical suffix (for example, `,_jsx(_components.code,{children:`server_1`}),`)`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`use-mcp-servers-from-claude-ai`,children:`Use MCP servers from claude.ai`}),`\n`,_jsxs(_components.p,{children:[`If you’ve logged into Claude Code with a `,_jsx(_components.a,{href:`https://claude.ai`,children:`claude.ai`}),` account, MCP servers you’ve added in claude.ai, known as `,_jsx(_components.a,{href:`https://claude.com/docs/connectors`,children:`connectors`}),`, are automatically available in Claude Code:`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Configure MCP servers in claude.ai`,children:_jsxs(_components.p,{children:[`Add servers at `,_jsx(_components.a,{href:`https://claude.ai/customize/connectors`,children:`claude.ai/customize/connectors`}),`. On Team and Enterprise plans, only admins can add servers.`]})}),_jsx(Step,{title:`Authenticate the MCP server`,children:_jsx(_components.p,{children:`Complete any required authentication steps in claude.ai.`})}),_jsxs(Step,{title:`View and manage servers in Claude Code`,children:[_jsx(_components.p,{children:`In Claude Code, use the command:`}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(_components.p,{children:`Servers from claude.ai appear in the list with indicators showing they come from claude.ai.`})]})]}),`\n`,_jsxs(_components.p,{children:[`Anthropic also provides some connectors itself, without you or an admin adding them. On accounts where `,_jsx(_components.a,{href:`/en/artifacts#write-a-document-with-claude-docs`,children:`Claude Docs`}),` is available, `,_jsx(_components.code,{children:`/mcp`}),` lists `,_jsx(_components.code,{children:`claude.ai Claude Docs`}),` with no setup, and Claude uses it when you ask for a document meant for other people. To turn off only this connector, see `,_jsx(_components.a,{href:`#disable-claude-ai-connectors`,children:`Disable claude.ai connectors`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code marks a connector `,_jsx(_components.code,{children:`managed`}),` in `,_jsx(_components.code,{children:`/mcp`}),` and in the `,_jsx(_components.a,{href:`/en/plugins/install`,children:_jsx(_components.code,{children:`/plugin`})}),` manager when your organization manages its authentication in claude.ai. Managed status doesn’t change how Claude Code connects to the connector or applies your organization’s `,_jsx(_components.a,{href:`#organization-controls-on-connector-tools`,children:`tool controls`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Connectors you have never signed in to are collapsed behind a `,_jsx(_components.code,{children:`Show unused connectors`}),` row at the end of the claude.ai section, so an organization-provisioned list doesn’t fill the panel. Select the row to expand them. A connector you signed in to before stays visible even when it currently needs re-authentication.`]}),`\n`,_jsxs(_components.p,{children:[`Connectors from claude.ai are fetched only when your active `,_jsx(_components.a,{href:`/en/authentication#authentication-precedence`,children:`authentication method`}),` is a claude.ai subscription login. They aren’t loaded, even if you previously ran `,_jsx(_components.code,{children:`/login`}),`, when:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`ANTHROPIC_API_KEY`}),`, `,_jsx(_components.code,{children:`ANTHROPIC_AUTH_TOKEN`}),`, or `,_jsx(_components.code,{children:`apiKeyHelper`}),` is active`]}),`\n`,_jsx(_components.li,{children:`A third-party provider such as Amazon Bedrock or Google Cloud’s Agent Platform is active`}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`ANTHROPIC_PROFILE`}),`, the federation variables, or an active `,_jsx(_components.a,{href:`/en/authentication#anthropic-profiles-and-federation-credentials`,children:`Anthropic profile`}),` supplies the credential`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`CLAUDE_CODE_OAUTH_TOKEN`}),` holds a token from `,_jsx(_components.a,{href:`/en/authentication#generate-a-long-lived-token`,children:_jsx(_components.code,{children:`claude setup-token`})}),`, which can only make model requests`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`If `,_jsx(_components.code,{children:`/mcp`}),` doesn’t list a connector you added, run `,_jsx(_components.code,{children:`/status`}),` to confirm which authentication method is active. Unset that environment variable, remove the `,_jsx(_components.code,{children:`apiKeyHelper`}),` setting, or `,_jsx(_components.a,{href:`/en/authentication#anthropic-profiles-and-federation-credentials`,children:`switch off the profile`}),`, then run `,_jsx(_components.code,{children:`/login`}),` to select your claude.ai account.`]}),`\n`,_jsx(_components.p,{children:`If a temporary network problem keeps the connector list from loading when your session starts, Claude Code retries the fetch up to three times in the background, and the connectors appear once a retry succeeds. If they still haven’t appeared, restart Claude Code to fetch the list again.`}),`\n`,_jsxs(_components.p,{children:[`If `,_jsx(_components.code,{children:`/mcp`}),` shows a connector as `,_jsx(_components.code,{children:`session token rejected`}),`, or its detail view shows `,_jsx(_components.a,{href:`/en/errors#claude-ai-rejected-the-session-token`,children:_jsx(_components.code,{children:`claude.ai rejected the session token`})}),`, claude.ai rejected the token from your Claude Code login. Authorizing the connector again doesn’t clear this state, because the connector’s own authorization in claude.ai isn’t what was rejected. To clear it:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Run `,_jsx(_components.code,{children:`/login`}),` to sign in again.`]}),`\n`,_jsxs(_components.li,{children:[`Reconnect the connector from `,_jsx(_components.code,{children:`/mcp`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Before v2.1.222, Claude Code marked connectors as needing authentication instead, and authorizing them didn’t resolve it.`}),`\n`,_jsxs(_components.p,{children:[`A server you’ve added in Claude Code takes `,_jsx(_components.a,{href:`#scope-hierarchy-and-precedence`,children:`precedence`}),` over a claude.ai connector that points at the same URL. When this happens, `,_jsx(_components.code,{children:`/mcp`}),` lists the connector as hidden and shows how to remove the duplicate if you’d rather use the connector.`]}),`\n`,_jsxs(_components.p,{children:[`Some Anthropic-hosted connectors, such as Microsoft 365, Gmail, and Google Calendar, don’t support local OAuth from Claude Code because the upstream identity provider only accepts the redirect URL that claude.ai registered. When a server you added with `,_jsx(_components.code,{children:`claude mcp add`}),` or in `,_jsx(_components.code,{children:`.mcp.json`}),` points at one of these hosts and you sign in to it from `,_jsx(_components.code,{children:`/mcp`}),` or with `,_jsx(_components.code,{children:`claude mcp login`}),`, Claude Code shows `,_jsx(_components.a,{href:`/en/errors#anthropic-hosted-and-doesnt-support-local-oauth`,children:_jsx(_components.code,{children:`is Anthropic-hosted and doesn't support local OAuth`})}),`, directing you to connect the service at `,_jsx(_components.a,{href:`https://claude.ai/customize/connectors`,children:`claude.ai/customize/connectors`}),` instead.`]}),`\n`,_jsxs(_components.p,{children:[`After you remove your entry with `,_jsx(_components.code,{children:`claude mcp remove \u003cname>`}),` and connect the service on claude.ai, the connector appears in Claude Code automatically.`]}),`\n`,_jsx(Heading,{level:`3`,id:`how-connectors-reach-claude-code`,children:`How connectors reach Claude Code`}),`\n`,_jsxs(_components.p,{children:[`Which settings govern a claude.ai connector depends on where your session runs, because only some sessions fetch connectors from claude.ai themselves. Each row below names how connectors arrive in one kind of session and what controls them there. The desktop app’s WSL sessions have no row because connectors are `,_jsx(_components.a,{href:`/en/desktop-wsl#check-for-the-terminal-and-connectors`,children:`still rolling out to them`}),`.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Where the session runs`}),_jsx(_components.th,{style:{textAlign:`left`},children:`How connectors arrive`}),_jsx(_components.th,{style:{textAlign:`left`},children:`What governs them`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[`Terminal, `,_jsx(_components.a,{href:`/en/vs-code`,children:`VS Code`}),`, `,_jsx(_components.a,{href:`/en/jetbrains`,children:`JetBrains`}),`, and `,_jsx(_components.a,{href:`/en/agent-sdk/claude-code-features`,children:`Agent SDK`}),` sessions`]}),_jsx(_components.td,{style:{textAlign:`left`},children:`Claude Code fetches them from claude.ai`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`The settings in this section and `,_jsx(_components.a,{href:`/en/managed-mcp`,children:`managed MCP configuration`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.a,{href:`/en/claude-code-on-the-web`,children:`Cloud sessions`})}),_jsx(_components.td,{style:{textAlign:`left`},children:`The cloud host passes them in`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`Your claude.ai organization settings, plus the `,_jsx(_components.a,{href:`/en/managed-mcp#policy-based-control-with-allowlists-and-denylists`,children:`allowlist and denylist`}),` settings that reach the session and any `,_jsx(_components.code,{children:`managed-mcp.json`}),` on the host that runs it`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{style:{textAlign:`left`},children:[`The `,_jsx(_components.a,{href:`/en/desktop`,children:`desktop app`}),`’s local and SSH sessions`]}),_jsx(_components.td,{style:{textAlign:`left`},children:`The desktop app delivers them in-process`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[_jsx(_components.code,{children:`blocked`}),` entries in your organization’s `,_jsx(_components.a,{href:`#organization-controls-on-connector-tools`,children:`connector tool controls`})]})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`#disable-claude-ai-connectors`,children:_jsx(_components.code,{children:`disableClaudeAiConnectors`})}),`, `,_jsx(_components.code,{children:`ENABLE_CLAUDEAI_MCP_SERVERS`}),`, and `,_jsx(_components.a,{href:`/en/settings-reference#allowallclaudeaimcps`,children:_jsx(_components.code,{children:`allowAllClaudeAiMcps`})}),` act only on the first row, the connectors Claude Code fetches itself. The other two rows differ from it in these ways:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Cloud sessions`}),`: `,_jsx(_components.code,{children:`allowedMcpServers`}),` and `,_jsx(_components.code,{children:`deniedMcpServers`}),` entries that reach the session, for example through `,_jsx(_components.a,{href:`/en/server-managed-settings`,children:`server-managed settings`}),`, filter the delivered connectors too. The session’s proxy rewrites each connector’s URL, so a `,_jsx(_components.code,{children:`serverUrl`}),` pattern written for the connector’s own URL doesn’t match it. To admit delivered connectors alongside a URL allowlist in a self-hosted environment, add the `,_jsx(_components.code,{children:`serverUrl`}),` entries listed under `,_jsx(_components.a,{href:`/en/self-hosted-environments-deploy#connector-traffic-leaves-your-network`,children:`Connector traffic leaves your network`}),`. Claude Code drops the delivered connectors when a `,_jsx(_components.code,{children:`managed-mcp.json`}),` is present on the host that runs the session, such as a `,_jsx(_components.a,{href:`/en/self-hosted-environments-configuration#mcp-servers`,children:`self-hosted runner host`}),`, whether or not you set `,_jsx(_components.code,{children:`allowAllClaudeAiMcps`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Desktop app local and SSH sessions`}),`: the desktop app registers the connectors as in-process `,_jsx(_components.code,{children:`type: \"sdk\"`}),` servers, and no MCP setting or `,_jsx(_components.code,{children:`managed-mcp.json`}),` reaches them. A user keeps a connector out of their own sessions by disconnecting it at `,_jsx(_components.a,{href:`https://claude.ai/customize/connectors`,children:`claude.ai/customize/connectors`}),`. An organization blocks a connector’s `,_jsx(_components.a,{href:`#organization-controls-on-connector-tools`,children:`tools`}),` or turns off `,_jsx(_components.a,{href:`/en/desktop#admin-console-controls`,children:`Claude Code in the desktop app`}),` entirely.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`organization-controls-on-connector-tools`,children:`Organization controls on connector tools`}),`\n`,_jsxs(_components.p,{children:[`Your organization can set per-tool controls on `,_jsx(_components.a,{href:`https://claude.com/docs/connectors`,children:`claude.ai connectors`}),`. Claude Code reads these settings at startup and enforces them locally, except in the desktop app’s `,_jsx(_components.a,{href:`#how-connectors-reach-claude-code`,children:`local and SSH sessions`}),`. There, the desktop app withholds `,_jsx(_components.code,{children:`blocked`}),` tools before it delivers a connector, and the `,_jsx(_components.code,{children:`ask`}),` setting doesn’t reach Claude Code, so it applies the session’s ordinary `,_jsx(_components.a,{href:`/en/permissions`,children:`permission rules`}),` to those tools instead of prompting on every call. In sessions where Claude Code fetches connectors itself, run `,_jsx(_components.code,{children:`/mcp`}),` to see which setting applies to each tool on a connector.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Tool set to `,_jsx(_components.code,{children:`ask`})]}),`: Claude Code prompts on every call with the reason `,_jsx(_components.code,{children:`Your organization requires approval for this tool`}),`. The prompt appears even in `,_jsx(_components.code,{children:`acceptEdits`}),`, `,_jsx(_components.code,{children:`auto`}),`, and `,_jsx(_components.code,{children:`bypassPermissions`}),` `,_jsx(_components.a,{href:`/en/permissions#permission-modes`,children:`permission modes`}),`. In the terminal, the prompt has no option to remember your choice. `,_jsx(_components.a,{href:`/en/permissions`,children:`Allow rules`}),` that match the tool don’t skip the prompt either. In `,_jsx(_components.code,{children:`dontAsk`}),` mode, which never prompts, Claude Code denies the call instead.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Tool set to `,_jsx(_components.code,{children:`blocked`})]}),`: Claude Code filters the tool out before Claude sees it, so it never appears in Claude’s tool list. In sessions where Claude Code fetches connectors itself, the `,_jsx(_components.code,{children:`/mcp`}),` tool list still shows the tool, marked `,_jsx(_components.code,{children:`disabled by your organization`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The desktop app and claude.ai chat apply the same `,_jsx(_components.code,{children:`blocked`}),` setting, so Claude can’t use a blocked tool there either, and you can’t withhold a tool from the desktop app’s sessions while keeping it available in chat. The desktop app skips a connector whose tools are all blocked.`]}),`\n`,_jsx(Heading,{level:`3`,id:`disable-claude-ai-connectors`,children:`Disable claude.ai connectors`}),`\n`,_jsxs(_components.p,{children:[`Claude Code applies `,_jsx(_components.a,{href:`/en/settings-reference#disableclaudeaiconnectors`,children:_jsx(_components.code,{children:`disableClaudeAiConnectors`})}),` only to the connectors it `,_jsx(_components.a,{href:`#how-connectors-reach-claude-code`,children:`fetches itself`}),`, not to the connectors a cloud host or the desktop app delivers. To turn off the connectors it fetches, set the setting to `,_jsx(_components.code,{children:`true`}),` in any settings scope:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"disableClaudeAiConnectors\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This setting uses any-source-true semantics: `,_jsx(_components.code,{children:`true`}),` in any settings source takes precedence. A checked-in project `,_jsx(_components.code,{children:`.claude/settings.json`}),` can opt a repository out of the connectors Claude Code fetches itself, but a project-level `,_jsx(_components.code,{children:`false`}),` can’t re-enable connectors that a user- or policy-level `,_jsx(_components.code,{children:`true`}),` has disabled. Servers passed explicitly via `,_jsx(_components.code,{children:`--mcp-config`}),` are unaffected.`]}),`\n`,_jsxs(_components.p,{children:[`You can also set the `,_jsx(_components.code,{children:`ENABLE_CLAUDEAI_MCP_SERVERS`}),` environment variable to `,_jsx(_components.code,{children:`false`}),`, which has the same effect for the current shell session:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ENABLE_CLAUDEAI_MCP_SERVERS`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`false`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` claude`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`To block individual claude.ai connectors instead of all of them, add them to `,_jsx(_components.a,{href:`/en/managed-mcp`,children:_jsx(_components.code,{children:`deniedMcpServers`})}),` by name or by URL pattern. For example, a `,_jsx(_components.code,{children:`serverName`}),` entry of `,_jsx(_components.code,{children:`\"claude.ai Slack\"`}),` blocks the Slack connector. You can also run `,_jsx(_components.code,{children:`/mcp`}),` to toggle any connector Claude Code fetches on or off for the current project only.`]}),`\n`,_jsx(Heading,{level:`2`,id:`use-claude-code-as-an-mcp-server`,children:`Use Claude Code as an MCP server`}),`\n`,_jsx(_components.p,{children:`You can use Claude Code itself as an MCP server that other applications can connect to:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Start Claude as a stdio MCP server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mcp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` serve`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The command prints nothing when it starts. A stdio MCP server communicates over stdin and stdout, so a silent, blocked terminal means the server is running and waiting for a client to connect.`}),`\n`,_jsx(_components.p,{children:`You can use this in Claude Desktop by adding this configuration to claude_desktop_config.json:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`10`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"claude-code\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"stdio\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"claude\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"mcp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"serve\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"env\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {}`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Configuring the executable path`}),`: the `,_jsx(_components.code,{children:`command`}),` field must reference the Claude Code executable. If the `,_jsx(_components.code,{children:`claude`}),` command is not in your system’s PATH, you’ll need to specify the full path to the executable.`]}),_jsx(_components.p,{children:`To find the full path:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`which`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` claude`})]}),`\n`]})})}),_jsx(_components.p,{children:`Then use the full path in your configuration:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`10`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"claude-code\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"stdio\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/full/path/to/claude\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"mcp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"serve\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"env\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {}`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.p,{children:[`Without the correct executable path, you’ll encounter errors like `,_jsx(_components.code,{children:`spawn claude ENOENT`}),`.`]})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`In Claude Desktop, try asking Claude to read files in a directory, make edits, and more.`}),`\n`,_jsx(_components.li,{children:`This MCP server only exposes Claude Code’s tools to your MCP client, so your own client is responsible for implementing user confirmation for individual tool calls.`}),`\n`]})]}),`\n`,_jsx(Heading,{level:`3`,id:`read-a-background-command’s-output-as-an-mcp-client`,children:`Read a background command’s output as an MCP client`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`backgroundOutputPath`}),` field in a Bash or PowerShell result from `,_jsx(_components.code,{children:`claude mcp serve`}),` means the call left its command running `,_jsx(_components.a,{href:`/en/tools-reference#background-commands`,children:`in the background`}),`. A command runs in the background when your client sets `,_jsx(_components.code,{children:`run_in_background: true`}),` on the call. A foreground command can also `,_jsx(_components.a,{href:`/en/tools-reference#foreground-commands-that-move-to-the-background`,children:`move to the background`}),` when it reaches its timeout.`]}),`\n`,_jsx(_components.p,{children:`The field is in the result’s JSON text and holds the path of the command’s output file.`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`To read the output so far`}),`: open the file at that path from your client, or pass the path as `,_jsx(_components.code,{children:`file_path`}),` to the server’s `,_jsx(_components.a,{href:`/en/tools-reference#read-tool-behavior`,children:_jsx(_components.code,{children:`Read`})}),` tool`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`To tell when the command has finished`}),`: append an `,_jsx(_components.code,{children:`echo`}),` of a fixed string to the `,_jsx(_components.code,{children:`command`}),` value, as in `,_jsx(_components.code,{children:`npm test; echo DONE`}),`. The command has finished once that string appears in the file. Without the string, nothing marks the end, because Claude Code adds no closing line to the file and doesn’t notify your client.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`To read the end of long output`}),`: `,_jsx(_components.code,{children:`Read`}),` with only `,_jsx(_components.code,{children:`file_path`}),` returns the `,_jsx(_components.a,{href:`/en/tools-reference#large-files`,children:`first page`}),`, or fails when the file exceeds the size limit. Pass `,_jsx(_components.code,{children:`offset`}),` and `,_jsx(_components.code,{children:`limit`}),` as well, which works at any file size:`,`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Call `,_jsx(_components.code,{children:`Read`}),` with `,_jsx(_components.code,{children:`offset`}),` and `,_jsx(_components.code,{children:`limit`}),` both set to `,_jsx(_components.code,{children:`1`}),`, and take `,_jsx(_components.code,{children:`totalLines`}),` from the result`]}),`\n`,_jsxs(_components.li,{children:[`Call `,_jsx(_components.code,{children:`Read`}),` again with `,_jsx(_components.code,{children:`offset`}),` set to `,_jsx(_components.code,{children:`totalLines`}),` minus nine and `,_jsx(_components.code,{children:`limit`}),` set to `,_jsx(_components.code,{children:`10`})]}),`\n`,_jsxs(_components.li,{children:[`Look for your `,_jsx(_components.code,{children:`echo`}),` string in the last ten lines, which the second call returns`]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`backgroundOutputPath`}),` field requires Claude Code v2.1.295 or later.`]}),`\n`,_jsx(Heading,{level:`2`,id:`mcp-output-limits-and-warnings`,children:`MCP output limits and warnings`}),`\n`,_jsx(_components.p,{children:`When MCP tools produce large outputs, Claude Code helps manage the token usage to prevent overwhelming your conversation context:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Output warning threshold`}),`: Claude Code displays a warning when any MCP tool output exceeds 10,000 tokens`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Configurable limit`}),`: you can adjust the maximum allowed MCP output tokens using the `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` environment variable`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Default limit`}),`: the default maximum is 25,000 tokens`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Scope`}),`: the environment variable applies to tools that don’t declare their own limit. Tools that set `,_jsx(_components.a,{href:`#raise-the-limit-for-a-specific-tool`,children:_jsx(_components.code,{children:`anthropic/maxResultSizeChars`})}),` use that value instead for text content, regardless of what `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` is set to. Tools that return image data are still subject to `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Over the limit`}),`: when a successful result with no image content exceeds the token limit, Claude Code saves it to a file and replaces it in the conversation with a message that names the file path, so Claude reads the file when it needs the content. The file goes in the session’s `,_jsx(_components.code,{children:`tool-results`}),` directory under `,_jsx(_components.a,{href:`/en/claude-directory#cleaned-up-automatically`,children:_jsx(_components.code,{children:`~/.claude/projects/`})}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Response size from HTTP and SSE servers`}),`: when a response from an `,_jsx(_components.a,{href:`#option-1-add-a-remote-http-server`,children:`HTTP`}),` or `,_jsx(_components.a,{href:`#option-2-add-a-remote-sse-server`,children:`SSE`}),` server passes 16 MiB, Claude Code stops reading it and the request fails. The limit applies after decompression to one JSON response body or one event of an event stream. If you maintain the server, return less data per response to stay under the limit, for example by paginating results`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Message size from WebSocket servers`}),`: when a `,_jsx(_components.a,{href:`#option-4-add-a-remote-websocket-server`,children:`WebSocket`}),` server sends one message over 16 MiB, Claude Code `,_jsx(_components.a,{href:`#mid-session-drops-of-a-remote-server`,children:`closes the connection`}),`, and calls in progress on that server fail. If you maintain the server, return less data per message to stay under the limit`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`A call that Claude Code has `,_jsx(_components.a,{href:`#automatic-backgrounding-of-long-tool-calls`,children:`moved to a background task`}),` reports its result through the task notification. Two more limits apply to a call that completes in the foreground:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Character limit for text results`}),`: for a tool that doesn’t declare `,_jsx(_components.a,{href:`#raise-the-limit-for-a-specific-tool`,children:_jsx(_components.code,{children:`anthropic/maxResultSizeChars`})}),`, Claude Code saves a successful result with no image content to a file once it’s longer than 50,000 characters, whatever its token count. Setting `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` doesn’t change this threshold`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Error results`}),`: when a tool returns a result marked `,_jsx(_components.code,{children:`isError: true`}),`, Claude receives the result’s text as the tool’s error message. Error text longer than about 11,000 characters keeps only its first 5,000 and last 5,000 characters, with a marker between them that says how many characters were removed`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`To change the token limit, set `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` in your shell before starting Claude Code:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` MAX_MCP_OUTPUT_TOKENS`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`50000`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`claude`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`raise-the-limit-for-a-specific-tool`,children:`Raise the limit for a specific tool`}),`\n`,_jsxs(_components.p,{children:[`If you’re building an MCP server, you can allow individual tools to return results larger than the default persist-to-disk threshold of 50,000 characters by setting `,_jsx(_components.code,{children:`_meta[\"anthropic/maxResultSizeChars\"]`}),` in the tool’s `,_jsx(_components.code,{children:`tools/list`}),` response entry. Claude Code raises that tool’s threshold to the annotated value, up to a hard ceiling of 500,000 characters.`]}),`\n`,_jsx(_components.p,{children:`This is useful for tools that return inherently large but necessary outputs, such as database schemas or full file trees. Without the annotation, successful results that exceed the default threshold are persisted to disk and replaced with a file reference in the conversation.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"get_schema\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"description\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Returns the full database schema\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"_meta\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"anthropic/maxResultSizeChars\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`200000`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The annotation applies independently of `,_jsx(_components.code,{children:`MAX_MCP_OUTPUT_TOKENS`}),` for text content, so users don’t need to raise the environment variable for tools that declare it. Tools that return image data are still subject to the token limit.`]}),`\n`,_jsx(Heading,{level:`3`,id:`images-in-tool-results`,children:`Images in tool results`}),`\n`,_jsxs(_components.p,{children:[`When an MCP tool returns a PNG, JPEG, GIF, or WebP image, Claude sees the image inline in the conversation. The inline copy may be scaled down or compressed to fit the model’s image size limits. Claude Code also saves the original bytes to a file in the session’s `,_jsx(_components.code,{children:`tool-results`}),` directory under `,_jsx(_components.a,{href:`/en/claude-directory#cleaned-up-automatically`,children:_jsx(_components.code,{children:`~/.claude/projects/`})}),` and gives Claude the path. Claude can then crop, convert, or reuse the full-resolution file with tools such as Bash.`]}),`\n`,_jsxs(_components.p,{children:[`If you disable session persistence with `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--no-session-persistence`})}),` or `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_SKIP_PROMPT_HISTORY`})}),`, Claude Code writes no image file and Claude receives only the inline copy.`]}),`\n`,_jsx(_components.p,{children:`Saving MCP image results to a file requires Claude Code v2.1.283 or later.`}),`\n`,_jsx(Heading,{level:`2`,id:`tool-input-schemas-with-a-root-level-combinator`,children:`Tool input schemas with a root-level combinator`}),`\n`,_jsxs(_components.p,{children:[`Some MCP servers declare a tool’s input schema as a JSON Schema union, with `,_jsx(_components.code,{children:`anyOf`}),`, `,_jsx(_components.code,{children:`oneOf`}),`, or `,_jsx(_components.code,{children:`allOf`}),` at the top level of the schema. The Claude API doesn’t accept those keywords at the schema root. It does accept combinators nested inside `,_jsx(_components.code,{children:`properties`}),`, which Claude Code sends unchanged.`]}),`\n`,_jsx(_components.p,{children:`Tools with a root-level combinator stay available. Before sending the tool to the API, Claude Code flattens the schema into a single object and prepends a sentence to the tool’s description that tells Claude which parameter groups belong together:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`allOf`}),`: properties from every branch are merged, and each branch’s `,_jsx(_components.code,{children:`required`}),` list still applies`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`anyOf`}),` and `,_jsx(_components.code,{children:`oneOf`}),`: properties from every branch are merged, and each branch’s `,_jsx(_components.code,{children:`required`}),` list is described in the tool description instead of enforced by the schema`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Your server receives whichever arguments Claude chose, so keep validating the combination server-side.`}),`\n`,_jsx(_components.p,{children:`When Claude Code can’t produce a schema the API accepts, or on a deployment that doesn’t receive the remote configuration that enables the rewrite, it skips that one tool, records the reason in the server’s log, and leaves the server’s other tools available.`}),`\n`,_jsx(Heading,{level:`2`,id:`tools-with-invalid-input-schemas`,children:`Tools with invalid input schemas`}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`If your session fails with a 400 error that names a tool by its position, follow the steps in `,_jsx(_components.a,{href:`/en/errors#tool-input-schema-is-invalid`,children:`Tool input schema is invalid`}),`.`]})}),`\n`,_jsx(_components.p,{children:`If one of your MCP server’s tools has an input schema that breaks either of two rules the API enforces, Claude Code excludes that tool. The server’s other tools are unaffected. Claude Code checks both rules as it loads the server’s tools:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Top-level property names must be 1 to 64 characters long and use only ASCII letters and digits, `,_jsx(_components.code,{children:`_`}),`, `,_jsx(_components.code,{children:`.`}),`, and `,_jsx(_components.code,{children:`-`})]}),`\n`,_jsxs(_components.li,{children:[`The schema must be valid against the JSON Schema draft 2020-12 meta-schema. Claude Code applies this check to schemas that declare no `,_jsx(_components.code,{children:`$schema`}),` and schemas that declare draft 2020-12. A schema that declares any other dialect skips this check, though the property-name check above still applies`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`When Claude Code excludes a tool, it records the reason in the server’s log and tells Claude which tools it excluded and why, so you can ask Claude why a tool is missing. If you fix the schema on the server, the tool comes back the next time Claude Code loads the server’s tools.`}),`\n`,_jsxs(_components.p,{children:[`When `,_jsx(_components.a,{href:`/en/env-vars#features-that-need-feature-flag-fetching`,children:`feature flag fetching`}),` is off or the flags have never arrived, as on an air-gapped machine, a tool that breaks a rule isn’t excluded:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Claude gets the tool unchanged, and the server’s log records `,_jsx(_components.code,{children:`input schema would be rejected by the Anthropic API`}),` for it`]}),`\n`,_jsxs(_components.li,{children:[`If the API then rejects the schema, see `,_jsx(_components.a,{href:`#tools-whose-input-schema-the-api-refuses`,children:`Tools whose input schema the API refuses`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Before v2.1.216, no deployment ran these checks.`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.a,{href:`#tool-input-schemas-with-a-root-level-combinator`,children:`root-level combinator handling`}),` is separate and keeps its own behavior when flag fetching is off or the flags have never arrived.`]}),`\n`,_jsx(Heading,{level:`3`,id:`tools-whose-input-schema-the-api-refuses`,children:`Tools whose input schema the API refuses`}),`\n`,_jsxs(_components.p,{children:[`If a line in the debug log contains `,_jsx(_components.code,{children:`the API refused this tool's input schema`}),`, it names a tool whose schema the API rejected in a request. Claude Code resends that request with the tool declared without parameters.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`If your session fails with a 400 error that names a tool by its position`}),`: follow the steps in `,_jsx(_components.a,{href:`/en/errors#tool-input-schema-is-invalid`,children:`Tool input schema is invalid`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`If you use the server`}),`: you don’t need to do anything. Claude can still call the tool, but doesn’t see its parameters`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`If you maintain the server`}),`: fix the tool’s input schema on the server. The log line ends with `,_jsx(_components.code,{children:`The API said:`}),` and the API’s reason for rejecting the schema. Validate the arguments the server receives, because Claude calls the tool without seeing its parameters`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Before v2.1.300, every turn that included the refused schema failed with `,_jsx(_components.a,{href:`/en/errors#tool-input-schema-is-invalid`,children:`a 400 error naming the tool by its position`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`tools-with-names-longer-than-128-characters`,children:`Tools with names longer than 128 characters`}),`\n`,_jsxs(_components.p,{children:[`If `,_jsx(_components.code,{children:`/mcp`}),` lists a tool that Claude can’t call, check whether the tool’s full name is longer than 128 characters. Run `,_jsx(_components.code,{children:`/mcp`}),` in your session and select the tool to see its full name, such as `,_jsx(_components.code,{children:`mcp__\u003cserver>__\u003ctool>`}),`. Claude Code leaves an MCP tool out of the tools it sends to Claude when its full name is over 128 characters. The Claude API rejects a request that includes such a tool, so leaving the tool out keeps the server’s other tools working.`]}),`\n`,_jsxs(_components.p,{children:[`For the message that names the tool and the ways to shorten its full name, see `,_jsx(_components.a,{href:`/en/errors#mcp-tool-name-over-128-characters`,children:`MCP tool name over 128 characters`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`require-approval-for-a-specific-tool`,children:`Require approval for a specific tool`}),`\n`,_jsxs(_components.p,{children:[`If you’re building an MCP server, you can mark a tool as requiring explicit approval on every call by setting `,_jsx(_components.code,{children:`_meta[\"anthropic/requiresUserInteraction\"]`}),` to `,_jsx(_components.code,{children:`true`}),` in the tool’s `,_jsx(_components.code,{children:`tools/list`}),` response entry. The value must be the JSON Boolean `,_jsx(_components.code,{children:`true`}),`; any other value is ignored.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code shows that tool’s permission prompt on every call, even in `,_jsx(_components.code,{children:`acceptEdits`}),`, `,_jsx(_components.code,{children:`auto`}),`, and `,_jsx(_components.code,{children:`bypassPermissions`}),` `,_jsx(_components.a,{href:`/en/permissions#permission-modes`,children:`permission modes`}),`, and doesn’t offer a “don’t ask again” option for it. `,_jsx(_components.a,{href:`/en/permissions#permission-rule-syntax`,children:`Allow rules`}),` that match the tool don’t skip the prompt either. In `,_jsx(_components.code,{children:`dontAsk`}),` mode, which never prompts, Claude Code denies the call instead.`]}),`\n`,_jsxs(_components.p,{children:[`The prompt has to reach a person. In non-interactive mode with `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--permission-prompt-tool`})}),`, an `,_jsx(_components.code,{children:`allow`}),` result from the prompt tool for a flagged tool is converted to a deny with the message `,_jsx(_components.code,{children:`MCP tool requires user interaction; not supported via --permission-prompt-tool`}),`. The Agent SDK’s `,_jsxs(_components.a,{href:`/en/agent-sdk/permissions`,children:[_jsx(_components.code,{children:`canUseTool`}),` callback`]}),` does receive these calls and can approve them, because your SDK application is expected to show them to a user.`]}),`\n`,_jsx(_components.p,{children:`Use this for tools whose permission prompt is itself the point, such as a consent or access-grant step where auto-approval would mean no human ever agreed. Other tools from the same server keep their normal permission behavior.`}),`\n`,_jsxs(_components.p,{children:[`The following `,_jsx(_components.code,{children:`tools/list`}),` entry marks one tool as always requiring approval.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"grant_access\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"description\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Requests access to a protected resource\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"_meta\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"anthropic/requiresUserInteraction\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Some surfaces, such as `,_jsx(_components.a,{href:`/en/remote-control`,children:`Remote Control`}),` and applications built on the `,_jsx(_components.a,{href:`/en/agent-sdk/overview`,children:`Agent SDK`}),`, normally let you approve tool calls with one tap. For a tool marked with this annotation, Claude Code withholds the one-tap action and shows the tool’s full permission prompt instead, so approval still comes from a person answering the prompt rather than a tap.`]}),`\n`,_jsx(_components.p,{children:`Claude Code withholds one-tap approval the same way for any permission request that only the terminal dialog can render in full, such as one that carries a safety warning or an always-allow option the remote surface can’t show. You answer that request in the terminal dialog rather than from Remote Control.`}),`\n`,_jsx(Heading,{level:`2`,id:`tool-calls-pending-when-a-connection-closes`,children:`Mark tools that are safe to call twice`}),`\n`,_jsxs(_components.p,{children:[`If you build an MCP server, mark the tools that are safe to call twice so Claude Code can repeat a call that was pending when a connection closed. Claude Code can repeat such a call to an HTTP server or a `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connector`}),` once, on a new connection. A call Claude Code doesn’t repeat can fail with `,_jsx(_components.a,{href:`/en/errors#connection-closed-before-the-tool-call-was-answered`,children:_jsx(_components.code,{children:`connection closed before the tool call was answered`})}),`.`]}),`\n`,_jsxs(_components.p,{children:[`To mark a tool, set one of these `,_jsx(_components.code,{children:`annotations`}),` to `,_jsx(_components.code,{children:`true`}),` in its `,_jsx(_components.code,{children:`tools/list`}),` entry:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`idempotentHint`})}),`: the tool can change something, and calling it again with the same arguments is safe`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`readOnlyHint`})}),`: the tool changes nothing. Claude Code also runs the tool’s calls in parallel with other read-only calls.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`For example, these fields in a `,_jsx(_components.code,{children:`tools/list`}),` entry mark the `,_jsx(_components.code,{children:`set_issue_status`}),` tool as safe to repeat:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"set_issue_status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"annotations\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"idempotentHint\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`respond-to-mcp-elicitation-requests`,children:`Respond to MCP elicitation requests`}),`\n`,_jsx(_components.p,{children:`MCP servers can request structured input from you mid-task using elicitation. When a server needs information it can’t get on its own, Claude Code displays an interactive dialog and passes your response back to the server. No configuration is required on your side: elicitation dialogs appear automatically when a server requests them.`}),`\n`,_jsx(_components.p,{children:`Servers can request input in two ways:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Form mode`}),`: Claude Code shows a dialog with form fields defined by the server (for example, a username and password prompt). Fill in the fields and submit.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`URL mode`}),`: Claude Code asks whether to open a link in your browser. Servers use this mode for a flow that finishes outside the terminal, such as sign-in.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`In URL mode, Claude Code passes the URL as a command-line argument to your system’s URL handler, and caps how long that argument can be. When the URL, once escaped for the command line, is over that cap, you can only decline the request. Every character that needs escaping, such as `,_jsx(_components.code,{children:`%`}),` or `,_jsx(_components.code,{children:`\u0026`}),`, counts four times toward the cap: its own character plus three escape characters. A URL with none of them reaches the cap at about 8,000 characters. A URL built largely of percent-escapes, where every third character is a `,_jsx(_components.code,{children:`%`}),`, reaches it at roughly 4,000.`]}),`\n`,_jsxs(_components.p,{children:[`To auto-respond to elicitation requests without showing a dialog, use the `,_jsxs(_components.a,{href:`/en/hooks#elicitation`,children:[_jsx(_components.code,{children:`Elicitation`}),` hook`]}),`.`]}),`\n`,_jsxs(_components.p,{children:[`If you’re building an MCP server that uses elicitation, see the `,_jsx(_components.a,{href:`https://modelcontextprotocol.io/docs/learn/client-concepts#elicitation`,children:`MCP elicitation specification`}),` for protocol details and schema examples.`]}),`\n`,_jsx(Heading,{level:`3`,id:`elicitation-modes-claude-code-declares`,children:`Elicitation modes Claude Code declares`}),`\n`,_jsxs(_components.p,{children:[`If you build an MCP server, the client capabilities Claude Code sends when it connects tell your server which elicitation modes it can request. Claude Code declares `,_jsx(_components.code,{children:`elicitation: {form: {}, url: {}}`}),` on the following connections, so a server on any of them can request both modes:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Connections that use `,_jsx(_components.a,{href:`#mcp-client-runtimes`,children:`protocol revision 2026-07-28`})]}),`\n`,_jsxs(_components.li,{children:[`Connections on the earlier protocol revisions, 2025-11-25 and older, to the stdio, `,_jsx(_components.code,{children:`sse`}),`, `,_jsx(_components.code,{children:`http`}),`, and `,_jsx(_components.code,{children:`ws`}),` servers in a user’s Claude Code MCP configuration. Requires Claude Code v2.1.287 or later`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`On its other connections on the earlier revisions, such as to `,_jsx(_components.a,{href:`#use-mcp-servers-from-claude-ai`,children:`claude.ai connectors`}),`, Claude Code declares the bare `,_jsx(_components.code,{children:`elicitation: {}`}),`, which permits elicitation requests in form mode only.`]}),`\n`,_jsxs(_components.p,{children:[`A server built on Java MCP SDK 0.17.0 or earlier can refuse a declaration that has `,_jsx(_components.code,{children:`form`}),` and `,_jsx(_components.code,{children:`url`}),` in it. See `,_jsx(_components.a,{href:`/en/errors#mcp-server-rejected-the-elicitation-capability`,children:`MCP server rejected the elicitation capability`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`use-mcp-resources`,children:`Use MCP resources`}),`\n`,_jsx(_components.p,{children:`MCP servers can expose resources that you can reference using @ mentions, similar to how you reference files.`}),`\n`,_jsx(Heading,{level:`3`,id:`reference-mcp-resources`,children:`Reference MCP resources`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`List available resources`,children:_jsxs(_components.p,{children:[`Type `,_jsx(_components.code,{children:`@`}),` in your prompt to see available resources from all connected MCP servers. Resources appear alongside files in the autocomplete menu.`]})}),_jsxs(Step,{title:`Reference a specific resource`,children:[_jsxs(_components.p,{children:[`Use the format `,_jsx(_components.code,{children:`@server:protocol://resource/path`}),` to reference a resource:`]}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Can you analyze @github:issue://123 and suggest a fix?`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Please review the API documentation at @docs:file://api/authentication`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})]}),_jsxs(Step,{title:`Multiple resource references`,children:[_jsx(_components.p,{children:`You can reference multiple resources in a single prompt:`}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Compare @postgres:schema://users with @docs:file://database/user-model`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})]})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Resources are automatically fetched and included as attachments when referenced`}),`\n`,_jsx(_components.li,{children:`Resource paths are fuzzy-searchable in the @ mention autocomplete`}),`\n`,_jsx(_components.li,{children:`Claude Code automatically provides tools to list and read MCP resources when servers support them`}),`\n`,_jsx(_components.li,{children:`Resources can contain any type of content that the MCP server provides (text, JSON, structured data, etc.)`}),`\n`]})]}),`\n`,_jsxs(_components.p,{children:[`MCP Apps UI resources are entries with a `,_jsx(_components.code,{children:`ui://`}),` URI or the `,_jsx(_components.code,{children:`text/html;profile=mcp-app`}),` media type: pages for a host application to render rather than content for Claude to read. They don’t appear in the `,_jsx(_components.code,{children:`@`}),` suggestions or in the resource list tool’s results, and a server that offers only UI resources shows an empty resource list. Reading a UI resource by its URI still works.`]}),`\n`,_jsx(Heading,{level:`2`,id:`scale-with-mcp-tool-search`,children:`Scale with MCP tool search`}),`\n`,_jsx(_components.p,{children:`Tool search keeps MCP context usage low by deferring tool definitions until Claude needs them. Only tool names and server instructions load at session start, so adding more MCP servers has minimal impact on your context window. Claude Code doesn’t impose a fixed per-server tool cap; the practical limit is your context window budget.`}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`Tool search isn’t supported on Microsoft Foundry `,_jsx(_components.a,{href:`https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry#hosting-options`,children:`deployments hosted on Azure`}),`, which reject it server-side: Claude Code detects the rejection and loads MCP tools upfront for that deployment instead. `,_jsx(_components.a,{href:`#configure-tool-search`,children:_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`})}),` can’t override this, since the rejection comes from the deployment itself.`]})}),`\n`,_jsx(`span`,{id:`for-mcp-server-authors`}),`\n`,_jsx(Heading,{level:`3`,id:`tool-search-for-mcp-server-authors`,children:`Tool search for MCP server authors`}),`\n`,_jsxs(_components.p,{children:[`If you’re building an MCP server, the server instructions field becomes more useful with tool search enabled. Server instructions help Claude understand when to search for your tools, similar to how `,_jsx(_components.a,{href:`/en/skills`,children:`skills`}),` work.`]}),`\n`,_jsx(_components.p,{children:`Add clear, descriptive server instructions that explain:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`What category of tasks your tools handle`}),`\n`,_jsx(_components.li,{children:`When Claude should search for your tools`}),`\n`,_jsx(_components.li,{children:`Key capabilities your server provides`}),`\n`]}),`\n`,_jsx(_components.p,{children:`Claude Code cuts a tool description or server instructions that run past these default limits, and Claude sees only the text before the cut:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Server instructions, and the description of a tool that loads upfront`}),`: 4,096 characters`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The description of a tool that Claude loads through tool search`}),`: 16,384 characters`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Keep descriptions and instructions concise, and put critical details near the start. When tool search matches Claude’s query against a tool’s description, it reads only the part within the shorter limit, so put the words Claude would search for near the start too. A tool loads upfront and keeps the shorter limit whenever it isn’t deferred, for example when `,_jsx(_components.a,{href:`#configure-tool-search`,children:`tool search is off`}),`, when the tool is `,_jsx(_components.a,{href:`#per-tool-alwaysload`,children:`marked to load upfront`}),`, or when its server is `,_jsx(_components.a,{href:`#exempt-a-server-from-deferral`,children:`exempt from deferral`}),`.`]}),`\n`,_jsx(_components.p,{children:`Before v2.1.296, the shorter limit was 2,048 characters, and before v2.1.295 it applied to every tool description, including one loaded through tool search.`}),`\n`,_jsx(Heading,{level:`4`,id:`change-the-description-length-limits`,children:`Change the description length limits`}),`\n`,_jsxs(_components.p,{children:[`To change the `,_jsx(_components.a,{href:`#for-mcp-server-authors`,children:`default limits`}),` of 4,096 and 16,384 characters for the MCP servers in your session, set `,_jsx(_components.a,{href:`/en/env-vars#variables`,children:_jsx(_components.code,{children:`CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`})}),` to a number of characters. Claude Code uses that number for both limits. With `,_jsx(_components.code,{children:`8192`}),`, for example, you raise the 4,096-character limit on server instructions and tool descriptions loaded upfront, and lower the 16,384-character limit on tool descriptions loaded through tool search. This variable requires Claude Code v2.1.280 or later.`]}),`\n`,_jsxs(_components.p,{children:[`Descriptions and instructions from some of the MCP servers that Anthropic hosts at `,_jsx(_components.code,{children:`api.anthropic.com`}),` reach Claude in full, and setting this variable doesn’t cut them.`]}),`\n`,_jsx(Heading,{level:`4`,id:`per-tool-alwaysload`,children:`Mark a tool to load upfront or stay deferred`}),`\n`,_jsxs(_components.p,{children:[`To control how one of your server’s tools loads, set `,_jsx(_components.code,{children:`\"anthropic/alwaysLoad\"`}),` in that tool’s `,_jsx(_components.code,{children:`_meta`}),` object. The person who adds your server to Claude Code can also set `,_jsx(_components.a,{href:`#exempt-a-server-from-deferral`,children:_jsx(_components.code,{children:`alwaysLoad`})}),` for the whole server in their configuration, and their setting can override yours:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Your tool’s value`}),_jsx(_components.th,{style:{textAlign:`left`},children:`What happens`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`true`})}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`The tool loads upfront. Startup doesn’t wait for your server because of this value. The person configuring your server can still `,_jsx(_components.a,{href:`#defer-a-servers-tools`,children:`defer all of its tools`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`false`})}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`The tool stays deferred when their configuration sets `,_jsx(_components.code,{children:`\"alwaysLoad\": true`}),`. This applies when your server is passed with `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--mcp-config`})}),`, supplied by an `,_jsx(_components.a,{href:`/en/agent-sdk/mcp#in-code`,children:`Agent SDK application`}),`, or provided by a `,_jsx(_components.a,{href:`#plugin-provided-mcp-servers`,children:`plugin`}),`. On other servers the tool loads upfront. Requires Claude Code v2.1.285 or later`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`The following `,_jsx(_components.code,{children:`tools/list`}),` entry asks for one tool to load upfront:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"search_tickets\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"description\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Searches the ticket tracker by keyword\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"_meta\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"anthropic/alwaysLoad\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`configure-tool-search`,children:`Configure tool search`}),`\n`,_jsx(_components.p,{children:`Tool search is enabled by default: MCP tools are deferred and discovered on demand.`}),`\n`,_jsxs(_components.p,{children:[`Setting `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`})}),` keeps tool search off. You can’t override it by setting `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`}),` yourself. On Claude Code v2.1.227 or later, your organization can keep tool search on under this variable through `,_jsx(_components.a,{href:`/en/managed-settings`,children:`managed settings`}),`. In a session that `,_jsx(_components.a,{href:`/en/hipaa-setup#check-how-developers-sign-in-and-connect`,children:`gets the HIPAA configuration`}),`, tool search is off, and neither `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`}),` nor managed settings turns it back on. `,_jsx(_components.a,{href:`/en/llm-gateway-protocol#disable-pre-release-capabilities`,children:`Disable pre-release capabilities`}),` covers where the override applies and what the variable strips.`]}),`\n`,_jsxs(_components.p,{children:[`Claude Code uses tool search on Claude Opus 4, Claude Sonnet 4, Claude Haiku 4.5, and later models, or Opus 4.5, Sonnet 4.5, Haiku 4.5, and later models on Google Cloud’s Agent Platform. On earlier models, Claude Code loads all MCP tools upfront, and `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=true`}),` doesn’t override this.`]}),`\n`,_jsx(_components.p,{children:`On Google Cloud’s Agent Platform, Claude Code decides by model generation:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Claude Opus 4.5, Sonnet 4.5, Haiku 4.5, and later`}),`: tool search is on by default, the same as on the Anthropic API.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Earlier Agent Platform models`}),`: Claude Code loads all MCP tools upfront, because their serving stacks reject the required beta header. `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=true`}),` doesn’t override this.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Before v2.1.221, Claude Code disabled tool search for all models on Google Cloud’s Agent Platform unless you set `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=true`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Control tool search behavior with the `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`}),` environment variable:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Value`}),_jsx(_components.th,{style:{textAlign:`left`},children:`Behavior`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`(unset)`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`All MCP tools deferred and loaded on demand. Loaded upfront on models earlier than Opus 4 and Sonnet 4, on the `,_jsx(_components.a,{href:`#configure-tool-search`,children:`earlier Agent Platform models`}),`, and on Microsoft Foundry deployments hosted on Azure`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`true`})}),_jsx(_components.td,{style:{textAlign:`left`},children:`MCP tools deferred, with the same fallbacks as (unset)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`auto`})}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`Threshold mode. Tools that would otherwise be deferred load upfront while their definitions total under 10% of the context window. At 10% or more, tool search turns on, and those tools can `,_jsx(_components.a,{href:`#tools-that-stay-deferred-below-the-threshold`,children:`stay deferred`}),` even if the total falls under 10%`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`auto:N`})}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`Threshold mode with a custom percentage, where `,_jsx(_components.code,{children:`N`}),` is 0-100. For example, `,_jsx(_components.code,{children:`auto:5`}),` for 5%`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`false`})}),_jsx(_components.td,{style:{textAlign:`left`},children:`All MCP tools loaded upfront, no deferral`})]})]})]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Use a custom 5% threshold`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ENABLE_TOOL_SEARCH`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`auto:5`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` claude`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Disable tool search entirely`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ENABLE_TOOL_SEARCH`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`false`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` claude`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Or set the value in your `,_jsxs(_components.a,{href:`/en/settings-reference#env`,children:[`settings.json `,_jsx(_components.code,{children:`env`}),` field`]}),`.`]}),`\n`,_jsxs(_components.p,{children:[`You can also disable the `,_jsx(_components.code,{children:`ToolSearch`}),` tool specifically:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"permissions\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"deny\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"ToolSearch\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`If you deny `,_jsx(_components.code,{children:`ToolSearch`}),` or leave it out of `,_jsx(_components.a,{href:`/en/cli-reference#cli-flags`,children:_jsx(_components.code,{children:`--tools`})}),`, MCP tools load upfront instead, but a request can still carry a placeholder `,_jsx(_components.code,{children:`defer_loading`}),` entry. If a gateway rejects that entry, see `,_jsx(_components.a,{href:`#tool-search-through-a-gateway`,children:`Tool search through an LLM gateway`}),`.`]}),`\n`,_jsx(Heading,{level:`4`,id:`tool-search-through-a-gateway`,children:`Tool search through an LLM gateway`}),`\n`,_jsxs(Note,{children:[_jsx(_components.p,{children:`These cases are covered elsewhere:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`You’ve set `,_jsx(_components.code,{children:`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`})]}),`: see `,_jsx(_components.a,{href:`#configure-tool-search`,children:`how it affects tool search`})]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`A request failed with an error that names `,_jsx(_components.code,{children:`defer_loading`}),` or `,_jsx(_components.code,{children:`tool_reference`})]}),`: see `,_jsx(_components.a,{href:`/en/errors#extra-inputs-are-not-permitted`,children:`Extra inputs are not permitted`})]}),`\n`]})]}),`\n`,_jsxs(_components.p,{children:[`When `,_jsx(_components.code,{children:`ANTHROPIC_BASE_URL`}),` points to a gateway, tool search is on by default, so requests include `,_jsx(_components.code,{children:`defer_loading`}),` tool fields and `,_jsx(_components.code,{children:`tool_reference`}),` blocks for the gateway to forward. While tool search is on, MCP tools are `,_jsx(_components.a,{href:`#scale-with-mcp-tool-search`,children:`deferred`}),`. To load every tool upfront instead, set `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=false`}),` in your shell or your `,_jsxs(_components.a,{href:`/en/settings-reference#env`,children:[`settings `,_jsx(_components.code,{children:`env`})]}),`. Before v2.1.304, tool search was off behind a gateway unless `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`}),` was `,_jsx(_components.code,{children:`true`}),`, `,_jsx(_components.code,{children:`auto`}),`, or `,_jsx(_components.code,{children:`auto:N`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`On v2.1.305 or later, Claude Code can `,_jsx(_components.a,{href:`/en/llm-gateway-protocol#retry-without-tool-search`,children:`retry a request without tool search`}),` after a `,_jsx(_components.code,{children:`400`}),` or `,_jsx(_components.code,{children:`422`}),` whose cause it doesn’t recognize. When the retry works, nothing shows on screen and you don’t need to do anything: MCP tools load upfront instead. Claude Code tries tool search again later, at the cost of another rejected request. To skip those requests, set `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=false`}),`.`]}),`\n`,_jsxs(Heading,{level:`4`,id:`tools-that-stay-deferred-below-the-threshold`,children:[`Tools that stay deferred below the `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH=auto`}),` threshold`]}),`\n`,_jsxs(_components.p,{children:[`If `,_jsx(_components.a,{href:`/en/commands#all-commands`,children:_jsx(_components.code,{children:`/context`})}),` labels tools `,_jsx(_components.code,{children:`(deferred)`}),` or `,_jsx(_components.code,{children:`(loaded on-demand)`}),` though their definitions total under the `,_jsx(_components.code,{children:`auto`}),` threshold, tool search was already on in this conversation and stayed on. The total can drop later, for example while MCP servers reconnect after you resume a session. You don’t need to do anything: Claude loads each of those tools when a task needs it.`]}),`\n`,_jsx(Heading,{level:`3`,id:`exempt-a-server-from-deferral`,children:`Exempt a server from deferral`}),`\n`,_jsxs(_components.p,{children:[`If a server’s tools should always be visible to Claude without a search step, set `,_jsx(_components.code,{children:`alwaysLoad`}),` to `,_jsx(_components.code,{children:`true`}),` in that server’s configuration. The server’s tools then load into context regardless of the `,_jsx(_components.code,{children:`ENABLE_TOOL_SEARCH`}),` setting. Use this for a small number of tools that Claude needs on every turn, since each upfront tool consumes context that would otherwise be available for your conversation.`]}),`\n`,_jsxs(_components.p,{children:[`The following `,_jsx(_components.code,{children:`.mcp.json`}),` entry exempts one HTTP server while leaving other servers deferred:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mcpServers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"core-tools\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"url\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://mcp.example.com/mcp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"alwaysLoad\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`alwaysLoad`}),` field is available on all server types.`]}),`\n`,_jsxs(_components.p,{children:[`Setting `,_jsx(_components.code,{children:`alwaysLoad: true`}),` also makes startup wait for the server’s tools, capped at the standard 5-second connect timeout, since they must be present when the first prompt is built. A remote server with a valid `,_jsxs(_components.a,{href:`#server-status-detail`,children:[_jsx(_components.code,{children:`cached`}),` entry`]}),` supplies its tools from the cache without connecting, so it doesn’t hold startup. Other servers connect in the background by default; set `,_jsx(_components.a,{href:`/en/env-vars`,children:_jsx(_components.code,{children:`MCP_CONNECTION_NONBLOCKING=0`})}),` to make startup wait for them too.`]}),`\n`,_jsx(Heading,{level:`3`,id:`defer-a-servers-tools`,children:`Defer a server’s tools`}),`\n`,_jsxs(_components.p,{children:[`To keep all of a server’s tools behind tool search, set `,_jsx(_components.code,{children:`\"alwaysLoad\": false`}),` in that server’s entry in your MCP configuration. That includes tools that the server’s author has `,_jsx(_components.a,{href:`#per-tool-alwaysload`,children:`marked to load upfront`}),`. If you leave `,_jsx(_components.code,{children:`alwaysLoad`}),` out, those marked tools load upfront. Requires Claude Code v2.1.287 or later.`]}),`\n`,_jsx(Heading,{level:`2`,id:`use-mcp-prompts-as-commands`,children:`Use MCP prompts as commands`}),`\n`,_jsx(_components.p,{children:`MCP servers can expose prompts that become available as commands in Claude Code.`}),`\n`,_jsxs(_components.p,{children:[`Prompts from a server named `,_jsx(_components.code,{children:`anthropic-skills`}),` don’t appear, because Claude Code `,_jsx(_components.a,{href:`/en/skills#names-reserved-for-synced-skills`,children:`reserves that name`}),` for skills synced from claude.ai. The server’s tools still work. Rename the server in your MCP configuration to list its prompts.`]}),`\n`,_jsx(Heading,{level:`3`,id:`execute-mcp-prompts`,children:`Execute MCP prompts`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Discover available prompts`,children:_jsxs(_components.p,{children:[`Type `,_jsx(_components.code,{children:`/`}),` to see the commands available to you, including those from MCP servers. Claude Code lists each MCP prompt as `,_jsx(_components.code,{children:`/servername:promptname (MCP)`}),`. Typing `,_jsx(_components.code,{children:`/mcp__servername__promptname`}),` also runs it.`]})}),_jsx(Step,{title:`Execute a prompt without arguments`,children:_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp__github__list_prs`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})}),_jsxs(Step,{title:`Execute a prompt with arguments`,children:[_jsx(_components.p,{children:`Many prompts accept arguments. Pass them space-separated after the command. Claude Code splits the arguments on whitespace, so each argument is a single token:`}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp__github__pr_review 456`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`/mcp__jira__create_issue login-bug high`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})]})]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Tips:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`MCP prompts are dynamically discovered from connected servers`}),`\n`,_jsx(_components.li,{children:`Arguments are parsed based on the prompt’s defined parameters`}),`\n`,_jsx(_components.li,{children:`Prompt results are injected directly into the conversation`}),`\n`,_jsxs(_components.li,{children:[`In the `,_jsx(_components.code,{children:`/mcp__servername__promptname`}),` form, Claude Code replaces any character in the server name outside `,_jsx(_components.code,{children:`A-Z`}),`, `,_jsx(_components.code,{children:`a-z`}),`, `,_jsx(_components.code,{children:`0-9`}),`, `,_jsx(_components.code,{children:`_`}),`, and `,_jsx(_components.code,{children:`-`}),` with `,_jsx(_components.code,{children:`_`}),`, and uses the prompt name as the server declares it`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`managed-mcp-configuration`,children:`Managed MCP configuration`}),`\n`,_jsxs(_components.p,{children:[`For organizations that need centralized control over which MCP servers users can connect to, see `,_jsx(_components.a,{href:`/en/managed-mcp`,children:`Managed MCP configuration`}),`. It covers deploying a fixed server set with `,_jsx(_components.code,{children:`managed-mcp.json`}),`, providing servers to every user with `,_jsx(_components.code,{children:`managedMcpServers`}),`, restricting servers with `,_jsx(_components.code,{children:`allowedMcpServers`}),` and `,_jsx(_components.code,{children:`deniedMcpServers`}),`, and what users see when a server is blocked.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"sidebarTitle":"Reference","title":"Connect Claude Code to tools via MCP","description":"Learn how to connect Claude Code to your tools with the Model Context Protocol.","keywords":["mcp","model context protocol","mcp server",".mcp.json","figma","linear"],"href":"/en/mcp"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What you can do with MCP","slug":"what-you-can-do-with-mcp","depth":2,"children":[]},{"title":"Find and build MCP servers","slug":"find-and-build-mcp-servers","depth":2,"children":[]},{"title":"Installing MCP servers","slug":"installing-mcp-servers","depth":2,"children":[{"title":"Option 1: Add a remote HTTP server","slug":"option-1-add-a-remote-http-server","depth":3,"children":[]},{"title":"Option 2: Add a remote SSE server","slug":"option-2-add-a-remote-sse-server","depth":3,"children":[]},{"title":"Option 3: Add a local stdio server","slug":"option-3-add-a-local-stdio-server","depth":3,"children":[]},{"title":"How Claude Code stops a stdio server","slug":"how-claude-code-stops-a-stdio-server","depth":4,"children":[]},{"title":"Option 4: Add a remote WebSocket server","slug":"option-4-add-a-remote-websocket-server","depth":3,"children":[]},{"title":"Add a server from setup instructions written for another client","slug":"add-a-server-from-setup-instructions-written-for-another-client","depth":3,"children":[]},{"title":"Add a server from a URL","slug":"add-a-server-from-a-url","depth":4,"children":[]},{"title":"Add a server from an npx, uvx, or binary command","slug":"add-a-server-from-an-npx-uvx-or-binary-command","depth":4,"children":[]},{"title":"Add a server from an mcpServers JSON block","slug":"add-a-server-from-an-mcpservers-json-block","depth":4,"children":[]},{"title":"Managing your servers","slug":"managing-your-servers","depth":3,"children":[]},{"title":"Server status","slug":"server-status","depth":4,"children":[]},{"title":"Project server approvals and workspace trust","slug":"project-server-approvals-and-workspace-trust","depth":4,"children":[]},{"title":"Server status detail","slug":"server-status-detail","depth":4,"children":[]},{"title":"Configuration warnings","slug":"configuration-warnings","depth":4,"children":[]},{"title":"Tool availability","slug":"tool-availability","depth":4,"children":[]},{"title":"Disable a server without removing it","slug":"disable-a-server-without-removing-it","depth":3,"children":[]},{"title":"MCP client runtimes","slug":"mcp-client-runtimes","depth":3,"children":[]},{"title":"Dynamic tool updates","slug":"dynamic-tool-updates","depth":3,"children":[]},{"title":"Notification streams on the v2 runtime","slug":"notification-streams-on-the-v2-runtime","depth":4,"children":[]},{"title":"Automatic reconnection","slug":"automatic-reconnection","depth":3,"children":[]},{"title":"Mid-session drops of a remote server","slug":"mid-session-drops-of-a-remote-server","depth":4,"children":[]},{"title":"Failed first connections","slug":"failed-first-connections","depth":4,"children":[]},{"title":"Stdio servers that exit or fail to start","slug":"stdio-servers-that-exit-or-fail-to-start","depth":4,"children":[]},{"title":"Failed discovery requests","slug":"failed-discovery-requests","depth":4,"children":[]},{"title":"Retry failed servers yourself","slug":"retry-failed-servers-yourself","depth":4,"children":[]},{"title":"How Claude learns that a server failed","slug":"how-claude-learns-that-a-server-failed","depth":4,"children":[]},{"title":"Push messages with channels","slug":"push-messages-with-channels","depth":3,"children":[]},{"title":"Time limits on MCP tool calls","slug":"time-limits-on-mcp-tool-calls","depth":3,"children":[]},{"title":"Automatic backgrounding of long tool calls","slug":"automatic-backgrounding-of-long-tool-calls","depth":3,"children":[]},{"title":"MCP tasks that run on the server","slug":"mcp-tasks-that-run-on-the-server","depth":3,"children":[]},{"title":"Stop an MCP task or get its result","slug":"stop-an-mcp-task-or-get-its-result","depth":4,"children":[]},{"title":"Answer a question from an MCP task","slug":"answer-a-question-from-an-mcp-task","depth":4,"children":[]},{"title":"Exit, clear, or resume while an MCP task runs","slug":"exit-clear-or-resume-while-an-mcp-task-runs","depth":4,"children":[]},{"title":"What a call needs to become an MCP task","slug":"requirements-for-mcp-tasks","depth":4,"children":[]},{"title":"Status messages on an MCP task","slug":"status-messages-on-an-mcp-task","depth":4,"children":[]},{"title":"Time limits on MCP tasks","slug":"time-limits-on-mcp-tasks","depth":4,"children":[]},{"title":"Make Claude wait for the result of an MCP task","slug":"make-claude-wait-for-the-result-of-an-mcp-task","depth":4,"children":[]},{"title":"MCP tasks for server authors","slug":"mcp-tasks-for-server-authors","depth":3,"children":[]},{"title":"Answer the call with a task","slug":"answer-the-call-with-a-task","depth":4,"children":[]},{"title":"Report status, results, and questions","slug":"report-status-results-and-questions","depth":4,"children":[]},{"title":"Plugin-provided MCP servers","slug":"plugin-provided-mcp-servers","depth":3,"children":[]}]},{"title":"MCP installation scopes","slug":"mcp-installation-scopes","depth":2,"children":[{"title":"Local scope","slug":"local-scope","depth":3,"children":[]},{"title":"Project scope","slug":"project-scope","depth":3,"children":[]},{"title":"User scope","slug":"user-scope","depth":3,"children":[]},{"title":"Scope hierarchy and precedence","slug":"scope-hierarchy-and-precedence","depth":3,"children":[]},{"title":"Environment variable expansion in .mcp.json","slug":"environment-variable-expansion-in-mcp-json","depth":3,"children":[]},{"title":"Example with variable expansion","slug":"example-with-variable-expansion","depth":4,"children":[]},{"title":"Unset variables without a default","slug":"unset-variables-without-a-default","depth":4,"children":[]},{"title":"Variables set to an empty string","slug":"variables-set-to-an-empty-string","depth":4,"children":[]},{"title":"Credential variables that read as empty","slug":"credential-variables-that-read-as-empty","depth":4,"children":[]},{"title":"How references appear in /mcp and CLI output","slug":"how-references-appear-in-/mcp-and-cli-output","depth":4,"children":[]}]},{"title":"Practical examples","slug":"practical-examples","depth":2,"children":[{"title":"Example: Connect to GitHub for code reviews","slug":"example-connect-to-github-for-code-reviews","depth":3,"children":[]},{"title":"Example: Query your PostgreSQL database","slug":"example-query-your-postgresql-database","depth":3,"children":[]}]},{"title":"Authenticate with remote MCP servers","slug":"authenticate-with-remote-mcp-servers","depth":2,"children":[{"title":"Authenticate from the command line","slug":"authenticate-from-the-command-line","depth":3,"children":[]},{"title":"Use a fixed OAuth callback port","slug":"use-a-fixed-oauth-callback-port","depth":3,"children":[]},{"title":"Use pre-configured OAuth credentials","slug":"use-pre-configured-oauth-credentials","depth":3,"children":[]},{"title":"Override OAuth metadata discovery","slug":"override-oauth-metadata-discovery","depth":3,"children":[]},{"title":"Restrict OAuth scopes","slug":"restrict-oauth-scopes","depth":3,"children":[]},{"title":"Use OAuth with a server behind an authenticating proxy","slug":"use-oauth-with-a-server-behind-an-authenticating-proxy","depth":3,"children":[]},{"title":"Use dynamic headers for custom authentication","slug":"use-dynamic-headers-for-custom-authentication","depth":3,"children":[]},{"title":"Where the helper runs","slug":"where-the-helper-runs","depth":4,"children":[]},{"title":"Which variables a helper can read","slug":"which-variables-a-helper-can-read","depth":4,"children":[]},{"title":"Trust a folder before its headersHelper runs","slug":"trust-a-folder-before-its-headershelper-runs","depth":4,"children":[]},{"title":"Sign in to an MCP server behind a gateway that requires a header","slug":"sign-in-to-an-mcp-server-behind-a-gateway-that-requires-a-header","depth":3,"children":[]}]},{"title":"Add MCP servers from JSON configuration","slug":"add-mcp-servers-from-json-configuration","depth":2,"children":[]},{"title":"Import MCP servers from Claude Desktop","slug":"import-mcp-servers-from-claude-desktop","depth":2,"children":[]},{"title":"Use MCP servers from claude.ai","slug":"use-mcp-servers-from-claude-ai","depth":2,"children":[{"title":"How connectors reach Claude Code","slug":"how-connectors-reach-claude-code","depth":3,"children":[]},{"title":"Organization controls on connector tools","slug":"organization-controls-on-connector-tools","depth":3,"children":[]},{"title":"Disable claude.ai connectors","slug":"disable-claude-ai-connectors","depth":3,"children":[]}]},{"title":"Use Claude Code as an MCP server","slug":"use-claude-code-as-an-mcp-server","depth":2,"children":[{"title":"Read a background command’s output as an MCP client","slug":"read-a-background-command’s-output-as-an-mcp-client","depth":3,"children":[]}]},{"title":"MCP output limits and warnings","slug":"mcp-output-limits-and-warnings","depth":2,"children":[{"title":"Raise the limit for a specific tool","slug":"raise-the-limit-for-a-specific-tool","depth":3,"children":[]},{"title":"Images in tool results","slug":"images-in-tool-results","depth":3,"children":[]}]},{"title":"Tool input schemas with a root-level combinator","slug":"tool-input-schemas-with-a-root-level-combinator","depth":2,"children":[]},{"title":"Tools with invalid input schemas","slug":"tools-with-invalid-input-schemas","depth":2,"children":[{"title":"Tools whose input schema the API refuses","slug":"tools-whose-input-schema-the-api-refuses","depth":3,"children":[]}]},{"title":"Tools with names longer than 128 characters","slug":"tools-with-names-longer-than-128-characters","depth":2,"children":[]},{"title":"Require approval for a specific tool","slug":"require-approval-for-a-specific-tool","depth":2,"children":[]},{"title":"Mark tools that are safe to call twice","slug":"tool-calls-pending-when-a-connection-closes","depth":2,"children":[]},{"title":"Respond to MCP elicitation requests","slug":"respond-to-mcp-elicitation-requests","depth":2,"children":[{"title":"Elicitation modes Claude Code declares","slug":"elicitation-modes-claude-code-declares","depth":3,"children":[]}]},{"title":"Use MCP resources","slug":"use-mcp-resources","depth":2,"children":[{"title":"Reference MCP resources","slug":"reference-mcp-resources","depth":3,"children":[]}]},{"title":"Scale with MCP tool search","slug":"scale-with-mcp-tool-search","depth":2,"children":[{"title":"Tool search for MCP server authors","slug":"tool-search-for-mcp-server-authors","depth":3,"children":[]},{"title":"Change the description length limits","slug":"change-the-description-length-limits","depth":4,"children":[]},{"title":"Mark a tool to load upfront or stay deferred","slug":"per-tool-alwaysload","depth":4,"children":[]},{"title":"Configure tool search","slug":"configure-tool-search","depth":3,"children":[]},{"title":"Tool search through an LLM gateway","slug":"tool-search-through-a-gateway","depth":4,"children":[]},{"title":"Tools that stay deferred below the ENABLE_TOOL_SEARCH=auto threshold","slug":"tools-that-stay-deferred-below-the-threshold","depth":4,"children":[]},{"title":"Exempt a server from deferral","slug":"exempt-a-server-from-deferral","depth":3,"children":[]},{"title":"Defer a server’s tools","slug":"defer-a-servers-tools","depth":3,"children":[]}]},{"title":"Use MCP prompts as commands","slug":"use-mcp-prompts-as-commands","depth":2,"children":[{"title":"Execute MCP prompts","slug":"execute-mcp-prompts","depth":3,"children":[]}]},{"title":"Managed MCP configuration","slug":"managed-mcp-configuration","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/claude-code/f164a83c5609d421/consent-loader.js","/docs/_mintlify/custom/claude-code/a14b5f5366e4b482/antalytics-loader.js","/docs/_mintlify/custom/claude-code/4cd6fefc4e377e79/toc-collapse.js","/docs/_mintlify/custom/claude-code/f6b3e97e7cbfc8d3/settings-anchor-redirect.js","/docs/_mintlify/custom/claude-code/45be325883f4820b/plugins-anchor-redirect.js","/docs/_mintlify/custom/claude-code/7c53cb088b8331b3/nav-tab-click.js"],"subdomain":"claude-code","siteName":"Claude Code Docs","title":"Connect Claude Code to tools via MCP - Claude Code Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/en/mcp","matchLevel":0},"fr":{"href":"/fr/mcp","matchLevel":1},"de":{"href":"/de/mcp","matchLevel":1},"it":{"href":"/it/mcp","matchLevel":1},"jp":{"href":"/ja/mcp","matchLevel":1},"es":{"href":"/es/mcp","matchLevel":1},"ko":{"href":"/ko/mcp","matchLevel":1},"zh-CN":{"href":"/zh-CN/mcp","matchLevel":1},"zh-TW":{"href":"/zh-TW/mcp","matchLevel":1},"ru":{"href":"/ru/mcp","matchLevel":1},"id":{"href":"/id/mcp","matchLevel":1},"pt-BR":{"href":"/pt/mcp","matchLevel":1}}},"lastModified":"2026-10-28T19:51:18.300Z","originalFileLocation":"en/mcp.mdx","locale":"en"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Learn how to connect Claude Code to your tools with the Model Context Protocol.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Claude Code Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Connect Claude Code to tools via MCP - Claude Code Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Learn how to connect Claude Code to your tools with the Model Context Protocol.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Claude Code Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://code.claude.com/docs/en/mcp\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://claude-code.mintlify.app/_mintlify/api/og/v2?division=MCP\u0026amp;title=Connect+Claude+Code+to+tools+via+MCP\u0026amp;description=Learn+how+to+connect+Claude+Code+to+your+tools+with+the+Model+Context+Protocol.\u0026amp;theme=8d9812df31da293aba4e8103\u0026amp;signature=e6eb1e2578555fcecaa5ff9466c873eb198d5a697f750e8f116be9f5f46b5d2a\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Connect Claude Code to tools via MCP - Claude Code Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Learn how to connect Claude Code to your tools with the Model Context Protocol.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://claude-code.mintlify.app/_mintlify/api/og/v2?division=MCP\u0026amp;title=Connect+Claude+Code+to+tools+via+MCP\u0026amp;description=Learn+how+to+connect+Claude+Code+to+your+tools+with+the+Model+Context+Protocol.\u0026amp;theme=8d9812df31da293aba4e8103\u0026amp;signature=e6eb1e2578555fcecaa5ff9466c873eb198d5a697f750e8f116be9f5f46b5d2a\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Claude Code Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0E0E0E\">\u003clink data-mint-head rel=\"canonical\" href=\"https://code.claude.com/docs/en/mcp\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/en/mcp.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"en\" href=\"https://code.claude.com/docs/en/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"fr\" href=\"https://code.claude.com/docs/fr/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"de\" href=\"https://code.claude.com/docs/de/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"it\" href=\"https://code.claude.com/docs/it/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ja\" href=\"https://code.claude.com/docs/ja/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"es\" href=\"https://code.claude.com/docs/es/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ko\" href=\"https://code.claude.com/docs/ko/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh-CN\" href=\"https://code.claude.com/docs/zh-CN/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh-TW\" href=\"https://code.claude.com/docs/zh-TW/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ru\" href=\"https://code.claude.com/docs/ru/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"id\" href=\"https://code.claude.com/docs/id/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"pt-BR\" href=\"https://code.claude.com/docs/pt/mcp\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"x-default\" href=\"https://code.claude.com/docs/en/mcp\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://code.claude.com/#organization\",\"name\":\"Claude Code Docs\",\"url\":\"https://code.claude.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/claude-code/c5r9_6tjPMzFdDDT/logo/light.svg?fit=max\u0026auto=format\u0026n=c5r9_6tjPMzFdDDT\u0026q=85\u0026s=78fd01ff4f4340295a4f66e2ea54903c\"}},{\"@type\":\"WebSite\",\"@id\":\"https://code.claude.com/docs#website\",\"name\":\"Claude Code Docs\",\"url\":\"https://code.claude.com/docs\",\"publisher\":{\"@id\":\"https://code.claude.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://code.claude.com/docs/en/mcp#webpage\",\"url\":\"https://code.claude.com/docs/en/mcp\",\"name\":\"Connect Claude Code to tools via MCP\",\"description\":\"Learn how to connect Claude Code to your tools with the Model Context Protocol.\",\"dateModified\":\"2026-10-28T19:51:18.300Z\",\"isPartOf\":{\"@id\":\"https://code.claude.com/docs#website\"},\"breadcrumb\":{\"@id\":\"https://code.claude.com/docs/en/mcp#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://code.claude.com/docs/en/mcp#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"MCP\",\"item\":\"https://code.claude.com/docs/en/mcp-quickstart\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Connect Claude Code to tools via MCP\",\"item\":\"https://code.claude.com/docs/en/mcp\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://code.claude.com/docs/en/mcp#article\",\"headline\":\"Connect Claude Code to tools via MCP\",\"name\":\"Connect Claude Code to tools via MCP\",\"description\":\"Learn how to connect Claude Code to your tools with the Model Context Protocol.\",\"url\":\"https://code.claude.com/docs/en/mcp\",\"mainEntityOfPage\":{\"@id\":\"https://code.claude.com/docs/en/mcp#webpage\"},\"dateModified\":\"2026-10-28T19:51:18.300Z\",\"keywords\":\"mcp, model context protocol, mcp server, .mcp.json, figma, linear\",\"publisher\":{\"@id\":\"https://code.claude.com/#organization\"},\"isPartOf\":{\"@id\":\"https://code.claude.com/docs#website\"}}]}\u003c/script>","siteName":"Claude Code Docs","nav":{"global":null,"languages":[{"language":"en","tabs":[{"tab":"Getting started","menu":[{"item":"Overview","description":"What Claude Code is and how to install it","pages":[{"title":"Overview","href":"/en/overview"}]},{"item":"Quickstart","description":"Install, start a session, make your first change","pages":[{"title":"Quickstart","href":"/en/quickstart"}]},{"item":"Core concepts","description":"How it works, what loads, what it costs","pages":[{"title":"Core concepts","href":"/en/how-claude-code-works"}]},{"item":"Use Claude Code","description":"Memory, sessions, workflows, and prompts","pages":[{"title":"Use Claude Code","href":"/en/memory"}]},{"item":"Platforms and integrations","description":"Terminal, IDEs, desktop, web, and Slack","pages":[{"title":"Platforms and integrations","href":"/en/platforms"}]},{"item":"Code review and pull requests","description":"PR reviews, local review, security, and CI","pages":[{"title":"Code review and pull requests","href":"/en/code-review"}]}],"pages":[{"title":"Getting started","href":"/en/overview"}]},{"tab":"Build with Claude Code","menu":[{"item":"Agents and parallel work","description":"Subagents, agent view, teams, worktrees","groups":[{"group":"Agents and parallel work","pages":[{"title":"Run agents in parallel","sidebarTitle":"Overview","href":"/en/agents"},{"title":"Create custom subagents","href":"/en/sub-agents"},{"title":"Manage multiple agents with agent view","sidebarTitle":"Agent view","href":"/en/agent-view"},{"title":"Orchestrate teams of Claude Code sessions","sidebarTitle":"Run agent teams","href":"/en/agent-teams"},{"title":"Message your other Claude Code sessions","sidebarTitle":"Cross-session messaging","href":"/en/cross-session-messaging"},{"title":"Orchestrate subagents at scale with dynamic workflows","sidebarTitle":"Dynamic workflows","href":"/en/workflows"},{"title":"Run parallel sessions with worktrees","sidebarTitle":"Isolate sessions with worktrees","href":"/en/worktrees"}]},{"group":"MCP","pages":[{"title":"Connect to MCP servers","sidebarTitle":"Quickstart","description":"Add an MCP server to Claude Code, verify the connection, and find the configuration on disk.","href":"/en/mcp-quickstart"},{"sidebarTitle":"Reference","title":"Connect Claude Code to tools via MCP","href":"/en/mcp"}]},{"group":"Skills","pages":[{"title":"Extend Claude with skills","description":"Create, manage, and share skills to extend Claude's capabilities in Claude Code. Includes custom commands and bundled skills.","href":"/en/skills"}]},{"group":"Artifacts","pages":[{"title":"Share session output as artifacts","href":"/en/artifacts"}]},{"group":"Automation","pages":[{"title":"Automate actions with hooks","sidebarTitle":"Automate with hooks","href":"/en/hooks-guide"},{"sidebarTitle":"Push external events to Claude","title":"Push events into a running session with channels","href":"/en/channels"},{"title":"Run prompts on a schedule","href":"/en/scheduled-tasks"},{"title":"Keep Claude working toward a goal","sidebarTitle":"Goals","href":"/en/goal"},{"title":"Run Claude Code programmatically","sidebarTitle":"Programmatic usage","href":"/en/headless"},{"title":"Launch sessions from links","href":"/en/deep-links"}]},{"group":"Guides","pages":[{"title":"Set up Claude Code in a monorepo or large codebase","sidebarTitle":"Monorepos and large repos","href":"/en/large-codebases"}]},{"group":"Troubleshooting","pages":[{"title":"Troubleshoot installation and login","href":"/en/troubleshoot-install"},{"title":"Troubleshooting","sidebarTitle":"Troubleshoot performance and stability","href":"/en/troubleshooting"},{"title":"Debug your configuration","sidebarTitle":"Debug configuration","href":"/en/debug-your-config"},{"title":"Error reference","href":"/en/errors"}]}]},{"item":"MCP","description":"Connect your tools and data","pages":[{"title":"MCP","href":"/en/mcp-quickstart"}]},{"item":"Skills","description":"Package workflows Claude can run","pages":[{"title":"Skills","href":"/en/skills"}]},{"item":"Artifacts","description":"Publish a page from a session","pages":[{"title":"Artifacts","href":"/en/artifacts"}]},{"item":"Automation","description":"Hooks, channels, schedules, non-interactive runs","pages":[{"title":"Automation","href":"/en/hooks-guide"}]},{"item":"Guides","description":"Work in large codebases","pages":[{"title":"Guides","href":"/en/large-codebases"}]},{"item":"Troubleshooting","description":"Install, configuration, and error fixes","pages":[{"title":"Troubleshooting","href":"/en/troubleshoot-install"}]}]},{"tab":"Plugins","menu":[{"item":"Plugins","description":"What plugins are and what they add","pages":[{"title":"Plugins","href":"/en/plugins/overview"}]},{"item":"Use plugins","description":"Find plugins and add them","pages":[{"title":"Use plugins","href":"/en/plugins/install"}]},{"item":"Create plugins","description":"Create, test, and publish a plugin","pages":[{"title":"Create plugins","href":"/en/plugins/create"}]},{"item":"Mods","description":"Change the Claude Code interface","pages":[{"title":"Mods","href":"/en/plugins/mods/overview"}]},{"item":"Run a marketplace","description":"Host and share plugins","pages":[{"title":"Run a marketplace","href":"/en/plugins/create-marketplace"}]},{"item":"Manage plugins for your organization","description":"Control plugins across a team","pages":[{"title":"Manage plugins for your organization","href":"/en/plugins/org"}]},{"item":"Troubleshooting","description":"Install and loading problems","pages":[{"title":"Troubleshooting","href":"/en/plugins/troubleshooting"}]},{"item":"Reference","description":"Manifests, CLI, and marketplace schema","pages":[{"title":"Reference","href":"/en/plugins/manifest-reference"}]}],"pages":[{"title":"Plugins","href":"/en/plugins/overview"}]},{"tab":"Administration","menu":[{"item":"Setup and access","description":"Install, sign-in, and managed settings","pages":[{"title":"Setup and access","href":"/en/admin-setup"}]},{"item":"Deployment","description":"Cloud providers, network, containers","pages":[{"title":"Deployment","href":"/en/third-party-integrations"}]},{"item":"Gateways","description":"Route requests through a gateway","pages":[{"title":"Gateways","href":"/en/gateways"}]},{"item":"Usage and costs","description":"Monitoring, spend, and analytics","pages":[{"title":"Usage and costs","href":"/en/monitoring-usage"}]},{"item":"Security and data","description":"Security, data use, and retention","pages":[{"title":"Security and data","href":"/en/security"}]},{"item":"Adoption","description":"Kits for rolling out to a team","pages":[{"title":"Adoption","href":"/en/communications-kit"}]}],"pages":[{"title":"Administration","href":"/en/admin-setup"}]},{"tab":"Configuration","menu":[{"item":"Settings","description":"Files, precedence, and keys","pages":[{"title":"Settings","href":"/en/settings"}]},{"item":"Permissions and sandboxing","description":"What Claude Code can do without asking","pages":[{"title":"Permissions and sandboxing","href":"/en/permissions"}]},{"item":"Environments","description":"Cloud and self-hosted environments","pages":[{"title":"Environments","href":"/en/cloud-environments"}]},{"item":"Model and responses","description":"Models, effort, and output styles","pages":[{"title":"Model and responses","href":"/en/model-config"}]},{"item":"Interface","description":"Terminal, keys, voice, and status line","pages":[{"title":"Interface","href":"/en/terminal-config"}]}],"pages":[{"title":"Configuration","href":"/en/settings"}]},{"tab":"Reference","menu":[{"item":"Reference","description":"Commands, flags, tools, hooks, and variables","pages":[{"title":"Reference","href":"/en/cli-reference"}]},{"item":"Glossary","description":"Terms used across the docs","pages":[{"title":"Glossary","href":"/en/glossary"}]}],"pages":[{"title":"Reference","href":"/en/cli-reference"}]},{"tab":"Agent SDK","menu":[{"item":"Agent SDK","description":"Overview, quickstart, and migration","pages":[{"title":"Agent SDK","href":"/en/agent-sdk/overview"}]},{"item":"Build agents","description":"Configuration and examples","pages":[{"title":"Build agents","href":"/en/agent-sdk/configuration"}]},{"item":"Core concepts","description":"The agent loop, features, and sessions","pages":[{"title":"Core concepts","href":"/en/agent-sdk/agent-loop"}]},{"item":"Input and output","description":"Streaming, user input, structured output","pages":[{"title":"Input and output","href":"/en/agent-sdk/streaming-vs-single-mode"}]},{"item":"Extend with tools","description":"Custom tools, MCP, and subagents","pages":[{"title":"Extend with tools","href":"/en/agent-sdk/custom-tools"}]},{"item":"Customize behavior","description":"System prompts, skills, and plugins","pages":[{"title":"Customize behavior","href":"/en/agent-sdk/modifying-system-prompts"}]},{"item":"Control and observability","description":"Permissions, hooks, cost, and tracing","pages":[{"title":"Control and observability","href":"/en/agent-sdk/permissions"}]},{"item":"Deployment","description":"Hosting and secure deployment","pages":[{"title":"Deployment","href":"/en/agent-sdk/hosting"}]},{"item":"SDK references","description":"TypeScript and Python","pages":[{"title":"SDK references","href":"/en/agent-sdk/typescript"}]}],"pages":[{"title":"Agent SDK","href":"/en/agent-sdk/overview"}]},{"tab":"What's New","pages":[{"title":"What's New","href":"/en/whats-new"}]},{"tab":"Resources","pages":[{"title":"Resources","href":"/en/legal-and-compliance"}]}]},{"language":"fr","pages":[{"title":"fr","href":"/fr/mcp"}]},{"language":"de","pages":[{"title":"de","href":"/de/mcp"}]},{"language":"it","pages":[{"title":"it","href":"/it/mcp"}]},{"language":"jp","pages":[{"title":"jp","href":"/ja/mcp"}]},{"language":"es","pages":[{"title":"es","href":"/es/mcp"}]},{"language":"ko","pages":[{"title":"ko","href":"/ko/mcp"}]},{"language":"zh-CN","pages":[{"title":"zh-CN","href":"/zh-CN/mcp"}]},{"language":"zh-TW","pages":[{"title":"zh-TW","href":"/zh-TW/mcp"}]},{"language":"ru","pages":[{"title":"ru","href":"/ru/mcp"}]},{"language":"id","pages":[{"title":"id","href":"/id/mcp"}]},{"language":"pt-BR","pages":[{"title":"pt-BR","href":"/pt/mcp"}]}]},"title":"Connect Claude Code to tools via MCP - Claude Code Docs","buildId":"dpl_DGmhKsAzJdVqypJzon18vViniWRY","deploymentId":"dpl_DGmhKsAzJdVqypJzon18vViniWRY","dynamics":[],"chunks":[]}