Part 1 of 7 · 2 min read
Overview
In this module you will
- Say what a transport is in MCP and what it is not: it carries messages and defines framing, request metadata, cancellation and shutdown, but never changes what a message means.
- Run an MCP server over stdio and over Streamable HTTP, and say which one to pick and why.
- Explain how progress, cancellation and change notifications travel on each transport.
- Handle a broken connection correctly, including the case where the server already did the work.
- List what an HTTP MCP endpoint must check before it is safe to expose: the
Originheader, the bind address, authentication, and whether the mirrored headers match the body. - Recognise the older transports (sessions, resumable streams, HTTP+SSE) well enough to talk to servers that still use them.
Module 2 showed what the messages are. This module is about how they get from one program to another, and that is where most real failures live: a debug print that corrupts a pipe, a connection that dies after the server charged a card, a stream that a proxy buffers until it looks hung, a local server that a web page on another site can reach. None of these is a model problem. All of them happen to agents.
It also matters for the next module. MCP authorisation (module 5) only applies to HTTP: a stdio server is started by the host and inherits the user's own permissions, so its security is the security of the process you chose to run. A remote server is a different trust situation, and the transport is what separates them.
About the examples, and about the protocol version
The example code is more real than in module 2, but still a teaching imitation. The stdio server really runs as a subprocess and the client talks to it over real pipes. The HTTP server and client use real sockets on 127.0.0.1, with the standard library's HTTP server and Server-Sent Events written by hand. What is missing: TLS, authentication (module 5), a real reverse proxy (one experiment uses a tiny gateway I wrote), sampling and elicitation (module 4), and the tasks extension. Both servers are Python threads in a process I control; a production server on a load balancer behaves differently.
The message shapes follow the specification pages I read on 24 October 2026: the stdio and Streamable HTTP pages, the subscriptions and cancellation pages (all under the site's draft path, which describe the changes in revision 2026-07-28), and the 2025-11-25 transports page for the earlier form. Where those pages gave no rule, I chose one and said so in the code and here. Timings depend on this machine and on loopback networking, so they show direction only. Check the current specification before you rely on a detail.