StreamableHTTP en profondeur
Sur cette page
StreamableHTTP est la solution de MCP à un problème fondamental : certaines fonctionnalités MCP nécessitent que le serveur fasse des requêtes au client, mais HTTP rend cela difficile. Explorons comment StreamableHTTP contourne cette limitation et dans quels cas vous pourriez avoir besoin de l’en empêcher. À la fin de cette leçon, vous saurez lire une session Streamable HTTP de l’ère 2025 de bout en bout : identifiant de session, flux SSE primaire, flux par appel d’outil, routage des messages.
Le problème central
Certaines fonctionnalités MCP comme le sampling, les notifications et les logs reposent sur l’initiation de requêtes par le serveur vers le client. Or HTTP est conçu pour que les clients fassent des requêtes aux serveurs, pas l’inverse.
La solution de StreamableHTTP : utiliser les Server-Sent Events (SSE) pour établir des connexions persistantes.
Comment fonctionne StreamableHTTP
Étape 1 : Configuration initiale de la connexion
Le processus commence comme toute connexion MCP :
1. Client → InitializeRequest → Serveur
2. Serveur → InitializeResult (avec en-tête mcp-session-id) → Client
3. Client → InitializedNotification (avec l'ID de session) → Serveur
L’ID de session est crucial — il identifie de façon unique le client et doit être inclus dans toutes les requêtes futures.
Étape 2 : La solution SSE
Après l’initialisation, le client peut faire une requête GET pour établir une connexion Server-Sent Events. Cette connexion crée une réponse HTTP longue durée que le serveur peut utiliser pour streamer des messages vers le client à tout moment.
Client → GET /mcp (avec mcp-session-id) → Serveur
Serveur → SSE stream (connexion ouverte indéfiniment) → Client
(le serveur peut maintenant envoyer des messages à tout moment)
Cette connexion SSE est la clé pour permettre la communication serveur-vers-client.
Étape 3 : Appels d’outils et double connexion SSE
Quand le client fait un appel d’outil, le système crée deux connexions SSE séparées :
Connexion SSE primaire (GET) :
→ Pour les requêtes initiées par le serveur
→ Reste ouverte indéfiniment
Connexion SSE spécifique à l'outil (POST) :
→ Créée pour chaque appel d'outil
→ Se ferme automatiquement quand le résultat est envoyé
Routage des messages
Différents types de messages sont routés vers différentes connexions :
| Message | Via |
|---|---|
| Notifications de progression | Connexion SSE primaire |
| Messages de log | Connexion SSE spécifique à l’outil |
| Résultats d’outils | Connexion SSE spécifique à l’outil |
| Requêtes de sampling | Connexion SSE primaire |
Visualisation du flux complet
CLIENT SERVEUR
│ │
│─── POST /mcp Initialize ──────►│
│◄── 200 (+ mcp-session-id) ─────│
│─── POST /mcp Initialized ─────►│
│ │
│─── GET /mcp (SSE primaire) ───►│ ← connexion persistante
│◄═══════════════════════════════│ (stream ouvert)
│ │
│─── POST /mcp tools/call ──────►│ ← appel d'outil
│◄═══ SSE outil (stream) ════════│ ← réponses streaming
│ ├── ProgressNotification │
│ ├── LoggingNotification │
│ └── CallToolResult │ ← ferme ce stream
│ │
│◄── CreateMessageRequest ───────│ ← via SSE primaire (sampling)
│─── CreateMessageResult ───────►│
Paramètres qui cassent la solution
StreamableHTTP inclut deux options de configuration importantes :
stateless_http=True: Désactive les sessions et la connexion SSE primairejson_response=True: Désactive le streaming des réponses POST
Activer ces paramètres rompt le mécanisme SSE de contournement.
Et depuis la version 2026-07-28
Le changelog de la version courante démonte précisément ce mécanisme : les sessions et l’en-tête Mcp-Session-Id disparaissent, le GET et resources/subscribe sont remplacés par un unique flux subscriptions/listen (une réponse POST longue, à laquelle le client s’abonne pour des types de changements précis), la reprise des flux SSE (Last-Event-ID) est supprimée (une requête interrompue se renvoie), et les requêtes du serveur vers le client n’existent plus. Le double flux décrit ici reste donc la bonne lecture des serveurs de l’ère 2025, que l’Inspector MCP sait inspecter en ère « legacy ».
À vous de jouer
- Lancez votre serveur en Streamable HTTP (
mcp.run(transport="streamable-http")en v1) et connectez-y l’Inspector MCP avec--transport http: dans la colonne Protocol, retrouvez l’identifiant de session renvoyé parinitialize. - Appelez un outil qui émet des logs et de la progression, et observez par quel flux chaque message arrive.
- Dans la spécification 2026-07-28, lisez la section
subscriptions/listenet notez ce qui remplace le GET.
Sources officielles : StreamableHTTP in depth (Claude Academy) · Streamable HTTP (spécification 2026-07-28) · Changelog 2026-07-28 · Inspector : ères de protocole
Points clés à retenir
- Ère 2025 :
initializepar POST renvoie un identifiant de session à joindre à toutes les requêtes. - Un flux SSE primaire (GET) pour les requêtes du serveur et la progression ; un flux SSE par appel d’outil (POST) pour les logs et le résultat, fermé à la fin.
stateless_http=Truesupprime session et flux primaire ;json_response=Truesupprime le streaming des réponses POST.- 2026-07-28 : plus de session ni de reprise SSE,
subscriptions/listenremplace le GET, plus de requêtes initiées par le serveur.