MCP defines two standard transports, and the choice is simple once you know the rule: use stdio when the server runs on the same machine as the AI client, and use Streamable HTTP when the server runs somewhere else and needs to serve clients over the network. stdio is for local tools; Streamable HTTP is for remote, multi-client servers. This guide explains how each works, the trade-offs, and how to pick without overthinking it.
New to MCP entirely? The MCP developer's guide covers the host/client/server model this builds on.
stdio: the local transport
With stdio, the client spawns your server as a child process and they exchange newline-delimited JSON-RPC over standard input and standard output. The client writes a request to the server's stdin, the server writes its response to stdout. That's it.
This is the transport for tools that live on the user's machine: a filesystem tool, a local database helper, a git wrapper. It's the simplest option, there's no HTTP server to run, no ports, no network surface at all. The server only exists while the client keeps the subprocess alive.
The one rule that trips everyone up: stdout is the protocol channel. Anything your server prints to stdout has to be valid JSON-RPC. A stray console.log corrupts the stream and the client sees garbage. Send all your logging to stderr instead.
Streamable HTTP: the remote transport
With Streamable HTTP, your server runs as an independent process that handles many client connections over HTTP. Clients send requests with HTTP POST, and the server can respond directly or, when it needs to stream multiple messages, use Server-Sent Events over a GET connection. One server process serves many clients at once.
This is the transport for anything hosted: a SaaS product exposing tools to its users, a shared internal server, a public MCP endpoint. GoHighLevel's official MCP server, for example, is Streamable HTTP, that's how it serves every agency's client over one endpoint. See Connecting AI Agents to GoHighLevel via MCP.
Streamable HTTP replaced the older HTTP-plus-SSE transport as the single standard for remote MCP. If you read older MCP material that describes a separate SSE transport, Streamable HTTP is the current, consolidated version.
Side by side
| Factor | stdio | Streamable HTTP |
|---|---|---|
| Where the server runs | Same machine as the client | Remote / hosted |
| Clients per server | One (spawned subprocess) | Many, concurrently |
| Network surface | None | HTTP endpoint |
| Setup complexity | Minimal | You run and secure a server |
| Auth | Implicit (local process) | You handle it (tokens, headers) |
| Best for | Local dev tools, personal utilities | SaaS, shared, public servers |
How to choose
Ask one question: does the server run on the same machine as the AI app, or somewhere else?
- Same machine (a tool for your own editor, a local utility, a dev-time integration): use stdio. It's simpler and has no network to secure.
- Somewhere else (a product other people install, a shared server, a public endpoint): use Streamable HTTP. It's the only option that serves remote, multiple clients.
A useful pattern while building: develop and test locally over stdio, since it's the fastest loop, then add a Streamable HTTP entry point when you're ready to host. The tool logic doesn't change, only the transport you connect at the end.
The stateless advantage for remote servers
The 2026 MCP spec made the protocol stateless at its core, which matters most for Streamable HTTP. A stateless server can sit behind a load balancer and have any instance handle any request, the same property that makes ordinary web apps easy to scale. If you're building a remote MCP server meant to handle real traffic, this is what lets it scale horizontally without sticky sessions. For a local stdio tool serving one client, statefulness was never a concern anyway.
Ready to build one? The TypeScript server guide starts on stdio (the easy loop), and the developer's guide covers the rest of the protocol.
Frequently asked questions
Which MCP transport should I use?
stdio if the server runs on the same machine as the AI client (local tools), Streamable HTTP if it runs remotely and serves clients over the network (hosted products). That's the whole decision.
What happened to the SSE transport?
Streamable HTTP consolidated it. The current standard is stdio and Streamable HTTP; the older separate HTTP-plus-SSE transport was replaced. Streamable HTTP can still use Server-Sent Events internally to stream responses.
Why does my stdio server output look corrupted?
You're printing to stdout, which is the JSON-RPC channel on stdio. Move all logging to stderr (console.error) so it doesn't corrupt the protocol stream.
Can one server support both transports?
Yes. The tool logic is the same, only the transport wiring differs. A common approach is to develop over stdio locally and expose the same server over Streamable HTTP when you host it.




