使用 MCP 連接外部工具
配置 MCP 伺服器以擴展您的代理程式的外部工具。涵蓋傳輸類型、大型工具集的工具搜尋、身份驗證和錯誤處理。
Model Context Protocol (MCP) 是一個開放標準,用於將 AI 代理程式連接到外部工具和資料來源。使用 MCP,您的代理程式可以查詢資料庫、與 Slack 和 GitHub 等 API 整合,以及連接到其他服務,而無需編寫自訂工具實現。
MCP 伺服器可以作為本地進程運行、通過 HTTP 連接或直接在您的 SDK 應用程式中執行。
本頁涵蓋 Agent SDK 的 MCP 配置。若要將 MCP 伺服器添加到 Claude Code CLI 以便在每個項目中加載,請參閱 MCP 安裝範圍。
快速開始
此示例使用 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);
}
}
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())
代理程式連接到文檔伺服器,搜尋有關 hooks 的信息,並返回結果。
添加 MCP 伺服器
您可以在調用 query() 時在代碼中配置 MCP 伺服器,或在通過 settingSources 加載的 .mcp.json 文件中配置。
在代碼中
在 mcpServers 選項中直接傳遞 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);
}
}
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 文件。當啟用 project 設置源時,該文件會被選取,這對於默認 query() 選項是默認的。如果您明確設置 settingSources,請包含 "project" 以便加載此文件:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}
允許 MCP 工具
MCP 工具需要明確的權限才能讓 Claude 使用它們。沒有權限,Claude 會看到工具可用,但無法調用它們。
工具命名約定
MCP 工具遵循命名模式 mcp__<server-name>__<tool-name>。例如,名為 "github" 的 GitHub 伺服器,其 list_issues 工具變為 mcp__github__list_issues。
使用 allowedTools 授予訪問權限
使用 allowedTools 指定 Claude 可以使用哪些 MCP 工具:
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 訪問,優先使用 allowedTools 而不是權限模式。 permissionMode: "acceptEdits" 不會自動批准 MCP 工具(僅限文件編輯和文件系統 Bash 命令)。permissionMode: "bypassPermissions" 會自動批准 MCP 工具,但也會禁用所有其他安全提示,這比必要的範圍更廣。allowedTools 中的通配符只授予您想要的 MCP 伺服器,沒有其他。有關完整比較,請參閱權限模式。
發現可用工具
要查看 MCP 伺服器提供的工具,請檢查伺服器的文檔或連接到伺服器並檢查 system init 消息:
for await (const message of query({ prompt: "...", options })) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available MCP tools:", message.mcp_servers);
}
}
傳輸類型
MCP 伺服器使用不同的傳輸協議與您的代理程式通信。檢查伺服器的文檔以查看它支持哪種傳輸:
- 如果文檔給您一個要運行的命令(如
npx @modelcontextprotocol/server-github),請使用 stdio - 如果文檔給您一個 URL,請使用 HTTP 或 SSE
- 如果您在代碼中構建自己的工具,請使用 SDK MCP 伺服器
stdio 伺服器
通過 stdin/stdout 通信的本地進程。對於在同一台機器上運行的 MCP 伺服器,請使用此方法:
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"]
}
};
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"],
)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
HTTP/SSE 伺服器
對於雲託管的 MCP 伺服器和遠程 API,請使用 HTTP 或 SSE:
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__*"]
}
};
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__*"],
)
{
"mcpServers": {
"remote-api": {
"type": "sse",
"url": "https://api.example.com/mcp/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
對於 HTTP(非流式),請改用 "type": "http"。
SDK MCP 伺服器
直接在應用程式代碼中定義自訂工具,而不是運行單獨的伺服器進程。有關實現詳情,請參閱自訂工具指南。
MCP 工具搜尋
當您配置了許多 MCP 工具時,工具定義可能會消耗上下文窗口的很大一部分。工具搜尋通過從上下文中隱藏工具定義並僅加載 Claude 每次轉換所需的工具來解決此問題。
工具搜尋默認啟用。有關配置選項和詳情,請參閱工具搜尋。
有關更多詳情,包括最佳實踐和將工具搜尋與自訂 SDK 工具一起使用,請參閱工具搜尋指南。
身份驗證
大多數 MCP 伺服器需要身份驗證才能訪問外部服務。通過伺服器配置中的環境變數傳遞憑據。
通過環境變數傳遞憑據
使用 env 字段將 API 密鑰、令牌和其他憑據傳遞給 MCP 伺服器:
const _ = {
options: {
mcpServers: {
github: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN
}
}
},
allowedTools: ["mcp__github__list_issues"]
}
};
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"],
)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
${GITHUB_TOKEN} 語法在運行時展開環境變數。
有關帶有調試日誌的完整工作示例,請參閱從存儲庫列出問題。
遠程伺服器的 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__*"]
}
};
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__*"],
)
{
"mcpServers": {
"secure-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
${API_TOKEN} 語法在運行時展開環境變數。
OAuth2 身份驗證
MCP 規範支持 OAuth 2.1 用於授權。SDK 不會自動處理 OAuth 流程,但您可以在應用程式中完成 OAuth 流程後通過標頭傳遞訪問令牌:
// After completing OAuth flow in your app
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__*"]
};
# After completing OAuth flow in your app
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__*"],
)
示例
從存儲庫列出問題
此示例連接到 GitHub MCP 伺服器 以列出最近的問題。該示例包括調試日誌以驗證 MCP 連接和工具調用。
運行前,創建一個具有 repo 範圍的 GitHub 個人訪問令牌,並將其設置為環境變數:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
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"]
}
})) {
// 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);
}
}
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,
):
# Verify MCP server connected successfully
if isinstance(message, SystemMessage) and message.subtype == "init":
print("MCP servers:", message.data.get("mcp_servers"))
# Log when Claude calls an MCP tool
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "name") and block.name.startswith("mcp__"):
print("MCP tool called:", block.name)
# Print the final result
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())
查詢資料庫
此示例使用 Postgres MCP 伺服器 查詢資料庫。連接字符串作為參數傳遞給伺服器。代理程式自動發現資料庫架構、編寫 SQL 查詢並返回結果:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Connection string from environment variable
const connectionString = process.env.DATABASE_URL;
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",
// Pass connection string as argument to the server
args: ["-y", "@modelcontextprotocol/server-postgres", connectionString]
}
},
// Allow only read queries, not writes
allowedTools: ["mcp__postgres__query"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
import asyncio
import os
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
# Connection string from environment variable
connection_string = os.environ["DATABASE_URL"]
options = ClaudeAgentOptions(
mcp_servers={
"postgres": {
"command": "npx",
# Pass connection string as argument to the server
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
connection_string,
],
}
},
# Allow only read queries, not writes
allowed_tools=["mcp__postgres__query"],
)
# Natural language query - Claude writes the 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 在每個查詢開始時發出一個 system 消息,子類型為 init。此消息包括每個 MCP 伺服器的連接狀態。檢查 status 字段以在代理程式開始工作前檢測連接失敗:
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");
}
}
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())
故障排除
伺服器顯示"失敗"狀態
檢查 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`);
}
}
}
常見原因:
- 缺少環境變數:確保設置了所需的令牌和憑據。對於 stdio 伺服器,檢查
env字段是否與伺服器期望的相匹配。 - 伺服器未安裝:對於
npx命令,驗證包存在且 Node.js 在您的 PATH 中。 - 無效的連接字符串:對於資料庫伺服器,驗證連接字符串格式以及資料庫是否可訪問。
- 網絡問題:對於遠程 HTTP/SSE 伺服器,檢查 URL 是否可訪問以及任何防火牆是否允許連接。
工具未被調用
如果 Claude 看到工具但不使用它們,請檢查您是否已使用 allowedTools 授予權限:
const _ = {
options: {
mcpServers: {
// your servers
},
allowedTools: ["mcp__servername__*"] // Required for Claude to use the tools
}
};
連接超時
MCP SDK 對伺服器連接的默認超時為 60 秒。如果您的伺服器需要更長時間才能啟動,連接將失敗。對於需要更多啟動時間的伺服器,請考慮:
- 使用更輕量級的伺服器(如果可用)
- 在啟動代理程式前預熱伺服器
- 檢查伺服器日誌以查找緩慢初始化的原因
相關資源
- 自訂工具指南:構建您自己的 MCP 伺服器,與您的 SDK 應用程式在進程中運行
- 權限:使用
allowedTools和disallowedTools控制您的代理程式可以使用哪些 MCP 工具 - TypeScript SDK 參考:完整的 API 參考,包括 MCP 配置選項
- Python SDK 參考:完整的 API 參考,包括 MCP 配置選項
- MCP 伺服器目錄:瀏覽可用的 MCP 伺服器,用於資料庫、API 等