Connecter à des outils externes avec MCP
Configurez les serveurs MCP pour étendre votre agent avec des outils externes. Couvre les types de transport, la recherche d'outils pour les grands ensembles d'outils, l'authentification et la gestion des erreurs.
Le Model Context Protocol (MCP) est une norme ouverte pour connecter les agents IA aux outils externes et aux sources de données. Avec MCP, votre agent peut interroger des bases de données, s'intégrer à des API comme Slack et GitHub, et se connecter à d'autres services sans écrire d'implémentations d'outils personnalisés.
Les serveurs MCP peuvent s'exécuter en tant que processus locaux, se connecter via HTTP ou s'exécuter directement dans votre application SDK.
Cette page couvre la configuration de MCP pour l'Agent SDK. Pour ajouter des serveurs MCP à l'interface de ligne de commande Claude Code afin qu'ils se chargent dans chaque projet, consultez Portées d'installation MCP.
Démarrage rapide
Cet exemple se connecte au serveur MCP de documentation Claude Code en utilisant le transport HTTP et utilise allowedTools avec un caractère générique pour autoriser tous les outils du serveur.
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())
L'agent se connecte au serveur de documentation, recherche des informations sur les hooks et retourne les résultats.
Ajouter un serveur MCP
Vous pouvez configurer les serveurs MCP dans le code lors de l'appel de query(), ou dans un fichier .mcp.json chargé via settingSources.
Dans le code
Transmettez les serveurs MCP directement dans l'option mcpServers. Cet exemple démarre un serveur MCP de système de fichiers local pour /Users/me/projects. Remplacez ce chemin par un répertoire sur votre machine :
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())
À partir d'un fichier de configuration
Créez un fichier .mcp.json à la racine de votre projet. Le fichier est détecté lorsque la source de paramètre project est activée, ce qui est le cas pour les options query() par défaut. Si vous définissez settingSources explicitement, incluez "project" pour que ce fichier soit chargé. Remplacez /Users/me/projects par un répertoire sur votre machine :
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}
Délai de connexion
Claude Code enregistre les serveurs que vous transmettez dans options.mcpServers au démarrage et émet le message init une fois que l'attente du premier tour, le cas échéant, est résolue. Sans options.mcpServers, Claude Code attend 2 secondes pour les serveurs en attente avant le premier tour, de sorte que les serveurs chargés à partir de fichiers de configuration tels que .mcp.json affichent généralement pending à l'initialisation. Quand chaque serveur options.mcpServers se connecte, et s'il retarde le premier tour, dépend de son type :
| Type de serveur | Retarde le premier tour ? | Délai d'attente du premier tour |
|---|---|---|
| Serveur stdio, ou serveur HTTP/SSE sans liste d'outils en cache | Oui, jusqu'à ce qu'il se connecte | MCP_TIMEOUT, 30 secondes par défaut ; la connexion échoue à cette limite |
| Serveur distant avec une liste d'outils en cache, enregistrée par Claude Code à partir d'une connexion précédente | Non ; les outils en cache sont disponibles dès le premier tour | Aucun ; se connecte lors de son premier appel d'outil, et cette connexion différée a son propre délai d'attente |
| Serveur SDK en processus | Non ; ne retarde jamais le premier tour | Aucun |
Pour bloquer le démarrage lui-même à une phase distincte et antérieure à l'attente du premier tour, avant que le message init soit envoyé :
- Définissez
MCP_CONNECTION_NONBLOCKINGà0pour bloquer sur tout le lot de connexions. Claude Code limite cette attente à 5 secondes par défaut. Ajustez la limite avec la variable d'environnementMCP_CONNECT_TIMEOUT_MS, en millisecondes. Les serveurs toujours en attente à cette limite continuent de se connecter en arrière-plan. - Définissez
alwaysLoad: truesur la configuration d'un serveur pour rendre ses outils disponibles à leurs schémas complets au premier tour, exempts du report de recherche d'outils. Claude Code attend au démarrage les outils de ce serveur, limités à la même limite, tandis que les autres serveurs continuent de se connecter en arrière-plan ; un serveur distant avec une liste d'outils en cache les fournit sans se connecter, selon le tableau ci-dessus.
Le message system avec le sous-type init rapporte l'état de chaque serveur au moment où il est émis ; voir Gestion des erreurs pour lire ces états.
Autoriser les outils MCP
Les outils MCP nécessitent une permission explicite avant que Claude puisse les utiliser. Sans permission, Claude verra que les outils sont disponibles mais ne pourra pas les appeler.
Convention de nommage des outils
Les outils MCP suivent le modèle de nommage mcp__<server-name>__<tool-name>. Par exemple, un serveur GitHub nommé "github" avec un outil list_issues devient mcp__github__list_issues.
Auto-approbation avec allowedTools
Utilisez allowedTools pour auto-approuver des outils MCP spécifiques afin que Claude puisse les utiliser sans invite de permission :
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
],
)
Les caractères génériques (*) vous permettent d'autoriser tous les outils d'un serveur sans lister chacun individuellement.
Préférez allowedTools aux modes de permission pour l'accès MCP. permissionMode: "acceptEdits" n'auto-approuve pas les outils MCP (uniquement les modifications de fichiers et les commandes Bash du système de fichiers). permissionMode: "bypassPermissions" auto-approuve les outils MCP mais désactive également la plupart des autres invites de sécurité, ce qui est plus large que nécessaire ; consultez Comment les permissions sont évaluées pour les invites qui restent. Un caractère générique dans allowedTools accorde exactement le serveur MCP que vous souhaitez et rien de plus. Consultez Modes de permission pour une comparaison complète.
Découvrir les outils disponibles
Pour voir quels outils un serveur MCP fournit, consultez la documentation du serveur ou inspectez le tableau tools dans le message init system. Les noms des outils MCP commencent par mcp__.
Claude Code émet le message init après l'attente de connexion au premier tour pour les serveurs passés dans options.mcpServers, donc le tableau tools liste les outils mcp__ de chaque serveur qui s'est connecté à ce moment-là, plus ceux des serveurs avec une liste d'outils en cache, qui se connectent à la première utilisation. Les outils de tout autre serveur qui ne s'est pas connecté sont absents ; consultez Gestion des erreurs pour lire l'état de chaque serveur.
Ce filtre imprime les noms des outils 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())
Vous pouvez également demander à Claude de lister les outils disponibles à partir d'un serveur.
Types de transport
Les serveurs MCP communiquent avec votre agent en utilisant différents protocoles de transport. Consultez la documentation du serveur pour voir quel transport il prend en charge :
- Si la documentation vous donne une commande à exécuter (comme
npx @modelcontextprotocol/server-filesystem), utilisez stdio - Si la documentation vous donne une URL, utilisez HTTP ou SSE
- Si vous créez vos propres outils dans le code, utilisez un serveur MCP SDK
Serveurs stdio
Des processus locaux qui communiquent via stdin/stdout. Utilisez ceci pour les serveurs MCP que vous exécutez sur la même machine. Pour le formulaire .mcp.json, utilisez les mêmes champs affichés à À partir d'un fichier de configuration. Dans le code, transmettez la commande et ses arguments. Remplacez /Users/me/projects par un répertoire sur votre machine :
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"],
)
Serveurs HTTP/SSE
Utilisez HTTP ou SSE pour les serveurs MCP hébergés dans le cloud et les API distantes. Pour le formulaire .mcp.json, utilisez les mêmes champs que l'exemple à En-têtes HTTP pour les serveurs distants, avec "type": "sse" pour un serveur SSE. Dans le code, transmettez l'URL du serveur :
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__*"],
)
Pour le transport HTTP en continu, utilisez "type": "http" à la place. Dans .mcp.json et autres fichiers de configuration JSON, "streamable-http" est accepté comme alias pour "http". Le type McpHttpServerConfig des SDK déclare uniquement "http", donc utilisez "http" pour les serveurs que vous transmettez dans le code.
Serveurs MCP SDK
Définissez des outils personnalisés directement dans le code de votre application au lieu d'exécuter un processus serveur séparé. Consultez le guide des outils personnalisés pour les détails de mise en œuvre.
Un serveur MCP SDK enregistré par une demande de contrôle initialize commence à se connecter dès que Claude Code traite la demande.
Recherche d'outils MCP
Lorsque vous avez de nombreux outils MCP configurés, les définitions d'outils peuvent consommer une part importante de votre fenêtre de contexte. La recherche d'outils résout ce problème en retenant les définitions d'outils du contexte et en chargeant uniquement ceux dont Claude a besoin à chaque tour.
La recherche d'outils est activée par défaut. Consultez Recherche d'outils pour les options de configuration, les meilleures pratiques et l'utilisation de la recherche d'outils avec les outils SDK personnalisés.
Authentification
La plupart des serveurs MCP nécessitent une authentification pour accéder aux services externes. Transmettez les identifiants via des variables d'environnement dans la configuration du serveur.
Transmettre les identifiants via des variables d'environnement
Utilisez le champ env pour transmettre les clés API, les jetons et autres identifiants au serveur 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__*"],
)
{
"mcpServers": {
"api-server": {
"command": "npx",
"args": ["-y", "@your-org/api-mcp-server"],
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}
La syntaxe ${API_KEY} développe les variables d'environnement au moment de l'exécution.
En-têtes HTTP pour les serveurs distants
Pour les serveurs HTTP et SSE, transmettez les en-têtes d'authentification directement dans la configuration du serveur :
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}"
}
}
}
}
La syntaxe ${API_TOKEN} développe les variables d'environnement au moment de l'exécution.
Pour un exemple complet et fonctionnel d'un serveur distant authentifié avec des en-têtes, consultez Lister les problèmes d'un référentiel.
Authentification OAuth2
La spécification MCP prend en charge OAuth 2.1 pour l'autorisation. Le SDK n'ouvre pas de navigateur ni n'exécute de flux OAuth interactif. Lorsqu'un serveur configuré retourne un défi d'autorisation et qu'aucun jeton stocké n'est disponible, l'exécution de l'agent continue sans les outils de ce serveur, et le serveur signale le statut needs-auth. Le tableau mcp_servers du message d'initialisation du système peut toujours afficher pending pour ce serveur lors de son émission. Pour confirmer si un serveur a besoin d'identifiants, interrogez mcpServerStatus() dans le SDK TypeScript ou get_mcp_status() en Python.
Pour fournir les identifiants, complétez le flux OAuth dans votre propre application et transmettez le jeton d'accès résultant dans les headers du serveur :
// 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__*"],
)
Exemples
Lister les problèmes d'un référentiel
Cet exemple se connecte au serveur MCP GitHub distant pour lister les problèmes récents. L'exemple inclut la journalisation de débogage pour vérifier la connexion MCP et les appels d'outils.
Avant d'exécuter, créez un jeton d'accès personnel GitHub avec accès en lecture aux référentiels que vous souhaitez interroger et définissez-le comme variable d'environnement :
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);
}
}
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())
Dans la ligne MCP servers :, un status de connected pour github confirme que le jeton fonctionne. Si Claude Code dispose d'une liste d'outils mise en cache pour le serveur, le statut peut afficher pending à la place et le serveur se connecte lors de son premier appel d'outil. Si le statut est failed ou needs-auth, consultez Gestion des erreurs avant de faire confiance au résultat, car Claude peut revenir aux outils intégrés lorsque le serveur n'est pas disponible.
Interroger une base de données
Cet exemple utilise DBHub pour interroger une base de données Postgres. L'agent découvre automatiquement le schéma de la base de données, écrit la requête SQL et retourne les résultats.
L'outil execute_sql de DBHub exécute toute requête SQL que l'agent émet, y compris les écritures, sauf si vous la limitez. Définir readonly = true dans le fichier de configuration DBHub fait que DBHub rejette les instructions INSERT, UPDATE, DELETE et DDL, de sorte que l'exemple ne peut pas modifier vos données même si l'agent émet une écriture. DBHub résout ${DATABASE_URL} à partir de l'environnement du processus lorsqu'il charge la configuration, de sorte que la chaîne de connexion reste en dehors du fichier. Créez ce dbhub.toml à côté de votre script :
[[sources]]
id = "production"
dsn = "${DATABASE_URL}"
[[tools]]
name = "execute_sql"
source = "production"
readonly = true
Le script pointe ensuite DBHub vers le fichier de configuration au lieu de passer une chaîne de connexion directement. Avant d'exécuter, définissez la variable d'environnement DATABASE_URL sur votre chaîne de connexion. Remplacez les valeurs d'espace réservé par les détails de votre propre base de données :
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);
}
}
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())
Gestion des erreurs
Les serveurs MCP peuvent échouer à se connecter pour diverses raisons : le processus du serveur pourrait ne pas être installé, les identifiants pourraient être invalides, ou un serveur distant pourrait être inaccessible.
Claude Code émet un message system avec le sous-type init au début de chaque requête. Ce message inclut l'état de la connexion pour chaque serveur MCP. Le champ status peut être "pending", "connected", "failed", "needs-auth", ou "disabled". Claude Code émet le message init après le délai d'attente de connexion à la première requête pour les serveurs passés dans options.mcpServers, donc un tel serveur qui s'est connecté dans le délai d'attente affiche "connected".
Dans le message init, ne traitez pas "pending" comme un échec en soi. Cela peut signifier l'une de ces situations :
- Le serveur ne s'est pas encore connecté. Voir combien de temps Claude Code attend avant la première requête
- La liste des outils du serveur a été servie à partir du cache, avec une connexion établie à la première utilisation
- Le délai de connexion a expiré. Un tel serveur rapporte
"pending"ou"failed"selon le timing
Vérifiez "failed" ou "needs-auth" pour détecter les serveurs qui ne seront pas utilisables :
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())
L'état d'un serveur distant peut également changer après qu'il rapporte "connected". Lorsque la connexion à celui-ci s'interrompt en cours de session, Claude Code ramène le serveur à "pending" pendant la reconnexion. Un appel ultérieur à mcpServerStatus() en TypeScript, ou ClaudeSDKClient.get_mcp_status() en Python, peut alors rapporter "pending" pour un serveur que vous aviez vu connecté plus tôt, sans aucun changement de configuration de votre côté.
Après cinq tentatives de reconnexion échouées, le serveur rapporte "failed", ou "needs-auth" lorsqu'il a besoin d'être autorisé à nouveau. Pour réessayer manuellement, appelez reconnectMcpServer() en TypeScript ou ClaudeSDKClient.reconnect_mcp_server() en Python.
Dépannage
Le serveur affiche un statut « failed »
Vérifiez le message init pour voir quels serveurs n'ont pas pu se connecter :
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")
Un statut "pending" ne signifie pas que le serveur a échoué. Consultez Gestion des erreurs pour connaître les cas qu'il couvre à l'initialisation. Pour obtenir les statuts mis à jour plus tard dans la session, appelez la méthode mcpServerStatus() de la requête dans le SDK TypeScript, ou ClaudeSDKClient.get_mcp_status() en Python.
Causes courantes :
- Variables d'environnement manquantes : Assurez-vous que les jetons et identifiants requis sont définis. Pour les serveurs stdio, vérifiez que le champ
envcorrespond à ce que le serveur attend. - Serveur non installé : Pour les commandes
npx, vérifiez que le package existe et que Node.js se trouve dans votre PATH. - Chaîne de connexion invalide : Pour les serveurs de base de données, vérifiez le format de la chaîne de connexion et que la base de données est accessible.
- Problèmes réseau : Pour les serveurs HTTP/SSE distants, vérifiez que l'URL est accessible et que les pare-feu autorisent la connexion.
Les outils ne sont pas appelés
Si Claude voit les outils mais ne les utilise pas, vérifiez que vous avez accordé la permission avec 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
)
Délais d'expiration de la connexion
Les connexions au serveur MCP expirent après 30 secondes par défaut. Pour modifier la durée maximale d'un appel d'outil en cours, définissez MCP_TOOL_TIMEOUT. Si votre serveur met plus de temps à démarrer, la connexion échoue. Augmentez la limite de connexion avec la variable d'environnement MCP_TIMEOUT, en millisecondes. Pour les serveurs qui ont besoin de plus de temps de démarrage, envisagez également :
- Utiliser un serveur plus léger si disponible
- Préchauffer le serveur avant de démarrer votre agent
- Vérifier les journaux du serveur pour les causes d'initialisation lente
En TypeScript, vous pouvez définir la limite d'appel d'outil pour un seul serveur MCP du SDK en passant timeout à createSdkMcpServer().
La sortie de l'outil dépasse le nombre maximum de jetons autorisés
Le SDK applique la même limite de sortie MCP que Claude Code. Lorsqu'un résultat d'outil est supérieur à 25 000 jetons, la sortie complète est enregistrée dans un fichier et le résultat de l'outil est remplacé par un message d'erreur qui nomme le chemin du fichier, afin que l'agent puisse relire la sortie par portions. Augmentez la limite avec la variable d'environnement MAX_MCP_OUTPUT_TOKENS. Consultez Limites et avertissements de sortie MCP pour le comportement complet, y compris la façon dont un serveur peut déclarer une limite supérieure par outil avec l'annotation anthropic/maxResultSizeChars.
Ressources connexes
- Guide des outils personnalisés : Créez votre propre serveur MCP qui s'exécute en processus avec votre application SDK
- Permissions : Contrôlez les outils MCP que votre agent peut utiliser avec
allowedToolsetdisallowedTools - Référence du SDK TypeScript : Référence API complète incluant les options de configuration MCP
- Référence du SDK Python : Référence API complète incluant les options de configuration MCP
- Répertoire des serveurs MCP : Parcourez les serveurs MCP disponibles pour les bases de données, les API, et bien d'autres