Skip to main content
Les outils personnalisés étendent le SDK Agent en vous permettant de définir vos propres fonctions que Claude peut appeler lors d’une conversation. En utilisant le serveur MCP en processus du SDK, vous pouvez donner à Claude accès aux bases de données, aux API externes, à la logique spécifique au domaine ou à toute autre capacité dont votre application a besoin.

Référence rapide

Créer un outil personnalisé

Un outil est défini par quatre parties, transmises en tant qu’arguments à la fonction d’assistance tool() en TypeScript ou au décorateur @tool en Python :
  • Nom : un identifiant unique que Claude utilise pour appeler l’outil.
  • Description : ce que fait l’outil. Claude lit ceci pour décider quand l’appeler.
  • Schéma d’entrée : les arguments que Claude doit fournir. En TypeScript, c’est toujours un schéma Zod, et les args du gestionnaire sont typés automatiquement à partir de celui-ci. En Python, c’est un dictionnaire mappant les noms aux types, comme {"latitude": float}, que le SDK convertit en JSON Schema pour vous. Le décorateur Python accepte également directement un dictionnaire JSON Schema complet lorsque vous avez besoin d’énumérations, de plages, de champs optionnels ou d’objets imbriqués.
  • Gestionnaire : la fonction asynchrone qui s’exécute lorsque Claude appelle l’outil. Elle reçoit les arguments validés et doit retourner un objet avec :
    • content (obligatoire) : un tableau de blocs de résultats, chacun avec un type de "text", "image", "audio", "resource" ou "resource_link". Voir Retourner des images et des ressources pour les blocs non-texte.
    • structuredContent (optionnel) : un objet JSON contenant le résultat sous forme de données lisibles par machine, retourné aux côtés de content. Voir Retourner des données structurées.
    • isError (optionnel) : définissez à true pour signaler un échec d’outil afin que Claude puisse y réagir. Voir Gérer les erreurs.
Après avoir défini un outil, enveloppez-le dans un serveur avec createSdkMcpServer (TypeScript) ou create_sdk_mcp_server (Python). Le serveur s’exécute en processus dans votre application, pas en tant que processus séparé.

Exemple d’outil météo

Cet exemple définit un outil get_temperature et l’enveloppe dans un serveur MCP. Il configure uniquement l’outil ; pour le transmettre à query et l’exécuter, voir Appeler un outil personnalisé ci-dessous.
Consultez la référence TypeScript tool() ou la référence Python @tool pour les détails complets des paramètres, y compris les formats de schéma d’entrée JSON et la structure de la valeur de retour.
Pour rendre un paramètre optionnel : en TypeScript, ajoutez .default() au champ Zod. En Python, le schéma dict traite chaque clé comme obligatoire, donc omettez le paramètre du schéma, mentionnez-le dans la chaîne de description, et lisez-le avec args.get() dans le gestionnaire. L’outil get_precipitation_chance ci-dessous montre les deux modèles.

Appeler un outil personnalisé

Transmettez le serveur MCP que vous avez créé à query via l’option mcpServers. La clé dans mcpServers devient le segment {server_name} dans le nom complètement qualifié de chaque outil : mcp__{server_name}__{tool_name}. Listez ce nom dans allowedTools afin que l’outil s’exécute sans invite de permission. Ces extraits réutilisent le weatherServer de l’exemple ci-dessus pour demander à Claude quelle est la météo dans un endroit spécifique.
Combinez cet extrait avec les définitions d’outil et de serveur de l’exemple d’outil météo dans un seul fichier, puis exécutez-le avec python weather.py pour Python ou npx tsx weather.ts pour TypeScript. Claude appelle get_temperature et le script affiche une réponse d’une ligne avec la température actuelle à San Francisco.

Ajouter plus d’outils

Un serveur contient autant d’outils que vous en listez dans son tableau tools. Avec plus d’un outil sur un serveur, vous pouvez lister chacun dans allowedTools individuellement ou utiliser le caractère générique mcp__weather__* pour couvrir tous les outils que le serveur expose. L’exemple ci-dessous définit un deuxième outil, get_precipitation_chance, et remplace la définition weatherServer de l’exemple d’outil météo par une qui liste les deux outils dans le tableau.
La recherche d’outils est activée par défaut et diffère les outils MCP du SDK : Claude voit le nom de chaque outil dans une liste compacte et charge son schéma complet à la demande. Avec la recherche d’outils désactivée, chaque outil de ce tableau consomme de l’espace de fenêtre de contexte à chaque tour. En TypeScript, passez alwaysLoad: true dans l’argument extras de tool() ou dans les options de createSdkMcpServer() pour conserver le schéma complet d’un outil dans l’invite initiale.

Ajouter des annotations d’outil

Les annotations d’outil sont des métadonnées optionnelles décrivant le comportement d’un outil. Transmettez-les en tant que cinquième argument à la fonction d’assistance tool() en TypeScript ou via l’argument de mot-clé annotations pour le décorateur @tool en Python. Tous les champs d’indice sont des booléens. Les annotations sont des métadonnées, pas une application. Un outil marqué readOnlyHint: true peut toujours écrire sur le disque si c’est ce que fait le gestionnaire. Gardez l’annotation exacte au gestionnaire. Cet exemple ajoute readOnlyHint à l’outil get_temperature de l’exemple d’outil météo.
Consultez ToolAnnotations dans la référence TypeScript ou Python.

Contrôler l’accès aux outils

L’exemple d’outil météo a enregistré un serveur et listé les outils dans allowedTools. Cette section couvre comment délimiter l’accès lorsque vous avez plusieurs outils ou que vous souhaitez restreindre les outils intégrés. Pour savoir comment les noms d’outils sont construits, consultez Appeler un outil personnalisé.

Configurer les outils autorisés

L’option tools et les listes d’autorisation/interdiction affectent deux couches : la disponibilité, qui contrôle si un outil apparaît dans le contexte de Claude, et la permission, qui contrôle si un appel est approuvé une fois que Claude le tente. tools et les entrées disallowedTools avec nom simple changent la disponibilité. allowedTools et les règles disallowedTools délimitées changent la permission. Si vous nommez l’un des outils de suivi des tâches dans allowedTools, Claude Code opte également la session. Pour supprimer complètement un outil intégré, omettez-le de tools ou listez son nom simple dans disallowedTools (Python : disallowed_tools) ; les deux gardent l’outil hors du contexte afin que Claude ne le tente jamais. Une règle disallowedTools délimitée bloque les appels correspondants mais laisse l’outil visible, donc Claude peut gaspiller un tour en le tentant. Consultez Configurer les permissions pour l’ordre d’évaluation complet.

Gérer les erreurs

Une erreur de gestionnaire n’arrête pas la boucle de l’agent. Le serveur MCP en processus du SDK capture les exceptions non capturées et les retourne sous forme de résultats d’erreur, donc la façon dont vous signalez une erreur détermine ce que Claude lit, non pas si la requête échoue : Dans les deux cas, Claude peut réessayer, essayer un outil différent ou expliquer l’échec. Capturez les erreurs vous-même quand le message d’exception brut n’est pas suffisant pour que Claude agisse. L’exemple ci-dessous capture deux types d’échecs à l’intérieur du gestionnaire et compose le message d’erreur que Claude lit. Un statut HTTP non-200 est capturé à partir de la réponse et retourné sous forme de résultat d’erreur. Une erreur réseau ou un JSON invalide est capturé par le try/except (Python) ou try/catch (TypeScript) environnant et est également retourné sous forme de résultat d’erreur. Dans les deux cas, Claude reçoit un message qui décrit l’échec au lieu d’une simple chaîne d’exception.

Retourner des images et des ressources

Le tableau content dans un résultat d’outil accepte les blocs text, image, audio, resource et resource_link. Vous pouvez les mélanger dans la même réponse. En TypeScript, le SDK enregistre les blocs audio sur le disque et Claude reçoit un bloc de texte avec le chemin du fichier enregistré ; en Python, le SDK supprime les blocs audio du résultat de l’outil et enregistre un avertissement. Claude reçoit chaque bloc de lien de ressource sous la forme d’un bloc de texte contenant le nom, l’URI et la description du lien. En TypeScript, votre application reçoit également les liens eux-mêmes sous la forme de resourceLinks sur le tool_use_result du message utilisateur ; en Python, le SDK les aplatit en texte avant que l’interface de ligne de commande ne voie le résultat, donc la clé Python resourceLinks n’est jamais produite pour les outils en processus.

Images

Un bloc d’image porte les octets de l’image en ligne, codés en base64. Il n’y a pas de champ URL. Pour retourner une image qui se trouve à une URL, récupérez-la dans le gestionnaire, lisez les octets de la réponse et encodez-les en base64 avant de les retourner. Le résultat est traité comme une entrée visuelle.

Ressources

Un bloc de ressource intègre un élément de contenu identifié par un URI. L’URI est une étiquette pour que Claude la référence ; le contenu réel se trouve dans le champ text ou blob du bloc. Utilisez ceci lorsque votre outil produit quelque chose qui a du sens à adresser par nom plus tard, comme un fichier généré ou un enregistrement d’un système externe. Cet exemple montre un bloc de ressource retourné de l’intérieur d’un gestionnaire d’outil. L’URI file:///tmp/report.md est une étiquette que Claude peut référencer plus tard ; le SDK ne lit pas à partir de ce chemin.
Ces formes de bloc proviennent du type MCP CallToolResult. Consultez la spécification MCP pour la définition complète.

Retourner des données structurées

structuredContent est un objet JSON optionnel sur le résultat, séparé du tableau content. Utilisez-le pour retourner des valeurs brutes que Claude peut lire comme des champs exacts au lieu de les analyser à partir d’une chaîne de texte ou d’une image. Lorsque structuredContent est défini, Claude reçoit le JSON plus tous les blocs d’image ou de ressource de content. Les blocs de texte dans content ne sont pas transmis, car on suppose qu’ils dupliquent les données structurées. L’exemple ci-dessous affiche un graphique sous forme de bloc d’image et retourne les points de données derrière celui-ci dans structuredContent à partir du même gestionnaire. Dans l’extrait, chartPngBuffer est un Buffer contenant les octets PNG rendus.
TypeScript
Le décorateur Python @tool transmet uniquement content et is_error du dictionnaire de retour du gestionnaire. Pour retourner structuredContent à partir de Python, exécutez un serveur MCP autonome au lieu d’un serveur SDK en processus.

Exemple : convertisseur d’unités

Cet outil convertit les valeurs entre les unités de longueur, de température et de poids. Un utilisateur peut demander « convertir 100 kilomètres en miles » ou « combien font 72°F en Celsius », et Claude choisit le bon type d’unité et les bonnes unités à partir de la demande. Il démontre deux modèles :
  • Schémas d’énumération : unit_type est limité à un ensemble fixe de valeurs. En TypeScript, utilisez z.enum(). En Python, le schéma dict ne supporte pas les énumérations, donc le schéma JSON Schema complet est requis.
  • Gestion des entrées non supportées : quand une paire de conversion n’est pas trouvée, le gestionnaire retourne isError: true pour que Claude puisse dire à l’utilisateur ce qui s’est mal passé plutôt que de traiter un échec comme un résultat normal.
Une fois le serveur défini, passez-le à query de la même manière que l’exemple météo. Cet exemple envoie trois invites différentes dans une boucle pour montrer le même outil gérant différents types d’unités. Pour chaque réponse, il inspecte les objets AssistantMessage (qui contiennent les appels d’outils que Claude a effectués pendant ce tour) et imprime chaque ToolUseBlock avant d’imprimer le texte final ResultMessage. Cela vous permet de voir quand Claude utilise l’outil par rapport à répondre à partir de ses propres connaissances. Parce que la recherche d’outils est activée par défaut, la sortie peut également inclure un appel ToolSearch alors que Claude charge le schéma d’outil différé.

Étapes suivantes

Vous pouvez mélanger les modèles de cette page dans le même serveur : un seul serveur peut contenir un outil de base de données, un outil de passerelle API et un moteur de rendu d’images côte à côte. À partir d’ici :
  • Si votre serveur s’agrandit à des dizaines d’outils, consultez recherche d’outils pour différer leur chargement jusqu’à ce que Claude en ait besoin.
  • Pour vous connecter à des serveurs MCP externes (système de fichiers, GitHub, Slack) au lieu de construire les vôtres, consultez Connecter les serveurs MCP.
  • Pour contrôler quels outils s’exécutent automatiquement par rapport à ceux nécessitant une approbation, consultez Configurer les permissions.