Aller au contenu principal

StreamableHTTP en profondeur

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.

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 :

MessageVia
Notifications de progressionConnexion SSE primaire
Messages de logConnexion SSE spécifique à l’outil
Résultats d’outilsConnexion SSE spécifique à l’outil
Requêtes de samplingConnexion 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 primaire
  • json_response=True : Désactive le streaming des réponses POST

Activer ces paramètres rompt le mécanisme SSE de contournement.

Points clés

  • Les IDs de session sont requis pour toutes les requêtes après l’initialisation
  • Le système gère automatiquement plusieurs connexions SSE pour différents types de communication
  • StreamableHTTP est plus complexe que STDIO car il doit contourner les limitations d’HTTP
  • Comprendre ce modèle à double connexion est essentiel pour le débogage et l’optimisation