stdio or streamable HTTP, at revision 2026-07-28, which removed sessions, GET streams and resumability. What moving off stdio forces you to add.
What an MCP transport is responsible for
A Model Context Protocol server exposes tools, resources, and prompts to a host application. The transport is the layer underneath that: it carries JSON-RPC messages between the client and the server, and it decides where the server runs and who can reach it.
Everything above the transport stays the same. Your tool definitions, your argument schemas, the way you return results: none of it changes when you move from one transport to the other. What changes is process lifetime, network reach, and how much security you have to write yourself.
The specification defines two. The description below is of revision 2026-07-28. The transport layer has already been rewritten twice, so the revision is worth checking against whatever you are reading elsewhere.
Running a server over stdio
The client launches your server as a subprocess. The server reads JSON-RPC messages from standard input and writes them to standard output, one message per line, and no message may contain an embedded newline.
One rule causes more broken servers than anything else in MCP:
The server MUST NOT write anything to its
stdoutthat is not a valid MCP message.
A stray print() or console.log() lands in the message stream and corrupts
the session. Logging goes to standard error, which the specification allows and
which clients may capture or ignore.
Because the server is a child process, it starts when the host starts it and dies with it. There is no port, no network surface, and nothing to authenticate. The specification says clients should support stdio whenever they can, and for a tool that runs on one person's machine it is the right answer.
Running a server over streamable HTTP
The server becomes an independent process serving many clients. It exposes a single endpoint, and in this revision that endpoint accepts POST and nothing else.
Each JSON-RPC request is its own POST. The server answers either with one JSON object or with a server-sent events stream scoped to that request, which carries progress notifications and then the final response. Closing that stream cancels the request, and the server must stop work on it.
Three mechanisms that earlier revisions had are gone in 2026-07-28:
- The standalone GET stream. There is no long-lived connection you open to receive server-initiated messages.
- Protocol-level sessions. No
Mcp-Session-Id, no HTTP DELETE to end a session. - Resumability.
Last-Event-IDdoes nothing, and streams do not replay.
If you read a tutorial written against an older revision, those three are the parts that will not work. A server built to the current revision answers a GET or DELETE with 405 and ignores both headers.
What moving off stdio forces you to add
On stdio, the only process that can talk to your server is the one that started it. On HTTP, anything that can reach the port can try. The specification turns that into requirements rather than advice:
- Servers MUST validate the
Originheader, and MUST answer an invalid one with 403. - When running locally, servers SHOULD bind to
127.0.0.1rather than0.0.0.0. - Servers SHOULD authenticate every connection.
The stated reason for the first two is DNS rebinding. A page in someone's
browser can resolve a hostname it controls to 127.0.0.1 and then issue
requests to a server listening there. Without origin checking, your local MCP
server answers them, and whatever tools it exposes belong to the attacker.
Binding to localhost does not save you, because the browser is on localhost.
Treat tool arguments the same way you treat any request body from the internet, because on this transport that is what they are. The permission check belongs in your handler, not in a tool description.
Choosing stdio or streamable HTTP
Ask where the server has to run, not which feels more modern.
Use stdio when the server does something on the user's machine: reading their files, driving a local database, running a command. The process model matches the job, and you get isolation without configuring anything.
Use streamable HTTP when the server is a service: shared by several users, holding credentials that are not theirs, or running somewhere they cannot. You are then writing a web service that speaks MCP, with the authentication, rate limiting, and monitoring any web service needs.
Plenty of servers ship both. The tool logic does not change, so supporting the second transport costs a different entry point and the security work above.
Checking which MCP revision you are reading about
The revision date is part of the protocol. Ask any server what it speaks, and check the current revision at the specification's versioning page before you trust an article written months earlier, this one included.
MCP marks features deprecated for at least twelve months before removing them, and keeps a registry of what is on the way out. The HTTP+SSE transport from 2024-11-05 has been deprecated since 2025-03-26 and still appears there. If you find code using it, it works today and will not work forever.
Further reading
- Streamable HTTP, revision 2026-07-28: the endpoint rules, the security requirements, and the backward compatibility guidance quoted above.
- Versioning: how revisions are named and which one is current.
- MCP in one sitting: the protocol above the transport, if you have not met it yet.
Knowledge check
Question 1 of 4
Sign in to save your progress and pick up where you left off.