Aller au contenu
Développement medium

Transports MCP : stdio, SSE et Streamable HTTP

8 min de lecture

logo python

Les messages JSON-RPC de MCP doivent circuler par un canal. Ce canal s'appelle le transport, et MCP en propose trois : stdio pour le local, Streamable HTTP pour le réseau, et SSE, en voie de retrait. Le choix n'est pas anodin : il détermine si votre serveur tourne dans l'hôte ou à côté, s'il est partageable, et comment vous le déployez. Ce guide explique chaque transport et montre, lab à l'appui, qu'un même serveur se sert indifféremment sur stdio ou sur HTTP. Public visé : développeur ayant déjà écrit un serveur MCP.

  • Comprendre ce qu'est un transport MCP et pourquoi il y en a plusieurs.
  • Distinguer stdio, Streamable HTTP et SSE.
  • Servir un même serveur sur deux transports sans changer sa logique.
  • Choisir le transport adapté à votre cas d'usage.

Ce guide prolonge Créer son premier serveur MCP et l'anatomie du protocole. Vous avez besoin de Python 3.10+ et du SDK mcp installé.

Le protocole MCP — les messages JSON-RPC, le cycle de vie — reste le même quel que soit le canal. Le transport ne change que la plomberie : par où les octets passent.

Cette séparation est volontaire. Un serveur MCP qui lit vos fichiers locaux n'a pas les mêmes besoins qu'un serveur partagé par toute une équipe. Le premier veut être simple et local ; le second veut être joignable sur le réseau. MCP laisse ce choix ouvert, sans toucher au reste.

Le transport stdio (entrée/sortie standard) est le plus simple. Le serveur est un sous-processus de l'hôte : l'hôte le lance, et la communication passe par les flux stdin et stdout du processus.

Conséquences directes : aucun réseau, aucun port, aucune authentification réseau à gérer. Le serveur vit et meurt avec l'hôte qui l'a démarré. C'est le mode idéal pour un serveur qui accède à des ressources de la machine locale — fichiers, dépôt Git, base SQLite — et qui ne sert qu'un seul hôte.

C'est aussi le transport par défaut de FastMCP : mcp.run() sans argument démarre en stdio.

Le transport Streamable HTTP fait du serveur un service HTTP indépendant. Le serveur tourne séparément, écoute sur une URL, et le client s'y connecte comme à n'importe quelle API web.

Tout change par rapport à stdio. Le serveur a une existence propre : on le lance une fois, il sert plusieurs clients, il peut tourner sur une autre machine. En contrepartie, il faut gérer ce qu'implique tout service réseau — un port, du TLS, une authentification, un éventuel reverse proxy.

C'est le standard recommandé pour tout serveur MCP destiné à être partagé ou déployé.

Le transport SSE (Server-Sent Events) est l'ancien transport réseau de MCP. Il fonctionne, mais il est progressivement remplacé par Streamable HTTP, qui couvre les mêmes besoins de façon plus simple et plus robuste.

La règle est claire : pour un nouveau projet, choisissez Streamable HTTP. Vous ne croiserez SSE que sur des serveurs anciens pas encore migrés. Le connaître suffit ; l'adopter, non.

La promesse de cette séparation, c'est qu'un serveur ne change pas quand on change de transport. Démontrons-le. Voici un serveur hello dont le transport est choisi en argument :

import sys
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-server", host="127.0.0.1", port=8765)
@mcp.tool()
def hello(name: str) -> str:
"""Renvoie un salut personnalisé."""
return f"Bonjour {name}, ici un serveur MCP."
if __name__ == "__main__":
transport = sys.argv[1] if len(sys.argv) > 1 else "stdio"
mcp.run(transport=transport)

Le tool hello est identique dans les deux cas. Seul l'argument de mcp.run() diffère. Côté client, en revanche, la connexion change.

En stdio, le client lance lui-même le serveur et communique par ses flux standard.

from mcp import StdioServerParameters
from mcp.client.stdio import stdio_client
params = StdioServerParameters(command=sys.executable, args=["server.py", "stdio"])
async with stdio_client(params) as (read, write):
...

Lancé sur les deux canaux, le serveur répond exactement pareil :

stdio -> Bonjour stdio, ici un serveur MCP.
http -> Bonjour HTTP, ici un serveur MCP.

La logique métier est écrite une fois. Le transport est un paramètre de déploiement, pas une réécriture.

Le bon transport découle de qui doit joindre le serveur et il tourne.

CritèrestdioStreamable HTTP
Cycle de vie du serveurLancé par l'hôteIndépendant
RéseauAucunPort, TLS, auth
Nombre de clientsUn seulPlusieurs
Serveur distantNonOui
Cas typiqueOutils locaux (fichiers, Git)Serveur partagé, déployé
Mise en placeImmédiateDemande du durcissement réseau

La règle pratique : stdio par défaut tant que le serveur est local et personnel ; Streamable HTTP dès qu'il doit être partagé ou déployé. SSE n'entre plus dans la décision pour un nouveau projet.

  • Le transport est le canal des messages MCP ; le protocole reste identique quel que soit le canal.
  • stdio : serveur lancé par l'hôte, local, mono-client, sans réseau — le défaut.
  • Streamable HTTP : serveur indépendant, joignable sur le réseau, multi-clients — le standard pour partager ou déployer.
  • SSE : ancien transport réseau, en voie de retrait — à connaître, pas à adopter.
  • Un même serveur se sert sur plusieurs transports sans changer sa logique : le transport est un paramètre de déploiement.
  • Un transport HTTP impose de sécuriser : authentification, TLS, accès contrôlé.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn