Connect to external tools with MCP changedagent-sdk/mcp
Nearest release: v2.1.309, published 2 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 22 Oct 2026 17:46 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 22 Oct 2026 18:07 UTC.
Upstream edited
Recorded here
Lines+23added
Lines−18removed
From line
8
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits21to this page, all time
The whole hunk
from line 8, old and new numbered
/
from line 8
88
99> [!NOTE]
1010>
11> This page covers MCP configuration for the Agent SDK. To add MCP servers to the Claude Code CLI so they load in every project, see [MCP installation scopes](/docs/en/mcp#mcp-installation-scopes).
11> This page covers MCP configuration for the Agent SDK. To add MCP servers to the Claude Code CLI so they load in every project, see [MCP installation scopes](/docs/en/mcp.md#mcp-installation-scopes).
1212
1313## Quickstart
1414
from line 148
148148| Remote server with a cached tool list, saved by Claude Code from a previous connection | No; the cached tools are available from the first turn | None; connects on its first tool call, and that deferred connect has its own timeout |
149149| In-process [SDK server](#sdk-mcp-servers) | Yes, until it connects and lists its tools | [`MCP_TIMEOUT`](/docs/en/env-vars), 30 seconds by default, per connect attempt; the connection fails at that deadline |
150150
151A server has a cached tool list only when the [MCP discovery cache](/docs/en/mcp#server-status-detail) is on.
151A server has a cached tool list only when the [MCP discovery cache](/docs/en/mcp.md#server-status-detail) is on.
152152
153153Servers from [settings files](#from-a-config-file) such as `.mcp.json`, or from plugins, often still show `pending` in the init message. How long the first turn waits for them depends on `options.mcpServers` and tool search:
154154
155155* **`options.mcpServers` includes a stdio, HTTP, or SSE server**: the first turn waits for the pending settings-file and plugin servers too, up to `MCP_TIMEOUT`.
156* **Otherwise, when `ANTHROPIC_BASE_URL` points to a [gateway](/docs/en/mcp#tool-search-through-a-gateway) and [`ENABLE_TOOL_SEARCH`](/docs/en/mcp#configure-tool-search) is unset**: the first turn waits up to 2 seconds for every pending settings-file and plugin server.
157* **Otherwise, with [tool search](/docs/en/agent-sdk/tool-search) on, which is the default**: the first turn waits up to 2 seconds, and only for pending servers that set [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral) or that you [named](#named-servers). The rest keep connecting in the background, and Claude [reaches their tools](/docs/en/mcp#tool-availability) once they connect.
156* **Otherwise, when `ANTHROPIC_BASE_URL` points to a [gateway](/docs/en/mcp.md#tool-search-through-a-gateway) and [`ENABLE_TOOL_SEARCH`](/docs/en/mcp#configure-tool-search) is unset**: the first turn waits up to 2 seconds for every pending settings-file and plugin server.
157* **Otherwise, with [tool search](/docs/en/agent-sdk/tool-search.md) on, which is the default**: the first turn waits up to 2 seconds, and only for pending servers that set [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral) or that you [named](#named-servers). The rest keep connecting in the background, and Claude [reaches their tools](/docs/en/mcp.md#tool-availability) once they connect.
158158* **Otherwise, with tool search off**: the first turn waits up to 2 seconds for every pending settings-file and plugin server. Tool search is off when your [`ENABLE_TOOL_SEARCH` value or model](/docs/en/agent-sdk/tool-search#configure-tool-search) turns it off, or when you exclude the `ToolSearch` tool, for example through `disallowedTools`.
159159
160160### Named servers
from line 178
178178Two settings make startup itself wait, before Claude Code sends the init message:
179179
180180* **[`MCP_CONNECTION_NONBLOCKING`](/docs/en/env-vars) set to `0`**: startup waits for the whole connection batch, up to 5 seconds by default. Set [`MCP_CONNECT_TIMEOUT_MS`](/docs/en/env-vars), in milliseconds, to change that cap. Servers still pending at the cap keep connecting in the background.
181* **`alwaysLoad: true` on a server's config**: startup waits up to the same cap for that server's tools, so the first turn has them at full schema, [exempt from tool search deferral](/docs/en/mcp#exempt-a-server-from-deferral). A remote server with a cached tool list supplies them without connecting or holding startup.
181* **`alwaysLoad: true` on a server's config**: startup waits up to the same cap for that server's tools, so the first turn has them at full schema, [exempt from tool search deferral](/docs/en/mcp.md#exempt-a-server-from-deferral). A remote server with a cached tool list supplies them without connecting or holding startup.
182182
183183The init message reports each server's status as of the moment Claude Code sends it.
184184
from line 197
197197| `github` | `mcp__github__list_issues` |
198198| `my.server` | `mcp__my_server__list_issues` |
199199
200Use the full tool names in `allowedTools` and in [MCP permission rules](/docs/en/permissions#mcp). For a server that a [plugin](/docs/en/agent-sdk/plugins) provides, `<server-name>` takes the [plugin-scoped form](/docs/en/mcp#plugin-provided-mcp-servers) and starts with `plugin_`.
200Use the full tool names in `allowedTools` and in [MCP permission rules](/docs/en/permissions.md#mcp). For a server that a [plugin](/docs/en/agent-sdk/plugins.md) provides, `<server-name>` takes the [plugin-scoped form](/docs/en/mcp.md#plugin-provided-mcp-servers) and starts with `plugin_`.
201201
202202### Auto-approve with allowedTools
203203
from line 235
235235
236236> [!NOTE]
237237>
238> **Prefer `allowedTools` over permission modes for MCP access.** `permissionMode: "acceptEdits"` does not auto-approve MCP tools (only file edits and filesystem Bash commands). `permissionMode: "bypassPermissions"` does auto-approve MCP tools but also disables most other safety prompts, which is broader than necessary; see [How permissions are evaluated](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) for the prompts that remain. A wildcard in `allowedTools` grants exactly the MCP server you want and nothing more. See [Permission modes](/docs/en/agent-sdk/permissions#permission-modes) for a full comparison.
238> **Prefer `allowedTools` over permission modes for MCP access.** `permissionMode: "acceptEdits"` does not auto-approve MCP tools (only file edits and filesystem Bash commands). `permissionMode: "bypassPermissions"` does auto-approve MCP tools but also disables most other safety prompts, which is broader than necessary; see [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for the prompts that remain. A wildcard in `allowedTools` grants exactly the MCP server you want and nothing more. See [Permission modes](/docs/en/agent-sdk/permissions.md#permission-modes) for a full comparison.
239239
240240### Discover available tools
241241
from line 364
364364
365365### SDK MCP servers
366366
367Define custom tools directly in your application code instead of running a separate server process. See the [custom tools guide](/docs/en/agent-sdk/custom-tools) for implementation details.
367Define custom tools directly in your application code instead of running a separate server process. See the [custom tools guide](/docs/en/agent-sdk/custom-tools.md) for implementation details.
368368
369369An SDK MCP server registered by an [`initialize` control request](/docs/en/agent-sdk/typescript#sdkcontrolinitializeresponse) begins connecting as soon as Claude Code processes the request.
370370
from line 372
372372
373373When you have many MCP tools configured, tool definitions can consume a significant portion of your context window. Tool search solves this by withholding tool definitions from context and loading only the ones Claude needs for each turn.
374374
375Tool search is enabled by default. See [Tool search](/docs/en/agent-sdk/tool-search) for configuration options, best practices, and using tool search with custom SDK tools.
375Tool search is enabled by default. See [Tool search](/docs/en/agent-sdk/tool-search.md) for configuration options, best practices, and using tool search with custom SDK tools.
376376
377377## Authentication
378378
from line 490
490490
491491### OAuth2 authentication
492492
493The [MCP specification supports OAuth 2.1](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for authorization. The SDK doesn't open a browser or run an interactive OAuth flow. When a configured server returns an authorization challenge and no stored token is available, the agent run continues without that server's tools, and the server reports status `needs-auth`. The `mcp_servers` array of the [system init message](/docs/en/agent-sdk/typescript#sdksystemmessage) may still show `pending` for that server when it's emitted. To confirm whether a server needs credentials, poll `mcpServerStatus()` in the TypeScript SDK or [`get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python.
493The [MCP specification supports OAuth 2.1](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for authorization. The SDK doesn't open a browser or run an interactive OAuth flow. When a configured server returns an authorization challenge and Claude Code has no token to send, the SDK reports the server as `needs-auth` or `failed`:
494494
495* **`needs-auth`**: Claude Code found no sign-in it can use for the server. Pass a token in `headers`, or [sign in from an interactive Claude Code session](/docs/en/mcp.md#authenticate-with-remote-mcp-servers) on the same machine before the run.
496* **`failed`**, with an `error` in its [`McpServerStatus`](/docs/en/agent-sdk/typescript#mcpserverstatus) entry that starts with `Couldn't read the stored credentials` or `A request to MCP server`: Claude Code couldn't read its credential store. For what to do, see [Couldn't read the stored credentials for MCP server](/docs/en/errors.md#couldnt-read-the-stored-credentials-for-mcp-server). Before Claude Code v2.1.307, the status was `needs-auth` instead when a Mac's login keychain was locked.
497
498In either case, the agent run continues without that server's tools. The `mcp_servers` array of the [system init message](/docs/en/agent-sdk/typescript.md#sdksystemmessage) may still show `pending` for that server when it's emitted. To confirm whether a server needs credentials, poll `mcpServerStatus()` in the TypeScript SDK or [`get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python.
499
495500To supply credentials, complete the OAuth flow in your own application and pass the resulting access token in the server's `headers`:
496501
497502```typescript TypeScript theme={null}
from line 805
800805asyncio.run(main())
801806```
802807
803A remote server's status can also change after it reports `"connected"`. When the connection to it drops mid-session, Claude Code moves the server back to `"pending"` while [reconnecting](/docs/en/mcp#automatic-reconnection). A later `mcpServerStatus()` call in TypeScript, or [`ClaudeSDKClient.get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python, can then report `"pending"` for a server you saw connected earlier, with no configuration change on your side.
808A remote server's status can also change after it reports `"connected"`. When the connection to it drops mid-session, Claude Code moves the server back to `"pending"` while [reconnecting](/docs/en/mcp.md#automatic-reconnection). A later `mcpServerStatus()` call in TypeScript, or [`ClaudeSDKClient.get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python, can then report `"pending"` for a server you saw connected earlier, with no configuration change on your side.
804809
805After five reconnection attempts fail, the server reports `"failed"`, or `"needs-auth"` when it needs authorizing again. A `"failed"` HTTP or SSE server can still return to `"connected"` without a call from you, because Claude Code keeps [retrying in the background](/docs/en/mcp#mid-session-drops-of-a-remote-server) after a transient error. To retry manually, call [`reconnectMcpServer()`](/docs/en/agent-sdk/typescript#methods) in TypeScript or [`ClaudeSDKClient.reconnect_mcp_server()`](/docs/en/agent-sdk/python#methods) in Python.
810After five reconnection attempts fail, the server reports `"failed"`, or `"needs-auth"` when it needs authorizing again. A `"failed"` HTTP or SSE server can still return to `"connected"` without a call from you, because Claude Code keeps [retrying in the background](/docs/en/mcp.md#mid-session-drops-of-a-remote-server) after a transient error. To retry manually, call [`reconnectMcpServer()`](/docs/en/agent-sdk/typescript#methods) in TypeScript or [`ClaudeSDKClient.reconnect_mcp_server()`](/docs/en/agent-sdk/python#methods) in Python.
806811
807812## Troubleshooting
808813
from line 891
886891
887892The SDK applies the same MCP output limits as Claude Code. When a successful tool result with no image content is larger than 25,000 tokens, Claude Code saves the output to a file and replaces the tool result with an error message that names the file path, so the agent can read the output back in portions.
888893
889To change the token limit, set the [`MAX_MCP_OUTPUT_TOKENS`](/docs/en/env-vars) environment variable. Unless the tool declares `anthropic/maxResultSizeChars`, a successful text result longer than 50,000 characters is saved to a file regardless of the token limit. See [MCP output limits and warnings](/docs/en/mcp#mcp-output-limits-and-warnings) for the full behavior, including how a server declares that annotation.
894To change the token limit, set the [`MAX_MCP_OUTPUT_TOKENS`](/docs/en/env-vars) environment variable. Unless the tool declares `anthropic/maxResultSizeChars`, a successful text result longer than 50,000 characters is saved to a file regardless of the token limit. See [MCP output limits and warnings](/docs/en/mcp.md#mcp-output-limits-and-warnings) for the full behavior, including how a server declares that annotation.
890895
891896## Related resources
892897
893* **[Custom tools guide](/docs/en/agent-sdk/custom-tools)**: Build your own MCP server that runs in-process with your SDK application
894* **[Permissions](/docs/en/agent-sdk/permissions)**: Control which MCP tools your agent can use with `allowedTools` and `disallowedTools`
895* **[TypeScript SDK reference](/docs/en/agent-sdk/typescript)**: Full API reference including MCP configuration options
896* **[Python SDK reference](/docs/en/agent-sdk/python)**: Full API reference including MCP configuration options
898* **[Custom tools guide](/docs/en/agent-sdk/custom-tools.md)**: Build your own MCP server that runs in-process with your SDK application
899* **[Permissions](/docs/en/agent-sdk/permissions.md)**: Control which MCP tools your agent can use with `allowedTools` and `disallowedTools`
900* **[TypeScript SDK reference](/docs/en/agent-sdk/typescript.md)**: Full API reference including MCP configuration options
901* **[Python SDK reference](/docs/en/agent-sdk/python.md)**: Full API reference including MCP configuration options
897902* **[MCP server directory](https://github.com/modelcontextprotocol/servers)**: Browse available MCP servers for databases, APIs, and more
898903
No line in this hunk matches that.