What transport mechanisms does MCP support, and when do you choose stdio vs. HTTP?
Quick Answer
MCP defines two standard transports. stdio: the client launches the server as a local subprocess and exchanges newline-delimited JSON-RPC messages over its stdin/stdout. Streamable HTTP: the client talks to a server over regular HTTP, POSTing JSON-RPC messages to a single endpoint, with the server optionally upgrading a response to a Server-Sent Events stream for server-initiated messages. Choose stdio for local-only integrations (a server reading local files, running local git commands, or accessing something only present on the user's machine) since it needs no networking, no auth, and no separately running server process. Choose Streamable HTTP for a remote/shared service — a hosted SaaS integration many users connect to concurrently — where the server runs independently of any one client and needs its own authentication and session management.
Detailed Answer
The transport is a separate concern from everything else in MCP — the same JSON-RPC messages, primitives, and lifecycle work identically regardless of which transport carries them.
stdio — for local processes
# Host launches the server as a child process
python weather_server.py
The host writes JSON-RPC requests to the subprocess's stdin (one JSON object per line) and reads responses/notifications from its stdout, also newline-delimited. The server's stderr is reserved for logging/diagnostics — it must never be written to for anything else, since it's not part of the protocol stream.
Streamable HTTP — for remote/shared services
POST https://mcp.example.com/mcp
Content-Type: application/json
Mcp-Session-Id: 9f86d0...
{"jsonrpc": "2.0", "id": 1, "method": "tools/call", ...}
A single HTTP endpoint accepts POSTed JSON-RPC messages; the server can respond with a plain JSON response, or upgrade the response to an SSE stream if it needs to send multiple messages (e.g., progress notifications followed by the final result) for that request.
Choosing between them
A filesystem or local-git server has no reason to run over the network — stdio is simpler and has a smaller attack surface. A hosted "connect your Slack workspace" server has to run remotely and serve many users, so Streamable HTTP with proper authorization is the only sensible option:
| stdio | Streamable HTTP | |
|---|---|---|
| Where the server runs | Local subprocess on the user's machine | Independent, possibly remote, host |
| Networking needed | No | Yes |
| Auth needed | Rarely (process-level trust) | Usually (OAuth 2.1) |
| Good fit for | Local file/git/shell access | SaaS integrations, multi-user services |
| Session management | Implicit (one process per client) | Explicit (Mcp-Session-Id header) |