תיעוד 179
חיבור לכלים חיצוניים עם MCP
הגדירו שרתי MCP כדי להרחיב את הסוכן עם כלים חיצוניים. העמוד מכסה סוגי תעבורה, חיפוש כלים עבור קבוצות כלים גדולות, אימות וטיפול בשגיאות.
Model Context Protocol (MCP) הוא תקן פתוח לחיבור סוכני AI לכלים ולמקורות נתונים חיצוניים. עם MCP, הסוכן יכול לשאול מסדי נתונים, להשתלב עם ממשקי API כמו Slack ו GitHub, ולהתחבר לשירותים אחרים בלי לכתוב מימושי כלים מותאמים אישית.
שרתי MCP יכולים לרוץ כתהליכים מקומיים, להתחבר דרך HTTP, או לרוץ ישירות בתוך יישום ה SDK.
[!NOTE]
עמוד זה מכסה הגדרת MCP עבור Agent SDK. כדי להוסיף שרתי MCP ל CLI של Claude Code כך שייטענו בכל פרויקט, ראו היקפי התקנת MCP.
#התחלה מהירה
דוגמה זו מתחברת לשרת MCP של התיעוד של Claude Code באמצעות תעבורת HTTP ומשתמשת ב 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
אפשר להגדיר שרתי MCP בקוד בעת הקריאה ל query(), או בקובץ .mcp.json שנטען דרך settingSources.
#הוספת שרת בקוד
העבירו שרתי MCP ישירות באפשרות mcpServers. דוגמה זו מפעילה שרת MCP מקומי של מערכת קבצים עבור /Users/me/projects. החליפו נתיב זה בתיקייה במחשב שלכם:
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" כדי שקובץ זה ייטען. החליפו את /Users/me/projects בתיקייה במחשב שלכם:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}#תזמון החיבור
Claude Code מתחיל לחבר את שרתי ה MCP כאשר ההפעלה מתחילה, ושולח את הודעת init ברגע שהמתנת התור הראשון, אם יש כזו, מסתיימת. משך ההמתנה של התור הראשון לשרת תלוי במקום שבו הגדרתם אותו. אם הגדרתם את permissionPromptToolName, התור הראשון תמיד ממתין לשרת של הכלי הזה, עד MCP_TIMEOUT, בכל מקום שבו הגדרתם אותו.
עבור שרת ב options.mcpServers, מצאו את הסוג שלו בעמודה הראשונה כדי לראות כמה זמן התור הראשון ממתין לו.
| סוג שרת | מעכב את התור הראשון? | פסק זמן של המתנת התור הראשון |
|---|---|---|
| שרת stdio, או שרת HTTP/SSE בלי רשימת כלים במטמון | כן, עד שהוא מתחבר | MCP_TIMEOUT, 30 שניות כברירת מחדל. החיבור נכשל במועד הזה |
| שרת מרוחק עם רשימת כלים במטמון, שנשמרה על ידי Claude Code מחיבור קודם | לא. הכלים שבמטמון זמינים מהתור הראשון | אין. מתחבר בקריאת הכלי הראשונה שלו, ולחיבור הדחוי הזה יש פסק זמן משלו |
| שרת SDK בתוך התהליך | כן, עד שהוא מתחבר ומפרט את הכלים שלו | MCP_TIMEOUT, 30 שניות כברירת מחדל, לכל ניסיון חיבור. החיבור נכשל במועד הזה |
לשרת יש רשימת כלים במטמון רק כאשר מטמון הגילוי של MCP פועל.
שרתים מקבצי הגדרות כגון .mcp.json, או מתוספים, עדיין מציגים לעתים קרובות pending בהודעת init. משך ההמתנה של התור הראשון עבורם תלוי ב options.mcpServers ובחיפוש כלים:
options.mcpServersכולל שרת stdio, HTTP או SSE: התור הראשון ממתין גם לשרתים הממתינים מקובץ ההגדרות ומתוספים, עדMCP_TIMEOUT.- אחרת, כאשר
ANTHROPIC_BASE_URLמצביע אל gateway וENABLE_TOOL_SEARCHלא מוגדר: התור הראשון ממתין עד 2 שניות לכל שרת ממתין מקובץ ההגדרות ומתוספים. - אחרת, כאשר חיפוש כלים פועל, וזה ברירת המחדל: התור הראשון ממתין עד 2 שניות, ורק עבור שרתים ממתינים שהגדירו
alwaysLoad: trueאו שנתתם להם שם. השאר ממשיכים להתחבר ברקע, ו Claude מגיע לכלים שלהם ברגע שהם מתחברים. - אחרת, כאשר חיפוש כלים כבוי: התור הראשון ממתין עד 2 שניות לכל שרת ממתין מקובץ ההגדרות ומתוספים. חיפוש כלים כבוי כאשר ערך
ENABLE_TOOL_SEARCHאו המודל מכבים אותו, או כאשר אתם מדירים את הכליToolSearch, למשל דרךdisallowedTools.
#שרתים עם שם
נותנים שם לשרת על ידי ציון של אחד מהכלים שלו, כגון mcp__github__list_issues או mcp__github__*, ב allowedTools או בכלל permissions.allow באפשרות settings. גם hook מסוג mcp_tool נותן שם לשרת שהוא קורא לו כאשר מגדירים אותו על אירוע של שליחת prompt, שימוש בכלי, הרשאה, subagent, משימה, elicitation או worktree. לפני v2.1.284, מתן שם לשרת לא השפיע על המתנת התור הראשון.
#קביעת המתנת התור הראשון בעצמכם
כדי לבחור בעצמכם את המתנת התור הראשון, הגדירו את CLAUDE_CODE_MCP_STARTUP_WAIT_MS באפשרות env, למשל CLAUDE_CODE_MCP_STARTUP_WAIT_MS: "5000". התור הראשון ממתין אז עד למספר הזה של אלפיות שנייה עבור שרתים ממתינים מקובץ ההגדרות ומתוספים, בין שחיפוש כלים פועל ובין שלא. אותה מגבלה מחליפה את המתנת MCP_TIMEOUT עבור שרתי stdio, HTTP ו SSE ב options.mcpServers.
שלוש המתנות חלות בכל ערך שתגדירו, כולל 0:
- שרת
permissionPromptToolName: עדMCP_TIMEOUT. - שרת SDK בתוך התהליך: עד
MCP_TIMEOUTלכל ניסיון חיבור. - שרת עם שם שעדיין מתחבר: לפחות עד 2 שניות, כך שערך מתחת ל
2000לא מקצר את ההמתנה שלו.
הגדירו את המשתנה ל 0 כדי לדלג על ההמתנה עבור כל שרת אחר. שרתים שעדיין ממתינים כאשר ההמתנה מסתיימת ממשיכים להתחבר ברקע. CLAUDE_CODE_MCP_STARTUP_WAIT_MS דורש Claude Code v2.1.274 או חדש יותר.
#גרימת ההפעלה להמתין לשרתים
שתי הגדרות גורמות להפעלה עצמה להמתין, לפני ש Claude Code שולח את הודעת init:
MCP_CONNECTION_NONBLOCKINGמוגדר ל0: ההפעלה ממתינה לכל אצוות החיבור, עד 5 שניות כברירת מחדל. הגדירו אתMCP_CONNECT_TIMEOUT_MS, באלפיות שנייה, כדי לשנות את התקרה הזו. שרתים שעדיין ממתינים בתקרה ממשיכים להתחבר ברקע.alwaysLoad: trueבהגדרת שרת: ההפעלה ממתינה עד אותה תקרה לכלים של השרת הזה, כך שהתור הראשון מקבל אותם בסכמה מלאה, בפטור מדחיית חיפוש כלים. שרת מרוחק עם רשימת כלים במטמון מספק אותם בלי להתחבר ובלי לעכב את ההפעלה.
הודעת init מדווחת על הסטטוס של כל שרת נכון לרגע שבו Claude Code שולח אותה.
#אישור כלי MCP
כלי MCP דורשים הרשאה מפורשת לפני ש Claude יכול להשתמש בהם. בלי הרשאה, Claude יראה שהכלים זמינים אבל לא יוכל לקרוא להם.
#מוסכמת שמות לכלים
כלי MCP נקראים mcp__<server-name>__<tool-name>, כאשר <server-name> הוא השם שבו רושמים את השרת, כגון המפתח שלו ב mcpServers.
תווים בשם השרת כגון . ורווחים מוחלפים ב _. טבלה זו מציגה את השם המלא של כלי list_issues עבור שני מפתחות שרת:
מפתח ב mcpServers | שם הכלי המלא |
|---|---|
github | mcp__github__list_issues |
my.server | mcp__my_server__list_issues |
השתמשו בשמות הכלים המלאים ב allowedTools ובכללי הרשאות MCP. עבור שרת שתוסף מספק, <server-name> מקבל את הצורה בהיקף התוסף ומתחיל ב plugin_.
#אישור אוטומטי עם 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
]
}
};options = ClaudeAgentOptions(
mcp_servers={
# your servers
},
allowed_tools=[
"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
],
)תווים כלליים (*) מאפשרים לאשר את כל הכלים משרת בלי לפרט כל אחד בנפרד.
[!NOTE]
העדיפו את
allowedToolsעל פני מצבי הרשאה לגישת MCP.permissionMode: "acceptEdits"לא מאשר אוטומטית כלי MCP (רק עריכות קבצים ופקודות Bash של מערכת הקבצים).permissionMode: "bypassPermissions"כן מאשר אוטומטית כלי MCP, אבל גם משבית את רוב בקשות הבטיחות האחרות, וזה רחב מהנדרש. ראו איך הרשאות מוערכות עבור הבקשות שנשארות. תו כללי בallowedToolsמעניק בדיוק את שרת ה MCP שאתם רוצים ותו לא. ראו מצבי הרשאה להשוואה מלאה.
#גילוי הכלים הזמינים
כדי לראות אילו כלים שרת MCP מספק, בדקו את התיעוד של השרת או עיינו במערך tools בהודעת init מסוג system. שמות כלי MCP מתחילים ב mcp__.
Claude Code פולט את הודעת init אחרי המתנת החיבור של התור הראשון עבור שרתים שהועברו ב options.mcpServers, כך שמערך 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);
}
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
# your servers
},
)
async for message in query(prompt="...", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
mcp_tools = [t for t in message.data.get("tools", []) if t.startswith("mcp__")]
print("Available MCP tools:", mcp_tools)
asyncio.run(main())אפשר גם לבקש מ Claude לפרט את הכלים הזמינים משרת.
#סוגי תעבורה
שרתי MCP מתקשרים עם הסוכן באמצעות פרוטוקולי תעבורה שונים. בדקו את התיעוד של השרת כדי לראות איזו תעבורה הוא תומך בה:
- אם התיעוד נותן פקודה להרצה (כמו
npx @modelcontextprotocol/server-filesystem), השתמשו ב stdio - אם התיעוד נותן URL, השתמשו ב HTTP או ב SSE
- אם אתם בונים כלים משלכם בקוד, השתמשו בשרת MCP של ה SDK
#שרתי stdio
תהליכים מקומיים שמתקשרים דרך stdin/stdout. השתמשו בזה עבור שרתי MCP שאתם מריצים על אותו מחשב. עבור הצורה של .mcp.json, השתמשו באותם שדות שמוצגים בהוספת שרת מקובץ הגדרות. בקוד, העבירו את הפקודה ואת הארגומנטים שלה. החליפו את /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"]
}
};options = ClaudeAgentOptions(
mcp_servers={
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/me/projects",
],
}
},
allowed_tools=["mcp__filesystem__read_file", "mcp__filesystem__list_directory"],
)#שרתי HTTP/SSE
השתמשו ב HTTP או ב SSE עבור שרתי MCP שמתארחים בענן וממשקי API מרוחקים. עבור הצורה של .mcp.json, השתמשו באותם שדות כמו בדוגמה בכותרות HTTP לשרתים מרוחקים, עם "type": "sse" עבור שרת 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__*"]
}
};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__*"],
)עבור תעבורת streamable HTTP, השתמשו ב "type": "http" במקום. ב .mcp.json ובקבצי הגדרה אחרים ב JSON, "streamable-http" מתקבל ככינוי עבור "http". הטיפוס McpHttpServerConfig של ה SDK מצהיר רק על "http", לכן השתמשו ב "http" עבור שרתים שאתם מעבירים בקוד.
#שרתי MCP של ה SDK
הגדירו כלים מותאמים ישירות בקוד היישום במקום להריץ תהליך שרת נפרד. ראו את מדריך הכלים המותאמים לפרטי המימוש.
שרת MCP של ה SDK שנרשם באמצעות בקשת בקרה initialize מתחיל להתחבר ברגע ש Claude Code מעבד את הבקשה.
#חיפוש כלי MCP
כשיש הרבה כלי MCP מוגדרים, הגדרות הכלים יכולות לתפוס חלק משמעותי מחלון ההקשר. חיפוש כלים פותר את זה על ידי מניעת הגדרות הכלים מההקשר וטעינה רק של אלה שקלוד צריך בכל תור.
חיפוש כלים מופעל כברירת מחדל. ראה Tool search לאפשרויות הגדרה, שיטות עבודה מומלצות ושימוש בחיפוש כלים עם כלי 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__*"]
}
};options = ClaudeAgentOptions(
mcp_servers={
"api-server": {
"command": "npx",
"args": ["-y", "@your-org/api-mcp-server"],
"env": {"API_KEY": os.environ["API_KEY"]},
}
},
allowed_tools=["mcp__api-server__*"],
).mcp.json:
{
"mcpServers": {
"api-server": {
"command": "npx",
"args": ["-y", "@your-org/api-mcp-server"],
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}התחביר ${API_KEY} מרחיב משתני סביבה בזמן ריצה.
#כותרות 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__*"],
).mcp.json:
{
"mcpServers": {
"secure-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}התחביר ${API_TOKEN} מרחיב משתני סביבה בזמן ריצה.
לדוגמה עובדת מלאה של שרת מרוחק שמאומת עם כותרות, ראה רשימת issues ממאגר.
#אימות OAuth2
מפרט MCP תומך ב-OAuth 2.1 להרשאה. ה-SDK לא פותח דפדפן ולא מריץ זרימת OAuth אינטראקטיבית. כששרת מוגדר מחזיר אתגר הרשאה ול-Claude Code אין אסימון לשלוח, ה-SDK מדווח על השרת כ-needs-auth או failed:
needs-auth: Claude Code לא מצא התחברות שאפשר להשתמש בה לשרת. העבר אסימון ב-headers, או התחבר מתוך הפעלת Claude Code אינטראקטיבית באותה מכונה לפני ההרצה.failed, עםerrorברשומתMcpServerStatusשמתחיל ב-Couldn't read the stored credentialsאוA request to MCP server: Claude Code לא הצליח לקרוא את מאגר פרטי הגישה שלו. למה לעשות, ראה Couldn't read the stored credentials for MCP server. לפני Claude Code v2.1.307, הסטטוס היהneeds-authבמקום זאת כשמחזיק המפתחות של ההתחברות ב-Mac היה נעול.
בכל אחד מהמקרים, הרצת הסוכן ממשיכה בלי הכלים של השרת הזה. המערך mcp_servers של הודעת init של המערכת עדיין יכול להציג pending לשרת הזה כשהיא נפלטת. כדי לאשר אם שרת צריך פרטי גישה, בדוק ב-mcpServerStatus() ב-SDK של TypeScript או ב-get_mcp_status() ב-Python.
כדי לספק פרטי גישה, השלם את זרימת 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__*"]
};# After completing OAuth flow in your app.
# Implement get_access_token_from_oauth_flow for your OAuth provider.
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__*"],
)#דוגמאות
#רשימת issues ממאגר
הדוגמה הזו מתחברת ל-שרת GitHub MCP המרוחק כדי לרשום issues אחרונים. הדוגמה כוללת רישום דיבוג כדי לאמת את חיבור MCP ואת קריאות הכלים.
לפני ההרצה, צור אסימון גישה אישי של GitHub עם גישת קריאה למאגרים שאתה רוצה לשאול עליהם, והגדר אותו כמשתנה סביבה:
export GITHUB_TOKEN=YOUR_GITHUB_PATimport { 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);
}
}import asyncio
import os
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
ResultMessage,
SystemMessage,
AssistantMessage,
)
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {"Authorization": f"Bearer {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())בשורה MCP servers:, status של connected עבור github מאשר שהאסימון עובד. אם ל-Claude Code יש רשימת כלים במטמון לשרת, הסטטוס יכול להיקרא pending במקום, והשרת מתחבר בקריאת הכלי הראשונה שלו. אם הסטטוס הוא failed או needs-auth, ראה טיפול בשגיאות לפני שמסתמכים על התוצאה, כי קלוד יכול לחזור לכלי מובנים כשהשרת לא זמין.
#שאילתה למסד נתונים
הדוגמה הזו משתמשת ב-DBHub כדי לשאול מסד נתונים Postgres. הסוכן מגלה אוטומטית את סכמת מסד הנתונים, כותב את שאילתת ה-SQL ומחזיר את התוצאות.
הכלי execute_sql של DBHub מריץ כל SQL שהסוכן פולט, כולל כתיבות, אלא אם מגבילים אותו. הגדרת readonly = true ב-קובץ ההגדרות של DBHub גורמת ל-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/mydbimport { 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);
}
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"postgres": {
"command": "npx",
# dbhub.toml sets readonly = true, so execute_sql rejects writes
"args": [
"-y",
"@bytebase/dbhub",
"--config",
"dbhub.toml",
],
}
},
allowed_tools=["mcp__postgres__execute_sql"],
)
# 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 יכולים להיכשל בחיבור מסיבות שונות: תהליך השרת אולי לא מותקן, פרטי הגישה אולי לא תקינים, או שרת מרוחק אולי לא ניתן להשגה.
Claude Code פולט הודעת system עם subtype init בתחילת כל שאילתה. ההודעה הזו כוללת את סטטוס החיבור של כל שרת MCP. השדה status יכול להיות "pending", "connected", "failed", "needs-auth" או "disabled". Claude Code פולט את הודעת init אחרי ההמתנה לחיבור בתור הראשון לשרתים שהועברו ב-options.mcpServers, כך ששרת כזה שהתחבר בתוך ההמתנה מציג "connected".
בהודעת init, אל תתייחס ל-"pending" ככישלון בפני עצמו. זה יכול להיות כל אחד מאלה:
- השרת עדיין לא התחבר. ראה כמה זמן Claude Code מחכה לו לפני התור הראשון
- רשימת הכלים של השרת הוגשה מהמטמון, עם חיבור שנעשה בשימוש הראשון
- תם מועד החיבור. שרת כזה מדווח
"pending"או"failed"לפי התזמון
בדוק "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}`);
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage, ResultMessage
async def main():
# Replace data_server with your server configuration
options = ClaudeAgentOptions(mcp_servers={"data-processor": data_server})
try:
async for message in query(prompt="Process data", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
unavailable_servers = [
s
for s in message.data.get("mcp_servers", [])
if s.get("status") in ("failed", "needs-auth")
]
if unavailable_servers:
print(f"Unavailable MCP servers: {unavailable_servers}")
if (
isinstance(message, ResultMessage)
and message.subtype == "error_during_execution"
):
print("Execution failed")
except Exception as error:
# A single-shot query() raises 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
# raise: use the status check above, and note that servers still
# "pending" at init need a later status check.
print(f"Session ended with an error: {error}")
asyncio.run(main())הסטטוס של שרת מרוחק יכול להשתנות גם אחרי שהוא מדווח "connected". כשהחיבור אליו נופל באמצע ההפעלה, Claude Code מחזיר את השרת ל-"pending" בזמן התחברות מחדש. קריאה מאוחרת יותר ל-mcpServerStatus() ב-TypeScript, או ל-ClaudeSDKClient.get_mcp_status() ב-Python, יכולה אז לדווח "pending" לשרת שראית מחובר קודם, בלי שינוי הגדרה מצדך.
אחרי שחמישה ניסיונות התחברות מחדש נכשלים, השרת מדווח "failed", או "needs-auth" כשהוא צריך הרשאה מחדש. שרת HTTP או SSE ב-"failed" עדיין יכול לחזור ל-"connected" בלי קריאה ממך, כי Claude Code ממשיך לנסות שוב ברקע אחרי שגיאה חולפת. כדי לנסות שוב ידנית, קרא ל-reconnectMcpServer() ב-TypeScript או ל-ClaudeSDKClient.reconnect_mcp_server() ב-Python.
#פתרון בעיות
#השרת מציג סטטוס "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`);
}
}
}if isinstance(message, SystemMessage) and message.subtype == "init":
for server in message.data.get("mcp_servers", []):
if server.get("status") == "failed":
print(f"Server {server['name']} failed to connect")סטטוס "pending" לא אומר שהשרת נכשל. ראו טיפול בשגיאות למקרים שהוא מכסה בזמן init. כדי לקבל סטטוסים מעודכנים בהמשך הסשן, קראו למתודה mcpServerStatus() של השאילתה ב-TypeScript SDK, או ל-ClaudeSDKClient.get_mcp_status() ב-Python.
סיבות נפוצות:
- משתני סביבה חסרים: ודאו שהאסימונים והאישורים הנדרשים מוגדרים. עבור שרתי stdio, בדקו ששדה
envתואם למה שהשרת מצפה לו. - השרת לא מותקן: עבור פקודות
npx, ודאו שהחבילה קיימת וש-Node.js נמצא ב-PATH. - מחרוזת חיבור לא תקינה: עבור שרתי מסד נתונים, ודאו את פורמט מחרוזת החיבור ושהמסד נתונים נגיש.
- בעיות רשת: עבור שרתי HTTP/SSE מרוחקים, בדקו שה-URL נגיש ושחומות אש מאפשרות את החיבור.
#כלים לא נקראים
אם קלוד רואה כלים אבל לא משתמש בהם, בדקו שהענקתם הרשאה עם allowedTools:
const _ = {
options: {
mcpServers: {
// your servers
},
allowedTools: ["mcp__servername__*"] // Auto-approve calls from this server
}
};options = ClaudeAgentOptions(
mcp_servers={
# your servers
},
allowed_tools=["mcp__servername__*"], # Auto-approve calls from this server
)#כלי חסר משרת MCP של ה-SDK
ב-TypeScript SDK, כשלא ניתן להמיר את סכמת הקלט של כלי ל-JSON Schema, השרת שיצרתם עם createSdkMcpServer() משמיט את הכלי הזה כשהוא מציג את רשימת הכלים שלו. ה-SDK פולט אזהרה בנקודה הזו. תחת Node.js האזהרה היא אזהרת תהליך עם הקוד CLAUDE_SDK_MCP_TOOL_SCHEMA_UNCONVERTIBLE, והיא מתחילה בטקסט הזה:
Tool "<name>" on SDK MCP server "<server>" was left out of the server's tool list, because its input schema cannot be converted to JSON Schemaשאר האזהרה מביא את הודעת שגיאת ההמרה כשיש כזו, ואז אומר מה לבדוק ולשנות.
לפני TypeScript Agent SDK v0.3.286, סכמה אחת שלא ניתן להמיר גרמה לכישלון של כל רשימת הכלים של השרת בלי האזהרה הזו, כך שאף אחד מהכלים של השרת הזה לא הגיע לקלוד.
#פסקי זמן של חיבור
חיבורי שרת MCP פוקעים אחרי 30 שניות כברירת מחדל. כדי לשנות כמה זמן קריאה לכלי שרץ רשאית להימשך, הגדירו את MCP_TOOL_TIMEOUT. אם השרת שלכם לוקח יותר זמן להתחיל, החיבור נכשל. העלו את מגבלת החיבור עם משתנה הסביבה MCP_TIMEOUT, באלפיות שנייה. עבור שרתים שצריכים יותר זמן אתחול, שקלו גם:
- להשתמש בשרת קל יותר אם יש כזה
- לחמם מראש את השרת לפני הפעלת הסוכן
- לבדוק לוגים של השרת כדי למצוא סיבות לאתחול איטי
ב-TypeScript אפשר להגדיר את מגבלת קריאת הכלי עבור שרת MCP של ה-SDK יחיד על ידי העברת timeout ל-createSdkMcpServer().
#פלט הכלי חורג ממספר האסימונים המרבי המותר
ה-SDK מחיל את אותן מגבלות פלט MCP כמו Claude Code. כשתוצאת כלי מוצלחת בלי תוכן תמונה גדולה מ-25,000 אסימונים, Claude Code שומר את הפלט לקובץ ומחליף את תוצאת הכלי בהודעת שגיאה שמציינת את נתיב הקובץ, כדי שהסוכן יוכל לקרוא את הפלט בחזרה בחלקים.
כדי לשנות את מגבלת האסימונים, הגדירו את משתנה הסביבה MAX_MCP_OUTPUT_TOKENS. אלא אם הכלי מצהיר על anthropic/maxResultSizeChars, תוצאת טקסט מוצלחת שארוכה מ-50,000 תווים נשמרת לקובץ בלי קשר למגבלת האסימונים. ראו מגבלות פלט MCP ואזהרות להתנהגות המלאה, כולל איך שרת מצהיר על ההערה הזו.
#משאבים קשורים
- מדריך כלים מותאמים אישית: בנו שרת MCP משלכם שרץ בתוך התהליך עם אפליקציית ה-SDK
- הרשאות: שלטו באילו כלי MCP הסוכן שלכם יכול להשתמש עם
allowedToolsו-disallowedTools - הפניית TypeScript SDK: הפניה מלאה ל-API כולל אפשרויות תצורת MCP
- הפניית Python SDK: הפניה מלאה ל-API כולל אפשרויות תצורת MCP
- ספריית שרתי MCP: עיינו בשרתי MCP זמינים למסדי נתונים, ממשקי API ועוד