اتصال به ابزارهای بیرونی با MCP
Model Context Protocol (MCP) یک استانداردِ باز برای اتصالِ ایجنتهای AI به ابزارها و منابعِ دادهی بیرونی است. با MCP، ایجنتِ تو میتواند به پایگاههای داده query بزند، با APIهایی مثلِ Slack و GitHub یکپارچه شود، و بدونِ نوشتنِ پیادهسازیِ سفارشیِ ابزار به سرویسهای دیگر متصل شود.
سرورهای MCP میتوانند بهصورتِ فرایندهای محلی اجرا شوند، روی HTTP متصل شوند، یا مستقیماً درونِ برنامهی SDKِ تو اجرا شوند.
شروعِ سریع
Section titled “شروعِ سریع”این مثال با استفاده از HTTP transport به سرورِ MCPِ مستنداتِ Claude Code متصل میشود و با allowedTools و یک wildcard همهی ابزارهای آن سرور را مجاز میکند.
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 asynciofrom 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 اضافه کن
Section titled “یک سرورِ MCP اضافه کن”میتوانی سرورهای MCP را هنگامِ فراخوانیِ query() در کد پیکربندی کنی، یا در یک فایلِ .mcp.json که از طریقِ settingSources بارگذاری میشود.
سرورهای MCP را مستقیماً در گزینهی mcpServers پاس بده:
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 asynciofrom 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())از یک فایلِ پیکربندی
Section titled “از یک فایلِ پیکربندی”یک فایلِ .mcp.json در ریشهی پروژهات بساز. این فایل وقتی برداشته میشود که setting sourceِ project فعال باشد، که برای گزینههای پیشفرضِ query() همینطور است. اگر settingSources را صریحاً تنظیم کنی، برای بارگذاریِ این فایل "project" را بگنجان:
{ "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"] } }}ابزارهای MCP را مجاز کن
Section titled “ابزارهای MCP را مجاز کن”ابزارهای MCP پیش از اینکه Claude بتواند از آنها استفاده کند، به مجوزِ صریح نیاز دارند. بدونِ مجوز، Claude میبیند که ابزارها در دسترساند اما نمیتواند آنها را فراخوانی کند.
قراردادِ نامگذاریِ ابزار
Section titled “قراردادِ نامگذاریِ ابزار”ابزارهای MCP الگوی نامگذاریِ mcp__<server-name>__<tool-name> را دنبال میکنند. برای مثال، یک سرورِ GitHub با نامِ "github" و ابزارِ list_issues به mcp__github__list_issues تبدیل میشود.
تأییدِ خودکار با allowedTools
Section titled “تأییدِ خودکار با 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 ] }};wildcardها (*) به تو امکان میدهند همهی ابزارهای یک سرور را بدونِ فهرستکردنِ تکتکِ آنها مجاز کنی.
ابزارهای در دسترس را کشف کن
Section titled “ابزارهای در دسترس را کشف کن”برای دیدنِ اینکه یک سرورِ MCP چه ابزارهایی ارائه میدهد، مستنداتِ سرور را بررسی کن یا به سرور متصل شو و پیامِ init از نوعِ system را بازرسی کن:
for await (const message of query({ prompt: "...", options })) { if (message.type === "system" && message.subtype === "init") { console.log("Available MCP tools:", message.mcp_servers); }}انواعِ transport
Section titled “انواعِ transport”سرورهای MCP با ایجنتِ تو از طریقِ پروتکلهای transportِ مختلف ارتباط برقرار میکنند. مستنداتِ سرور را بررسی کن تا ببینی کدام transport را پشتیبانی میکند:
- اگر مستندات یک دستور برای اجرا به تو میدهند (مثلِ
npx @modelcontextprotocol/server-github)، از stdio استفاده کن - اگر مستندات یک URL به تو میدهند، از HTTP یا SSE استفاده کن
- اگر داری ابزارهای خودت را در کد میسازی، از یک سرورِ SDK MCP استفاده کن
سرورهای stdio
Section titled “سرورهای 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
Section titled “سرورهای 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}" } } }}برای transportِ streamable HTTP، بهجای آن از "type": "http" استفاده کن. در .mcp.json و دیگر فایلهای پیکربندیِ JSON، مقدارِ "streamable-http" بهعنوانِ نامِ مستعارِ "http" پذیرفته میشود. گزینهی برنامهنویسیِ mcpServers فقط "http" را میپذیرد.
سرورهای SDK MCP
Section titled “سرورهای SDK MCP”ابزارهای سفارشی را بهجای اجرای یک فرایندِ سرورِ جداگانه، مستقیماً در کدِ برنامهات تعریف کن. برای جزئیاتِ پیادهسازی به راهنمای ابزارهای سفارشی نگاه کن.
جستوجوی ابزارِ MCP
Section titled “جستوجوی ابزارِ MCP”وقتی ابزارهای MCPِ زیادی پیکربندی کردهای، تعاریفِ ابزار میتوانند بخشِ قابلِتوجهی از پنجرهی کانتکستت را مصرف کنند. جستوجوی ابزار این را با نگهداشتنِ تعاریفِ ابزار بیرونِ کانتکست و بارگذاریِ فقط آنهایی که Claude در هر نوبت لازم دارد حل میکند.
جستوجوی ابزار بهصورتِ پیشفرض فعال است. برای گزینههای پیکربندی و جزئیات به Tool search نگاه کن.
برای جزئیاتِ بیشتر، از جمله بهترین شیوهها و استفاده از جستوجوی ابزار با ابزارهای سفارشیِ SDK، به راهنمای جستوجوی ابزار نگاه کن.
احراز هویت
Section titled “احراز هویت”بیشترِ سرورهای MCP برای دسترسی به سرویسهای بیرونی به احراز هویت نیاز دارند. اعتبارنامهها را از طریقِ متغیرهای محیطی در پیکربندیِ سرور پاس بده.
پاسدادنِ اعتبارنامهها از طریقِ متغیرهای محیطی
Section titled “پاسدادنِ اعتبارنامهها از طریقِ متغیرهای محیطی”از فیلدِ 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} متغیرهای محیطی را در زمانِ اجرا گسترش میدهد.
برای یک مثالِ کاملِ کارا با لاگگیریِ debug به فهرستکردنِ issueها از یک مخزن نگاه کن.
هدرهای HTTP برای سرورهای راهدور
Section titled “هدرهای 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
Section titled “احراز هویتِ OAuth2”مشخصاتِ MCP از OAuth 2.1 پشتیبانی میکند برای authorization. SDK جریانهای OAuth را خودکار مدیریت نمیکند، اما میتوانی بعد از تکمیلِ جریانِ OAuth در برنامهات، توکنهای دسترسی را از طریقِ هدرها پاس بدهی:
// After completing OAuth flow in your appconst 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 appaccess_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__*"],)مثالها
Section titled “مثالها”فهرستکردنِ issueها از یک مخزن
Section titled “فهرستکردنِ issueها از یک مخزن”این مثال به سرورِ MCPِ GitHub متصل میشود تا issueهای اخیر را فهرست کند. مثال شاملِ لاگگیریِ debug است تا اتصالِ MCP و فراخوانیهای ابزار را تأیید کند.
پیش از اجرا، یک personal access tokenِ GitHub با scopeِ repo بساز و آن را بهعنوانِ متغیرِ محیطی تنظیم کن:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxximport { 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 asyncioimport osfrom 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())query زدن به یک پایگاه داده
Section titled “query زدن به یک پایگاه داده”این مثال از سرورِ MCPِ Postgres برای query زدن به یک پایگاه داده استفاده میکند. رشتهی اتصال بهعنوانِ یک آرگومان به سرور پاس داده میشود. ایجنت خودکار schemaِ پایگاه داده را کشف میکند، queryی SQL را مینویسد و نتایج را برمیگرداند:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Connection string from environment variableconst 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 asyncioimport osfrom 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())مدیریتِ خطا
Section titled “مدیریتِ خطا”سرورهای MCP میتوانند به دلایلِ گوناگون در اتصال شکست بخورند: ممکن است فرایندِ سرور نصب نشده باشد، اعتبارنامهها نامعتبر باشند، یا یک سرورِ راهدور در دسترس نباشد.
SDK در آغازِ هر query یک پیامِ system با subtypeِ 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 asynciofrom 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())عیبیابی
Section titled “عیبیابی”سرور وضعیتِ “failed” نشان میدهد
Section titled “سرور وضعیتِ “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`); } }}علتهای رایج:
- متغیرهای محیطیِ گمشده: مطمئن شو توکنها و اعتبارنامههای لازم تنظیم شدهاند. برای سرورهای stdio، بررسی کن فیلدِ
envبا آنچه سرور انتظار دارد مطابقت دارد. - سرور نصبنشده: برای دستورهای
npx، تأیید کن پکیج وجود دارد و Node.js در PATHِ توست. - رشتهی اتصالِ نامعتبر: برای سرورهای پایگاه داده، قالبِ رشتهی اتصال و دسترسپذیریِ پایگاه داده را تأیید کن.
- مشکلاتِ شبکه: برای سرورهای راهدورِ HTTP/SSE، بررسی کن URL در دسترس است و فایروالها اتصال را مجاز میکنند.
ابزارها فراخوانی نمیشوند
Section titled “ابزارها فراخوانی نمیشوند”اگر Claude ابزارها را میبیند اما از آنها استفاده نمیکند، بررسی کن که با allowedTools مجوز دادهای:
const _ = { options: { mcpServers: { // your servers }, allowedTools: ["mcp__servername__*"] // Auto-approve calls from this server }};timeoutهای اتصال
Section titled “timeoutهای اتصال”MCP SDK یک timeoutِ پیشفرضِ ۶۰ ثانیهای برای اتصالِ سرورها دارد. اگر سرورت برای شروع بیشتر طول بکشد، اتصال شکست میخورد. برای سرورهایی که به زمانِ راهاندازیِ بیشتری نیاز دارند، اینها را در نظر بگیر:
- استفاده از یک سرورِ سبکتر اگر در دسترس است
- گرمکردنِ سرور پیش از شروعِ ایجنتت
- بررسیِ لاگهای سرور برای علتهای راهاندازیِ کند
منابعِ مرتبط
Section titled “منابعِ مرتبط”- راهنمای ابزارهای سفارشی: سرورِ MCPِ خودت را بساز که درونفرایندی با برنامهی SDKِ تو اجرا میشود
- Permissions: با
allowedToolsوdisallowedToolsکنترل کن ایجنتت کدام ابزارهای MCP را میتواند به کار ببرد - مرجعِ TypeScript SDK: مرجعِ کاملِ API شاملِ گزینههای پیکربندیِ MCP
- مرجعِ Python SDK: مرجعِ کاملِ API شاملِ گزینههای پیکربندیِ MCP
- دایرکتوریِ سرورهای MCP: سرورهای MCPِ در دسترس برای پایگاههای داده، APIها و بیشتر را مرور کن