SpyBara
Go Premium

agent-sdk/mcp.md 2026-09-17 05:00 UTC to 2026-09-18 23:58 UTC

This page contains 12 additions and 1 deletion.

2026
Thu 10 23:00 Mon 14 22:58 Fri 18 23:58

使用 MCP 连接外部工具

配置 MCP 服务器以扩展您的代理的外部工具。涵盖传输类型、大型工具集的工具搜索、身份验证和错误处理。

Model Context Protocol (MCP) 是一个开放标准,用于将 AI 代理连接到外部工具和数据源。使用 MCP,您的代理可以查询数据库、与 Slack 和 GitHub 等 API 集成,以及连接到其他服务,而无需编写自定义工具实现。

MCP 服务器可以作为本地进程运行、通过 HTTP 连接或直接在您的 SDK 应用程序中执行。

快速开始

此示例使用 HTTP 传输 连接到 Claude Code 文档 MCP 服务器,并使用 allowedTools 与通配符来允许来自服务器的所有工具。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
prompt: "Use the docs MCP server to explain what hooks are in Claude Code",
options: {
mcpServers: {
"claude-code-docs": {
type: "http",
url: "https://code.claude.com/docs/mcp"
}
},
allowedTools: ["mcp__claude-code-docs__*"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

代理连接到文档服务器,搜索有关 hooks 的信息,并返回结果。

添加 MCP 服务器

您可以在调用 query() 时在代码中配置 MCP 服务器,或在通过 settingSources 加载的 .mcp.json 文件中配置。

在代码中

在 mcpServers 选项中直接传递 MCP 服务器。此示例为 /Users/me/projects 启动本地文件系统 MCP 服务器。将该路径替换为您机器上的目录:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
prompt: "List files in my project",
options: {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
},
allowedTools: ["mcp__filesystem__*"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

从配置文件

在您的项目根目录创建一个 .mcp.json 文件。当启用 project 设置源时,该文件会被加载,默认 query() 选项已启用此功能。如果您显式设置 settingSources,请包含 "project" 以加载此文件。将 /Users/me/projects 替换为您机器上的目录:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    }
  }
}

连接时序

Claude Code 在启动时注册你在 options.mcpServers 中传递的服务器,并在第一轮等待(如果有的话)解决后发出 init 消息。每个 options.mcpServers 服务器是否延迟第一轮,以及何时连接,取决于其类型:

服务器类型 延迟第一轮? 第一轮等待超时
stdio 服务器,或没有缓存工具列表的 HTTP/SSE 服务器 是,直到连接 MCP_TIMEOUT,默认 30 秒;连接在该截止时间失败
具有缓存工具列表的远程服务器,由 Claude Code 从之前的连接保存 否;缓存的工具从第一轮开始可用 无;在其第一次工具调用时连接,该延迟连接有其自己的超时
进程内 SDK 服务器 是,直到连接并列出其工具 无;连接和工具列表请求各有其自己的超时

从 settings 文件(如 .mcp.json)或从插件加载的服务器通常在 init 消息中显示 pending。当 options.mcpServers 包含 stdio、HTTP 或 SSE 服务器时,第一轮等待这些待处理的服务器,最多等待 MCP_TIMEOUT。当 options.mcpServers 为空或仅包含 SDK 服务器时,第一轮改为最多等待 2 秒:

  • 使用 tool search(默认):等待涵盖仍待处理的服务器,这些服务器配置了 alwaysLoad: true,不包括其余的。其余的继续在后台连接。Tool availability 描述了 Claude 在它们连接后如何访问它们的工具。
  • 不使用 tool search:等待涵盖每个待处理的服务器。Configure tool search 涵盖了关闭 tool search 的内容。例如,如果你通过 disallowedTools 从会话中排除 ToolSearch 工具,会话也会在没有 tool search 的情况下运行。

如果你设置了 permissionPromptToolName,第一轮也会在所有情况下等待该工具的服务器,最多等待 MCP_TIMEOUT。

要自己设置第一轮等待,请将 CLAUDE_CODE_MCP_STARTUP_WAIT_MS 添加到 env 选项,例如 CLAUDE_CODE_MCP_STARTUP_WAIT_MS: "5000"。第一轮然后等待最多那么多毫秒以等待每个待处理的服务器,无论 tool search 是否可用。此截止时间也替代了 options.mcpServers 中 stdio、HTTP 和 SSE 服务器的 MCP_TIMEOUT 第一轮等待。CLAUDE_CODE_MCP_STARTUP_WAIT_MS 需要 Claude Code v2.1.274 或更高版本。

当等待结束时仍待处理的服务器继续在后台连接。将变量设置为 0 以跳过等待。permissionPromptToolName 服务器无论该值如何都保持其自己的 MCP_TIMEOUT 等待。

要在发送 init 消息之前的单独的、更早的阶段阻止启动本身:

  • 将 MCP_CONNECTION_NONBLOCKING 设置为 0 以阻止整个连接批次。Claude Code 默认将该等待上限设为 5 秒。使用 MCP_CONNECT_TIMEOUT_MS 环境变量调整上限,单位为毫秒。在该截止时间仍待处理的服务器继续在后台连接。
  • 在服务器的配置上设置 alwaysLoad: true 以使其工具在第一轮时以完整架构可用,豁免于工具搜索延迟。Claude Code 在启动时等待该服务器的工具,上限为相同的截止时间,而其他服务器继续在后台连接;具有缓存工具列表的远程服务器根据上表提供它们而无需连接。

具有 init 子类型的 system 消息在发出时报告每个服务器的状态;请参阅 错误处理 以读取这些状态。

允许 MCP 工具

MCP 工具需要明确的权限才能让 Claude 使用它们。没有权限的情况下,Claude 会看到工具可用,但无法调用它们。

工具命名约定

MCP 工具遵循命名模式 mcp__<server-name>__<tool-name>。例如,一个名为 "github" 的 GitHub 服务器,其中有一个 list_issues 工具,会变成 mcp__github__list_issues。

使用 allowedTools 自动批准

使用 allowedTools 自动批准特定的 MCP 工具,这样 Claude 就可以在没有权限提示的情况下使用它们:

const _ = {
options: {
mcpServers: {
// your servers
},
allowedTools: [
"mcp__github__*", // All tools from the github server
"mcp__db__query", // Only the query tool from db server
"mcp__slack__send_message" // Only send_message from slack server
]
}
};

通配符(*)让你可以允许来自一个服务器的所有工具,而无需逐个列出。

发现可用工具

要查看 MCP 服务器提供的工具,请检查服务器的文档或检查 system init 消息中的 tools 数组。MCP 工具名称以 mcp__ 开头。

Claude Code 在 首次连接等待 之后为在 options.mcpServers 中传递的服务器发出 init 消息,因此 tools 数组列出了到那时已连接的每个服务器的 mcp__ 工具,以及具有 缓存工具列表 的服务器的工具,这些服务器在首次使用时连接。任何其他尚未连接的服务器的工具不存在;请参阅 错误处理 了解如何读取每个服务器的状态。

此过滤器打印 MCP 工具名称:

import { query } from "@anthropic-ai/claude-agent-sdk";

const options = {
mcpServers: {
// your servers
},
};

for await (const message of query({ prompt: "...", options })) {
if (message.type === "system" && message.subtype === "init") {
const mcpTools = message.tools.filter((name) => name.startsWith("mcp__"));
console.log("Available MCP tools:", mcpTools);
}
}

你也可以要求 Claude 列出来自服务器的可用工具。

传输类型

MCP 服务器使用不同的传输协议与您的代理进行通信。检查服务器的文档以查看它支持哪种传输:

  • 如果文档给您一个要运行的命令(如 npx @modelcontextprotocol/server-filesystem),请使用 stdio
  • 如果文档给您一个 URL,请使用 HTTP 或 SSE
  • 如果您在代码中构建自己的工具,请使用 SDK MCP 服务器

stdio 服务器

通过 stdin/stdout 进行通信的本地进程。对于在同一台机器上运行的 MCP 服务器,请使用此方法。对于 .mcp.json 形式,请使用 From a config file 中显示的相同字段。在代码中,传递命令及其参数。将 /Users/me/projects 替换为您机器上的目录:

const _ = {
options: {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
},
allowedTools: ["mcp__filesystem__read_file", "mcp__filesystem__list_directory"]
}
};

HTTP/SSE 服务器

对于云托管的 MCP 服务器和远程 API,请使用 HTTP 或 SSE。对于 .mcp.json 形式,请使用 HTTP headers for remote servers 中示例的相同字段,对于 SSE 服务器使用 "type": "sse"。在代码中,传递服务器的 URL:

const _ = {
options: {
mcpServers: {
"remote-api": {
type: "sse",
url: "https://api.example.com/mcp/sse",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`
}
}
},
allowedTools: ["mcp__remote-api__*"]
}
};

对于可流式传输的 HTTP 传输,请改用 "type": "http"。在 .mcp.json 和其他 JSON 配置文件中,"streamable-http" 被接受为 "http" 的别名。SDK 的 McpHttpServerConfig 类型仅声明 "http",因此对于您在代码中传递的服务器,请使用 "http"。

SDK MCP 服务器

直接在您的应用程序代码中定义自定义工具,而不是运行单独的服务器进程。有关实现详情,请参阅 custom tools guide。

由 initialize control request 注册的 SDK MCP 服务器在 Claude Code 处理请求后立即开始连接。

当你配置了许多 MCP 工具时,工具定义可能会消耗上下文窗口的很大一部分。工具搜索通过从上下文中隐藏工具定义并仅加载 Claude 每轮所需的工具来解决这个问题。

工具搜索默认启用。有关配置选项、最佳实践以及将工具搜索与自定义 SDK 工具一起使用的信息,请参阅工具搜索。

身份验证

大多数 MCP 服务器需要身份验证才能访问外部服务。通过服务器配置中的环境变量传递凭证。

通过环境变量传递凭证

使用 env 字段将 API 密钥、令牌和其他凭证传递给 MCP 服务器:

const _ = {
options: {
mcpServers: {
"api-server": {
command: "npx",
args: ["-y", "@your-org/api-mcp-server"],
env: {
API_KEY: process.env.API_KEY
}
}
},
allowedTools: ["mcp__api-server__*"]
}
};

远程服务器的 HTTP 头

对于 HTTP 和 SSE 服务器,直接在服务器配置中传递身份验证头:

const _ = {
options: {
mcpServers: {
"secure-api": {
type: "http",
url: "https://api.example.com/mcp",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`
}
}
},
allowedTools: ["mcp__secure-api__*"]
}
};

有关使用头进行身份验证的远程服务器的完整工作示例,请参阅从存储库列出问题。

OAuth2 身份验证

MCP 规范支持 OAuth 2.1 用于授权。SDK 不会打开浏览器或运行交互式 OAuth 流程。当配置的服务器返回授权质询且没有可用的存储令牌时,代理运行将继续而不使用该服务器的工具,服务器报告状态为 needs-auth。系统初始化消息的 mcp_servers 数组在发出时可能仍会为该服务器显示 pending。要确认服务器是否需要凭证,请在 TypeScript SDK 中轮询 mcpServerStatus() 或在 Python 中轮询 get_mcp_status()。

要提供凭证,请在您自己的应用程序中完成 OAuth 流程,并在服务器的 headers 中传递生成的访问令牌:

// After completing OAuth flow in your app.
// Implement getAccessTokenFromOAuthFlow for your OAuth provider.
const accessToken = await getAccessTokenFromOAuthFlow();

const options = {
mcpServers: {
"oauth-api": {
type: "http",
url: "https://api.example.com/mcp",
headers: {
Authorization: `Bearer ${accessToken}`
}
}
},
allowedTools: ["mcp__oauth-api__*"]
};

示例

从仓库列出问题

此示例连接到远程 GitHub MCP 服务器以列出最近的问题。该示例包括调试日志以验证 MCP 连接和工具调用。

运行前,创建一个具有对要查询的仓库的读取访问权限的 GitHub 个人访问令牌,并将其设置为环境变量:

export GITHUB_TOKEN=YOUR_GITHUB_PAT
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
prompt: "List the 3 most recent issues in anthropics/claude-code",
options: {
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`
}
}
},
allowedTools: ["mcp__github__list_issues"]
}
})) {
// Verify MCP server connected successfully
if (message.type === "system" && message.subtype === "init") {
console.log("MCP servers:", message.mcp_servers);
}

// Log when Claude calls an MCP tool
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "tool_use" && block.name.startsWith("mcp__")) {
console.log("MCP tool called:", block.name);
}
}
}

// Print the final result
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

在 MCP servers: 行中,github 的 status 为 connected 确认令牌有效。如果 Claude Code 对服务器有 缓存的工具列表,状态可以改为 pending,服务器在首次工具调用时连接。如果状态为 failed 或 needs-auth,在信任结果之前请参阅 错误处理,因为当服务器不可用时 Claude 可能会回退到内置工具。

查询数据库

此示例使用 DBHub 查询 Postgres 数据库。代理自动发现数据库架构、编写 SQL 查询并返回结果。

DBHub 的 execute_sql 工具运行代理发出的任何 SQL,包括写入操作,除非您限制它。在 DBHub 配置文件 中设置 readonly = true 会使 DBHub 拒绝 INSERT、UPDATE、DELETE 和 DDL 语句,因此即使代理发出写入操作,该示例也无法修改您的数据。DBHub 在加载配置时从进程环境解析 ${DATABASE_URL},因此连接字符串保持在文件之外。在脚本旁边创建此 dbhub.toml:

[[sources]]
id = "production"
dsn = "${DATABASE_URL}"

[[tools]]
name = "execute_sql"
source = "production"
readonly = true

脚本随后指向 DBHub 的配置文件,而不是直接传递连接字符串。运行前,将 DATABASE_URL 环境变量设置为您的连接字符串。用您自己的数据库详细信息替换占位符值:

export DATABASE_URL=postgresql://user:password@localhost:5432/mydb
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
// Natural language query - Claude writes the SQL
prompt: "How many users signed up last week? Break it down by day.",
options: {
mcpServers: {
postgres: {
command: "npx",
// dbhub.toml sets readonly = true, so execute_sql rejects writes
args: ["-y", "@bytebase/dbhub", "--config", "dbhub.toml"]
}
},
allowedTools: ["mcp__postgres__execute_sql"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

错误处理

MCP 服务器可能因各种原因连接失败:服务器进程可能未安装、凭证可能无效,或远程服务器可能无法访问。

Claude Code 在每个查询开始时发出一条 system 类型、子类型为 init 的消息。此消息包括每个 MCP 服务器的连接状态。status 字段可以是 "pending"、"connected"、"failed"、"needs-auth" 或 "disabled"。Claude Code 在 首次转换连接等待 之后为在 options.mcpServers 中传递的服务器发出 init 消息,因此在等待时间内连接的服务器会显示 "connected"。

在 init 消息中,不要将 "pending" 本身视为失败。它可能意味着以下任何一种情况:

检查 "failed" 或 "needs-auth" 以检测无法使用的服务器:

import { query } from "@anthropic-ai/claude-agent-sdk";

try {
for await (const message of query({
prompt: "Process data",
options: {
mcpServers: {
// Replace dataServer with your server configuration
"data-processor": dataServer
}
}
})) {
if (message.type === "system" && message.subtype === "init") {
const unavailableServers = message.mcp_servers.filter(
(s) => s.status === "failed" || s.status === "needs-auth"
);

if (unavailableServers.length > 0) {
console.warn("Unavailable MCP servers:", unavailableServers);
}
}

if (message.type === "result" && message.subtype === "error_during_execution") {
console.error("Execution failed");
}
}
} catch (error) {
// A single-shot query() throws after yielding an error result. If the
// failure was an error result, the error subtype branch above has
// already run; a failure to start or reach the Claude Code process
// yields no result message. MCP servers that fail to connect don't
// throw: use the status check above, and note that servers still
// "pending" at init need a later status check.
console.log(`Session ended with an error: ${error}`);
}

远程服务器的状态在报告 "connected" 后也可能会改变。当连接在会话中途断开时,Claude Code 会在 重新连接 时将服务器移回 "pending"。之后在 TypeScript 中调用 mcpServerStatus(),或在 Python 中调用 ClaudeSDKClient.get_mcp_status(),可能会为您之前看到已连接的服务器报告 "pending",而您这一方没有进行任何配置更改。

在五次重新连接尝试失败后,服务器报告 "failed",或在需要再次授权时报告 "needs-auth"。要手动重试,请在 TypeScript 中调用 reconnectMcpServer() 或在 Python 中调用 ClaudeSDKClient.reconnect_mcp_server()。

故障排除

服务器显示"failed"状态

检查 init 消息以查看哪些服务器连接失败:

if (message.type === "system" && message.subtype === "init") {
for (const server of message.mcp_servers) {
if (server.status === "failed") {
console.error(`Server ${server.name} failed to connect`);
}
}
}

"pending" 状态并不意味着服务器连接失败。请参阅错误处理了解它在初始化时涵盖的情况。要在会话后期获取更新的状态,请在 TypeScript SDK 中调用查询的 mcpServerStatus() 方法,或在 Python 中调用 ClaudeSDKClient.get_mcp_status()。

常见原因:

  • 缺少环境变量:确保设置了所需的令牌和凭证。对于 stdio 服务器,检查 env 字段是否与服务器期望的相匹配。
  • 服务器未安装:对于 npx 命令,验证该包是否存在以及 Node.js 是否在您的 PATH 中。
  • 无效的连接字符串:对于数据库服务器,验证连接字符串格式以及数据库是否可访问。
  • 网络问题:对于远程 HTTP/SSE 服务器,检查 URL 是否可达以及任何防火墙是否允许连接。

工具未被调用

如果 Claude 看到工具但不使用它们,请检查您是否已使用 allowedTools 授予权限:

const _ = {
options: {
mcpServers: {
// your servers
},
allowedTools: ["mcp__servername__*"] // Auto-approve calls from this server
}
};

连接超时

MCP 服务器连接默认在 30 秒后超时。要更改运行中的工具调用可能需要的时间,请设置 MCP_TOOL_TIMEOUT。如果您的服务器需要更长时间才能启动,连接将失败。使用 MCP_TIMEOUT 环境变量(以毫秒为单位)提高连接限制。对于需要更多启动时间的服务器,还应考虑:

  • 使用更轻量级的服务器(如果可用)
  • 在启动代理之前预热服务器
  • 检查服务器日志以查找缓慢初始化的原因

在 TypeScript 中,您可以通过将 timeout 传递给 createSdkMcpServer() 来为单个 SDK MCP 服务器 设置工具调用限制。

工具输出超过最大允许令牌数

SDK 应用与 Claude Code 相同的 MCP 输出限制。当没有图像内容的工具结果大于 25,000 个令牌时,Claude Code 会将输出保存到文件中,并用错误消息替换工具结果,该消息命名文件路径,以便代理可以分部分读取输出。

使用 MAX_MCP_OUTPUT_TOKENS 环境变量提高限制。请参阅 MCP 输出限制和警告 了解完整行为,包括服务器如何使用 anthropic/maxResultSizeChars 注释声明更高的每工具限制。