Un regard critique sur MCP
(raz.sh)- MCP est un protocole basé sur JSON-RPC destiné à permettre aux LLM/agents d’utiliser des outils externes et des sources de données de manière standardisée, mais il est critiqué car la conception du transport HTTP et la qualité de la documentation alourdissent l’implémentation
- Le principal point de friction est que, pour implémenter une simple communication bidirectionnelle sur HTTP, il reconstitue de façon détournée un comportement proche de WebSocket avec HTTP+SSE et Streamable HTTP
- Streamable HTTP multiplie les chemins de création de session, de connexion SSE et de livraison des réponses, ce qui augmente la charge de gestion d’état, le débogage, les problèmes d’interopérabilité, de scalabilité et de sécurité
- Le transport HTTP s’accompagne d’exigences d’autorisation centrées sur OAuth2, tandis que stdio est censé récupérer les identifiants depuis les variables d’environnement, ce qui fait varier le modèle d’authentification selon le mode de transport
- Le transport HTTP devrait être simplifié avec WebSocket, plus proche des flux d’entrée/sortie de stdio, et la conception devrait être optimisée pour les cas d’usage courants plutôt que pour les cas exceptionnels
La diffusion rapide de MCP
- MCP(Model Context Protocol) est un protocole ouvert qui standardise la manière dont les applications fournissent du contexte aux LLM
- Anthropic compare MCP au port USB-C des applications d’IA et le présente comme une manière standard de connecter les modèles d’IA à diverses sources de données et à des outils
- Au cours du dernier mois, MCP s’est rapidement diffusé, et de nouveaux serveurs et clients MCP apparaissent chaque jour, visibles sur des sites comme mcp.so et pulsemcp.com
- IBM a publié Agent Communication Protocol(ACP) comme un « standard orthogonal » à MCP, et Google a également annoncé Agent2Agent(A2A)
- La critique centrale reste que, malgré les dépenses massives des grands acteurs pour l’entraînement et le fine-tuning des modèles, la maturité de la documentation, des SDK et des guides d’implémentation demeure faible
Le protocole lui-même et la couche de transport
- MCP est un protocole JSON-RPC avec des méthodes et des endpoints prédéfinis pour être utilisés avec des LLM
- Les principaux modes de transport se divisent entre stdio, proche d’une exécution locale, et les transports basés sur HTTP
-
stdio
- Un serveur MCP local est lancé, puis ses pipes
stdoutetstdinsont reliés au client pour échanger du JSON, tandis questderrsert au logging - L’usage du paradigme des pipes Unix/Linux pour une communication bidirectionnelle prête à critique, mais il fonctionne facilement sur tous les systèmes d’exploitation et reste simple à comprendre car il ne nécessite pas de gestion de sockets
- Un serveur MCP local est lancé, puis ses pipes
-
Transport basé sur HTTP
- Il fonctionne au-dessus de HTTP et comprend HTTP+SSE ainsi que Streamable HTTP, censé le remplacer
- Dans les deux cas, la complexité augmente parce qu’ils tentent d’implémenter un simple échange de messages bidirectionnel à l’aide d’une combinaison de requêtes HTTP et de connexions SSE
-
Critique de HTTP+SSE et de Streamable HTTP
- Le transport HTTP existant repose sur HTTP+SSE (Server-Sent Events), et la nouvelle spécification cherche à le remplacer par Streamable HTTP
- Avec HTTP+SSE, pour obtenir du full duplex, le client ouvre une session SSE en lecture avec une requête du type
GET /sse, reçoit dans la première réponse une URL d’écriture, puis envoie une requête du typePOST /a-endpoint?session-id=1234- Le serveur renvoie
202 Acceptedavec un corps vide - La réponse réelle doit ensuite être lue sur la connexion
/ssedéjà ouverte
- Le serveur renvoie
- Streamable HTTP traite l’ID de session dans un en-tête HTTP plutôt que via un endpoint séparé, et permet d’ouvrir une session SSE avec
GETouPOST /mcp- La réponse peut arriver dans un nouveau flux SSE
- Elle peut arriver dans le corps de la réponse au
POSTavec un200 - Elle peut être livrée plus tard via l’un des flux SSE déjà existants
- Cette conception se rapproche d’une tentative de faire fonctionner SSE comme WebSocket, et l’argumentaire pour éviter d’utiliser un vrai WebSocket est discuté dans modelcontextprotocol/pull/206
- Le transport HTTP cherche à imiter stdio, mais comme il ne s’agit pas d’un vrai socket, l’implémentation côté serveur doit supporter la charge de raccorder plusieurs appels et connexions HTTP
Les problèmes de documentation et de SDK révélés par l’expérience d’implémentation
- Lors d’une tentative d’implémentation d’un serveur MCP en Go, il n’existait pas de SDK Go officiel, et comprendre le protocole demandait pratiquement de faire de la rétro-ingénierie
- La documentation de modelcontextprotocol.io passe sous silence ou omet des détails importants du protocole, et ne fournit pas d’exemples de flux de conversation
- Le site web pousse davantage vers des tutoriels d’implémentation via SDK que vers la lecture directe du standard lui-même
- Les serveurs d’exemple sont implémentés en Python ou en JavaScript, avec l’hypothèse d’une exécution locale en stdio
- Python et JavaScript sont critiqués comme de mauvais choix pour des outils locaux censés fonctionner de manière fiable sur l’ordinateur d’autrui
- Le fait que les exemples soient aussi fournis sous forme de conteneurs Docker semble montrer que ce problème est au moins partiellement reconnu
- Pour une exécution locale de MCP, des langages plus portables comme Rust, Go, Java ou C# seraient jugés plus adaptés
La complexité introduite par Streamable HTTP
- Avec Streamable HTTP, une nouvelle session peut être créée de trois façons
- une requête
GETvide - une requête
POSTvide - une requête
POSTcontenant un appel RPC
- une requête
- Une connexion SSE peut elle aussi être ouverte de quatre manières
- un
GETd’initialisation - un
GETpour rejoindre une session précédente - un
POSTpour initialiser une session - un
POSTcontenant une requête et renvoyant la réponse via SSE
- un
- Les réponses aux requêtes peuvent ensuite être livrées de trois façons
- dans la réponse HTTP au
POSTcontenant l’appel RPC - dans les événements SSE ouverts en réponse à ce
POST - dans n’importe quel événement SSE déjà ouvert précédemment
- dans la réponse HTTP au
- Comme il existe de nombreux chemins pour obtenir le même résultat, la charge cognitive, la difficulté de débogage et le coût de maintenance augmentent
- Si le client et le serveur n’implémentent chacun qu’un sous-ensemble de ce qu’ils jugent nécessaire, des problèmes d’interopérabilité peuvent apparaître et conduire à des comportements inattendus
- Dans une architecture serveur répartie sur plusieurs machines, la gestion de l’état des connexions et des mécanismes de réponse peut devenir un goulot d’étranglement pour la scalabilité
Les problèmes de sécurité et d’autorisation
- La flexibilité de Streamable HTTP soulève plusieurs préoccupations de sécurité
- La gestion de l’état de session à travers HTTP et SSE est complexe, et peut ouvrir la voie à des détournements de session, des attaques par rejeu et des DoS
- La multiplication des points d’entrée pour la création de session et la connexion SSE élargit la surface d’attaque
- La diversité des modes de démarrage de session et de livraison des réponses peut servir à dissimuler des activités malveillantes
- La spécification authorization du protocole le plus récent recommande que les implémentations basées sur HTTP suivent cette spécification
- Cette même spécification recommande que les implémentations utilisant STDIO ne la suivent pas, et récupèrent plutôt les identifiants depuis l’environnement
- Ce schéma suscite des critiques, car il donne l’impression que le transport HTTP impose une procédure OAuth2, tandis qu’avec stdio un accès de niveau API key semble possible
Proposition : simplifier le transport HTTP avec WebSocket
- MCP repose sur un unique protocole JSON-RPC, et stdio semble clairement être le mode de transport privilégié
- Le transport HTTP devrait ressembler autant que possible à stdio, et ne s’en écarter qu’en cas de nécessité réelle
- Les variables d’environnement de stdio peuvent correspondre aux en-têtes HTTP
- Les flux d’entrée/sortie de type socket de stdio peuvent correspondre à WebSocket côté HTTP
- Utiliser WebSocket permettrait de réduire la complexité de la gestion d’état entre serveurs et de nombreux corner cases liés aux sessions
- Cela dit, l’autorisation peut dans certains cas devenir plus complexe, certains pare-feu peuvent bloquer WebSocket, il peut y avoir un surcoût pour les sessions courtes et la reprise après coupure de session peut être plus difficile
- La spécification MCP indique elle-même qu’il s’agit d’un protocole agnostique vis-à-vis du transport, implémentable sur tout canal de communication prenant en charge l’échange de messages bidirectionnel
- L’industrie devrait optimiser pour les cas d’usage les plus courants, et non pour les corner cases
Évaluation complémentaire d’ACP et d’A2A
- MCP est un protocole qui expose des API aux LLM, tandis qu’ACP et A2A se rapprochent davantage de protocoles exposant des agents aux LLM
- À la lecture de la spécification A2A, son utilité semble limitée, et beaucoup de ses fonctions paraissent pouvoir être couvertes par MCP tel quel ou avec de petites extensions
- ACP et A2A pourraient être implémentés non comme des protocoles séparés, mais comme des outils d’un serveur MCP
- IBM présente aussi ce point de vue dans la documentation MCP adapter, où un agent ACP peut être vu comme une ressource MCP et invoqué comme un outil MCP
- ACP est perçu comme ayant aussi une dimension promotionnelle pour l’outil de création d’agents d’IBM, BeeAI
- Les principaux avantages apportés par ACP et A2A seraient une couche de transport plus complète et un meilleur mécanisme de découverte des agents
Aucun commentaire pour le moment.