Guide · Tools & MCP
Which MCP transport — stdio, SSE or Streamable HTTP?
Published 1 August 2026 · revised 10 August 2026
An MCP server is how Claude reaches outside the conversation — it exposes tools, resources and prompts over a standard protocol, so one integration works in any MCP client. More in the Tools & MCP track.
Streamable HTTP is now the default MCP transport, SSE is legacy but still supported, and stdio is for local processes — and the choice is decided by deployment reality rather than preference: who runs the process, who holds the credentials, who upgrades it.
The three MCP transports
- stdio. The client launches your server as a child process and talks over standard input and output. One process per client, local, no network.
- Streamable HTTP. Your server is an HTTP endpoint. The client POSTs requests and the server can stream responses back over the same connection. Remote, multi-client, the current recommendation for anything network-facing.
- HTTP + SSE. The older remote pattern: a POST channel for requests and a separate Server-Sent Events stream for responses. Superseded by Streamable HTTP, but still what many deployed servers and clients speak.
How do you choose an MCP transport?
One question decides most cases: does the server need the user's machine?
- Yes → stdio. Reading local files, running local commands, touching local git, using credentials already on that machine. A remote server cannot do these things without you building a tunnel you do not want to own.
- No → Streamable HTTP. Wrapping a SaaS API, querying a shared database, anything you want to update centrally without asking every user to upgrade.
Second question, when both are viable: who has to install it? stdio means every user installs a runtime and your package, and their version is whatever they last pulled. HTTP means you deploy once and everyone is instantly current. For a team tool that difference dominates.
What each transport costs
stdio
- No auth layer to build — the process runs as the user, with the user's rights. That is also the risk: no isolation, and a prompt-injected tool call runs with full local privileges.
- Anything your server writes to stdout that is not a protocol message corrupts the stream. Log to stderr. This single mistake accounts for a large share of "my server won't connect".
- Cold start per session, and no shared state between clients.
- Debugging is awkward: no request log, no URL to curl, failures surface as a client that silently shows no tools.
Streamable HTTP
- You own auth, and you must own it properly — token validation per request, per-user scoping, and no trusting a client-supplied user id.
- You own session identity across requests, plus the usual network concerns: timeouts, retries, proxies that buffer streamed responses.
- You get real operational tooling: logs, metrics, staged rollout, one place to fix a bug.
- Origin checks matter. A server bound to localhost over HTTP without origin validation can be reached by a web page in the user's browser.
SSE
- Two channels to keep alive, and the reconnect semantics are the part everyone gets wrong.
- Choose it only for compatibility with a client you do not control. For new work, Streamable HTTP.
Failure modes worth recognising
- Server connects, no tools listed. Almost always the handshake: a capability the client expected was not advertised, or stdout was polluted before initialization completed.
- Works locally, hangs when deployed. A proxy is buffering the stream. Check that the response is not being collected before it is forwarded.
- Intermittent disconnects on SSE. An idle-timeout on an intermediary. Keep-alives or move to Streamable HTTP.
- Works for you, fails for a colleague. stdio version skew. Pin the version in the client configuration.
A concrete pair of decisions
A server that formats and stages a git commit: stdio. It needs the working tree, the local git config and the user's signing key. Remote is not a trade-off; it is not possible without moving the repository.
A server that opens tickets in your issue tracker for the whole team: Streamable HTTP, deployed once, holding the tracker's API token server-side and mapping the authenticated user to a tracker identity. Under stdio you would be distributing that token to every laptop — a credential-management problem you can simply not create.
Can you support stdio and Streamable HTTP?
Yes, and it is cheap if you plan for it: keep your tool handlers transport-agnostic and put the transport at the edge as a thin adapter. The trap is letting local assumptions leak into the handlers — reading a file path from the environment, assuming a single user, caching in a module-level variable. Under HTTP those become cross-user bugs. If you intend to offer both, write the handlers as if they are remote and multi-tenant from day one.
Review checklist
- Does the server need the user's machine? If not, why is it stdio?
- Under stdio: is all logging on stderr, and is the version pinned?
- Under HTTP: is every request authenticated and scoped server-side, and is the origin checked?
- Is any handler assuming a single user or a local path?
- Have you tested through the proxy you will actually deploy behind?
Where this fits
Transport choice sits in the Tools & MCP part of the track, upstream of tool schema design and versioning. The judgement being tested is deployment-shaped: who runs the process, who holds the credentials, and who has to upgrade when you fix a bug.
Related guides
- What is MCP, and what is an MCP server?
- Structured output or function calling — how do you stop drift?
Keep going
- the Tools & MCP track — the full module list this guide belongs to.
- Practise this with the coach — a Socratic session with Tools & MCP preselected.