Chapitre 5 — Protocoles de transport et découverte
Cinquième billet de la tournée chapitre par chapitre de LLM Primer IV : Concevoir la cognition de l'IA avec MCP. Chaque message des Chapitres 3 et 4 flottait dans l'air entre hôte et serveur — mais les messages ne flottent pas, ils voyagent sur un transport, et le transport décide discrètement de presque tout ce qui est opérationnel dans une intégration.
Pourquoi ce chapitre existe
MCP définit son format de message — JSON-RPC 2.0 sur un canal duplex — puis définit trois transports qui implémentent ce canal. Les transports ne sont pas interchangeables. Chacun convient à un patron de déploiement, porte un bagage opérationnel différent, et expose des surfaces de sécurité différentes. Une seconde question plane sur le même territoire : comment l'hôte trouve-t-il un serveur en premier lieu ? Tant que l'hôte ne sait pas qu'un serveur existe et où il vit, le protocole le mieux spécifié du monde ne produit aucune conversation.
Ce chapitre parcourt les deux. Les transports décident si le serveur est colocalisé ou distant, si vous avez une authentification ou une isolation de processus, et comment le serveur se met à l'échelle. La couche de découverte décide si votre serveur est quelque chose qu'un ingénieur utilise ou quelque chose qu'une équipe peut adopter.
.well-known/mcp.json plus les Server Cards sont ce qui transforme un problème de configuration en un problème de recherche.5.1 stdio, SSE et Streamable HTTP
stdio, c'est l'hôte qui lance le serveur comme un processus fils. L'hôte écrit du JSON-RPC dans le stdin de l'enfant et lit les réponses depuis stdout ; stderr porte les logs. Pas de port, pas de socket, pas de réseau. L'authentification est gérée par la frontière de lancement de processus de l'OS. Claude Desktop, Cursor et l'inspecteur MCP officiel utilisent tous stdio pour les serveurs locaux. Le modèle est honnête sur ce qu'il est : un outil sur votre propre machine, colocalisé, dans le même domaine de confiance que l'hôte. Il ne peut pas être partagé entre hôtes, ne peut pas tourner sur une autre machine, et un-par-hôte est la seule multiplicité disponible — cinq clients voulant le même serveur consomment cinq processus.
HTTP+SSE a été la première réponse de MCP au cas réseau. Bidirectionnel, mais duplex assemblé à partir de deux pièces unidirectionnelles. Déprécié. Encore dans la nature. Vous croiserez des serveurs basés SSE pendant encore un certain temps.
Streamable HTTP est le transport réseau préféré. Un endpoint unique — typiquement /mcp — accepte des requêtes JSON-RPC et répond soit par une réponse unique (pour les appels synchrones), soit par un flux de Server-Sent Events lorsqu'il y a plusieurs messages, y compris des notifications initiées par le serveur. Les sessions sont identifiées par un en-tête Mcp-Session-Id posé à l'initialisation et glissé dans toutes les requêtes suivantes. La session est l'unité d'état, libérable par DELETE ou récoltée par timeout. Le transport se compose proprement avec équilibreurs de charge, reverse proxies, caches périphériques et TLS. La mise à l'échelle horizontale fonctionne par session collante sur l'ID de session. Rien de tout cela n'est une ingénierie HTTP novatrice ; le point, c'est que MCP s'inscrit dedans sans inventer de nouvelle couche.
Le choix est autant une décision de sécurité que de déploiement. Les serveurs stdio penchent vers le sur-privilège — ils héritent des droits réseau et de système de fichiers de l'utilisateur, sans authentification puisqu'il n'y a pas d'appelant distant. Les serveurs réseau font face à l'internet ouvert et doivent authentifier chaque requête, OAuth 2.1 étant maintenant le standard de convergence. Choisir le mauvais transport pour sa posture de sécurité oblige à ajouter après coup ce qui aurait dû être construit dès le départ.
5.2 Découverte de serveurs : .well-known/mcp.json et Server Cards
Un protocole qui exige que chaque hôte soit configuré à la main avec l'adresse de chaque serveur ne devient pas un écosystème. Il devient un cauchemar de configuration. La couche de découverte de MCP emprunte le patron d'URI bien connu de la RFC 8615 — le même mécanisme utilisé par robots.txt et .well-known/openid-configuration. Un serveur publie .well-known/mcp.json à son URL de base. Un hôte la récupère, l'analyse, et apprend ce que le serveur prétend de lui-même : l'endpoint MCP, la version du protocole, le schéma d'authentification, des métadonnées d'identité, et un pointeur vers la Server Card.
La Server Card est l'openapi.json de MCP : un artefact auto-descriptif que machines et humains peuvent consommer. Un hôte peut montrer la carte à l'utilisateur pendant le flux de connexion — « ce serveur dit qu'il peut accéder à votre workspace Linear, qu'il lira les tickets mais ne les supprimera pas, qu'il est exploité par Linear lui-même, qu'il utilise OAuth » — et l'utilisateur peut décider si la déclaration est acceptable. Les cartes, sous leur forme non signée, sont des déclarations, pas une preuve. L'atténuation est une attestation signée, avec un modèle de signature qui a convergé vers un style sigstore-OIDC : une carte signée via l'intégration OIDC de GitHub sous github.com/some-org/mcp-server peut être vérifiée par tout hôte qui fait confiance aux déclarations d'identité de GitHub. Les hôtes peuvent superposer une politique — ne faire confiance qu'aux cartes signées, qu'aux cartes signées par un fournisseur précis, qu'à celles qui ne sont pas sur une liste de révocation.
Le flux ressemble à l'ajout d'un réseau Wi-Fi. Une fois. L'hôte stocke la configuration ; les sessions suivantes sautent la découverte. Ce que « quelque chose a changé » veut dire en pratique — bumps de version, expansions de portée, glissements de capacité — devrait déclencher un consentement renouvelé, comme le fait un changement de certificat TLS. Les hôtes qui sautent cette étape laissent les serveurs étendre leur portée silencieusement au fil du temps, ce qui est exactement la dérive lente de capacités qui compromet la confiance dans toute intégration de longue durée.
5.3 Les parties ennuyeuses qui décident si vous livrez
Trois soucis opérationnels méritent leur propre traitement parce que chacun est un endroit où une implémentation négligente produit soit des intégrations cassées, soit des trous de sécurité.
CORS compte pour tout serveur MCP joignable depuis un hôte basé navigateur. La tentation est de poser Access-Control-Allow-Origin: * et de passer à autre chose. C'est une erreur. Combiné à de l'authentification par cookies, c'est un désastre CSRF ; combiné à des bearer tokens dans localStorage, c'est un risque d'exfiltration de token. Utilisez une liste autorisée par origine, et préférez les en-têtes Authorization aux cookies, pour que la même origine ne soit pas votre seule ligne de défense.
La validation d'origine, c'est CORS appliqué côté serveur, parce que les clients hors navigateur ne font respecter rien. La défaillance classique : un développeur lance un serveur MCP sur localhost:8000, visite une page web qui connaît la convention, la page tire une requête, et le serveur — sans vérification d'origine — fait ce que la page lui demande. Validez Origin sur chaque serveur Streamable HTTP.
Les en-têtes de cache sont le troisième. La documentation statique peut être mise en cache agressivement ; une ligne de base de données seulement aussi longtemps que les abonnements sont câblés ; un document en cours d'édition pas du tout. Renvoyez les bons Cache-Control et ETag par ressource. L'interaction entre cache et abonnements est l'endroit où les ingénieurs se font mordre — un intermédiaire qui sert une copie périmée signifie que la notification resources/updated de l'hôte ne se déclenche jamais, parce que le mécanisme d'abonnement n'atteint jamais le serveur vivant.
Le DNS rebinding complète le voisinage et affecte de façon disproportionnée les serveurs locaux. Liez à 127.0.0.1 et non à 0.0.0.0, validez l'en-tête Host contre une liste autorisée, exigez un token d'authentification même pour localhost. Un serveur MCP local sans ces mesures est à une démo près d'être un avis de sécurité.
Ce que prépare le Chapitre 5
Ceci clôt la Partie II du livre. Nous avons le protocole en main : primitives serveur au Chapitre 3, primitives client au Chapitre 4, le fil et la couche de découverte ici. Nous savons quels messages voyagent, dans quelle direction, sur quel transport, entre quels domaines de confiance, après quelle poignée de main. La Partie III passe des primitives aux patrons. Un serveur unique connecté à un hôte unique est utile ; le gain architectural de MCP, c'est la composition — plusieurs serveurs, plusieurs agents, plusieurs modèles, coopérant vers des buts plus grands.
Prochaine étape — Chapitre 6 : Stratégies d'orchestration fondamentales. Quand un agent unique bien outillé bat une conception multi-agents, et les deux formes fondatrices — pipelines séquentiels et concurrence scatter-gather — sur lesquelles s'appuie la plupart des déploiements de production.