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 :
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 récupéré 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 se charge :
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}
Autoriser les outils MCP
Les outils MCP nécessitent une autorisation explicite avant que Claude puisse les utiliser. Sans autorisation, 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.
Approbation automatique avec allowedTools
Utilisez allowedTools pour approuver automatiquement 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
]
}
};
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'approuve pas automatiquement les outils MCP (uniquement les modifications de fichiers et les commandes Bash du système de fichiers). permissionMode: "bypassPermissions" approuve automatiquement les outils MCP mais désactive également tous les autres messages de sécurité, ce qui est plus large que nécessaire. 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 connectez-vous au serveur et inspectez le message d'initialisation system :
for await (const message of query({ prompt: "...", options })) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available MCP tools:", message.mcp_servers);
}
}
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 supporte :
- Si la documentation vous donne une commande à exécuter (comme
npx @modelcontextprotocol/server-github), utilisez stdio - Si la documentation vous donne une URL, utilisez HTTP ou SSE
- Si vous construisez vos propres outils dans le code, utilisez un serveur MCP SDK
Serveurs stdio
Les processus locaux qui communiquent via stdin/stdout. Utilisez ceci pour les serveurs MCP que vous exécutez sur la même machine :
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}"
}
}
}
}
Serveurs HTTP/SSE
Utilisez HTTP ou SSE pour les serveurs MCP hébergés dans le cloud et les API distantes :
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}"
}
}
}
}
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". L'option programmatique mcpServers accepte uniquement "http".
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 d'implémentation.
Recherche d'outils MCP
Lorsque vous avez de nombreux outils MCP configurés, les définitions d'outils peuvent consommer une partie 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 pour chaque tour.
La recherche d'outils est activée par défaut. Consultez Recherche d'outils pour les options de configuration et les détails.
Pour plus de détails, y compris les meilleures pratiques et l'utilisation de la recherche d'outils avec les outils SDK personnalisés, consultez le guide de recherche d'outils.
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: {
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}"
}
}
}
}
La syntaxe ${GITHUB_TOKEN} développe les variables d'environnement au moment de l'exécution.
Consultez Lister les problèmes d'un référentiel pour un exemple complet fonctionnant avec la journalisation de débogage.
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.
Authentification OAuth2
La spécification MCP supporte OAuth 2.1 pour l'autorisation. Le SDK ne gère pas les flux OAuth automatiquement, mais vous pouvez transmettre les jetons d'accès via les en-têtes après avoir complété le flux OAuth dans votre application :
// 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__*"],
)
Exemples
Lister les problèmes d'un référentiel
Cet exemple se connecte au serveur GitHub MCP 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 la portée repo et définissez-le comme variable d'environnement :
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())
Interroger une base de données
Cet exemple utilise le serveur Postgres MCP pour interroger une base de données. La chaîne de connexion est transmise comme argument au serveur. L'agent découvre automatiquement le schéma de la base de données, écrit la requête SQL et retourne les résultats :
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())
Gestion des erreurs
Les serveurs MCP peuvent échouer à se connecter pour diverses raisons : le processus serveur peut ne pas être installé, les identifiants peuvent être invalides, ou un serveur distant peut être inaccessible.
Le SDK é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. Vérifiez le champ status pour détecter les défaillances de connexion avant que l'agent ne commence à travailler :
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())
Dépannage
Le serveur affiche le 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`);
}
}
}
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 est 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
}
};
Délais d'expiration de la connexion
Le SDK MCP a un délai d'expiration par défaut de 60 secondes pour les connexions serveur. Si votre serveur prend plus de temps pour démarrer, la connexion échouera. Pour les serveurs qui ont besoin de plus de temps de démarrage, envisagez :
- 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 de lenteur d'initialisation
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 quels outils MCP votre agent peut utiliser avec
allowedToolsetdisallowedTools - Référence SDK TypeScript : Référence API complète incluant les options de configuration MCP
- Référence 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