MCP stdio vs Streamable HTTP: pick the right transport
My answer is boring on purpose: start with stdio for a local tool launched by one client. Choose Streamable HTTP when the server must live independently, accept remote connections, or serve more than one client.
People keep treating MCP transport as a maturity ladder. stdio is framed as the beginner option, Streamable HTTP as the serious option, and then a tiny local tool acquires a web server, OAuth, session storage, reverse-proxy rules, and four new ways to fail before it can read one file.
That is backwards. The transport should match the process boundary. If the MCP client can launch the server on the same machine, stdio is usually the cleaner design. If the server needs its own address, lifecycle, users, or fleet, Streamable HTTP earns its extra machinery.
The concrete answer: use stdio for local, client-spawned, single-user tools. Use Streamable HTTP for remote or shared services. If you cannot name the remote or multi-client requirement, do not volunteer for HTTP operations yet.
What the two transports actually change
The current MCP transport specification defines two standard transports. Both carry UTF-8 JSON-RPC messages. The difference is not the tool schema or the quality of the model response. The difference is how the client and server meet, who owns the process, and what infrastructure sits between them.
| Question | stdio | Streamable HTTP |
|---|---|---|
| Who starts the server? | The MCP client launches it as a subprocess. | The server runs independently. |
| Where does it normally run? | On the same machine as the client. | Locally, on a private network, or remotely. |
| How do messages move? | JSON-RPC over stdin and stdout. | JSON-RPC over HTTP POST and GET, with optional SSE streaming. |
| Multiple clients? | Usually one server process per client launch. | An independent service can handle multiple client connections. |
| Auth model? | Credentials normally come from the local environment or client configuration. | HTTP authorization, discovery, scopes, and token validation become relevant. |
| Operational burden? | Process startup, logs, packaging, and local permissions. | All of that plus endpoint security, deployment, TLS, auth, sessions, and network failure. |
Choose stdio when the client should own the process
In stdio, the client launches the MCP server as a subprocess. The client writes valid MCP messages to the server's standard input, and the server writes valid MCP messages to standard output. Logs belong on standard error because one stray debug line on stdout can corrupt the protocol stream.
That model is excellent for a local filesystem tool, a repo inspector, a desktop utility, or a personal database explorer. The server starts when the client needs it, inherits a deliberately scoped environment, and can stop when the client exits. There is no port to expose and no remote endpoint to defend.
stdio also gives you a useful default isolation shape: one launched process belongs to one client session. That is not a complete security boundary. The process can still read anything its operating-system identity can reach, so allowed directories, read-only modes, and narrow credentials still matter. But you are not adding a network listener just to make a local tool look impressive.
The official transport spec goes further and says clients should support stdio whenever possible. That is a strong hint about the protocol's intended baseline, not an apology for an old transport.
stdio is the right default when:
- one desktop or CLI client launches the tool;
- the data should stay on the user's machine;
- credentials can be injected through the local environment;
- each user can run their own process;
- you do not need a stable URL or independently running service.
Choose Streamable HTTP when the server needs its own life
Streamable HTTP is not merely stdio sent through a URL. The server becomes an independent process with one MCP endpoint that supports POST and GET. It can return a JSON response or use Server-Sent Events for streaming. It can also create stateful sessions with the MCP-Session-Id header, although sessions are optional rather than automatic.
This is the right shape for a centrally deployed service, a private internal tool used by several people, a cloud product, or a server that must stay alive when any one client disconnects. A stable endpoint lets clients connect without installing and launching the server package locally.
The price is real. The same spec requires Streamable HTTP servers to validate the Origin header to prevent DNS rebinding attacks. A local HTTP server should bind to 127.0.0.1, not 0.0.0.0. Servers should authenticate connections. Once the endpoint is remote, TLS, rate limits, tenant separation, logging, revocation, and deployment health are no longer optional background details.
Streamable HTTP is justified when:
- the server is remote from the client;
- multiple users or clients need the same service;
- the server owns shared state or expensive long-lived resources;
- central deployment and updates matter more than per-user installation;
- you are prepared to operate an authenticated network service.
The auth difference is bigger than most transport guides admit
The MCP authorization specification is explicit: HTTP-based transports should follow the MCP authorization flow when authorization is supported, while stdio implementations should not copy that flow and should retrieve credentials from the environment instead.
That makes sense. A local subprocess and a remote resource server have different trust boundaries. For HTTP, the MCP server acts as an OAuth resource server. The current specification uses protected resource metadata so clients can discover the appropriate authorization server, then request and present access tokens for the MCP resource.
Do not reduce that to “put a bearer token in a header.” The IETF's OAuth 2.0 Security Best Current Practice, RFC 9700, says access-token privileges should be limited to the minimum required and tokens should be audience-restricted to the intended resource server. The resource server must reject a token that was not meant for it. Scopes, audience checks, expiry, and revocation are part of the design, not polish for later.
Blunt rule: if your Streamable HTTP plan is “one permanent token shared by everybody,” you have chosen a multi-user transport without designing multi-user authorization.
Check client support before you choose a remote transport
A standards-compliant server is still useless to a client that cannot connect to its transport. This is where a lot of otherwise sensible plans become bridge projects.
A current question in the official MCP project's GitHub discussions captures the buyer pain cleanly: a builder had a Streamable HTTP server, a client path centered on stdio, and then needed a proxy. The follow-up questions moved immediately to authentication and identifying which user's requests were crossing that bridge.
That discussion is not a protocol guarantee and I am not using it as one. It is useful buyer evidence: transport compatibility and user identity have to be checked together. A stdio-to-HTTP bridge can solve a client gap, but it also becomes another process that handles credentials, errors, updates, and trust. Use a bridge when compatibility forces it, not as your default architecture.
A decision tree that does not waste your week
- Must the server run on another machine? If yes, choose Streamable HTTP.
- Must several users or client instances share one service? If yes, Streamable HTTP is usually the honest answer.
- Does the server need to stay alive independently of the client? If yes, use Streamable HTTP or another deliberately managed service boundary.
- Can the client launch a local process and keep the data local? If yes, choose stdio.
- Does your target client support the chosen transport directly? If no, change the transport or budget for a reviewed bridge.
Local repo tool
Pick stdio. The client launches one scoped process. Keep logs on stderr and restrict filesystem access.
Shared company knowledge server
Pick Streamable HTTP. Central identity, scopes, tenant rules, TLS, and endpoint monitoring belong in the plan.
Personal tool running as a localhost daemon
Probably stdio. Use local HTTP only if independent process lifetime or multiple local clients are actual requirements.
Hosted MCP product
Pick Streamable HTTP. A remote product needs a remote transport and a real authorization model.
How to migrate without rewriting the actual tools
Transport should sit at the edge of the server. Keep tool handlers, validation, and business logic independent from stdin, stdout, HTTP requests, and session headers. Then the migration is an adapter change instead of a rewrite.
- Separate tool logic from transport startup.
- Define the user and tenant identity that every tool call receives.
- Add Streamable HTTP behind TLS with strict Origin validation.
- Implement MCP authorization discovery and validate token audience and scopes.
- Decide whether the server is stateless or uses secure session IDs.
- Test the exact target clients before removing stdio support.
- Keep both transports only if you can test and maintain both honestly.
That last point matters. Supporting two transports expands your compatibility surface and your failure surface. Dual support is valuable when real clients need it. It is waste when it exists for a roadmap screenshot.
My recommendation
Start with stdio for a local MCP server. It matches the client-spawned process model, avoids exposing a port, and keeps the first version focused on whether the tools are useful.
Move to Streamable HTTP when you have a named requirement for remote access, shared service state, multiple clients, or centralized deployment. At that point, treat the server like the network service it is. Validate origins. Bind local endpoints narrowly. Use TLS. Design authorization around users, audiences, scopes, and revocation. Check client support before launch.
The right transport is not the one with more infrastructure. It is the one that makes the boundary obvious and leaves you with the fewest unnecessary ways to fail.
Need MCP tools you can inspect instead of more architecture theater?
The MCP Bundle is the practical lane: scoped servers, real tool surfaces, and setup material you can evaluate against the decision above.
See the MCP Bundle →Sources and methodology
This is a sourced architecture analysis, not a first-person test report. I mapped transport, authorization, and token claims to the current stable MCP specification and IETF security guidance retrieved July 16, 2026. The GitHub discussion is included only as buyer evidence about compatibility friction.
- Model Context Protocol, “Transports,” specification version 2025-11-25.
- Model Context Protocol, “Authorization,” specification version 2025-11-25.
- IETF, RFC 9700: Best Current Practice for OAuth 2.0 Security.
- MCP project discussion #1940 (buyer compatibility signal, not normative evidence).