Transports MCP : stdio ou Streamable HTTP, lequel choisir ?

Quand vous installez un serveur MCP, la documentation vous demande souvent de choisir : une commande à lancer en local, ou une URL à renseigner. Derrière ce choix se cache le transport, c’est-à-dire la façon dont les messages circulent entre le client et le serveur. Le protocole en définit deux : stdio et Streamable HTTP.

Ce choix n’est pas anodin : il détermine où tourne le serveur, qui peut s’y connecter et comment le sécuriser. Voici comment fonctionne chacun, et lequel choisir selon votre situation.

Le comparatif en bref

CritèrestdioStreamable HTTP
Où tourne le serveurSur la machine de l’utilisateur, lancé par le clientSur n’importe quelle machine, locale ou distante
ConnexionEntrée et sortie standard d’un sous-processusRequêtes HTTP vers une URL unique
UtilisateursUn seul client par processusPlusieurs clients simultanés
AuthentificationVariables d’environnement, droits locauxOAuth 2.1, prévu par la spécification
Mise en placeUne commande dans la configurationUn service web à héberger
Idéal pourOutils locaux : fichiers, Git, IDEServices en ligne, équipes, SaaS

📇 Dans notre annuaire des serveurs MCP, chaque fiche indique la commande d’installation ou l’URL du serveur.

Ce que transporte un transport

Quel que soit le transport, les messages échangés sont les mêmes : des requêtes, des réponses et des notifications au format JSON-RPC 2.0. Une session commence par une phase d’initialisation où client et serveur annoncent leur version du protocole et leurs capacités ; le client peut ensuite lister et appeler les outils, lire les ressources, etc. Le transport ne change que le « tuyau » : le contenu reste identique, ce qui permet à un même serveur de proposer les deux modes.

stdio : le serveur local lancé par le client

Comment ça marche

Avec stdio, c’est le client qui démarre le serveur comme un sous-processus. Il lui écrit ses messages sur l’entrée standard (stdin) et lit les réponses sur la sortie standard (stdout), un message JSON par ligne. La sortie d’erreur (stderr) reste libre pour les journaux. Quand le client se ferme, il arrête le processus.

Côté configuration, on déclare simplement une commande et ses arguments, avec au besoin une clé env pour les variables d’environnement. Exemple avec le serveur de fichiers de référence :

{
  "mcpServers": {
    "fichiers": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/vous/Documents"]
    }
  }
}

Points forts

  • Aucune infrastructure : pas de port, pas de serveur web, pas de certificat.
  • Le serveur accède directement aux ressources locales : fichiers, dépôt Git, applications.
  • Latence minimale, et fonctionnement hors ligne pour les outils qui n’appellent pas d’API.

Limites

  • Un processus par client : impossible de partager un même serveur entre plusieurs personnes.
  • Le serveur s’exécute avec vos droits utilisateur : un paquet malveillant accède à tout ce à quoi vous avez accès.
  • Chaque utilisateur doit installer l’environnement nécessaire (Node.js, Python, Docker…).
  • Les clients web, comme les interfaces en ligne des assistants, ne peuvent pas lancer de processus local.

Streamable HTTP : le serveur accessible par une URL

Comment ça marche

Avec Streamable HTTP, le serveur est un service web indépendant qui expose un point d’accès unique, par exemple https://exemple.com/mcp. Le client envoie chacun de ses messages dans une requête POST. Le serveur répond soit avec un simple JSON, soit en ouvrant un flux SSE (Server-Sent Events) lorsqu’il doit envoyer plusieurs messages, par exemple des notifications de progression pendant une tâche longue. Le client peut aussi ouvrir un flux par une requête GET pour recevoir des messages à l’initiative du serveur.

Le serveur peut attribuer un identifiant de session, transmis dans l’en-tête Mcp-Session-Id, et le client indique la version du protocole utilisée via l’en-tête MCP-Protocol-Version. Un serveur peut aussi fonctionner sans état, ce qui facilite son déploiement derrière un répartiteur de charge ou sur une plateforme serverless.

Côté client, il suffit de renseigner l’URL. Dans Claude Code par exemple :

claude mcp add --transport http mon-serveur https://exemple.com/mcp

Côté serveur, avec le SDK Python, un seul paramètre change :

mcp.run(transport="streamable-http")

Points forts

  • Un seul serveur pour toute une équipe ou tous vos clients, mis à jour de façon centralisée.
  • Rien à installer pour l’utilisateur : une URL et une connexion suffisent.
  • Authentification standardisée : la spécification s’appuie sur OAuth 2.1 pour les serveurs distants.
  • Compatible avec les clients web qui ne peuvent pas lancer de processus local.

Limites

  • Il faut héberger, surveiller et sécuriser un service web.
  • Chaque appel traverse le réseau : latence plus élevée et dépendance à la connexion.
  • Le serveur n’a pas accès aux fichiers de l’utilisateur, sauf si on les lui transmet.

Et l’ancien transport HTTP+SSE ?

Les premières versions du protocole utilisaient un transport HTTP+SSE reposant sur deux points d’accès : un flux SSE permanent pour les messages du serveur et une URL séparée pour ceux du client. Il a été remplacé par Streamable HTTP dans la révision de mars 2025 de la spécification, notamment parce que cette connexion permanente compliquait l’hébergement et la reprise après coupure.

Beaucoup de clients le prennent encore en charge pour la compatibilité, et certains serveurs l’exposent toujours sur une URL en /sse. Si vous développez un nouveau serveur, partez directement sur Streamable HTTP ; si vous en maintenez un ancien, prévoyez la migration, qui se limite souvent à changer d’option dans le SDK.

Lequel choisir ?

  • Choisissez stdio si le serveur a besoin de votre machine (fichiers, terminal, applications locales), s’il est destiné à un usage personnel, ou si vous débutez : c’est le plus simple à écrire et à tester.
  • Choisissez Streamable HTTP si le serveur enveloppe un service en ligne, doit être partagé par une équipe, doit fonctionner avec des clients web, ou si vous le proposez à vos clients comme un produit.
  • Proposez les deux si vous publiez un serveur open source : stdio pour ceux qui veulent l’exécuter chez eux, HTTP pour une version hébergée. C’est déjà le choix de plusieurs éditeurs, comme Figma avec ses serveurs local et distant (voir notre guide Figma MCP).

Les réflexes de sécurité selon le transport

En stdio, le risque principal est le code lui-même : n’installez que des serveurs issus de sources fiables, idéalement dans une version figée, et donnez-leur des jetons aux droits limités.

En Streamable HTTP, le serveur devient une cible réseau. En local, liez-le à 127.0.0.1 plutôt qu’à toutes les interfaces, et vérifiez l’en-tête Origin des requêtes, comme le demande la spécification, pour bloquer les attaques par DNS rebinding. En production, exigez une authentification et ne considérez jamais l’identifiant de session comme une preuve d’identité. Tous ces points sont détaillés dans notre guide pour sécuriser un serveur MCP.

Déboguer une connexion

MCP Inspector sait se connecter aux deux transports : lancez npx @modelcontextprotocol/inspector, choisissez le type de transport, puis indiquez la commande ou l’URL. En stdio, consultez aussi les journaux du client (Claude Desktop les enregistre dans un dossier logs) ; en HTTP, les journaux du serveur et les outils réseau du navigateur suffisent généralement.

Questions fréquentes

Un même serveur peut-il proposer stdio et Streamable HTTP ?

Oui. Les messages échangés sont identiques, seul le transport change. Avec les SDK officiels, une option ou un argument de ligne de commande suffit souvent pour passer de l'un à l'autre.

Existe-t-il un transport WebSocket ?

La spécification ne définit que stdio et Streamable HTTP comme transports standard. Elle autorise des transports personnalisés, mais ils ne seront compatibles qu'avec les clients qui les prennent en charge.

Streamable HTTP utilise-t-il encore SSE ?

Oui, de façon optionnelle : le serveur peut répondre à une requête par un flux SSE lorsqu'il doit envoyer plusieurs messages. Contrairement à l'ancien transport HTTP+SSE, aucune connexion permanente n'est obligatoire.

Peut-on utiliser un serveur stdio à distance ?

Pas directement. Il faut l'exécuter derrière une passerelle qui l'expose en HTTP. Des outils open source font cette conversion, mais pensez alors à ajouter une authentification.

Conclusion

stdio et Streamable HTTP ne sont pas concurrents : le premier excelle pour les outils locaux et personnels, le second pour les services partagés et hébergés. Commencez en stdio pour prototyper, puis passez en HTTP lorsque votre serveur doit sortir de votre machine, en soignant alors l’authentification. Pour vous lancer, notre tutoriel pour créer un serveur MCP en Python montre les deux modes.