Zum Hauptinhalt springen
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. Dieser Leitfaden behandelt, wie Sie Tools mit Eingabeschemas und Handlern definieren, sie in einen MCP-Server bündeln, sie an query übergeben und kontrollieren, auf welche Tools Claude zugreifen kann. Er behandelt auch Fehlerbehandlung, Tool-Annotationen und die Rückgabe von Nicht-Text-Inhalten wie Bildern.

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-Dekorator in Python übergeben werden:
  • Name: ein eindeutiger Bezeichner, den Claude verwendet, um das Tool aufzurufen.
  • Beschreibung: was das Tool tut. Claude liest dies, um zu entscheiden, wann es aufgerufen werden soll.
  • Eingabeschema: die Argumente, die Claude bereitstellen muss. In TypeScript ist dies immer ein Zod-Schema, und die args des Handlers werden automatisch davon typisiert. In Python ist dies ein Dict, das Namen auf Typen abbildet, wie {"latitude": float}, das das SDK für Sie in JSON Schema konvertiert. Der Python-Dekorator 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 empfängt die validierten Argumente und muss ein Objekt mit folgenden Eigenschaften zurückgeben:
    • content (erforderlich): ein Array von Ergebnisblöcken, jeder mit einem type von "text", "image", "audio", "resource" oder "resource_link". Siehe Geben Sie Bilder und Ressourcen zurück für Nicht-Text-Blöcke.
    • structuredContent (optional): ein JSON-Objekt, das das Ergebnis als maschinenlesbare Daten enthält, das zusammen mit content zurückgegeben wird. Siehe Geben Sie strukturierte Daten zurück.
    • isError (optional): setzen Sie auf true, um einen Tool-Fehler zu signalisieren, damit Claude darauf reagieren kann. Siehe Fehler behandeln.
Nach dem Definieren eines Tools wickeln Sie es mit createSdkMcpServer (TypeScript) oder create_sdk_mcp_server (Python) in einen Server ein. Der Server läuft im Prozess in Ihrer Anwendung, nicht als separater Prozess.

Beispiel für ein Wetter-Tool

Dieses Beispiel definiert ein get_temperature-Tool und wickelt es in einen MCP-Server ein. Es richtet nur das Tool ein; um es an query zu übergeben und auszuführen, siehe Rufen Sie ein benutzerdefiniertes Tool auf unten.
Siehe die tool()-TypeScript-Referenz oder die @tool-Python-Referenz für vollständige Parameterdetails, einschließlich JSON-Schema-Eingabeformate und Rückgabewertstruktur.
Um einen Parameter optional zu machen: Fügen Sie in TypeScript .default() zum Zod-Feld hinzu. In Python behandelt das Dict-Schema jeden Schlüssel als erforderlich, also lassen Sie den Parameter aus dem Schema weg, erwähnen Sie ihn in der Beschreibungszeichenkette und lesen Sie ihn mit args.get() im Handler. Das get_precipitation_chance-Tool unten zeigt beide Muster.

Rufen Sie ein benutzerdefiniertes Tool auf

Übergeben Sie den MCP-Server, den Sie erstellt haben, an query über die mcpServers-Option. Der Schlüssel in mcpServers wird zum {server_name}-Segment im vollständig qualifizierten Namen jedes Tools: mcp__{server_name}__{tool_name}. Listen Sie diesen Namen in allowedTools auf, damit das Tool ohne Genehmigungsaufforderung ausgeführt wird. Diese Snippets verwenden den weatherServer aus dem Beispiel oben wieder, um Claude zu fragen, wie das Wetter an einem bestimmten Ort ist.

Fügen Sie weitere Tools hinzu

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 verfügbar macht. Das Beispiel unten fügt ein zweites Tool, get_precipitation_chance, zum weatherServer aus dem Wetter-Tool-Beispiel hinzu und erstellt ihn mit beiden Tools im Array neu.
Jedes Tool in diesem Array verbraucht Kontextfensterplatz bei jedem Durchgang. Wenn Sie Dutzende von Tools definieren, siehe Tool-Suche, um sie stattdessen bei Bedarf zu laden.

Fügen Sie Tool-Annotationen hinzu

Tool-Annotationen 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-Dekorator in Python. Alle Hint-Felder sind Boolesche Werte. Annotationen 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 Annotation 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.

Tool-Zugriff kontrollieren

Das Wetter-Tool-Beispiel registrierte einen Server und listete Tools in allowedTools auf. Dieser Abschnitt behandelt, wie Tool-Namen konstruiert werden und wie Sie den Zugriff scoped, wenn Sie mehrere Tools haben oder integrierte Tools einschränken möchten.

Tool-Namensformat

Wenn MCP-Tools Claude verfügbar gemacht werden, folgen ihre Namen einem bestimmten Format:
  • Muster: mcp__{server_name}__{tool_name}
  • Beispiel: Ein Tool namens get_temperature im Server weather wird zu mcp__weather__get_temperature

Zulässige Tools konfigurieren

Die tools-Option und die zulässigen/nicht zulässigen Listen beeinflussen zwei Ebenen: Verfügbarkeit, die steuert, ob ein Tool in Claudes Kontext angezeigt wird, und Berechtigung, die steuert, ob ein Aufruf genehmigt wird, sobald Claude ihn versucht. tools und einfache disallowedTools-Einträge ändern die Verfügbarkeit. allowedTools und scoped disallowedTools-Regeln ändern nur die Berechtigung. Um ein integriertes Tool vollständig zu entfernen, lassen Sie es aus tools weg oder listen Sie seinen einfachen Namen in disallowedTools (Python: disallowed_tools) auf; beide halten das Tool aus dem Kontext, damit Claude es nie versucht. Eine scoped disallowedTools-Regel blockiert übereinstimmende Aufrufe, lässt das Tool aber sichtbar, daher kann Claude möglicherweise einen Durchgang damit verschwenden. 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 nicht abgefangene 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 versuchen oder den Fehler erklären. Fangen Sie Fehler selbst ab, wenn die rohe Ausnahmemeldung nicht ausreicht, damit Claude handeln kann. Das Beispiel unten fängt zwei Arten von Fehlern im Handler ab und verfasst die Fehlermeldung, die Claude liest. Ein Nicht-200-HTTP-Status wird aus der Antwort abgefangen und als Fehler-Ergebnis zurückgegeben. Ein Netzwerkfehler oder ungültiges JSON wird durch das umgebende try/except (Python) oder try/catch (TypeScript) abgefangen und auch als Fehler-Ergebnis zurückgegeben. In beiden Fällen erhält Claude eine Meldung, die den Fehler beschreibt, anstatt einer bloßen Ausnahmemeldung.

Geben Sie Bilder und Ressourcen zurück

Das content-Array in einem Tool-Ergebnis akzeptiert text-, image-, audio-, resource- und resource_link-Blöcke. Sie können sie in derselben Antwort mischen. In TypeScript werden Audio-Blöcke auf der Festplatte gespeichert und Claude erhält einen Text-Block mit dem gespeicherten Dateipfad; in Python löscht das SDK Audio-Blöcke aus dem Tool-Ergebnis und protokolliert eine Warnung. Resource-Link-Blöcke werden in einen Text-Block konvertiert, der den Namen, die URI und die Beschreibung des Links enthält.

Bilder

Ein Bildblock trägt die Bildbytes 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 Antwortbytes und kodieren Sie sie Base64, bevor Sie sie zurückgeben. Das Ergebnis wird als visueller Input verarbeitet.

Ressourcen

Ein Ressourcenblock bettet ein Stück Inhalt ein, das durch einen URI identifiziert wird. Der URI ist ein Label für Claude, um darauf zu verweisen; der tatsächliche Inhalt befindet sich im text- oder blob-Feld des Blocks. Verwenden Sie dies, wenn Ihr Tool etwas produziert, das sinnvoll ist, um später nach Name adressiert zu werden, wie eine generierte Datei oder ein Datensatz aus einem externen System. Dieses Beispiel zeigt einen Ressourcenblock, der von innen aus einem Tool-Handler zurückgegeben wird. Der URI file:///tmp/report.md ist ein Label, das Claude später referenzieren kann; das SDK liest nicht aus diesem Pfad.
Diese Block-Formen stammen aus dem MCP-CallToolResult-Typ. Siehe die MCP-Spezifikation für die vollständige Definition.

Geben Sie strukturierte Daten zurück

structuredContent ist ein optionales JSON-Objekt auf dem Ergebnis, getrennt vom content-Array. Verwenden Sie es, um Rohwerte zurückzugeben, die Claude als exakte Felder lesen kann, anstatt sie aus einer Textzeichenkette oder einem Bild zu analysieren. Wenn structuredContent gesetzt ist, empfängt 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 Beispiel unten rendert ein Diagramm als Bildblock und gibt die Datenpunkte dahinter in structuredContent vom selben Handler zurück.
TypeScript
Der Python-@tool-Dekorator leitet nur content und is_error aus dem Rückgabe-Dict des Handlers weiter. Um structuredContent von Python zurückzugeben, führen Sie stattdessen einen eigenständigen MCP-Server aus.

Beispiel: Einheitenkonverter

Dieses Tool konvertiert Werte zwischen Einheiten der Länge, Temperatur und des Gewichts. Ein Benutzer kann fragen „100 Kilometer in Meilen konvertieren” oder „Was ist 72°F in Celsius”, und Claude wählt den richtigen Einheitstyp und die Einheiten aus der Anfrage. 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 sagen kann, was schief gelaufen ist, anstatt einen Fehler als normales Ergebnis zu behandeln.
Sobald der Server definiert ist, übergeben Sie ihn an query auf die gleiche Weise wie das Wetter-Beispiel. Dieses Beispiel sendet drei verschiedene Prompts in einer Schleife, um zu zeigen, wie dasselbe Tool verschiedene Einheitstypen handhabt. Für jede Antwort inspiziert es AssistantMessage-Objekte (die die Tool-Aufrufe enthalten, die Claude während dieses Durchgangs gemacht hat) und gibt jeden ToolUseBlock aus, bevor es den endgültigen ResultMessage-Text ausgibt. Dies lässt Sie sehen, wann Claude das Tool verwendet, im Gegensatz zu Antworten aus seinem eigenen Wissen.

Nächste Schritte

Benutzerdefinierte Tools wickeln asynchrone Funktionen in einer Standardschnittstelle ein. Sie können die Muster auf dieser Seite im selben Server mischen: Ein einzelner Server kann ein Datenbank-Tool, ein API-Gateway-Tool und einen Bild-Renderer nebeneinander halten. 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 mit externen MCP-Servern (Dateisystem, GitHub, Slack) zu verbinden, anstatt Ihre eigenen zu erstellen, siehe Verbinden Sie MCP-Server.
  • Um zu kontrollieren, welche Tools automatisch ausgeführt werden, im Gegensatz zu denen, die Genehmigung erfordern, siehe Konfigurieren Sie Berechtigungen.