Use stdio for local MCP servers and Streamable HTTP for remote ones
DrFritzi · Reviewed · Updated 28 Sept 2026 · Markdown
Answer
Pick stdio when the MCP client (the host application) should launch your server as a local subprocess and own its lifetime. Pick Streamable HTTP when the server runs as an independent process that many clients reach over the network through a single endpoint such as https://example.com/mcp. Do not start new work on the old HTTP+SSE transport from protocol version 2024-11-05: it has been deprecated since 2025-03-26. This page describes MCP specification 2026-07-28, the latest revision.
Details
Side-by-side
| stdio | Streamable HTTP | |
|---|---|---|
| Who starts the server | The client launches it as a subprocess | The server runs independently |
| Clients per server | One (the parent process) | Many |
| Framing | One JSON-RPC message per line on stdin/stdout, no embedded newlines | Each client message is its own HTTP POST to one MCP endpoint |
| Server replies | Lines on stdout | A single JSON object or an SSE stream scoped to that request |
| Logging | Server MAY write UTF-8 to stderr | Your own log pipeline; the client does not capture stderr |
| Cancelling a request | Client sends notifications/cancelled |
Client closes that request's response stream |
| Metadata | Only in the JSON-RPC body (_meta) |
Body plus mirrored headers (MCP-Protocol-Version, Mcp-Method, Mcp-Name) |
| Security baseline | Runs with the user's local permissions | MUST validate Origin; SHOULD bind to 127.0.0.1 when local; SHOULD authenticate |
| Shutdown | Client closes stdin, waits, then terminates the process | Connection close |
When to pick stdio
- A desktop app, IDE or CLI agent runs a tool on the user's machine.
- You want zero network setup and no port to secure.
- One client per server process is fine.
The rule that catches people: the server MUST NOT write anything to stdout that is not a valid MCP message. A single debug print on stdout breaks the stream. Log to stderr.
When to pick Streamable HTTP
- The server is shared by many users or clients, or runs in the cloud.
- You need standard HTTP infrastructure: load balancers, gateways, auth.
- Clients cannot spawn local processes (for example, hosted agents).
In 2026-07-28 the spec copies selected body fields into headers so that intermediaries can route requests without parsing JSON. The body stays the source of truth. A header that does not match the body gets 400 Bad Request with error -32020 (HeaderMismatch).
The deprecated HTTP+SSE transport (2024-11-05)
The original remote transport used two endpoints. The client opened a long-lived SSE connection. The server's first event was endpoint, which gave a separate URL that the client used for every POST. Streamable HTTP replaced it in 2025-03-26. The 2026-07-28 revision puts HTTP+SSE in the "Deprecated" state under the new feature lifecycle policy, which means it can be removed in a later revision.
Clients that still need to reach old servers POST to the URL first. If that returns 400, 404 or 405 and the body is not a recognized modern JSON-RPC error, they send a GET and expect an endpoint event.
Version note
Protocol revisions from 2025-03-26 to 2025-11-25 also had an optional GET stream, Mcp-Session-Id sessions and resumable SSE streams on Streamable HTTP. Revision 2026-07-28 removes all three. See mcp-streamable-http-sessions.