Quand une équipe « ajoute un outil » à un agent, elle superpose souvent trois choses différentes sous le même mot : les étapes d'un SKILL.md, une capacité appelable sur un serveur MCP, et le JSON Schema de Function Calling / d'une API HTTP. Les trois peuvent contenir du JSON, mais ils ne résolvent pas le même problème. Cet article est daté du 17/09/2026 : d'abord séparer les trois couches, puis un arbre de décision et un Tool Schema recettable dans l'espace de travail. Comment les Skills se chargent à la demande : Pourquoi un agent a besoin de Skills ; comment l'API Responses et MCP entrent dans le même tableau tools : Agent DevDay 2026 ; pourquoi la couche contrat est du JSON : Pourquoi l'IA aime JSON.
En 2026, les produits Agent parlent déjà trois vocabulaires à la fois. Cursor, Claude Code et Codex scannent SKILL.md ; les mêmes produits se connectent aussi à MCP ; l'API Responses d'OpenAI, le tool_use de Claude et les function declarations de Gemini continuent de consommer Function Calling. Le « vs » du titre pousse à prendre parti. En production, on empile plus souvent : le Skill fixe l'ordre, MCP ou l'API exécutent, le Schema valide. Ce qu'on rate n'est pas une marque, c'est une couche.
Pourquoi « choisir un outil » fait rater la couche
« Ajouter un outil à l'agent » sonne comme un achat. Les vrais ratés sont généralement ces trois-là :
- Prendre le manuel pour un outil. Huit étapes de mise en production, une classification d'incidents, un catalogue de types de schémas deviennent un serveur MCP, et chaque appel ne renvoie qu'un paragraphe d'explication. Le protocole tourne à vide, le contexte gonfle quand même.
- Transformer une fonction unique en bus. Seul votre backend appelle
create_invoice, mais vous ouvrez un MCP dédié, configurez l'authentification, écrivez la config Host. Réutilisation nulle, surface de panne en plus. - Écrire les types de champs dans la prose. Le corps du Skill dit « le prix est un nombre », l'API envoie une chaîne ; l'
inputSchemaMCP recopie une troisième version. Les trois couches ne s'alignent pas, la validation dérive partout.
Donc trois questions avant de choisir l'implémentation : est-ce une étape, ou une action ? Combien de Host doivent partager cette action ? Les entrées / sorties peuvent-elles être figées par un Schema ? Les étapes vont dans un Skill ; une action à réutiliser entre Host, avec isolation des identifiants, va dans MCP ; une action qui ne sert que votre boucle va dans API / Function Calling. Le contrat s'écrit d'abord en JSON Schema.
En une phrase. Le Skill répond à how, MCP à access, l'API à « le contrat de ce saut ». Le JSON Tool Schema est l'interface dure des deux dernières couches — et la part qu'un Skill ne doit pas remplacer par de la prose.
D'abord trois couches : manuel, bus, interface
Une fois le runtime retiré, les trois couches ressemblent à ceci :
Les flèches indiquent une dépendance, pas l'obligation d'empiler les trois couches. Un agent de facturation interne peut n'avoir que Function Calling + un court prompt système. Une équipe qui veut partager « consulter une commande » entre éditeur, CLI et boucle maison a intérêt à ranger l'action dans MCP et les étapes d'acceptation dans un Skill.
SKILL.md : connaissance procédurale, pas un outil appelable
Un Agent Skill est un dossier : à la racine, SKILL.md, le frontmatter YAML porte name et description, le corps écrit les étapes ; les longs tableaux vont dans references/, les fragments exécutables dans scripts/. Au démarrage, le runtime n'enregistre que l'index ; le déploiement a lieu après correspondance de tâche ou commande slash. C'est du chargement progressif, pas du RPC.
Un Skill ne fournit pas de données temps réel, et n'exécute pas d'effets de bord à votre place. Il dit à l'agent : lire les tokens de marque avant de dessiner ; passer ces 8 étapes avant une mise en production ; en cas d'échec de requête, lire d'abord le code d'erreur avant de réessayer ou de s'arrêter. L'outil lui-même se branche ailleurs. Dans la communauté, i-have-adhd contraint la forme de sortie, diagram-design charge à la demande un manuel de types de schémas — les deux sont des processus, pas une action du type « créer une GitHub Release ». Détails dans l'article précédent Pourquoi les Coding Agents ont besoin de Skills.
description est la ligne la plus importante de cette couche. « Traiter un incident » ne sera pas routé ; des mots-clés de déclenchement et des limites d'applicabilité clairs le chargeront sur la bonne tâche. C'est la même intuition d'ingénierie que la description d'outil, un cran plus haut : choisir le mauvais Skill, c'est ouvrir le mauvais manuel.
Figer la frontière. Envelopper un get_order isolé dans un Skill est généralement du gaspillage. Un Skill vaut le coup quand il y a plusieurs étapes, des jugements, des conditions d'arrêt. Un appel unique tient dans la description de l'outil.
Serveur MCP : runtime d'outils standardisé
MCP (Model Context Protocol) est un protocole client-serveur, sous-jacent JSON-RPC. Le Server expose tools, resources, prompts ; le Host (Cursor, Claude Code, agent maison, MCP distant de certains cloud) découvre et appelle. Vous écrivez le Server une fois ; plusieurs Host compatibles listent le même jeu d'outils. Le transport peut être stdio local ou HTTP distant.
Ce que MCP achète, ce n'est pas « plus intelligent que Function Calling », ce sont ces trois choses :
- Réutilisation. La même capacité de requête, de création d'issue, de pilotage de navigateur, sans adapter chaque produit Agent.
- Isolation. Identifiants et effets de bord restent dans le processus Server ; le modèle ne voit que le nom d'outil et le Schema.
- Découverte. Le Host liste les outils selon le protocole ; la description et
inputSchemadécident quand le modèle tend la main.
Le contrat d'outil reste du JSON Schema. L'inputSchema MCP (et de plus en plus l'outputSchema) et les parameters de Function Calling sont le même type d'objet, seuls les champs d'enveloppe changent. L'API Responses d'OpenAI peut déjà mettre un MCP distant et une function maison dans le même tableau tools — le protocole entre dans la plateforme, cela n'autorise pas à sauter le Schema. Voir Le contrat Agent après le DevDay.
N'ouvrez pas un MCP pour une fonction que « seule votre boucle appellera, sans besoin d'isolation ». Protocole, processus, config Host : tout a un coût. Quand la surface de réutilisation est nulle, l'API directe est plus courte.
API / Function Calling : contrat métier en ligne directe
Ici, API désigne deux choses souvent mélangées :
- Function Calling / tool calling côté modèle. Vous déclarez
name,description,parameters(JSON Schema) dans la requête ; le modèle renvoie un appel structuré ; votre code exécute puis renvoie le résultat. OpenAI, Claude, Gemini ont des enveloppes différentes, le cœur est ce Schema. - HTTP / RPC métier. Vos APIs de facturation, stock, recherche. C'est l'état de ces systèmes que l'agent finit par modifier. Function Calling peut les frapper directement, ou un serveur MCP peut les envelopper.
L'avantage de Function Calling est la courte : pas de second processus, pas de liste Host, les identifiants ne quittent pas votre backend. L'inconvénient est clair : changer de produit Agent, c'est redéclarer ; trop d'outils, et il faut un chargement différé ou une recherche, sinon les descriptions saturent le contexte.
Les vendeurs glissent aussi des capacités intégrées dans le tableau d'outils (web, exécution de code, MCP distant). C'est de l'exécution hébergée par la plateforme, pas une raison d'omettre le Schema. Vos actions propres ont toujours besoin d'entrées / sorties validables. Définition : Qu'est-ce que la Structured Output ; dériver depuis un exemple : Comment générer un Schema.
JSON Tool Schema : la couche contrat partagée
Dans les trois couches, la seule chose à « figer d'abord, puis distribuer » est la forme de l'objet outil. Maintenez un Schema cœur, puis les enveloppes :
- OpenAI function :
type: "function"+parameters, en mode strict l'objet veut souventadditionalProperties: false. - Claude tool :
input_schema. - Gemini :
parameters/ function declarations, sous-ensemble plus étroit. - MCP tool :
inputSchema,outputSchemaoptionnel.
Un Skill ne remplace pas ce contrat. Le Skill peut dire « d'abord get_order, s'il manque order_id on s'arrête », mais il ne peut pas figer en prose que total est un number. Types, required, enum, extra fields autorisés ou non : seulement dans le Schema. Sinon le même outil diverge en silence entre MCP et API.
Quand un Coding Agent modifie mcp.json / settings.json, c'est la même intuition : le fichier est un correctif texte, la validité de l'objet reste du parse et du Schema. Voir Comment un agent modifie une config JSON.
Arbre de décision : quelle couche, quand
Posez les questions dans cet ordre : moins de Server inutiles, moins de longs prompts permanents.
- Surtout des étapes, des jugements, des conditions d'arrêt, pas un effet de bord unique ? Écrire un Skill. La
descriptionporte les mots-clés de déclenchement ; le corps reste court ; les longs catalogues vont dansreferences/. - Une action (ou quelques-unes), et seule votre boucle backend l'appelle ? Function Calling ou API HTTP maison. Schema dans la requête, exécution dans votre processus.
- La même action pour deux Host ou plus, ou les identifiants doivent quitter le processus du modèle ? Serveur MCP. Le Host ne voit que la liste d'outils et le Schema.
- À la fois jugements multi-étapes et vraie action ? Skill + (MCP ou API). Le Skill gère l'ordre et l'acceptation, l'outil l'exécution. N'omettez pas une couche en la réduisant à de la prose.
- Pas encore d'objet exemple parsable ? Ne choisissez pas le bus. D'abord un exemple, puis le Schema, puis la couche.
Une règle empirique : l'échelle minimale raisonnable de MCP est « un second Host s'y branchera » ou « les identifiants ne doivent pas entrer dans le prompt ». Celle d'un Skill : « sans lui, le modèle saute des étapes ou tend la main au mauvais moment sur des tâches hors sujet ».
Tableau comparatif
| Skill | MCP | API / Function Calling | |
|---|---|---|---|
| Question | Quand, dans quel ordre | D'où vient l'outil, comment le découvrir | Entrée / sortie de ce saut |
| Forme | Dossier SKILL.md |
Serveur JSON-RPC | Déclaration d'outil dans la requête, ou HTTP |
| Contrat | frontmatter + Markdown | inputSchema / URI de ressource |
JSON Schema parameters |
| Chargement | À la demande après correspondance | Le Host liste, le modèle décide d'appeler | Déclaré avec la requête, ou recherche différée |
| Effets de bord | Aucun (sauf si scripts sont exécutés) |
Dans le processus Server | Dans votre backend |
| Multi-produit | Fort (convention de dossier ouverte) | Fort (couche protocole) | Faible (enveloppes différentes selon les vendeurs) |
| Convient à | Manuel, acceptation, forme de sortie | Capacités partagées, isolation des identifiants | Boucle mono-app, chemin court |
Les trois s'utilisent souvent ensemble : une Rule ou un Skill court fige « interdiction de committer une clé » ; un Skill impose « ces 8 étapes avant une mise en production » ; MCP fournit « créer une Release » ; si la Release n'est créée que dans votre Agent CI, ce peut aussi être Function Calling. Un seul Schema à maintenir.
Signaux fréquents d'une mauvaise couche
- MCP enveloppe un texte d'explication. Le résultat n'est qu'un manuel Markdown. C'est un Skill, ça ne mérite pas un Server.
- MCP pour une fonction unique. Pas de second Host, pas besoin d'isolation. Revenir à Function Calling.
- 80 lignes d'étapes de requête en prompt système permanent. Les tâches hors sujet en héritent aussi. Migrer vers un Skill ; la description d'outil ne garde qu'une ligne de déclenchement.
- Trois définitions du même champ. Prose du Skill, Schema API, Schema MCP chacun de son côté. Fusionner d'abord en un objet cœur.
- Remplacer l'authentification par un Skill. « Ne pas supprimer la base de prod » dans le manuel n'empêche pas le modèle qui a vraiment obtenu
delete_*. Les règles de refus et le moindre privilège sont à la couche outil, pas dans le Markdown. - Laisser l'agent réécrire toute la config MCP. Tableaux écrasés, commentaires mangés. Lire d'abord, puis le plus petit correctif : Comment modifier une config JSON.
Un Tool Schema recettable en local
Voici l'objet cœur d'une action de facturation. Ce n'est pas encore l'enveloppe OpenAI / MCP, seulement le contrat. Les trois enveloppes vendeurs et l'inputSchema MCP poussent à partir d'ici.
{
"tool": "create_invoice",
"description": "Create a draft invoice for an existing order. Use when the user asks to bill, issue, or generate an invoice. Do not call if order_id is missing.",
"arguments": {
"order_id": "ord_1042",
"currency": "USD",
"line_items": [
{
"sku": "seat-pro",
"quantity": 12,
"unit_cents": 4900
}
],
"require_approval": true
},
"result": {
"invoice_id": "inv_7781",
"status": "draft",
"total_cents": 58800
}
}
Le Schema cœur correspondant doit d'abord refermer trois points : order_id / currency / line_items required ; unit_cents est un integer, pas une chaîne ; additionalProperties de l'objet d'abord à false, pour éviter que le modèle glisse un note. require_approval est une décision produit : ne l'écrivez pas seulement dans le corps du Skill — si la couche outil ne le voit pas, elle ne bloquera pas un mauvais appel.
Côté Skill, seulement les étapes : s'il manque order_id, s'arrêter ; d'abord get_order puis create_invoice ; si status n'est pas draft, ne pas envoyer l'e-mail. Ces phrases n'entrent pas dans le Schema.
Recetter dans la Boîte à outils JSON
- Coller les
arguments/resultci-dessus dans le formatage JSON, confirmer que ça parse. - Avec JSON → Schema ou Structured Output, générer le contrat cœur, compléter required et
additionalProperties. - Les mêmes champs via Function Calling et MCP Tool, sans recopier deux jeux de types.
- Un second vrai retour dans la validation Schema ; si ça ne s'aligne pas avec l'exemple, la comparaison JSON.
Tout est traité dans le navigateur, rien n'est envoyé au serveur. D'abord un objet validable, ensuite seulement décider s'il se branche derrière un Skill, MCP ou une API.
FAQ
Agent Skills et MCP, c'est la même chose ?
Non. Un Skill est un manuel : SKILL.md répond à quand, dans quel ordre. MCP est un bus : le Server répond d'où viennent les outils, comment les découvrir et les appeler. Un Skill ne se connecte pas à une base ; MCP n'écrit pas l'ordre d'une mise en production.
On a déjà Function Calling / API, pourquoi MCP ?
Function Calling sert cette requête-ci. MCP permet à plusieurs Host de découvrir la même capacité, et laisse les identifiants dans le Server. Une seule boucle, sans besoin d'isolation : pas besoin de MCP.
Quand écrire seulement une API, sans brancher MCP ?
L'outil n'est appelé que par votre backend, les identifiants ne quittent pas ce processus, aucun second Host. MCP achète la réutilisation et l'isolation, pas un appel unitaire plus rapide.
À quelle couche écrire le JSON Tool Schema ?
À la couche contrat d'outil : parameters de Function Calling, ou inputSchema de MCP. Le Skill n'écrit que les étapes et les conditions d'arrêt. Un seul Schema cœur, puis les enveloppes de chaque vendeur.
Comment savoir qu'on a choisi la mauvaise couche ?
Ouvrir un MCP pour une fonction ; étapes de requête en prompt permanent ; types fixés en prose ; champs copiés à part dans l'API et MCP, et qui ne s'alignent pas. D'abord figer l'objet en Schema, puis choisir le bus.
En résumé
Choisir un outil pour un agent IA, ce n'est pas désigner un gagnant parmi Skill, MCP et API. Le Skill range les processus métier reproductibles en manuel à la demande ; MCP range en serveur les actions à réutiliser entre Host et à isoler côté identifiants ; API / Function Calling range en chemin le plus court les actions qui ne servent que votre boucle. Sous les trois couches, le même JSON Tool Schema : types, required, extra fields se figent ici, les enveloppes peuvent changer. Pour le développeur, la suite n'est pas d'abord un Server, ni un prompt plus long, mais un objet exemple parsable — index court, contrat dur, manuel à la demande, bus facturé à la surface de réutilisation.