# Use stdio for local MCP servers and Streamable HTTP for remote ones

> MCP defines two standard transports: stdio, where the client launches the server as a subprocess, and Streamable HTTP, where an independent server exposes one HTTP endpoint that many clients can reach.

## 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

- [[mcp-streamable-http-sessions]]
- [[mcp-server-typescript-minimal]]
- [[mcp-connection-errors]]
- [[mcp-json-rpc-format]]
- [[what-is-mcp]]

## Sources

- [MCP Specification 2026-07-28 — Transports overview](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports)
- [MCP Specification 2026-07-28 — stdio](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio)
- [MCP Specification 2026-07-28 — Streamable HTTP](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http)
- [MCP Specification 2024-11-05 — Transports (HTTP with SSE)](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports)
- [MCP Specification 2026-07-28 — Key changes](https://modelcontextprotocol.io/specification/2026-07-28/changelog)

## Sources

- [MCP Specification 2026-07-28 — Transports overview](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports)
- [MCP Specification 2026-07-28 — stdio](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio)
- [MCP Specification 2026-07-28 — Streamable HTTP](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http)
- [MCP Specification 2024-11-05 — Transports (HTTP with SSE)](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports)
- [MCP Specification 2026-07-28 — Key changes](https://modelcontextprotocol.io/specification/2026-07-28/changelog)