Skip to main content
Benutzerdefinierte Tools erweitern das Agent SDK, indem Sie Ihre eigenen Funktionen definieren können, die Claude während einer Konversation aufrufen kann. Mit dem In-Process-MCP-Server des SDK können Sie Claude Zugriff auf Datenbanken, externe APIs, domänenspezifische Logik oder jede andere Funktionalität geben, die Ihre Anwendung benötigt.

Schnellreferenz

Erstellen Sie ein benutzerdefiniertes Tool

Ein Tool wird durch vier Teile definiert, die als Argumente an den tool() Helper in TypeScript oder den @tool Decorator in Python übergeben werden:
  • Name: ein eindeutiger Bezeichner, den Claude zum Aufrufen des Tools verwendet.
  • Beschreibung: was das Tool tut. Claude liest dies, um zu entscheiden, wann es aufgerufen werden soll.
  • Input-Schema: die Argumente, die das Tool akzeptiert, je nach Sprache deklariert:
    • TypeScript: ein Zod-Schema. Die args des Handlers übernehmen ihre Typen davon. Rufen Sie .describe() für ein Feld auf, um ihm eine Beschreibung zu geben, die Claude sieht.
    • Python: ein Dict, das Namen auf Typen abbildet, wie {"latitude": float}, das das SDK für Sie in JSON Schema konvertiert. Umschließen Sie einen Typ mit Annotated, wie {"latitude": Annotated[float, "Latitude coordinate"]}, um dem Feld eine Beschreibung zu geben, die Claude sieht. Der Decorator akzeptiert auch direkt ein vollständiges JSON Schema Dict, wenn Sie Enums, Bereiche, optionale Felder oder verschachtelte Objekte benötigen.
  • Handler: die asynchrone Funktion, die ausgeführt wird, wenn Claude das Tool aufruft. Sie erhält die validierten Argumente und muss ein Objekt mit folgenden Eigenschaften zurückgeben:
    • content (erforderlich): ein Array von Ergebnis-Blöcken, jeder mit einem type von "text", "image", "audio", "resource" oder "resource_link". Siehe Bilder und Ressourcen zurückgeben für Nicht-Text-Blöcke.
    • structuredContent (optional): ein JSON-Objekt, das das Ergebnis als maschinenlesbare Daten enthält und zusammen mit content zurückgegeben wird. Siehe Strukturierte Daten zurückgeben.
    • isError (optional): auf true setzen, um einen Tool-Fehler zu signalisieren, damit Claude darauf reagieren kann. Siehe Fehler behandeln.
Nach der Definition eines Tools wickeln Sie es mit createSdkMcpServer (TypeScript) oder create_sdk_mcp_server (Python) in einen Server ein. Der Server läuft prozessinternal in Ihrer Anwendung, nicht als separater Prozess. Python-Beispiele auf dieser Seite, die HTTP-Anfragen senden, verwenden httpx. Fügen Sie es mit dem Paketmanager hinzu, den Ihr Projekt verwendet:

Beispiel für ein Wetter-Tool

Dieses Beispiel definiert ein get_temperature Tool und wickelt es in einen MCP-Server ein, ohne den Server an query zu übergeben. Um das Tool auszuführen, siehe Ein benutzerdefiniertes Tool aufrufen unten.
Siehe die tool() TypeScript-Referenz oder die @tool Python-Referenz für vollständige Parameterdetails, einschließlich JSON Schema Input-Formate und Rückgabewertstruktur.

Einen Parameter optional machen

Um einen Parameter optional zu machen, deklarieren Sie ihn im Schema als optional und wenden Sie den Standardwert im Handler an:
  • TypeScript: Fügen Sie .optional() zum Zod-Feld hinzu.
  • Python: Das Dict-Schema behandelt jeden Schlüssel als erforderlich. Verwenden Sie die JSON-Schema-Form, lassen Sie den Parameter aus required weg und lesen Sie ihn mit args.get(). Für ein typisiertes Schema mit optionalen Schlüsseln siehe TypedDict-Klasse.
Das get_precipitation_chance Tool unten zeigt beide Muster.

Ein benutzerdefiniertes Tool aufrufen

Übergeben Sie den MCP-Server, den Sie erstellt haben, über die Option mcpServers an query. Der vollständig qualifizierte Name jedes Tools lautet mcp__{server_name}__{tool_name}, wobei {server_name} der Schlüssel ist, den Sie dem Server in mcpServers geben. Wenn der Schlüssel Zeichen wie . oder Leerzeichen enthält, ersetzen Sie diese durch _, wenn Sie {server_name} schreiben. Listen Sie den vollständig qualifizierten Namen in allowedTools auf, damit das Tool ohne Berechtigungsabfrage ausgeführt wird. Diese Snippets verwenden den weatherServer aus dem Wetter-Tool-Beispiel erneut, um Claude zu fragen, wie das Wetter an einem bestimmten Ort ist.
Kombinieren Sie diesen Snippet mit den Tool- und Server-Definitionen aus dem Wetter-Tool-Beispiel in einer Datei, weather.py oder weather.ts, und führen Sie ihn dann in Ihrem Terminal aus:
Claude ruft get_temperature auf und das Skript gibt eine einzeilige Antwort mit der aktuellen Temperatur in San Francisco aus.

Weitere Tools hinzufügen

Ein Server enthält so viele Tools, wie Sie in seinem tools Array auflisten. Mit mehr als einem Tool auf einem Server können Sie jedes einzelne in allowedTools auflisten oder das Wildcard mcp__weather__* verwenden, um alle Tools abzudecken, die der Server bereitstellt. Das Beispiel unten definiert ein zweites Tool, get_precipitation_chance, und ersetzt die weatherServer Definition aus dem Wetter-Tool-Beispiel durch eine, die beide Tools im Array auflistet.
Tool-Suche ist standardmäßig aktiviert und verzögert SDK MCP Tools: Claude sieht jeden Tool-Namen in einer kompakten Liste und lädt sein vollständiges Schema bei Bedarf. Mit deaktivierter Tool-Suche verbraucht jedes Tool in diesem Array bei jedem Durchgang Kontextfensterplatz. In TypeScript übergeben Sie alwaysLoad: true im extras Argument von tool() oder in den Optionen von createSdkMcpServer(), um das vollständige Schema eines Tools in der anfänglichen Eingabeaufforderung zu behalten.

Tool-Anmerkungen hinzufügen

Tool-Anmerkungen sind optionale Metadaten, die beschreiben, wie sich ein Tool verhält. Übergeben Sie sie als fünftes Argument an den tool() Helper in TypeScript oder über das annotations Schlüsselwortargument für den @tool Decorator in Python. Alle Hinweisfelder sind Boolesche Werte. Anmerkungen sind Metadaten, keine Durchsetzung. Ein Tool, das mit readOnlyHint: true markiert ist, kann immer noch auf die Festplatte schreiben, wenn das der Handler tut. Halten Sie die Anmerkung genau zum Handler. Dieses Beispiel fügt readOnlyHint zum get_temperature Tool aus dem Wetter-Tool-Beispiel hinzu.
Siehe ToolAnnotations in der TypeScript oder Python Referenz.

Zugriff auf Tools steuern

Das Wetter-Tool-Beispiel registrierte einen Server und listete Tools in allowedTools auf. Dieser Abschnitt behandelt, wie Sie den Zugriff einschränken, wenn Sie mehrere Tools haben oder integrierte Tools beschränken möchten. Informationen zur Konstruktion von Tool-Namen finden Sie unter Ein benutzerdefiniertes Tool aufrufen.

Zulässige Tools konfigurieren

Die Option tools und die Zulassungs-/Ausschlusslisten beeinflussen zwei Ebenen: Verfügbarkeit, die steuert, ob ein Tool im Kontext von Claude angezeigt wird, und Berechtigung, die steuert, ob ein Aufruf genehmigt wird, sobald Claude ihn versucht. tools und Einträge in disallowedTools ohne Bereichsangabe ändern die Verfügbarkeit. allowedTools und Regeln in disallowedTools mit Bereichsangabe ändern die Berechtigung. Wenn Sie eines der Task-Tracking-Tools in allowedTools nennen, wird die Sitzung auch in Claude Code aktiviert. Um ein integriertes Tool vollständig zu entfernen, lassen Sie es aus tools weg oder listen Sie seinen Namen ohne Bereichsangabe in disallowedTools auf (Python: disallowed_tools); beide halten das Tool aus dem Kontext heraus, sodass Claude es nie versucht. Eine Regel in disallowedTools mit Bereichsangabe blockiert übereinstimmende Aufrufe, behält das Tool aber sichtbar, sodass Claude möglicherweise einen Zug damit verschwenden kann. Siehe Berechtigungen konfigurieren für die vollständige Evaluierungsreihenfolge.

Fehler behandeln

Ein Handler-Fehler stoppt die Agent-Schleife nicht. Der In-Process-MCP-Server des SDK fängt unerwartete Ausnahmen ab und gibt sie als Fehler-Ergebnisse zurück. Daher bestimmt, wie Sie einen Fehler melden, was Claude liest, nicht ob die Abfrage fehlschlägt: In beiden Fällen kann Claude erneut versuchen, ein anderes Tool verwenden oder den Fehler erklären. Fangen Sie Fehler selbst ab, wenn die rohe Ausnahmemeldung nicht ausreicht, damit Claude handeln kann. Das folgende Beispiel fängt zwei Arten von Fehlern im Handler ab und verfasst die Fehlermeldung, die Claude liest. Ein HTTP-Status ungleich 200 wird aus der Antwort abgefangen und als Fehler-Ergebnis zurückgegeben. Ein Netzwerkfehler oder ungültiges JSON wird durch den umgebenden try/except (Python) oder try/catch (TypeScript) abgefangen und ebenfalls als Fehler-Ergebnis zurückgegeben. In beiden Fällen erhält Claude eine Meldung, die den Fehler beschreibt, anstelle einer bloßen Ausnahmemeldung.

Bilder und Ressourcen zurückgeben

Das content-Array in einem Tool-Ergebnis akzeptiert text-, image-, audio-, resource- und resource_link-Blöcke. Sie können diese in derselben Antwort mischen. In TypeScript speichert das SDK Audio-Blöcke auf der Festplatte und Claude erhält einen Text-Block mit dem gespeicherten Dateipfad; in Python verwirft das SDK Audio-Blöcke aus dem Tool-Ergebnis und protokolliert eine Warnung. Claude empfängt jeden Resource-Link-Block als Text-Block, der den Namen, die URI und die Beschreibung des Links enthält. In TypeScript erhält Ihre Anwendung die Links auch als resourceLinks in der tool_use_result der Benutzernachricht; in Python vereinfacht das SDK diese zu Text, bevor die CLI das Ergebnis sieht, daher wird der Python-Schlüssel resourceLinks für In-Process-Tools nie erzeugt.

Bilder

Ein Bild-Block enthält die Bild-Bytes inline, kodiert als Base64. Es gibt kein URL-Feld. Um ein Bild zurückzugeben, das sich unter einer URL befindet, rufen Sie es im Handler ab, lesen Sie die Antwort-Bytes und kodieren Sie sie mit Base64, bevor Sie sie zurückgeben. Ein PNG-, JPEG-, GIF- oder WebP-Bild erreicht Claude als visuelle Eingabe; ein Bild eines anderen Typs wird auf der Festplatte gespeichert und Claude erhält seinen Dateipfad als Text statt dessen.

Ressourcen

Ein Ressourcen-Block bettet ein Stück Inhalt ein, das durch eine URI identifiziert wird. Der tatsächliche Inhalt befindet sich im text- oder blob-Feld des Blocks. Verwenden Sie dies, wenn Ihr Tool eine generierte Datei oder einen Datensatz aus einem externen System erzeugt. Dieses Beispiel zeigt einen Ressourcen-Block, der von innerhalb eines Tool-Handlers zurückgegeben wird. Das SDK liest nicht aus dem URI des Beispiels, file:///tmp/report.md.
Diese Block-Formen stammen aus dem MCP-Typ CallToolResult. Siehe die MCP-Spezifikation für die vollständige Definition.

Strukturierte Daten zurückgeben

structuredContent ist ein optionales JSON-Objekt im Ergebnis, getrennt vom content-Array. Verwenden Sie es, um Rohwerte zurückzugeben, die Claude als exakte Felder lesen kann, anstatt sie aus einer Textzeichenfolge oder einem Bild zu analysieren. Wenn structuredContent gesetzt ist, erhält Claude das JSON plus alle Bild- oder Ressourcenblöcke aus content. Textblöcke in content werden nicht weitergeleitet, da angenommen wird, dass sie die strukturierten Daten duplizieren. Das folgende Beispiel rendert ein Diagramm als Bildblock und gibt die dahinter liegenden Datenpunkte in structuredContent vom gleichen Handler zurück. Im Snippet ist chartPngBuffer ein Buffer, das die gerenderten PNG-Bytes enthält.
TypeScript
Der Python-Dekorator @tool leitet nur content und is_error aus dem Rückgabewörterbuch des Handlers weiter. Um structuredContent aus Python zurückzugeben, führen Sie stattdessen einen eigenständigen MCP-Server anstelle eines In-Process-SDK-Servers aus.

Beispiel: Einheitenkonverter

Dieses Tool konvertiert Werte zwischen Längen-, Temperatur- und Gewichtseinheiten. Ein Benutzer kann „100 Kilometer in Meilen umrechnen“ oder „Was sind 72°F in Celsius?“ fragen, und Claude wählt den richtigen Einheitstyp und die richtigen Einheiten aus der Anfrage aus. Es demonstriert zwei Muster:
  • Enum-Schemas: unit_type ist auf einen festen Satz von Werten beschränkt. In TypeScript verwenden Sie z.enum(). In Python unterstützt das Dict-Schema keine Enums, daher ist das vollständige JSON-Schema-Dict erforderlich.
  • Behandlung nicht unterstützter Eingaben: Wenn ein Konvertierungspaar nicht gefunden wird, gibt der Handler isError: true zurück, damit Claude dem Benutzer mitteilen kann, was schief gelaufen ist, anstatt einen Fehler als normales Ergebnis zu behandeln.
Nachdem der Server definiert ist, übergeben Sie ihn an query auf die gleiche Weise wie im Wetter-Beispiel. Dieses Beispiel sendet drei verschiedene Eingabeaufforderungen in einer Schleife, um zu zeigen, dass das gleiche Tool verschiedene Einheitstypen verarbeitet. Für jede Antwort inspiziert es AssistantMessage-Objekte (die die Tool-Aufrufe enthalten, die Claude während dieser Runde getätigt hat) und gibt jeden ToolUseBlock aus, bevor es den endgültigen ResultMessage-Text ausgibt. Dies ermöglicht es Ihnen zu sehen, wann Claude das Tool verwendet, im Gegensatz zu Antworten aus seinem eigenen Wissen. Da Tool-Suche standardmäßig aktiviert ist, kann die Ausgabe auch einen ToolSearch-Aufruf enthalten, wenn Claude das verzögerte Tool-Schema lädt.

Nächste Schritte

Sie können die Muster auf dieser Seite auf demselben Server kombinieren: Ein einzelner Server kann ein Datenbanktool, ein API-Gateway-Tool und einen Bildrenderer nebeneinander enthalten. Von hier aus:
  • Wenn Ihr Server auf Dutzende von Tools wächst, siehe Tool-Suche, um das Laden zu verschieben, bis Claude sie benötigt.
  • Um sich stattdessen mit externen MCP-Servern (Dateisystem, GitHub, Slack) zu verbinden, anstatt Ihre eigenen zu erstellen, siehe MCP-Server verbinden.
  • Um zu steuern, welche Tools automatisch ausgeführt werden, im Vergleich zu denen, die eine Genehmigung erfordern, siehe Berechtigungen konfigurieren.