Skip to content
Wiki

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.

See also

Sources