INDEPENDENT CLAUDE LEARNING · NO AFFILIATION WITH ANTHROPIC PBC

Guide · Tools & MCP

Which MCP transport — stdio, SSE or Streamable HTTP?

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

Keep going

Independent practitioner notes from ClaudeMaster.ai. This is not official documentation and is not affiliated with Anthropic PBC. Verify anything version-specific against the vendor’s own docs.

Independence & disclaimer · Your data · Privacy policy · Contact · ©2026 ClaudeMaster.ai