explanation/deux-transports-mcp.md

Pourquoi deux transports MCP — stdio et HTTP

Un serveur MCP fait une chose : exposer des outils invocables à un client agentique, en dialoguant en JSON-RPC 2.0. Cette mécanique d'appel est indépendante du canal par lequel les messages circulent. Ce canal — le transport — peut prendre deux formes : un sous-processus local piloté par le client (stdio) ou un service réseau interrogé à distance (HTTP).

Cette pièce explique pourquoi les deux coexistent, ce que chacun coûte et rapporte, et sur quels critères trancher. Elle ne décrit pas comment les configurer : pour la recette côté client, voir le guide Brancher un client agentique ; pour le contrat exact du serveur (points d'entrée, handshake, codes d'erreur), voir la référence Serveur MCP.

Une distinction : le protocole n'est pas le transport

MCP définit ce qui est échangé — un handshake d'initialisation, un catalogue d'outils, des appels d'outils, des réponses. Il ne définit pas par où ces messages transitent. La même conversation JSON-RPC peut donc voyager sur deux tuyaux différents sans que la logique métier du serveur change d'une ligne.

C'est cette séparation qui rend le double support peu coûteux : le serveur écrit sa logique une fois, et deux adaptateurs de transport la branchent sur deux canaux. Le choix du transport n'est pas un choix de fonctionnalité — les mêmes outils sont exposés dans les deux cas — mais un choix de topologie de déploiement et de modèle de menace.

stdio — le serveur vit dans la machine du client

En stdio, le client lance lui-même le serveur comme un sous-processus enfant et lui parle sur l'entrée/sortie standard : une requête écrite sur stdin, une réponse lue sur stdout, un message JSON par ligne.

Ce que ce modèle apporte :

  • Aucune surface rĂ©seau. Il n'y a ni port ouvert, ni Ă©coute, ni requĂŞte qui sort de la machine. Rien Ă  exposer, donc rien Ă  attaquer depuis le rĂ©seau. Pour une charge de travail confidentielle ou une machine sans connectivitĂ© vers un serveur distant, c'est un argument de sĂ©curitĂ© fort.
  • Le secret reste local. Le token d'authentification est passĂ© dans l'environnement du sous-processus, transmis d'un parent Ă  son enfant sur la mĂŞme machine. Il ne traverse aucun lien rĂ©seau.
  • Le cycle de vie est trivial. Le serveur naĂ®t quand le client le dĂ©marre et meurt quand le client s'arrĂŞte. Pas de service Ă  superviser, Ă  redĂ©marrer, Ă  surveiller.
  • IdĂ©al en dĂ©veloppement. On itère sur le code du serveur et le client relance le sous-processus ; pas de dĂ©ploiement dans la boucle.

Ce qu'il coûte :

  • CouplĂ© Ă  la machine. Le binaire du serveur — et donc tout son environnement d'exĂ©cution, ses dĂ©pendances, sa base de donnĂ©es, son cĹ“ur de recherche — doit tourner lĂ  oĂą tourne le client. Un serveur qui a besoin d'une infrastructure lourde n'est pas raisonnablement dĂ©ployable sur chaque poste.
  • Mono-client par nature. Chaque client dĂ©marre son sous-processus. Il n'y a pas de service partagĂ© : rien n'est mutualisĂ© entre plusieurs utilisateurs ou plusieurs postes.
  • Fragile au canal. Puisque le protocole s'appuie sur stdout, tout ce qui pollue la sortie standard casse le dialogue. Les journaux doivent impĂ©rativement partir sur la sortie d'erreur, et les fins de ligne parasites (par exemple CRLF sur certaines plateformes) suffisent Ă  corrompre le parsing. Le transport le plus simple a ses propres pièges, purement mĂ©caniques.

HTTP — le serveur est un service que l'on interroge

En HTTP, le serveur est un service déployé que le client contacte par le réseau. Le client n'a plus rien à lancer : il envoie ses messages JSON-RPC à un point d'entrée et reçoit les réponses ; un canal en flux (SSE) permet au serveur de pousser des messages quand c'est nécessaire.

Ce que ce modèle apporte :

  • Accessible Ă  distance. Le serveur peut vivre lĂ  oĂą est son infrastructure — proche de sa base de donnĂ©es et de son cĹ“ur de recherche — et ĂŞtre consommĂ© depuis n'importe quel poste, n'importe quel rĂ©pertoire de travail, sans rien installer localement.
  • Multi-clients par construction. Un seul service rĂ©pond Ă  plusieurs clients. Cela autorise la mutualisation : un dĂ©ploiement, plusieurs consommateurs, et une logique de locataires/pĂ©rimètres appliquĂ©e cĂ´tĂ© serveur.
  • IndĂ©pendant de l'environnement local. Le client n'a pas besoin des dĂ©pendances du serveur ; il n'a besoin que d'un accès rĂ©seau et d'un token.

Ce qu'il coûte — et c'est le cœur de l'arbitrage :

  • Il expose une surface rĂ©seau. Dès qu'un service Ă©coute, il devient une cible. L'authentification n'est plus une commoditĂ© locale mais une frontière dĂ©fensive : chaque appel doit prĂ©senter un jeton, transportĂ© cette fois dans un en-tĂŞte de la requĂŞte, c'est-Ă -dire sur le rĂ©seau. Ce dĂ©placement du secret hors de la machine est prĂ©cisĂ©ment ce que stdio Ă©vitait. Il impose des exigences que le local n'avait pas : chiffrement du transport, jeton rĂ©vocable, refus explicite et distinct selon que le jeton manque ou n'est plus valide.
  • Le handshake devient un Ă©tat Ă  gĂ©rer. En local, une conversation = un sous-processus, et l'Ă©tat de session est implicite. Sur le rĂ©seau, plusieurs clients partagent le mĂŞme service : le serveur doit savoir Ă  quelle conversation rattacher chaque message. D'oĂą une notion de session et une phase d'initialisation Ă  respecter — un appel d'outil Ă©mis avant la fin du handshake est lĂ©gitimement rejetĂ©. Cette statefulness est le prix du partage. (Le dĂ©tail du handshake et des identifiants de session est dans la rĂ©fĂ©rence.)
  • Plus de pièces Ă  opĂ©rer. Un service rĂ©seau se dĂ©ploie, se supervise, se met Ă  jour, se protège. Ce que stdio obtenait gratuitement — naĂ®tre et mourir avec le client — devient une responsabilitĂ© d'exploitation.

Le même serveur, deux modèles de menace

Le point à retenir n'est pas qu'un transport serait « plus sûr » que l'autre dans l'absolu, mais qu'ils déplacent le risque à des endroits différents :

  • En stdio, le secret et l'exĂ©cution restent dans le pĂ©rimètre de confiance de la machine du client. Il n'y a pas de rĂ©seau Ă  dĂ©fendre ; la sĂ©curitĂ© repose sur la machine elle-mĂŞme.
  • En HTTP, le secret franchit le rĂ©seau et le service est atteignable de l'extĂ©rieur. La sĂ©curitĂ© repose alors sur l'authentification, le confinement des pĂ©rimètres d'accès et la discipline d'exploitation du service.

Le serveur applique par ailleurs les mêmes garde-fous au-dessus du transport, quel qu'il soit : vérification du jeton, périmètres d'accès (scopes), quotas, journal d'audit, confinement des chemins de fichiers lisibles. Ces protections ne dépendent pas du canal — elles s'appliquent identiquement aux deux. Le transport ne change que d'où vient l'appelant et par où voyage le secret.

Comment trancher

Le critère décisif est simple : où vit le serveur par rapport au client ?

  • Le serveur tourne sur la machine du client — dĂ©veloppement, poste isolĂ©, charge confidentielle, absence de connectivitĂ© vers un service distant : stdio. On gagne la simplicitĂ© et l'absence de surface rĂ©seau, on accepte le couplage Ă  la machine et le mono-client.
  • Le serveur est dĂ©ployĂ© ailleurs et sert plusieurs consommateurs — cas par dĂ©faut d'un composant partagĂ© et multi-locataire : HTTP. On gagne l'accès distant et la mutualisation, on accepte d'exposer et de dĂ©fendre une surface rĂ©seau.

Il n'y a pas de transport supérieur : il y a une topologie, et un modèle de menace qui en découle. Supporter les deux, c'est refuser de figer ce choix dans le composant — et laisser chaque déploiement le trancher selon sa situation.

Pour aller plus loin

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.