Aller au contenu principal

Le transport STDIO

Les clients et serveurs MCP communiquent en échangeant des messages JSON, mais comment ces messages sont-ils réellement transmis ? Le canal de communication utilisé s’appelle un transport, et il existe plusieurs façons de l’implémenter — des requêtes HTTP aux WebSockets, en passant par les entrées/sorties standard.

Comparaison des transports MCP : STDIO vs StreamableHTTP

Le transport STDIO

Quand vous développez un serveur ou client MCP pour la première fois, le transport le plus couramment utilisé est le transport STDIO (Standard Input/Output). Cette approche est simple : le client lance le serveur MCP comme un sous-processus et communique via les flux d’entrée/sortie standard.

Voici comment ça fonctionne :

Client → stdin du serveur   (envoi de messages)
Serveur → stdout            (envoi de réponses)

Caractéristiques clés :

  • L’un ou l’autre peut envoyer un message à n’importe quel moment
  • Fonctionne uniquement quand client et serveur tournent sur la même machine
  • Idéal pour le développement et les tests locaux

Voir STDIO en action

Vous pouvez tester un serveur MCP directement depuis votre terminal sans écrire de client séparé. Quand vous lancez un serveur avec uv run server.py, il écoute stdin et écrit les réponses vers stdout.

Cela signifie que vous pouvez coller des messages JSON directement dans votre terminal et voir immédiatement les réponses du serveur.

La séquence de connexion MCP

Toute connexion MCP doit commencer par un handshake spécifique en trois messages :

1. InitializeRequest     ← Le client envoie ceci en premier
2. InitializeResult      ← Le serveur répond avec ses capacités
3. InitializedNotification ← Le client confirme (aucune réponse attendue)

Seulement après ce handshake, vous pouvez envoyer d’autres requêtes comme des appels d’outils ou des listes de prompts.

Quatre scénarios de communication

Avec n’importe quel transport, vous devez gérer quatre patterns de communication différents :

DirectionMécanisme
Client → Serveur (requête)Le client écrit sur stdin
Serveur → Client (réponse)Le serveur écrit sur stdout
Serveur → Client (requête)Le serveur écrit sur stdout
Client → Serveur (réponse)Le client écrit sur stdin

La beauté du transport STDIO est sa simplicité : chaque partie peut initier la communication à tout moment en utilisant ces deux canaux.

Exemple de session STDIO

// Client → Serveur : Initialize
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {"name": "my-client", "version": "1.0"}
  }
}

// Serveur → Client : Initialize Result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {"tools": {}, "resources": {}, "prompts": {}},
    "serverInfo": {"name": "my-server", "version": "1.0"}
  }
}

// Client → Serveur : Appel d'outil
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "read_doc_contents",
    "arguments": {"doc_id": "rapport.pdf"}
  }
}

Pourquoi comprendre STDIO est important

Le transport STDIO représente le cas “idéal” où la communication bidirectionnelle est transparente. Quand nous passerons aux autres transports comme HTTP, nous rencontrerons des limitations où le serveur ne peut pas toujours initier des requêtes vers le client.

Le transport STDIO sert de référence pour comprendre à quoi ressemble une communication MCP complète, avant d’aborder les contraintes des autres méthodes de transport.

Pour le développement et les tests, STDIO est parfait. Pour les déploiements en production où client et serveur doivent tourner sur des machines différentes, vous devrez considérer d’autres options de transport.