# Which MCP transport should a new remote server choose: stdio, Streamable HTTP, or legacy SSE?

Canonical: https://mudpie.ai/webmcp/guides/choose-mcp-transport-for-a-new-remote-server/
Breadcrumb: [Home](https://mudpie.ai/) / [WebMCP guides](https://mudpie.ai/webmcp/guides/) / [Which MCP transport should a new remote server choose: stdio, Streamable HTTP, or legacy SSE?](https://mudpie.ai/webmcp/guides/choose-mcp-transport-for-a-new-remote-server/)
Author: Ali Abouelatta (https://mudpie.ai/authors/ali-abouelatta/)
Published: 2026-09-19
Updated: 2026-09-19
Research type: guide
Method: Documentation-derived transport decision using the current MCP specification, SDK guidance, and one named vendor setup as context. No interoperability benchmark was executed.

Short version: use `stdio` for a local server the client launches, Streamable HTTP for a hosted server, and legacy HTTP+SSE only when a named client still needs it. For a new remote service, legacy SSE is a compatibility branch, not the default architecture.

The transport choice is really a deployment choice. Where does the server run? Who owns the process? Does it need to serve more than one client? How will authentication, reconnects, and proxy behavior be operated after the demo?

## The three choices

The [current MCP transport specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports) lists `stdio` and Streamable HTTP as the standard mechanisms. It says Streamable HTTP replaces the older HTTP+SSE transport, then documents a backward-compatibility path for clients and servers that still need it.

| Transport | Fits when | Useful part | Cost or risk |
| --- | --- | --- | --- |
| `stdio` | A client can launch a local server process | Simple local boundary; no public endpoint to operate | Packaging, local credentials, process lifecycle, and client-specific setup become your problem |
| Streamable HTTP | You are running a hosted or shared service | One MCP endpoint can handle POST and GET, with JSON or optional SSE responses | You now own authentication, Origin validation, sessions, proxy behavior, timeouts, and reconnects |
| Legacy HTTP+SSE | A known older client cannot use Streamable HTTP | Buys compatibility for a real user or customer | Two-endpoint behavior and a migration path you eventually need to remove |

This is not a standards popularity contest. A local developer tool and a hosted customer integration have different failure surfaces.

## Choose `stdio` for a local server

`stdio` is the clean choice when the client launches your server as a subprocess. The official spec describes messages moving over standard input and output. That is a good fit for a CLI, an IDE extension, or a local developer utility where the user already controls the machine.

The tradeoff is distribution. You need a reliable install path, a runtime story, a way to handle local credentials, and logs that do not corrupt the protocol stream. The server cannot casually print debugging text to stdout if stdout is carrying MCP messages.

I would choose `stdio` when all three are true:

- the workflow is local or single-user;
- the client already knows how to launch the process; and
- putting the server on the public internet would add more security and operations than the task needs.

If the customer must connect from several machines, share one service across a team, or use a hosted credential boundary, you are probably describing Streamable HTTP instead.

## Choose Streamable HTTP for a hosted service

Streamable HTTP uses one MCP endpoint that supports POST and GET. A request can receive one JSON response or an SSE stream, depending on what the server returns and what the client accepts. The GET path does not require every server to offer server-sent events: the specification allows a legitimate HTTP 405 response when the endpoint does not provide an SSE stream. That lets a simple server stay simple while leaving room for server-to-client messages and longer workflows when needed.

It also creates real operating work. The specification requires Origin validation to reduce DNS-rebinding risk and recommends proper authentication. A local service should bind to localhost rather than every network interface. Those are not optional polish items to add after launch.

The [TypeScript SDK server documentation](https://ts.sdk.modelcontextprotocol.io/server) is useful here because it distinguishes stateless and stateful Streamable HTTP examples. Start stateless when the task can carry its own explicit identifiers and does not need hidden connection state. Choose stateful behavior only when resumability, notifications, or multi-step continuity earn that complexity.

For a new hosted server, my default is:

1. One Streamable HTTP endpoint.
2. Explicit authentication and Origin checks.
3. A read-only tool for the first pilot.
4. A bounded timeout and an explicit reconnect or status path.
5. A small owned fixture that tests initialization, one tool call, one invalid input, and one dropped connection.

## Keep legacy SSE only for a known compatibility reason

The spec’s compatibility guidance gives clients a way to try the new endpoint and fall back when they receive errors such as 400, 404, or 405. That is useful when you have a real older client to support. It is not a reason to make every new service carry two transport architectures forever.

Linear’s current [MCP setup documentation](https://linear.app/docs/mcp) is a concrete example of this posture. It presents Streamable HTTP as the primary endpoint, documents a read-only route, and describes its SSE endpoint as a deprecated fallback for clients that do not support the newer transport. The lesson is not “copy Linear.” It is “name the compatibility case and give it an exit condition.”

## The founder decision

Choose `stdio` when the client owns the process. Choose Streamable HTTP when you own a hosted service. Keep legacy SSE only when a specific client, customer, or migration window justifies it.

Do not hide auth and proxy work behind the transport label. The transport is part of the product boundary. Pick the one that matches where your users are, then prove the smallest real workflow on an owned fixture before you promise compatibility to anyone else.

## Method note

This is a documentation-derived fit guide. No live interoperability benchmark, third-party action, or adoption measurement was performed.


## Author disclosure

I cofound Lazyweb and publish Mudpie. This is an owner-written publication, not an independent testing organization. Research notes distinguish observations, sourced reporting and editorial judgment.
