Function Calling / Tool Calling / MCP JSON-RPC — quatre round-trips / dialectes de schémas / observabilité et isolation
Ouvrez Cursor, Claude Code ou un log de debug d'un framework Agent : presque chaque payload est du JSON — catalogues d'outils en JSON Schema, tool_calls du modèle en JSON, frames MCP Server en JSON-RPC 2.0. Ce n'est pas accidentel — les Agents doivent relier langage naturel imprévisible et interfaces programmatiques exécutables, et JSON est le format d'échange que les deux côtés peuvent parser fiablement.
Cet article parcourt Function Calling → Tool Calling → MCP et cartographie les quatre round-trips JSON d'une invocation d'outil complète. Si vous déployez un MCP Server sur un Mac cloud ou choisissez des frameworks depuis notre sélection GitHub Agent, comprendre ce flux vaut mieux que mémoriser les docs API pour déboguer.
Les Agents parlent JSON presque partout
Les LLM émettent des flux de tokens ; Shell, bases de données et API HTTP exigent des arguments structurés. La pratique initiale était le prompting « réponds dans ce format JSON » — les modèles ajoutaient des virgules finales, omettaient des guillemets ou enveloppaient du Markdown, et les parseurs échouaient sans cesse.
Depuis 2023, les grandes API ont déplacé les actions structurées dans le protocole : le modèle n'émet plus librement du texte JSON arbitraire ; le serveur contraint la forme de sortie et le Host exécute. Le pipeline devient :
- Declare — déclarer les outils avec JSON Schema ;
- Decide — choisir nom d'outil et paramètres dans une grammaire contrainte ;
- Execute — exécuter via code local ou MCP Server ;
- Write back — réécrire les résultats en messages JSON dans le contexte.
Principe de design : observabilité Agent = logger, rejouer et diff chaque étape JSON. Sans intermédiaires structurés, l'automatisation n'est pas auditable.
Function Calling : du langage naturel aux actions structurées
L'objet function de l'ère OpenAPI
OpenAI a ajouté functions / tools à Chat Completions : vous attachez des définitions d'outils à la requête ; le modèle retourne function_call ou tool_calls au lieu de texte à parser par regex.
Snippet de requête typique
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Météo à Tokyo ?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Météo actuelle par ville",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}]
}Les templates JSON écrits à la main dans les prompts sont remplacés par des contraintes protocolaires ; le Host valide arguments contre le schéma puis appelle de vraies fonctions. Function Calling fixe ce que le modèle dit — pas où les outils tournent, comment ils sont découverts ou comment l'auth fonctionne. Les écosystèmes Tool Calling et MCP gèrent cela.
Tool Calling : quatre round-trips JSON par tour
- Register — le Host envoie
tools[]avec JSON Schema à l'API modèle ; - Decide — l'API retourne
tool_callsavecid,name,arguments(chaîne JSON) ; - Execute — le Host parse les arguments et appelle le code local ou MCP ;
- Write back — messages
role: toolretournent les résultats ; le modèle produit la réponse utilisateur.
{
"tool_calls": [{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Tokyo\"}"
}
}]
}arguments est une chaîne, pas un objet imbriqué — pour le streaming et la compatibilité SDK. Les Hosts doivent JSON.parse(arguments) avant validation. Appuyez sur Ctrl + Shift + I dans DevTools et vous verrez la même structure dans Network.
| Étape | Direction | Payload | Parser |
|---|---|---|---|
| ① Register | Host → API | tools[] + JSON Schema | Gateway API |
| ② Decide | API → Host | tool_calls | Host / SDK |
| ③ Execute | Host → Tool | Objet parsé | Impl. outil |
| ④ Write back | Host → API | {role:"tool", content:"..."} | Modèle |
Dialectes de schémas API
- OpenAI / endpoints compatibles
tools+tool_choice; le streaming utilise des chunksdelta.tool_calls.- Anthropic
toolsavecinput_schema; réponses avec blocstool_useet repliestool_result.- Google Gemini
functionDeclarationsetfunctionCallavec des noms de champs différents.- Ollama local
toolscompatible OpenAI ; capacité dépend de l'entraînement du modèle.
Des frameworks comme LangGraph et DeepSeek Harness (voir notre guide Harness) compressent ces dialectes dans une abstraction Tool — toujours du JSON en dessous.
MCP : JSON-RPC standardise la couche outils
Model Context Protocol (MCP) se situe sous Function Calling : comment les processus outils sont découverts, paramétrés et réutilisés entre Hosts. Le transport peut être stdio ou SSE, mais les messages sont toujours JSON-RPC 2.0.
| Couche | Protocol | Exemples |
|---|---|---|
| Model API | REST / compatible OpenAI | chat/completions + tools |
| MCP | JSON-RPC 2.0 | tools/list, tools/call |
| Business | Tout | fichiers, DB, HTTP |
Les Hosts appellent tools/list au démarrage, traduisent les catalogues en tools[] API, puis envoient tools/call après la décision du modèle — deux conversions de dialecte, une pipeline sémantique.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": { "path": "/tmp/demo.txt" }
}
}Comment les frames JSON sont délimités en mode stdio ?
MCP stdio utilise en-têtes Content-Length + corps JSON (comme LSP), pas du JSON délimité par newline. Les gros payloads (ex. ressources base64) tiennent dans un frame. SSE enveloppe JSON-RPC dans des flux d'événements HTTP pour des Servers multi-clients.
Flux complet : entrée utilisateur jusqu'à l'exécution
- Les logs capturent chaque version
tools/listet le nombre d'outils ? argumentsest validé par schéma avant exécution ?- Les timeouts MCP sont mappés sur des messages
toollisibles ? - Les secrets sont supprimés avant logging ?
Même idée que l'étape Verify dans notre AI Coding Workflow : sans intermédiaires parseables, vous ne pouvez pas auto-vérifier que l'Agent a bien appelé le bon outil.
Pourquoi pas Protobuf ou XML ?
- APIs modèles sont JSON-first ; le binaire ajoute des couches de sérialisation ;
- Debugging — les ingénieurs lisent les paramètres dans les logs ;
- Écosystème schémas — JSON Schema et OpenAPI sont des standards de facto ;
- Scripts et navigateurs — curl, n8n, démos front-end supposent JSON.
Tradeoff : taille et CPU. Les setups high-QPS cachent en interne et compressent les logs ; les gros blobs passent en base64 dans des champs JSON — sans remplacer l'enveloppe JSON.
Coûts du JSON et correctifs d'ingénierie
| Symptôme | Cause | Correctif |
|---|---|---|
| arguments parse error | Chaîne JSON invalide du modèle | Schéma plus strict, température plus basse, retry |
| Mauvais outil | Descriptions floues ou trop nombreuses | Fusionner outils, exemples négatifs |
| MCP bloqué | Frame stdio incomplet ou processus mort | Superviseur launchd, health checks |
| Secrets dans les logs | Résultat outil inclut des variables d'env | Redacter résultats, compte d'exécution séparé |
Astuce production : faire tourner MCP sur un Mac cloud isolé — Cursor sur votre laptop envoie JSON-RPC via SSH ; Shell ne vit jamais sur votre machine quotidienne.
Les Agents dépendent de JSON car décisions en langage naturel et exécution programmatique ont besoin d'un contrat lisible par l'humain, validable par la machine et pluggable. Function Calling définit ce que le modèle dit ; Tool Calling définit comment le Host exécute un tour ; MCP définit comment les processus outils s'intègrent à l'écosystème — JSON est le fil à travers les trois.
Exécuter le plan JSON de MCP sur un Mac cloud
Nœuds M4 dédiés, facturation journalière, SSH prêt
Singapour · Japon · Corée · Hong Kong · régions US
Faites atterrir tools/call sur un Mac cloud isolé ; votre Host local ne transporte que du JSON-RPC. Voir les forfaits ZekVPS Mac mini cloud