SpyBara
Go Premium

agent-sdk/mcp.md 2026-11-09 23:02 UTC to 2026-11-10 21:57 UTC

No changes for this document in this history range.

2026
Mon 9 23:02

Mit MCP zu externen Tools verbinden

Konfigurieren Sie MCP-Server, um Ihren Agenten mit externen Tools zu erweitern. Behandelt Transporttypen, Tool-Suche für große Tool-Sets, Authentifizierung und Fehlerbehandlung.

Das Model Context Protocol (MCP) ist ein offener Standard für die Verbindung von KI-Agenten mit externen Tools und Datenquellen. Mit MCP kann Ihr Agent Datenbanken abfragen, sich mit APIs wie Slack und GitHub integrieren und sich mit anderen Diensten verbinden, ohne benutzerdefinierte Tool-Implementierungen zu schreiben.

MCP-Server können als lokale Prozesse ausgeführt werden, sich über HTTP verbinden oder direkt in Ihrer SDK-Anwendung ausgeführt werden.

[!NOTE]

Diese Seite behandelt die MCP-Konfiguration für das Agent SDK. Um MCP-Server zur Claude Code CLI hinzuzufügen, damit sie in jedem Projekt geladen werden, siehe MCP-Installationsbereiche.

Schnellstart

Dieses Beispiel verbindet sich mit dem Claude Code-Dokumentations-MCP-Server unter Verwendung von HTTP-Transport und verwendet allowedTools mit einem Platzhalter, um alle Tools vom Server zuzulassen.

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())

Der Agent verbindet sich mit dem Dokumentationsserver, sucht nach Informationen über hooks und gibt die Ergebnisse zurück.

MCP-Server hinzufügen

Sie können MCP-Server im Code beim Aufrufen von query() konfigurieren oder in einer .mcp.json-Datei, die über settingSources geladen wird.

Server im Code hinzufügen

Übergeben Sie MCP-Server direkt in der Option mcpServers. Dieses Beispiel startet einen lokalen Dateisystem-MCP-Server für /Users/me/projects. Ersetzen Sie diesen Pfad durch ein Verzeichnis auf Ihrem Computer:

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())

Server aus einer Konfigurationsdatei hinzufügen

Erstellen Sie eine .mcp.json-Datei im Stammverzeichnis Ihres Projekts. Die Datei wird geladen, wenn die project-Einstellungsquelle aktiviert ist, was sie standardmäßig für query()-Optionen ist. Wenn Sie settingSources explizit festlegen, fügen Sie "project" ein, damit diese Datei geladen wird. Ersetzen Sie /Users/me/projects durch ein Verzeichnis auf Ihrem Computer:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    }
  }
}

Verbindungszeitpunkt

Claude Code beginnt beim Start der Sitzung, Ihre MCP-Server zu verbinden, und sendet die Init-Nachricht, sobald die Wartezeit für den ersten Turn, falls vorhanden, endet. Wie lange der erste Turn auf einen Server wartet, hängt davon ab, wo Sie ihn konfiguriert haben. Wenn Sie permissionPromptToolName setzen, wartet der erste Turn immer auf den Server dieses Tools, bis zu MCP_TIMEOUT, unabhängig davon, wo Sie ihn konfiguriert haben.

Suchen Sie für einen Server in options.mcpServers seinen Typ in der ersten Spalte, um zu sehen, wie lange der erste Turn auf ihn wartet.

Servertyp Verzögert die erste Runde? Wartezeit-Timeout für die erste Runde
Stdio-Server oder HTTP/SSE-Server ohne zwischengespeicherte Werkzeugliste Ja, bis zur Verbindung MCP_TIMEOUT, standardmäßig 30 Sekunden; die Verbindung schlägt bei dieser Frist fehl
Remote-Server mit zwischengespeicherter Werkzeugliste, gespeichert von Claude Code aus einer vorherigen Verbindung Nein; die zwischengespeicherten Werkzeuge sind ab der ersten Runde verfügbar Keine; verbindet sich beim ersten Werkzeugaufruf, und diese aufgeschobene Verbindung hat ihr eigenes Timeout
In-Process-SDK-Server Ja, bis zur Verbindung und Auflistung der Werkzeuge MCP_TIMEOUT, standardmäßig 30 Sekunden pro Verbindungsversuch; die Verbindung schlägt bei dieser Frist fehl

Ein Server hat nur dann eine zwischengespeicherte Tool-Liste, wenn der MCP-Discovery-Cache aktiviert ist.

Server aus Einstellungsdateien wie .mcp.json oder aus Plugins zeigen in der Init-Nachricht häufig noch pending an. Wie lange der erste Turn auf sie wartet, hängt von options.mcpServers und der Tool-Suche ab:

  • options.mcpServers enthält einen Stdio-, HTTP- oder SSE-Server: Der erste Turn wartet auch auf die ausstehenden Server aus Einstellungsdateien und Plugins, bis zu MCP_TIMEOUT.
  • Andernfalls, wenn ANTHROPIC_BASE_URL auf ein Gateway verweist und ENABLE_TOOL_SEARCH nicht gesetzt ist: Der erste Turn wartet bis zu 2 Sekunden auf jeden ausstehenden Server aus Einstellungsdateien und Plugins.
  • Andernfalls, wenn die Tool-Suche aktiviert ist, was der Standard ist: Der erste Turn wartet bis zu 2 Sekunden, und zwar nur auf ausstehende Server, die alwaysLoad: true setzen oder die Sie benannt haben. Die übrigen verbinden sich weiter im Hintergrund, und Claude greift auf ihre Tools zu, sobald sie verbunden sind.
  • Andernfalls, wenn die Tool-Suche deaktiviert ist: Der erste Turn wartet bis zu 2 Sekunden auf jeden ausstehenden Server aus Einstellungsdateien und Plugins. Die Tool-Suche ist deaktiviert, wenn Ihr ENABLE_TOOL_SEARCH-Wert oder Ihr Modell sie ausschaltet oder wenn Sie das Tool ToolSearch ausschließen, beispielsweise durch disallowedTools.

Benannte Server

Sie benennen einen Server, indem Sie eines seiner Tools, etwa mcp__github__list_issues oder mcp__github__*, in allowedTools oder in einer permissions.allow-Regel in der Option settings aufführen. Ein mcp_tool-Hook benennt ebenfalls den Server, den er aufruft, wenn Sie ihn für ein Ereignis zur Prompt-Übermittlung, Tool-Nutzung, Berechtigung, zu Subagenten, Tasks, Elicitation oder Worktrees konfigurieren. Vor v2.1.284 hatte das Benennen eines Servers keine Auswirkung auf die Wartezeit für den ersten Turn.

Die Wartezeit für den ersten Turn selbst festlegen

Um die Wartezeit für den ersten Turn selbst festzulegen, setzen Sie CLAUDE_CODE_MCP_STARTUP_WAIT_MS in der env-Option, beispielsweise CLAUDE_CODE_MCP_STARTUP_WAIT_MS: "5000". Der erste Turn wartet dann bis zu dieser Anzahl von Millisekunden auf ausstehende Server aus Einstellungsdateien und Plugins, unabhängig davon, ob die Tool-Suche aktiviert ist. Dieselbe Frist ersetzt die MCP_TIMEOUT-Wartezeit für die Stdio-, HTTP- und SSE-Server in options.mcpServers.

Drei Wartezeiten gelten unabhängig vom gesetzten Wert, einschließlich 0:

  • Ein permissionPromptToolName-Server: bis zu MCP_TIMEOUT.
  • Ein In-Process-SDK-Server: bis zu MCP_TIMEOUT pro Verbindungsversuch.
  • Ein benannter Server, der sich noch verbindet: mindestens bis zu 2 Sekunden, sodass ein Wert unter 2000 seine Wartezeit nicht verkürzt.

Setzen Sie die Variable auf 0, um die Wartezeit für jeden anderen Server zu überspringen. Server, die noch ausstehend sind, wenn die Wartezeit endet, verbinden sich weiter im Hintergrund. CLAUDE_CODE_MCP_STARTUP_WAIT_MS erfordert Claude Code v2.1.274 oder später.

Den Start auf Server warten lassen

Zwei Einstellungen lassen bereits den Start warten, bevor Claude Code die Init-Nachricht sendet:

  • MCP_CONNECTION_NONBLOCKING auf 0 gesetzt: Der Start wartet auf den gesamten Verbindungsstapel, standardmäßig bis zu 5 Sekunden. Setzen Sie MCP_CONNECT_TIMEOUT_MS in Millisekunden, um diese Obergrenze zu ändern. Server, die bei Erreichen der Obergrenze noch ausstehend sind, verbinden sich weiter im Hintergrund.
  • alwaysLoad: true in der Konfiguration eines Servers: Der Start wartet bis zur selben Obergrenze auf die Tools dieses Servers, sodass der erste Turn sie mit vollständigem Schema hat, ausgenommen vom Aufschub durch die Tool-Suche. Ein Remote-Server mit einer zwischengespeicherten Tool-Liste stellt sie bereit, ohne sich zu verbinden oder den Start aufzuhalten.

Die Init-Nachricht meldet den Status jedes Servers zu dem Zeitpunkt, an dem Claude Code sie sendet.

MCP-Tools zulassen

MCP-Tools erfordern eine explizite Genehmigung, bevor Claude sie verwenden kann. Ohne Genehmigung sieht Claude, dass Tools verfügbar sind, kann sie aber nicht aufrufen.

Benennungskonvention für Tools

MCP-Tools werden nach dem Muster mcp__<server-name>__<tool-name> benannt, wobei <server-name> der Name ist, unter dem Sie den Server registrieren, etwa sein Schlüssel in mcpServers.

Zeichen im Servernamen wie . und Leerzeichen werden durch _ ersetzt. Diese Tabelle zeigt den vollständigen Namen eines list_issues-Tools für zwei Serverschlüssel:

Schlüssel in mcpServers Vollständiger Tool-Name
github mcp__github__list_issues
my.server mcp__my_server__list_issues

Verwenden Sie die vollständigen Tool-Namen in allowedTools und in MCP-Berechtigungsregeln. Bei einem Server, den ein Plugin bereitstellt, hat <server-name> die Plugin-bezogene Form und beginnt mit plugin_.

Automatische Genehmigung mit allowedTools

Verwenden Sie allowedTools, um bestimmte MCP-Tools automatisch zu genehmigen:

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
    ],
)

Platzhalter (*) ermöglichen es Ihnen, alle Tools von einem Server zuzulassen, ohne jedes einzeln aufzulisten.

[!NOTE]

Bevorzugen Sie allowedTools gegenüber Berechtigungsmodi für MCP-Zugriff. permissionMode: "acceptEdits" genehmigt MCP-Tools nicht automatisch (nur Dateibearbeitungen und Dateisystem-Bash-Befehle). permissionMode: "bypassPermissions" genehmigt MCP-Tools automatisch, deaktiviert aber auch die meisten anderen Sicherheitsaufforderungen, was breiter ist als nötig; siehe Wie Berechtigungen ausgewertet werden für die verbleibenden Aufforderungen. Ein Platzhalter in allowedTools gewährt genau den MCP-Server, den Sie möchten, und nichts mehr. Siehe Berechtigungsmodi für einen vollständigen Vergleich.

Verfügbare Tools entdecken

Um zu sehen, welche Tools ein MCP-Server bereitstellt, überprüfen Sie die Dokumentation des Servers oder inspizieren Sie das tools-Array in der system-Init-Nachricht. MCP-Tool-Namen beginnen mit mcp__.

Claude Code gibt die Init-Nachricht nach der Verbindungswartzeit beim ersten Durchgang für Server aus, die in options.mcpServers übergeben werden, sodass das tools-Array die mcp__-Tools jedes Servers auflistet, der bis dahin verbunden ist, plus die von Servern mit einer zwischengespeicherten Tool-Liste, die beim ersten Gebrauch verbunden werden. Tools von anderen Servern, die noch nicht verbunden sind, fehlen; siehe Fehlerbehandlung zum Lesen des Status jedes Servers.

Dieser Filter gibt die MCP-Tool-Namen aus:

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())

Sie können Claude auch bitten, die verfügbaren Tools von einem Server aufzulisten.

Transporttypen

MCP-Server kommunizieren mit Ihrem Agenten über verschiedene Transportprotokolle. Überprüfen Sie die Dokumentation des Servers, um zu sehen, welcher Transport unterstützt wird:

  • Wenn die Dokumentation Ihnen einen Befehl zum Ausführen gibt (wie npx @modelcontextprotocol/server-filesystem), verwenden Sie stdio
  • Wenn die Dokumentation Ihnen eine URL gibt, verwenden Sie HTTP oder SSE
  • Wenn Sie Ihre eigenen Tools im Code erstellen, verwenden Sie einen SDK MCP-Server

stdio-Server

Lokale Prozesse, die über stdin/stdout kommunizieren. Verwenden Sie dies für MCP-Server, die Sie auf demselben Computer ausführen. Für das .mcp.json-Format verwenden Sie die gleichen Felder wie unter Server aus einer Konfigurationsdatei hinzufügen. Im Code übergeben Sie den Befehl und seine Argumente. Ersetzen Sie /Users/me/projects durch ein Verzeichnis auf Ihrem Computer:

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-Server

Verwenden Sie HTTP oder SSE für Cloud-gehostete MCP-Server und Remote-APIs. Für das .mcp.json-Format verwenden Sie die gleichen Felder wie im Beispiel unter HTTP headers for remote servers, mit "type": "sse" für einen SSE-Server. Im Code übergeben Sie die URL des Servers:

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__*"],
)

Für den streamfähigen HTTP-Transport verwenden Sie stattdessen "type": "http". In .mcp.json und anderen JSON-Konfigurationsdateien wird "streamable-http" als Alias für "http" akzeptiert. Der McpHttpServerConfig-Typ der SDKs deklariert nur "http", verwenden Sie also "http" für Server, die Sie im Code übergeben.

SDK MCP-Server

Definieren Sie benutzerdefinierte Tools direkt in Ihrem Anwendungscode, anstatt einen separaten Serverprozess auszuführen. Weitere Implementierungsdetails finden Sie im custom tools guide.

Ein SDK MCP-Server, der von einer initialize-Steueranforderung registriert wird, beginnt die Verbindung, sobald Claude Code die Anforderung verarbeitet.

MCP-Werkzeugsuche

Wenn Sie viele MCP-Werkzeuge konfiguriert haben, können Werkzeugdefinitionen einen erheblichen Teil Ihres Kontextfensters verbrauchen. Die Werkzeugsuche löst dieses Problem, indem sie Werkzeugdefinitionen aus dem Kontext vorenthält und nur die Werkzeuge lädt, die Claude für jeden Durchgang benötigt.

Die Werkzeugsuche ist standardmäßig aktiviert. Weitere Informationen zu Konfigurationsoptionen, Best Practices und der Verwendung der Werkzeugsuche mit benutzerdefinierten SDK-Werkzeugen finden Sie unter Werkzeugsuche.

Authentifizierung

Die meisten MCP-Server erfordern eine Authentifizierung für den Zugriff auf externe Dienste. Übergeben Sie Anmeldedaten über Umgebungsvariablen in der Serverkonfiguration.

Anmeldedaten über Umgebungsvariablen übergeben

Verwenden Sie das Feld env, um API-Schlüssel, Token und andere Anmeldedaten an den MCP-Server zu übergeben:

[tab] Im Code

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__*"],
)

[tab] .mcp.json

{
  "mcpServers": {
    "api-server": {
      "command": "npx",
      "args": ["-y", "@your-org/api-mcp-server"],
      "env": {
        "API_KEY": "${API_KEY}"
      }
    }
  }
}

Die Syntax ${API_KEY} erweitert Umgebungsvariablen zur Laufzeit.

HTTP-Header für Remote-Server

Für HTTP- und SSE-Server übergeben Sie Authentifizierungs-Header direkt in der Serverkonfiguration:

[tab] Im Code

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__*"],
)

[tab] .mcp.json

{
  "mcpServers": {
    "secure-api": {
      "type": "http",
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}"
      }
    }
  }
}

Die Syntax ${API_TOKEN} erweitert Umgebungsvariablen zur Laufzeit.

Ein vollständiges funktionierendes Beispiel eines Remote-Servers mit Header-Authentifizierung finden Sie unter Probleme aus einem Repository auflisten.

OAuth2-Authentifizierung

Die MCP-Spezifikation unterstützt OAuth 2.1 für die Autorisierung. Das SDK öffnet keinen Browser und führt keinen interaktiven OAuth-Flow aus. Wenn ein konfigurierter Server eine Autorisierungsaufforderung zurückgibt und Claude Code kein Token zum Senden hat, meldet das SDK den Server als needs-auth oder failed:

In beiden Fällen wird die Agent-Ausführung ohne die Tools dieses Servers fortgesetzt. Das Array mcp_servers der System-Init-Nachricht kann für diesen Server immer noch pending anzeigen, wenn es ausgegeben wird. Um zu bestätigen, ob ein Server Anmeldedaten benötigt, fragen Sie mcpServerStatus() im TypeScript SDK oder get_mcp_status() in Python ab.

Um Anmeldedaten bereitzustellen, führen Sie den OAuth-Flow in Ihrer eigenen Anwendung durch und übergeben Sie das resultierende Zugriffs-Token in den headers des Servers:

// Nach Abschluss des OAuth-Flows in Ihrer App.
// Implementieren Sie getAccessTokenFromOAuthFlow für Ihren 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__*"]
};
# Nach Abschluss des OAuth-Flows in Ihrer App.
# Implementieren Sie get_access_token_from_oauth_flow für Ihren 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__*"],
)

Beispiele

Probleme aus einem Repository auflisten

Dieses Beispiel verbindet sich mit dem Remote-GitHub MCP Server, um aktuelle Probleme aufzulisten. Das Beispiel enthält Debug-Protokollierung, um die MCP-Verbindung und Toolaufrufe zu überprüfen.

Erstellen Sie vor der Ausführung ein GitHub Personal Access Token mit Lesezugriff auf die Repositories, die Sie abfragen möchten, und legen Sie es als Umgebungsvariable fest:

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())

In der Zeile MCP servers: bestätigt ein status von connected für github, dass das Token funktioniert. Wenn Claude Code eine zwischengespeicherte Toolliste für den Server hat, kann der Status stattdessen pending anzeigen und der Server verbindet sich beim ersten Toolaufruf. Wenn der Status failed oder needs-auth ist, siehe Fehlerbehandlung, bevor Sie dem Ergebnis vertrauen, da Claude auf integrierte Tools zurückgreifen kann, wenn der Server nicht verfügbar ist.

Eine Datenbank abfragen

Dieses Beispiel verwendet DBHub, um eine Postgres-Datenbank abzufragen. Der Agent erkennt das Datenbankschema automatisch, schreibt die SQL-Abfrage und gibt die Ergebnisse zurück.

Das execute_sql-Tool von DBHub führt jede SQL aus, die der Agent ausgibt, einschließlich Schreibvorgänge, es sei denn, Sie beschränken es. Das Setzen von readonly = true in der DBHub-Konfigurationsdatei bewirkt, dass DBHub INSERT-, UPDATE-, DELETE- und DDL-Anweisungen ablehnt, sodass das Beispiel Ihre Daten nicht ändern kann, selbst wenn der Agent einen Schreibvorgang ausgibt. DBHub löst ${DATABASE_URL} aus der Prozessumgebung auf, wenn es die Konfiguration lädt, sodass die Verbindungszeichenfolge aus der Datei bleibt. Erstellen Sie diese dbhub.toml neben Ihrem Skript:

[[sources]]
id = "production"
dsn = "${DATABASE_URL}"

[[tools]]
name = "execute_sql"
source = "production"
readonly = true

Das Skript verweist dann DBHub auf die Konfigurationsdatei, anstatt eine Verbindungszeichenfolge direkt zu übergeben. Legen Sie vor der Ausführung die Umgebungsvariable DATABASE_URL auf Ihre Verbindungszeichenfolge fest. Ersetzen Sie die Platzhalterwerte durch Ihre eigenen Datenbankdetails:

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())

Fehlerbehandlung

MCP-Server können aus verschiedenen Gründen keine Verbindung herstellen: Der Server-Prozess ist möglicherweise nicht installiert, die Anmeldedaten könnten ungültig sein, oder ein Remote-Server könnte unerreichbar sein.

Claude Code sendet eine system-Nachricht mit dem Subtyp init am Anfang jeder Abfrage. Diese Nachricht enthält den Verbindungsstatus für jeden MCP-Server. Das Feld status kann "pending", "connected", "failed", "needs-auth" oder "disabled" sein. Claude Code sendet die Init-Nachricht nach dem Wartezeit für die Verbindung beim ersten Durchgang für Server, die in options.mcpServers übergeben werden, sodass ein solcher Server, der sich innerhalb der Wartezeit verbunden hat, "connected" anzeigt.

In der Init-Nachricht sollten Sie "pending" nicht als Fehler an sich behandeln. Es kann eines der folgenden bedeuten:

Prüfen Sie auf "failed" oder "needs-auth", um Server zu erkennen, die nicht verwendbar sind:

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())

Der Status eines Remote-Servers kann sich auch ändern, nachdem er "connected" meldet. Wenn die Verbindung zu ihm während einer Sitzung unterbrochen wird, verschiebt Claude Code den Server zurück zu "pending", während Wiederverbindung stattfindet. Ein späterer mcpServerStatus()-Aufruf in TypeScript oder ClaudeSDKClient.get_mcp_status() in Python kann dann "pending" für einen Server melden, den Sie zuvor verbunden gesehen haben, ohne dass sich die Konfiguration auf Ihrer Seite ändert.

Nach fünf fehlgeschlagenen Wiederverbindungsversuchen meldet der Server "failed" oder "needs-auth", wenn er erneut autorisiert werden muss. Ein HTTP- oder SSE-Server mit dem Status "failed" kann auch ohne einen Aufruf Ihrerseits wieder zu "connected" zurückkehren, da Claude Code nach einem vorübergehenden Fehler im Hintergrund weiterhin Wiederholungsversuche unternimmt. Um manuell erneut zu versuchen, rufen Sie reconnectMcpServer() in TypeScript oder ClaudeSDKClient.reconnect_mcp_server() in Python auf.

Fehlerbehebung

Server zeigt Status „failed“ an

Überprüfen Sie die init-Nachricht, um zu sehen, welche Server keine Verbindung herstellen konnten:

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")

Ein Status "pending" bedeutet nicht, dass der Server fehlgeschlagen ist. Siehe Fehlerbehandlung für die Fälle, die er bei der Initialisierung abdeckt. Um später in der Sitzung aktualisierte Status zu erhalten, rufen Sie die Methode mcpServerStatus() der Abfrage im TypeScript SDK auf, oder ClaudeSDKClient.get_mcp_status() in Python.

Häufige Ursachen:

  • Fehlende Umgebungsvariablen: Stellen Sie sicher, dass erforderliche Token und Anmeldedaten gesetzt sind. Überprüfen Sie bei stdio-Servern, dass das Feld env dem entspricht, was der Server erwartet.
  • Server nicht installiert: Überprüfen Sie bei npx-Befehlen, dass das Paket vorhanden ist und Node.js in Ihrem PATH liegt.
  • Ungültige Verbindungszeichenfolge: Überprüfen Sie bei Datenbankservern das Format der Verbindungszeichenfolge und dass die Datenbank erreichbar ist.
  • Netzwerkprobleme: Überprüfen Sie bei Remote-HTTP/SSE-Servern, dass die URL erreichbar ist und dass Firewalls die Verbindung zulassen.

Tools werden nicht aufgerufen

Wenn Claude Tools sieht, sie aber nicht verwendet, überprüfen Sie, dass Sie die Berechtigung mit allowedTools erteilt haben:

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
)

Ein Tool fehlt in einem SDK-MCP-Server

Wenn sich im TypeScript SDK das Eingabe-Schema eines Tools nicht in JSON Schema konvertieren lässt, lässt der Server, den Sie mit createSdkMcpServer() erstellt haben, dieses Tool weg, wenn er seine Tools auflistet. Das SDK gibt an dieser Stelle eine Warnung aus. Unter Node.js ist die Warnung eine Prozesswarnung mit dem Code CLAUDE_SDK_MCP_TOOL_SCHEMA_UNCONVERTIBLE, und sie beginnt mit diesem Text:

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

Der Rest der Warnung enthält die Meldung des Konvertierungsfehlers, sofern vorhanden, und beschreibt anschließend, was Sie überprüfen und ändern sollten.

Vor TypeScript Agent SDK v0.3.286 führte ein einziges nicht konvertierbares Schema dazu, dass die gesamte Tool-Auflistung des Servers ohne diese Warnung fehlschlug, sodass keines der Tools dieses Servers Claude erreichte.

Verbindungs-Timeouts

MCP-Serververbindungen werden standardmäßig nach 30 Sekunden unterbrochen. Um zu ändern, wie lange ein laufender Tool-Aufruf dauern darf, setzen Sie MCP_TOOL_TIMEOUT. Wenn Ihr Server länger zum Starten braucht, schlägt die Verbindung fehl. Erhöhen Sie das Verbindungslimit mit der Umgebungsvariablen MCP_TIMEOUT in Millisekunden. Für Server, die mehr Startzeit benötigen, sollten Sie auch Folgendes in Betracht ziehen:

  • Verwendung eines leichteren Servers, falls verfügbar
  • Vorwärmung des Servers vor dem Starten Ihres Agenten
  • Überprüfung der Serverprotokolle auf langsame Initialisierungsursachen

In TypeScript können Sie das Tool-Aufruf-Limit für einen einzelnen SDK MCP Server setzen, indem Sie timeout an createSdkMcpServer() übergeben.

Tool-Ausgabe überschreitet maximale zulässige Token

Das SDK wendet dieselben MCP-Ausgabelimits wie Claude Code an. Wenn ein erfolgreiches Tool-Ergebnis ohne Bildinhalt größer als 25.000 Token ist, speichert Claude Code die Ausgabe in einer Datei und ersetzt das Tool-Ergebnis durch eine Fehlermeldung, die den Dateipfad benennt, damit der Agent die Ausgabe in Teilen zurücklesen kann.

Um das Token-Limit zu ändern, setzen Sie die Umgebungsvariable MAX_MCP_OUTPUT_TOKENS. Sofern das Tool nicht anthropic/maxResultSizeChars deklariert, wird ein erfolgreiches Textergebnis mit mehr als 50.000 Zeichen unabhängig vom Token-Limit in einer Datei gespeichert. Siehe MCP-Ausgabelimits und Warnungen für das vollständige Verhalten, einschließlich der Frage, wie ein Server diese Anmerkung deklariert.

Verwandte Ressourcen