How MCP Transports Work — stdio, HTTP, and Message Framing

How MCP Transports Work — stdio, HTTP, and Message Framing

2026-03-24

The MCP data layer defines WHAT messages look like (JSON-RPC requests, responses, notifications). The transport layer defines HOW those messages move between client and server.

MCP supports two transports. The same JSON-RPC messages work over both — the transport is pluggable.

stdio — Local Servers

The simplest transport. The client launches the server as a child process and communicates through stdin/stdout.

Client (Host) parent process Server child process stdin (JSON-RPC) stdout (JSON-RPC) stderr → logs (optional) Messages delimited by newlines. No network involved.

How it works:

  1. Client spawns the server as a subprocess (like running a command)
  2. Client writes JSON-RPC messages to the server's stdin
  3. Server writes JSON-RPC messages to its stdout
  4. Each message is one line of JSON, delimited by \n
  5. Server can write logs to stderr (client may capture or ignore them)
  6. Client closes stdin to terminate the connection

Rules:

  • Messages MUST NOT contain embedded newlines (one JSON object per line)
  • Server MUST NOT write non-JSON-RPC content to stdout
  • Client MUST NOT write non-JSON-RPC content to the server's stdin
  • The server's stderr is for logging only — not protocol messages

When to use: local MCP servers that run on the same machine. Filesystem access, local databases, git operations, code analysis, local build tools.

Advantages: zero network overhead, simple to implement, natural process lifecycle (client kills the subprocess on shutdown).

Limitations: single client only (one stdin), local only (no network access), subprocess management adds complexity.

Streamable HTTP — Remote Servers

For servers that need to run remotely, serve multiple clients, or persist across sessions. Uses standard HTTP with optional Server-Sent Events (SSE) for streaming.

How it works:

The server exposes a single HTTP endpoint (e.g., https://example.com/mcp). This endpoint handles both POST and GET.

Sending messages (client → server): Every JSON-RPC message from the client is an HTTP POST to the MCP endpoint. One message per request.

POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream

{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}

The server responds either with:

  • Content-Type: application/json — a single JSON response
  • Content-Type: text/event-stream — an SSE stream that may contain multiple messages (the response plus any server-initiated requests or notifications)

Receiving messages (server → client): The client can open an SSE stream via HTTP GET to receive server-initiated messages (notifications, requests) without first sending a POST.

GET /mcp HTTP/1.1
Accept: text/event-stream

When to use: remote MCP servers, SaaS integrations (GitHub, Sentry, Slack), shared team tools, any server that needs to serve multiple clients.

Session Management

Streamable HTTP supports stateful sessions:

  1. During initialization, the server returns an Mcp-Session-Id header
  2. The client includes this header on all subsequent requests
  3. The server uses it to maintain state across requests
  4. Either side can terminate the session (client sends HTTP DELETE, or server returns 404)

Session IDs should be cryptographically secure (UUIDs or JWTs). If a client receives 404 for its session ID, the session expired and it must re-initialize.

Resumability

Network connections break. SSE streams disconnect. The Streamable HTTP transport supports resuming:

  1. The server attaches an id field to each SSE event
  2. If the client reconnects, it sends Last-Event-ID header with the last event ID received
  3. The server replays missed events from that point

This prevents message loss during temporary network interruptions — critical for long-running tool executions.

Authentication

The stdio transport doesn't need authentication — if you can launch a subprocess, you have access.

The Streamable HTTP transport uses standard HTTP authentication:

  • Bearer tokens
  • API keys
  • OAuth 2.0 (recommended by the spec)
  • Custom headers

MCP recommends OAuth for production deployments. The server validates credentials on every request.

Security for HTTP Transport

Remote servers face additional threats:

DNS rebinding — a malicious website tricks the browser into connecting to a local MCP server. Defense: servers MUST validate the Origin header on all requests.

Localhost binding — local HTTP servers should bind to 127.0.0.1, not 0.0.0.0. Binding to all interfaces exposes the server to the network.

TLS — remote servers should use HTTPS. Without it, tool calls and responses (potentially containing secrets) travel in plaintext.

Choosing a Transport

stdioStreamable HTTP
NetworkLocal onlyLocal or remote
ClientsSingleMultiple
LatencyMicrosecondsMilliseconds
AuthenticationProcess-levelHTTP-based
ResumabilityN/ASupported
SessionsImplicit (process lifetime)Explicit (session ID)
Best forLocal toolsRemote services, SaaS
stdio (local) Client Server stdin stdout same machine, no network

Streamable HTTP (remote) Client Server POST JSON/SSE Client 2 Client 3 multiple clients, over network

Most MCP servers today use stdio because most use cases are local (Claude Code running a filesystem server, Cursor running a database server). As the ecosystem matures, Streamable HTTP will grow for shared, remote, and team-level tools.

Next Steps