cd /news/ai-agents/claude-code-runs-mcp-tasks-in-public… · home › topics › ai-agents › article
[ARTICLE · art-161070] src=code.claude.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Claude Code runs MCP Tasks in public beta

Anthropic released a public beta of MCP Tasks in Claude Code, letting the coding agent run Model Context Protocol servers as background tasks that push results back into a session. The release adds `streamable-http` as an accepted alias for the `http` transport type in `.mcp.json`, `~/.claude.json` and `claude mcp add-json` configurations, so server documentation copied verbatim works without edits. Claude Code now also rejects entries that carry a `url` but no `type` with the error `MCP server "<name>" has a "url" but no "type"`, since such entries were previously read as stdio servers and skipped.

by read79 min views3 publishedOct 28, 2026
Claude Code runs MCP Tasks in public beta
Image: source

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 quickstartfor a step-by-step walkthrough. This page is the full reference.

What you can do with MCP #

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 achannel that pushes messages into your session, so Claude reacts to Telegram messages, Discord chats, or webhook events while you’re away.

Find and build MCP servers #

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. To build your own server, see the MCP server guidefor protocol fundamentals and the

Claude connector building docsfor authentication, testing, and Directory submission. You can also have Claude scaffold a server for you with the official

[.](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev)

`mcp-server-dev` plugin

Install the plugin

Install a plugininstead of this step. In a terminal, start Claude Code by running

claude, then enter this at its prompt:

  • 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, seePlugin not found in marketplace .

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. Run the build skill

Installing MCP servers #

MCP servers can be configured in several ways depending on your needs:

Option 1: Add a remote HTTP server

HTTP servers are the recommended option for connecting to remote MCP servers. This is the most widely supported transport for cloud-based services..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](https://code.claude.com/docs/en/agent-sdk/mcp)application or the

[desktop app](https://code.claude.com/docs/en/desktop), 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. --output-format stream-json runs, Claude Code also reports a skipped --mcp-config entry in the system/init event’s , so scripts can detect that the server never loaded.

mcp_server_errors field

Option 2: Add a remote SSE server

Some services still expose only an SSE endpoint. Add these with the sameclaude 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:

Option 3: Add a local stdio server

Stdio servers run as local processes on your machine. They’re ideal for tools that need direct system access or custom scripts. Claude Code setsCLAUDE_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 directoryyou’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. -- (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

--, 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.

How Claude Code stops a stdio server

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 sendsSIGINT , thenSIGTERM if the process is still running 100 milliseconds later, thenSIGKILL 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.

Option 4: Add a remote WebSocket server

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 theclaude mcp add --transport flag, while WebSocket supports neither. Configure WebSocket servers in .mcp.json or with claude mcp add-json: 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 . The

headersHelper`` 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 noclaude 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 ashttps://mcp.example.com/mcp : the server is remote.
  • A launch command such asnpx -y @example/mcp-server : the server runs on your machine.
  • An mcpServers JSON block : configuration written for another client’s settings file.

Installing MCP serverstake. Find the shape you have below to turn it into the command Claude Code accepts. Each command writes to

[local scope](#local-scope)unless you add

`--scope project` or `--scope user`.

Add a server from a URL

A URL means the server is remote. For anhttps:// endpoint, add it with --transport http, or follow Option 2when the instructions say the endpoint uses SSE. For a

`wss://` endpoint, use [Option 4](#option-4-add-a-remote-websocket-server)instead, since

`--transport` doesn’t accept `ws`:
`--header` as shown in [Option 1](#option-1-add-a-remote-http-server).

Add a server from an npx, uvx, or binary command

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 --:

[Option 3](#option-3-add-a-local-stdio-server)covers the

`--` separator in full.

Add a server from an mcpServers JSON block

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 notype as a stdio server, so aurl entry without atype 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.

Add MCP servers from JSON configurationcovers 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 scopecovers 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 statuscovers the statuses it shows and the approval step for

.mcp.json servers.

Managing your servers

Once configured, you can manage your MCP servers with these commands:

in your shell before claude mcp logout <name>`` claude mcp remove <name>.

Server status

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 bothclaude mcp list andclaude mcp get <name> . Runclaude interactively to review and approve it.
  • ✘ Rejected (see disabledMcpjsonServers in settings) : a.mcp.json server that adisabledMcpjsonServers entry rejects. Claude Code shows it only inclaude mcp get <name> .
  • ⊘ Disabled for this project (re-enable via /mcp) : a server that the project’sdisabledMcpServers list names. Claude Code shows it in bothclaude mcp list andclaude 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 bothclaude mcp list andclaude mcp get <name> . A server blocked by an allowlist, a denylist, or another restriction inmanaged MCP configuration is hidden from both commands rather than shown with this status. Ask your administrator which policy blocks the server.

Project server approvals and workspace trust

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: or

enableAllProjectMcpServers

committed to the project’s enabledMcpjsonServers``.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/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 . Before v2.1.207, Claude Code applied approvals from an untracked

CLAUDE_CONFIG_DIR``.claude/settings.local.json even in a folder you’d never trusted. A disabledMcpjsonServers entry in any settings file still rejects the server.

Server status detail

In/mcp, including a server’s menu there, and in the manager, a remote HTTP or SSE server you’ve used before can show a

/plugin`` 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 to turn it on, or

MCP_DISCOVERY_CACHE=1`` 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.

url shows as not configured in /mcp, in claude mcp list, and in the 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

/plugin``/mcp reads No URL configured for this server; set the entry’s url to connect it.

Configuration warnings

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 checkscommand ,url , eachargs entry, and the values and key names underenv andheaders . Claude Code shows the warning inclaude mcp list output and in/mcp , naming the affected fields without echoing their values, for exampleLeading 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 onescope with different endpoints, Claude Code warns about the conflict inclaude 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 withclaude 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, includingworkspace ,claude-in-chrome ,computer-use ,Claude Preview , andClaude 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 andClaude Browser both name the built-in server that theClaude 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 inclaude 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’surl andheaders , some credential variablesread as empty instead, with no warning.

Tool availability

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](#scale-with-mcp-tool-search), the default** : the wait happens inside the`ToolSearch` call.
  • Without tool search : Claude uses theWaitForMcpServers tool instead. Configurations without tool search includeENABLE_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 anANTHROPIC_BASE_URL gateway, seeTool search through an LLM gateway .
  • On a Microsoft Foundry deployment hosted on Azure : Claude starts on the tool-search path rather than withWaitForMcpServers , since Claude Code discovers the deployment’s server-side rejection only from the API. After Claude Code switches that deployment toupfront , tools from a server that finishes connecting become available on Claude’s next request.
[retrying after a failed attempt](#automatic-reconnection), the call fails with the

`No such tool available` [tool error](https://code.claude.com/docs/en/errors#no-such-tool-available).

Disable a server without removing it

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 organizationprovides through managed settings , the claude.ai connectors Claude Codefetches 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 inDisable claude.ai connectors , Claude Code writes it to this list under its display name, for exampleclaude.ai Slack .
  • enabledMcpServers : an opt-in list for built-in servers that default to off, such ascomputer-use . Claude Code connects to a default-off server only when you list it here.

enabledMcpServers, or a default-off built-in server to disabledMcpServers, Claude Code ignores the entry. disabledMcpServers and enabledMcpServers are unrelated to and

enabledMcpjsonServers , which control approval of servers defined in a project’s

disabledMcpjsonServers``.mcp.json file.

MCP client runtimes

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 signed in through a Claude apps gateway

  • Sessions where you turn off telemetry or feature-flag fetching, for example with DISABLE_TELEMETRY

  • 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](#notification-streams-on-the-v2-runtime) .
- Doesn’t register a [channel](#push-messages-with-channels) server that connects on the newer revision, because that revision can’t carry channel messages.
- Fails an [MCP OAuth sign-in](#authenticate-with-remote-mcp-servers) whose authorization response names an unexpected issuer.

to MCP_SDK_GENERATION`` v1 or v2. To decide whether Claude Code asks, set to

MCP_PROTOCOL_NEGOTIATION`` auto or legacy.

Dynamic tool updates

An MCP server can change the tools, prompts, or resources it offers while connected and send alist_changed notification. When one arrives:

  • In an interactive terminal session , Claude Code fetches the updated list from that server, so you don’t need to reconnect it.
  • In non-interactive mode with the -p flag and in the Agent SDK , Claude Code refreshes only the tool list on these notifications.

Notification streams on the v2 runtime

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.

/mcp.

Automatic reconnection

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.

Mid-session drops of a remote server

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 anMCP 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 thestatusfailed , and your code canreconnect the server . To reconnect it inclaude -p , start the run again.
    • When the server needs you to sign in again : Claude Code stops retrying, and an Agent SDK session reports the server’s status asneeds-auth . Sign in withclaude mcp login <name> in your shell. Then start the run again or, in an Agent SDK session,reconnect the server instead.

Failed first connections

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 stdio server’s first connection. To try it again, see Stdio servers that exit or fail to start
  • 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 theAuthorization header, Claude Code retries an authentication error anyway, because it re-runs the helper on each attempt and can pick up a fresh credential

Stdio servers that exit or fail to start

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, aclaude -p run, or an Agent SDK session.

Failed discovery requests

After a server connects, Claude Code sends it capability discovery requests such astools/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.

Retry failed servers yourself

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.

How Claude learns that a server failed

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.

  • In any configuration without tool search , Claude Code doesn’t report failed server connections to Claude.

Push messages with channels

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 theclaude/channel capability and you opt it in with the --channels flag at startup. See Channelsto use an officially supported channel, or

Channels referenceto 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

to MCP_PROTOCOL_NEGOTIATION`` legacy, which keeps every server on it.

Time limits on MCP tool calls

To limit how long an MCP tool call can run:

  • Per server : add atimeout field in milliseconds to that server’s configuration entry

  • Across servers : setMCP_TOOL_TIMEOUT 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 connectorserver 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 connectorservers, and to 30 minutes for stdio servers. Set the

environment variable in milliseconds to change the idle window, or set it to

CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`` 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.

Automatic backgrounding of long tool calls

If a background call’s detail view in
[shows](https://code.claude.com/docs/en/commands#all-commands)

/tasks`` 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

, 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

/tasks`` timeout or , and the idle timeout set by MCP_TOOL_TIMEOUT

. To change or turn off automatic backgrounding: CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT

elicitation dialogisn’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.

MCP tasks that run on the server

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.

What a call needs to become an MCP tasklists the sessions and servers that get them.

Stop an MCP task or get its result

To stop a running task, select it in

and press /tasks`` 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:

Answer a question from an MCP task

A running task can open an

elicitation dialogto 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-interactivesession, Claude Code asks the server to cancel a task that requests input, without running your

or calling the Agent SDK’s Elicitation hooksonElicitation callback.

Exit, clear, or resume while an MCP task runs

A task on a remote server keeps running after you exit. A stdio server’s process stops when Claude Code exits, though its tasks showruns 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.

What a call needs to become an MCP task

A tool call becomes an MCP task only when all of these conditions hold:

- The call comes from the main conversation, not from a [subagent](https://code.claude.com/docs/en/sub-agents)
- Either the session is interactive, or an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview) session or a`claude -p` run reading`--input-format stream-json` has:
  - [`CLAUDE_AUTO_BACKGROUND_TASKS`](https://code.claude.com/docs/en/env-vars) at` 1`
  • CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND not1
  • CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS not0

Automatic backgrounding of long tool callssays 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 tasksafter input closes. A one-shot claude -p "<prompt>" run doesn’t get MCP tasks.

Status messages on an MCP task

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.

Time limits on MCP tasks

By default, a task in the background has no Claude Code time limit. The

[tool call time limits](#time-limits-on-mcp-tool-calls), including the wall-clock limit and the idle timeout, apply until the server answers the call with the task. If you

[make Claude wait](#make-claude-wait-for-the-result-of-an-mcp-task), they apply for the whole task. Answered status checks count as activity for the idle timeout.

Make Claude wait for the result of an MCP task

To make Claude wait for a task’s result in an interactive session, set one of two environment variables, for example in theenv block of :

settings.json

  • CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS set to 0 : Claude waits for every MCP tool call until the call ends
  • CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND set to 1 : Claude waits for a task’s result. Whileautomatic 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

Esc or reaching the wall-clock limit or idle timeoutends 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:

MCP tasks for server authors

If you build an MCP server, you can answer a long-running`tools/call` with a task. The [MCP tasks extension](https://modelcontextprotocol.io/extensions/tasks/overview)defines the messages you send. On a

[protocol revision 2026-07-28](#mcp-client-runtimes)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 taskomits that extension.

Answer the call with a task

Answer with a task only when the request carries the extension, or Claude gets the tool errorUnsupported 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:

per-request timer, so accept the job and answer first, then do the work.

Report status, results, and questions

Right after the task answer, Claude Code sendstasks/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:

Plugin-provided MCP servers

Pluginscan bundle MCP servers that provide tools and integrations when you enable the plugin.

How plugin MCP servers work:

  • Plugins define MCP servers in .mcp.json at the plugin root or inline inplugin.json
  • When you enable a plugin, Claude Code starts its MCP servers automatically
  • Claude Code offers plugin MCP tools alongside manually configured MCP tools
  • You add and remove plugin servers by installing or uninstalling the plugin, not with /mcp commands. You can stilltoggle 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: plugin.json: Plugin MCP features:

  • 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 thecached 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 Codeskips 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
  • At session startup, Claude Code connects the servers for enabled plugins automatically. In
  • Path placeholders :${CLAUDE_PLUGIN_ROOT} resolves to the plugin’s installation directory,${CLAUDE_PLUGIN_DATA} to itspersistent state directory, and${CLAUDE_PROJECT_DIR} to the stable project root. Substitution applies to:
    • stdio servers:command ,args ,env
    • http ,sse , andws servers:url ,headers , andheadersHelper
  • 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

/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

[find the plugin on disk](https://code.claude.com/docs/en/plugins/#find-plugins-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:

[permission rules](https://code.claude.com/docs/en/permissions), a skill’s

`allowed-tools` list, a [subagent’s](https://code.claude.com/docs/en/sub-agents#available-tools), or a

tools field

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 . See the

mcp_tool hook’s server field plugin components referencefor details on bundling MCP servers with plugins.

MCP installation scopes #

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

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. ~/.claude.json (your home directory), while general local settings use .claude/settings.local.json (in the project directory). See Settingsfor details on settings file locations.

~/.claude.json. The example below shows the result when you run it from /path/to/your/project:

Project scope

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. .mcp.json file follows a standardized format: .mcp.json files. To reset those approval choices, run claude mcp reset-project-choices.

In `claude -p` runs, [Agent SDK](https://code.claude.com/docs/en/headless)sessions, and

[cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web)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 set in your user settings or in managed settings. To keep a server out anyway:

skipDangerousModePermissionPrompt

  • Add it to disabledMcpjsonServers , which blocks it in every permission mode.
  • 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 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. SeeExclusive control with managed-mcp.json for what the flag does under a managed MCP file.

Project server approvals and workspace trustcovers how approvals committed to the repository interact with workspace trust.

User scope

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.

Scope hierarchy and precedence

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.

  1. Local scope
  2. Project scope
  3. User scope
4. [Plugin-provided servers](https://code.claude.com/docs/en/plugins/components#mcp-servers)
5. [claude.ai connectors](#use-mcp-servers-from-claude-ai)

: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 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

managedMcpServers

Desktop app’s Code tabwith 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.

Environment variable expansion in .mcp.json

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

Example with variable expansion

In this server entry, the URL is the value ofAPI_BASE_URL followed by /mcp, with https://api.example.com as the default, and the API key comes from API_KEY:

Unset variables without a default

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 inclaude 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 emptyinstead, with no warning.

Variables set to an empty string

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.

Credential variables that read as empty

In a remote server’surl 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 andANTHROPIC_AUTH_TOKEN
  • Your cloud provider’s credentials, such as AWS_BEARER_TOKEN_BEDROCK
  • Other credentials your environment carries, such as HTTPS_PROXY andNPM_TOKEN

:-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.

How references appear in /mcp and CLI output

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 andclaude mcp get output

/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.

Practical examples #

Example: Connect to GitHub for code reviews

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:

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 detailincludes the HTTP status the server returned, such as a 401. Then work with GitHub:

Example: Query your PostgreSQL database

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: /mcp and check that the db row shows a checkmark. Then query your database naturally:

Authenticate with remote MCP servers #

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 with401 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 , a401 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 thesession-token-rejected state instead.
  • For a server whose Authorization header you configured, inheaders or through aheadersHelper , a 401 or403 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 Codereads 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 atclaude.ai/customize/connectors rather than from the session.

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 errorinstead. 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 connectorsthat 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 searchenabled, 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. Add the server that requires authentication

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:

Use the /mcp command within Claude Code

Authenticate from the command line

Theclaude 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 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.

Use a fixed OAuth callback port

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).

Use pre-configured OAuth credentials

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. Register an OAuth app with the server

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. Add the server with your credentials

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

--client-id to pass your app’s client ID. The --client-secret flag prompts for the secret with masked input: Authenticate in Claude Code

/mcp in Claude Code and follow the browser login flow.

Override OAuth metadata discovery

Point Claude Code at a specific OAuth authorization server metadata URL to bypass the default discovery chain. SetauthServerMetadataUrl 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: https://. The metadata URL’s scopes_supported overrides the scopes the upstream server advertises.

Restrict OAuth scopes

Setoauth.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 [message that names the scope the server asks for. The server shows as needing authentication in](https://code.claude.com/docs/en/errors#mcp-server-needs-you-to-sign-in-again)

needs additional permissions``/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 aheadersHelper , under the name the proxy reads
  • The OAuth sign-in : keepAuthorization out of the configured headers, then sign in withclaude mcp login <name> in your shell. If you configure anAuthorization header, Claude Code uses it as the server’s credential and doesn’t fall back to OAuth for that server.

Use dynamic headers for custom authentication

When authentication such as Kerberos, short-lived tokens, or internal SSO needs headers generated at connection time, set the server’sheadersHelper to a command. Claude Code runs it when connecting and merges its output into the headers it sends. This example uses a script: Requirements:

  • 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 onPATH
  • Dynamic headers override any static headers with the same name

trust rule for project and local-scope serverslets 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: headersHelper can’t reference the plugin’s values, because the command runs through a shell. Claude Code reports the server as misconfigured with an

`${user_config.*}`
[error](https://code.claude.com/docs/en/errors#plugin-command-references-user-config)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.

Where the helper runs

Claude Code picks theheadersHelper command’s working directory from the configuration that declares the server. A cd that Claude runs in Bash doesn’t move it, and 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

/cd`` headersHelper command resolves against.

Which variables a helper can read

AheadersHelper 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 atuser orlocal scope , inmanaged MCP , from aclaude.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

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 url carries 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.

Trust a folder before its headersHelper runs

Claude Code executes aheadersHelper 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 dialogfor 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 aclaude -p or SDK session gets forhooks in settings files
  • Until you trust the folder : Claude Code connects the server with its staticheaders alone. In aclaude -p or SDK session it also prints oneheadersHelper not run line per server to stderr, telling you how to grant the trust.
  • Trust without a dialog : setprojects["<path>"].hasTrustDialogAccepted totrue in~/.claude.json .<path> is the folderProject allow rules and workspace trust says Claude Code keys the trust on.

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 asX-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 whose configuration you can edit : set it inheaders or return it from a headersHelper
  • 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

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.

Add MCP servers from JSON configuration #

If you have a JSON configuration for an MCP server, you can add it directly: Add an MCP server from JSON

Verify the server was added

Import MCP servers from Claude Desktop #

If you’ve already configured MCP servers in Claude Desktop, you can import them:
Import servers from Claude Desktop

Select which servers to import

Verify the servers were imported

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.

Use MCP servers from claude.ai #

If you’ve logged into Claude Code with a
[claude.ai](https://claude.ai)account, MCP servers you’ve added in claude.ai, known as

[connectors](https://claude.com/docs/connectors), are automatically available in Claude Code:

Configure MCP servers in claude.ai

claude.ai/customize/connectors. On Team and Enterprise plans, only admins can add servers.

Authenticate the MCP server

View and manage servers in Claude Code

Claude Docsis 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 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

/plugin

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 methodis a claude.ai subscription login. They aren’t loaded, even if you previously ran

/login, when:

  • ANTHROPIC_API_KEY ,ANTHROPIC_AUTH_TOKEN , orapiKeyHelper 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](https://code.claude.com/docs/en/authentication#anthropic-profiles-and-federation-credentials) supplies the credential
- `CLAUDE_CODE_OAUTH_TOKEN` holds a token from[`claude setup-token`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token) , which can only make model requests

/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  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 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:](https://code.claude.com/docs/en/errors#claude-ai-rejected-the-session-token)

claude.ai rejected the session token

  1. Run /login to sign in again.
  2. Reconnect the connector from /mcp .

precedenceover 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 , directing you to connect the service at

is Anthropic-hosted and doesn't support local OAuth claude.ai/customize/connectorsinstead. After you remove your entry with

claude mcp remove <name> and connect the service on claude.ai, the connector appears in Claude Code automatically.

How connectors reach Claude Code

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](https://code.claude.com/docs/en/desktop-wsl#check-for-the-terminal-and-connectors).

[,](#disable-claude-ai-connectors)

disableClaudeAiConnectors`` ENABLE_CLAUDEAI_MCP_SERVERS, and act only on the first row, the connectors Claude Code fetches itself. The other two rows differ from it in these ways:

allowAllClaudeAiMcps

  • Cloud sessions :allowedMcpServers anddeniedMcpServers entries that reach the session, for example throughserver-managed settings , filter the delivered connectors too. The session’s proxy rewrites each connector’s URL, so aserverUrl 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 theserverUrl entries listed underConnector traffic leaves your network . Claude Code drops the delivered connectors when amanaged-mcp.json is present on the host that runs the session, such as aself-hosted runner host , whether or not you setallowAllClaudeAiMcps .
  • Desktop app local and SSH sessions : the desktop app registers the connectors as in-processtype: "sdk" servers, and no MCP setting ormanaged-mcp.json reaches them. A user keeps a connector out of their own sessions by disconnecting it atclaude.ai/customize/connectors . An organization blocks a connector’stools or turns offClaude Code in the desktop app entirely.

Organization controls on connector tools

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 rulesto 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 inacceptEdits ,auto , andbypassPermissionspermission 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. IndontAsk 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, markeddisabled by your organization .

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.

Disable claude.ai connectors

Claude Code applies

only to the connectors it disableClaudeAiConnectors 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: 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:

by name or by URL pattern. For example, a deniedMcpServers`` 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.

Use Claude Code as an MCP server #

You can use Claude Code itself as an MCP server that other applications can connect to:

Read a background command’s output as an MCP client

AbackgroundOutputPath 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 backgroundwhen 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 asfile_path to the server’sRead tool
  • To tell when the command has finished : append anecho of a fixed string to thecommand value, as innpm 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 onlyfile_path returns thefirst page , or fails when the file exceeds the size limit. Passoffset andlimit as well, which works at any file size:
    1. Call Read withoffset andlimit both set to1 , and taketotalLines from the result
    2. Call Read again withoffset set tototalLines minus nine andlimit set to10
    3. Look for your echo string in the last ten lines, which the second call returns
  • Call

backgroundOutputPath field requires Claude Code v2.1.295 or later.

MCP output limits and warnings #

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 theMAX_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 setanthropic/maxResultSizeChars use that value instead for text content, regardless of whatMAX_MCP_OUTPUT_TOKENS is set to. Tools that return image data are still subject toMAX_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’stool-results directory under~/.claude/projects/ .
  • Response size from HTTP and SSE servers : when a response from anHTTP orSSE 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 aWebSocket server sends one message over 16 MiB, Claude Codecloses 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

moved to a background taskreports 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 declareanthropic/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. SettingMAX_MCP_OUTPUT_TOKENS doesn’t change this threshold
  • Error results : when a tool returns a result markedisError: 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

MAX_MCP_OUTPUT_TOKENS in your shell before starting Claude Code:

Raise the limit for a specific tool

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. 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.

Images in tool results

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’stool-results directory under 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

~/.claude/projects/

[or](https://code.claude.com/docs/en/cli-reference#cli-flags)

`--no-session-persistence`

, 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.

CLAUDE_CODE_SKIP_PROMPT_HISTORY

Tool input schemas with a root-level combinator #

Some MCP servers declare a tool’s input schema as a JSON Schema union, withanyOf, 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’srequired list still applies
  • anyOf andoneOf : properties from every branch are merged, and each branch’srequired list is described in the tool description instead of enforced by the schema

Tools with invalid input schemas #

Tool input schema is invalid.

  • 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

feature flag fetchingis 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
- If the API then rejects the schema, see [Tools whose input schema the API refuses](#tools-whose-input-schema-the-api-refuses)

[root-level combinator handling](#tool-input-schemas-with-a-root-level-combinator)is separate and keeps its own behavior when flag fetching is off or the flags have never arrived.

Tools whose input schema the API refuses

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](https://code.claude.com/docs/en/errors#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 withThe 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

a 400 error naming the tool by its position.

Tools with names longer than 128 characters #

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.

Require approval for a specific tool #

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 bypassPermissions permission modes, and doesn’t offer a “don’t ask again” option for it.

Allow rulesthat 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 , an --permission-prompt-tool`` 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 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

canUseTool callbacktools/list entry marks one tool as always requiring approval.

Remote Controland 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.

Mark tools that are safe to call twice #

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](#use-mcp-servers-from-claude-ai)once, on a new connection. A call Claude Code doesn’t repeat can fail with

[. To mark a tool, set one of these](https://code.claude.com/docs/en/errors#connection-closed-before-the-tool-call-was-answered)

connection closed before the tool call was answered`` 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.

tools/list entry mark the set_issue_status tool as safe to repeat:

Respond to MCP elicitation requests #

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.

% 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 . If you’re building an MCP server that uses elicitation, see the

Elicitation hook MCP elicitation specificationfor protocol details and schema examples.

Elicitation modes Claude Code declares

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 that use [protocol revision 2026-07-28](#mcp-client-runtimes)
  • Connections on the earlier protocol revisions, 2025-11-25 and older, to the stdio, sse ,http , andws servers in a user’s Claude Code MCP configuration. Requires Claude Code v2.1.287 or later

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.

Use MCP resources #

MCP servers can expose resources that you can reference using @ mentions, similar to how you reference files.

Reference MCP resources

List available resources

@ in your prompt to see available resources from all connected MCP servers. Resources appear alongside files in the autocomplete menu. Reference a specific resource

@server:protocol://resource/path to reference a resource: Multiple resource references

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. deployments hosted on Azure, which reject it server-side: Claude Code detects the rejection and loads MCP tools upfront for that deployment instead.

can’t override this, since the rejection comes from the deployment itself. ENABLE_TOOL_SEARCH

Tool search for MCP server authors

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](https://code.claude.com/docs/en/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

  • 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

[tool search is off](#configure-tool-search), when the tool is

[marked to load upfront](#per-tool-alwaysload), 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.

Change the description length limits

To change the

default limitsof 4,096 and 16,384 characters for the MCP servers in your session, set to a number of characters. Claude Code uses that number for both limits. With

CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`` 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.

Mark a tool to load upfront or stay deferred

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 for the whole server in their configuration, and their setting can override yours:

alwaysLoad`` tools/list entry asks for one tool to load upfront:

Configure tool search

Tool search is enabled by default: MCP tools are deferred and discovered on demand. Setting

keeps tool search off. You can’t override it by setting CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`` 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 capabilitiescovers 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.

ENABLE_TOOL_SEARCH=true. Control tool search behavior with the ENABLE_TOOL_SEARCH environment variable:

settings.json. You can also disable the env fieldToolSearch tool specifically: ToolSearch or leave it out of , MCP tools load upfront instead, but a request can still carry a placeholder

--tools`` defer_ entry. If a gateway rejects that entry, see Tool search through an LLM gateway.

Tool search through an LLM gateway

- **You’ve set `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`** : see[how it affects tool search](#configure-tool-search)
- **A request failed with an error that names `defer_` or `tool_reference`** : see[Extra inputs are not permitted](https://code.claude.com/docs/en/errors#extra-inputs-are-not-permitted)

ANTHROPIC_BASE_URL points to a gateway, tool search is on by default, so requests include defer_ 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. Before v2.1.304, tool search was off behind a gateway unless

env`` ENABLE_TOOL_SEARCH was true, auto, or auto:N.

On v2.1.305 or later, Claude Code can retry a request without tool searchafter 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 labels tools /context``(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.

Exempt a server from deferral

If a server’s tools should always be visible to Claude without a search step, setalwaysLoad 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: 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 supplies its tools from the cache without connecting, so it doesn’t hold startup. Other servers connect in the background by default; set

cached entry

to make startup wait for them too. MCP_CONNECTION_NONBLOCKING=0

Defer a server’s tools

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.

Use MCP prompts as commands #

MCP servers can expose prompts that become available as commands in Claude Code. Prompts from a server namedanthropic-skills don’t appear, because Claude Code reserves that namefor skills synced from claude.ai. The server’s tools still work. Rename the server in your MCP configuration to list its prompts.

Execute MCP prompts

Discover available prompts

/ 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. Execute a prompt without arguments

Execute a prompt with arguments

Managed MCP configuration #

For organizations that need centralized control over which MCP servers users can connect to, see
[Managed MCP configuration](https://code.claude.com/docs/en/managed-mcp). 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.

── more in #ai-agents 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/claude-code-runs-mcp…] indexed:0 read:79min 2026-10-28 · —