Appearance
MCP(Model Context Protocol)让 Claude Code Agent 调用外部工具,包括查询数据库、访问 GitHub、Slack 等 API。配置方式有代码内定义和 .mcp.json 文件两种。支持三种传输:stdio(本地进程)、HTTP/SSE(远程服务)和 SDK 内嵌。必须通过 allowedTools 显式授权工具名(格式 mcp__服务器名__工具名),通配符可批量授权。认证凭据通过 env 字段或 HTTP headers 传递。连接失败时检查 init 消息中的 status 字段,常见原因包括环境变量缺失、服务器未安装、网络不通。本页提供完整示例和排错步骤。
Claude Code Agent SDK MCP 配置:连接外部工具
Model Context Protocol (MCP) 是连接 AI Agent 与外部工具和数据源的开源标准。通过 MCP,你的 Agent 可以直接查询数据库、接入 Slack/GitHub 等 API,无需为每个工具单独编写集成代码。
MCP 服务器可以以本地进程运行、通过 HTTP 连接,或直接集成在 SDK 应用中。
本页仅介绍 Agent SDK 中的 MCP 配置。若要在 Claude Code CLI 中全局加载 MCP 服务器(每个项目都可用),请参见 MCP 安装范围。
快速开始
下面通过 HTTP 传输 连接 Claude Code 文档 MCP 服务器,并用 allowedTools 的通配符 * 允许该服务器的所有工具:
typescript
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);
}
}python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"claude-code-docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp",
}
},
allowed_tools=["mcp__claude-code-docs__*"],
)
async for message in query(
prompt="Use the docs MCP server to explain what hooks are in Claude Code",
options=options,
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())上述代码中,Agent 连接到文档服务器,搜索关于 hooks 的信息并返回结果。
添加 MCP 服务器
你可以在调用 query() 时通过代码配置,也可以通过 .mcp.json 文件加载(配合 settingSources 使用)。
在代码中配置
将 MCP 服务器作为 mcpServers 选项传入:
typescript
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);
}
}python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/me/projects",
],
}
},
allowed_tools=["mcp__filesystem__*"],
)
async for message in query(prompt="List files in my project", options=options):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())从配置文件加载
在项目根目录创建 .mcp.json 文件。当 settingSources 包含 "project"(默认 query() 选项已包含)时,该文件会自动加载。如果你显式设置了 settingSources,记得加入 "project":
json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}授权 MCP 工具
Claude 使用 MCP 工具前必须获得显式授权。没有授权时,Claude 会看到工具可用但无法调用。
工具命名规则
MCP 工具的名称遵循 mcp__<服务器名>__<工具名> 格式。例如,名为 "github" 的服务器中有一个 list_issues 工具,其完整的工具名就是 mcp__github__list_issues。
通过 allowedTools 授予访问权限
使用 allowedTools 指定 Claude 可以使用的 MCP 工具:
typescript
const _ = {
options: {
mcpServers: {
// 你的服务器配置
},
allowedTools: [
"mcp__github__*", // github 服务器上的所有工具
"mcp__db__query", // db 服务器上的 query 工具
"mcp__slack__send_message" // slack 服务器上的 send_message 工具
]
}
};通配符 * 可以一次允许某个服务器的所有工具,无需逐一列出。
推荐使用
allowedTools而非权限模式(permission modes)来管控 MCP 工具访问。permissionMode: "acceptEdits"不会自动批准 MCP 工具(只自动批准文件编辑和文件系统 Bash 命令)。permissionMode: "bypassPermissions"虽然会自动批准 MCP 工具,但同时关闭了所有其他安全提示,范围过大。而allowedTools中的通配符只精确开放你想要的服务器,不做多余的事。完整对比请参考权限模式。
查看可用工具
要了解 MCP 服务器提供了哪些工具,可以检查其文档,或在连接后查看 system 类型消息中的 mcp_servers 字段:
typescript
for await (const message of query({ prompt: "...", options })) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available MCP tools:", message.mcp_servers);
}
}传输类型(Transport)
MCP 服务器通过不同的传输协议与你的 Agent 通信。根据服务器的文档选择对应的类型:
- 如果文档给出 命令(如
npx @modelcontextprotocol/server-github),使用 stdio - 如果文档给出 URL,使用 HTTP 或 SSE
- 如果你自己在代码中构建工具,使用 SDK MCP 服务器
stdio 服务器
本地进程通过 stdin/stdout 通信。适用于与 Agent 运行在同一台机器上的 MCP 服务器:
```typescript TypeScript hidelines={1,-1} theme={null}
const _ = {
options: {
mcpServers: {
github: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN
}
}
},
allowedTools: ["mcp__github__list_issues", "mcp__github__search_issues"]
}
};
```
```python Python theme={null}
options = ClaudeAgentOptions(
mcp_servers={
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": os.environ["GITHUB_TOKEN"]},
}
},
allowed_tools=["mcp__github__list_issues", "mcp__github__search_issues"],
)
```
配置文件版 `.mcp.json`:
```json theme={null}
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
```
HTTP/SSE 服务器
用于云托管或远程 API 的 MCP 服务器:
```typescript TypeScript hidelines={1,-1} theme={null}
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__*"]
}
};
```
```python Python theme={null}
options = ClaudeAgentOptions(
mcp_servers={
"remote-api": {
"type": "sse",
"url": "https://api.example.com/mcp/sse",
"headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
}
},
allowed_tools=["mcp__remote-api__*"],
)
```
配置文件版:
```json theme={null}
{
"mcpServers": {
"remote-api": {
"type": "sse",
"url": "https://api.example.com/mcp/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
```
对于流式 HTTP 传输,使用 "type": "http"。在 .mcp.json 等 JSON 配置文件中,"streamable-http" 可以作为 "http" 的别名。程序化 mcpServers 选项只接受 "http"。
SDK MCP 服务器
直接在应用代码中定义自定义工具,无需运行独立的服务器进程。具体实现请参见自定义工具指南。
MCP 工具搜索(Tool Search)
当你配置了大量 MCP 工具时,工具定义会占用相当一部分上下文窗口。工具搜索通过将工具定义从上下文移出,只在每次回合中加载 Claude 需要的工具来解决这一问题。
工具搜索默认开启。配置选项和详情请见工具搜索。
认证
大多数 MCP 服务器需要认证才能访问外部服务。你需要将凭据通过环境变量传递给服务器配置。
通过环境变量传递凭据
使用 env 字段向 MCP 服务器传递 API key、token 等:
```typescript TypeScript hidelines={1,-1} theme={null}
const _ = {
options: {
mcpServers: {
github: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN
}
}
},
allowedTools: ["mcp__github__list_issues"]
}
};
```
```python Python theme={null}
options = ClaudeAgentOptions(
mcp_servers={
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": os.environ["GITHUB_TOKEN"]},
}
},
allowed_tools=["mcp__github__list_issues"],
)
```
配置文件版 `.mcp.json`:
```json theme={null}
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
```
`${GITHUB_TOKEN}` 语法会在运行时展开环境变量。
完整的可运行示例(包含调试日志)请见从仓库列出 issue。
远程服务器的 HTTP 头认证
对于 HTTP/SSE 服务器,直接在服务器配置中传递认证头:
```typescript TypeScript hidelines={1,-1} theme={null}
const _ = {
options: {
mcpServers: {
"secure-api": {
type: "http",
url: "https://api.example.com/mcp",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`
}
}
},
allowedTools: ["mcp__secure-api__*"]
}
};
```
```python Python theme={null}
options = ClaudeAgentOptions(
mcp_servers={
"secure-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
}
},
allowed_tools=["mcp__secure-api__*"],
)
```
配置文件版:
```json theme={null}
{
"mcpServers": {
"secure-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
```
`${API_TOKEN}` 语法会在运行时展开环境变量。
OAuth 2.0 认证
MCP 规范支持 OAuth 2.1。SDK 不会自动处理 OAuth 流程,但你可以在应用中完成 OAuth 流程后,将 access token 通过 headers 传入:
typescript
// 在你的应用中完成 OAuth 流程后
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__*"]
};python
# 在你的应用中完成 OAuth 流程后
access_token = await get_access_token_from_oauth_flow()
options = ClaudeAgentOptions(
mcp_servers={
"oauth-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {"Authorization": f"Bearer {access_token}"},
}
},
allowed_tools=["mcp__oauth-api__*"],
)示例
从仓库列出 Issue
下面连接 GitHub MCP 服务器 列出最近 Issue。示例中包含调试日志,验证 MCP 连接和工具调用。
运行前,创建一个拥有 repo 权限的 GitHub personal access token,并设置为环境变量:
bash
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxtypescript
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: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN
}
}
},
allowedTools: ["mcp__github__list_issues"]
}
})) {
// 验证 MCP 服务器已成功连接
if (message.type === "system" && message.subtype === "init") {
console.log("MCP servers:", message.mcp_servers);
}
// 记录 Claude 调用 MCP 工具的时刻
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);
}
}
}
// 打印最终结果
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}python
import asyncio
import os
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
ResultMessage,
SystemMessage,
AssistantMessage,
)
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": os.environ["GITHUB_TOKEN"]},
}
},
allowed_tools=["mcp__github__list_issues"],
)
async for message in query(
prompt="List the 3 most recent issues in anthropics/claude-code",
options=options,
):
# 验证 MCP 服务器已成功连接
if isinstance(message, SystemMessage) and message.subtype == "init":
print("MCP servers:", message.data.get("mcp_servers"))
# 记录 Claude 调用 MCP 工具的时刻
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "name") and block.name.startswith("mcp__"):
print("MCP tool called:", block.name)
# 打印最终结果
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())查询数据库
下面使用 Postgres MCP 服务器 查询数据库。连接字符串作为参数传给服务器。Agent 会自动发现数据库 schema,编写 SQL 并返回结果:
typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
// 从环境变量获取连接字符串
const connectionString = process.env.DATABASE_URL;
for await (const message of query({
// 自然语言查询 - Claude 会写 SQL
prompt: "How many users signed up last week? Break it down by day.",
options: {
mcpServers: {
postgres: {
command: "npx",
// 把连接字符串作为参数传给服务器
args: ["-y", "@modelcontextprotocol/server-postgres", connectionString]
}
},
// 只允许读查询,不允许写
allowedTools: ["mcp__postgres__query"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}python
import asyncio
import os
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
# 从环境变量获取连接字符串
connection_string = os.environ["DATABASE_URL"]
options = ClaudeAgentOptions(
mcp_servers={
"postgres": {
"command": "npx",
# 把连接字符串作为参数传给服务器
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
connection_string,
],
}
},
# 只允许读查询,不允许写
allowed_tools=["mcp__postgres__query"],
)
# 自然语言查询 - Claude 会写 SQL
async for message in query(
prompt="How many users signed up last week? Break it down by day.",
options=options,
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())错误处理
MCP 服务器可能因为多种原因连接失败:服务器进程未安装、凭据无效、远程服务器不可达等。
SDK 会在每次 query 开始时发出一个 system 类型 subtype 为 init 的消息。该消息包含每个 MCP 服务器的连接状态。你可以在 Agent 开始工作前检查 status 字段以检测连接失败:
typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Process data",
options: {
mcpServers: {
"data-processor": dataServer
}
}
})) {
if (message.type === "system" && message.subtype === "init") {
const failedServers = message.mcp_servers.filter((s) => s.status !== "connected");
if (failedServers.length > 0) {
console.warn("Failed to connect:", failedServers);
}
}
if (message.type === "result" && message.subtype === "error_during_execution") {
console.error("Execution failed");
}
}python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage, ResultMessage
async def main():
options = ClaudeAgentOptions(mcp_servers={"data-processor": data_server})
async for message in query(prompt="Process data", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
failed_servers = [
s
for s in message.data.get("mcp_servers", [])
if s.get("status") != "connected"
]
if failed_servers:
print(f"Failed to connect: {failed_servers}")
if (
isinstance(message, ResultMessage)
and message.subtype == "error_during_execution"
):
print("Execution failed")
asyncio.run(main())排错
服务器状态显示 "failed"
检查 init 消息中哪些服务器连接失败:
typescript
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`);
}
}
}常见原因:
- 环境变量缺失:确保所需的 token 和凭据已设置。对于 stdio 服务器,检查
env字段是否匹配服务器期待的值。 - 服务器未安装:对于
npx命令,验证包是否存在且 Node.js 在 PATH 中。 - 连接字符串无效:对于数据库服务器,检查连接字符串的格式,确认数据库可达。
- 网络问题:对于远程 HTTP/SSE 服务器,检查 URL 能否正常访问,防火墙是否放行。
工具未被调用
如果 Claude 看到了工具但不使用,请确认已通过 allowedTools 授予权限:
typescript
const _ = {
options: {
mcpServers: {
// 你的服务器
},
allowedTools: ["mcp__servername__*"] // 必须设置,Claude 才能调用工具
}
};连接超时
MCP SDK 的服务器连接默认超时时间为 60 秒。如果服务器启动耗时较长,连接会失败。针对启动慢的服务器,可考虑:
- 选用更轻量的服务器(如有)
- 在启动 Agent 前预热服务器
- 检查服务器日志,定位初始化慢的原因
相关资源
- 自定义工具指南:构建在 SDK 应用内运行的 MCP 服务器
- 权限:通过
allowedTools和disallowedTools控制 Agent 可用的 MCP 工具 - TypeScript SDK 参考:完整 API 参考,包含 MCP 配置选项
- Python SDK 参考:完整 API 参考,包含 MCP 配置选项
- MCP 服务器目录:浏览可用的 MCP 服务器(数据库、API 等)
常见问题
我配置了 allowedTools 但 Claude 还是不调用 MCP 工具,为什么?
最常见的原因是 allowedTools 中工具名的格式有误。确认格式为 mcp__<服务器名>__<工具名>(两个连续下划线)。如果使用了通配符 *,检查服务器名是否完全匹配。另外,检查 permissionMode 是否被错误设置:permissionMode: "acceptEdits" 不会自动批准 MCP 工具。
MCP 服务器连接失败,如何定位问题?
在 Agent 输出的 system 类型消息(subtype: "init")中查看 mcp_servers 数组,每个服务器都有 status 字段。如果 status 不是 "connected",检查环境变量是否正确传递、服务器程序是否在 PATH 中、URL 是否可达。代码示例见错误处理章节。
如何将本地数据库的密码传给 MCP 服务器?
通过 env 字段传递环境变量,或直接在 args 中嵌入连接字符串(注意安全)。推荐从环境变量读取,例如 TypeScript 中用 env: { PASSWORD: process.env.DB_PASSWORD },Python 中用 env={"PASSWORD": os.environ["DB_PASSWORD"]}。对于 .mcp.json 配置文件,使用 ${DB_PASSWORD} 语法,SDK 会在运行时展开环境变量。