stdio vs HTTP vs SSE: MCP's Transport Options
MCP separates message schema (JSON-RPC 2.0 capabilities) from transport (how those messages move).
Search across all documentation pages
MCP separates message schema (JSON-RPC 2.0 capabilities) from transport (how those messages move).
The same tools/resources/prompts can ride on a local subprocess pipe or a remote HTTP endpoint. Choosing the wrong transport is one of the most common production mistakes.
MCP defines methods and capability negotiation. Transports only need to:
Application logic (tools/resources/prompts)
↑
JSON-RPC messages
↑
Transport (stdio | Streamable HTTP | legacy SSE | custom)If you redesign tool handlers when you change transport, you coupled layers incorrectly.
| Name | Status (typical 2025-2026 specs) | Role |
|---|---|---|
| stdio | Current standard | Local subprocess stdin/stdout |
| Streamable HTTP | Current standard remote transport | Single HTTP endpoint; POST (+ GET); optional SSE for multi-message streams |
| HTTP+SSE (legacy) | Older remote design | Separate streams / dual-channel style; keep for compatibility |
People say "SSE transport" casually to mean either legacy HTTP+SSE or "SSE mode inside Streamable HTTP." Be precise in architecture docs.
How it works:
Host/client --spawn--> server process
<--JSON-RPC lines over pipes-->Strengths:
npx / uvx / binary commands in config filesWeaknesses:
Best fit: developer machines, desktop hosts, sandboxed local tools, reference servers.
How it works (conceptual):
/mcp).Client --POST /mcp--> Server
<-- JSON or SSE events --
Client --GET /mcp--> Server (optional stream)This design replaces the older HTTP+SSE transport for new work while allowing SSE as a streaming mechanism inside the newer model.
Strengths:
Weaknesses:
Best fit: team platforms, SaaS MCP products, multi-agent backends, cross-service tools.
Older specs used a more rigid HTTP+SSE split (client POST for messages, dedicated SSE channel for server messages).
Why it still appears:
MCPServerSse-style helpers for compatibilityGuidance:
| Constraint | Prefer | Avoid |
|---|---|---|
| Laptop / IDE plugin | stdio | Public HTTP without need |
| Shared company tools | Streamable HTTP | Spawning heavy stdio per request in a web farm without a plan |
| No inbound ports to private net | Tunnel + remote pattern or outbound gateway | Opening raw public MCP ports casually |
| Long-running streams | Streamable HTTP with SSE streaming | Forcing unary POST only if you need multi-message progress |
| Maximum client simplicity for local demos | stdio | Overbuilt remote stack |
stdio (client config idea):
{
"mcpServers": {
"files": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./mcp-demo"]
}
}
}Streamable HTTP (client config idea):
{
"mcpServers": {
"internal": {
"url": "https://mcp.example.internal/mcp",
"headers": {
"Authorization": "Bearer ${MCP_TOKEN}"
}
}
}
}Exact config keys differ by host (Claude Desktop, VS Code, Cursor, custom agents). Verify at build.
| Transport | Boundary | Typical controls |
|---|---|---|
| stdio | OS process + filesystem | User permissions, path allowlists, sandbox |
| Streamable HTTP | Network service | TLS, OAuth/API keys, mTLS, gateway policy |
| Tunnelled remote | Hybrid | Outbound-only connectors, identity at gateway |
stdio is not "inherently safe."
A local filesystem server with $HOME scope is still dangerous.
| Concern | stdio | Streamable HTTP |
|---|---|---|
| Horizontal scale | Weak (process-per-client) | Strong with normal web ops |
| Cold start | Per spawn | Amortized on service |
| Observability | Client-side logs + stderr | Central metrics, traces, access logs |
| Multi-tenant isolation | OS user / container | Authz + namespaces in app |
The protocol allows pluggable transports if both ends agree. Use custom transports sparingly (for example specialized message buses). Document them as non-portable extensions.
| Design | Strength | Weakness | Best fit |
|---|---|---|---|
| stdio only | Simple local DX | Poor multi-user remote | IDE agents |
| Streamable HTTP only | Clean remote model | Heavier local DX | Platforms |
| Dual support | Max reach | Two test matrices | Public servers |
| Legacy SSE only | Compat with old clients | Technical debt | Migration window only |
stdio for a personal/local tool; Streamable HTTP if the server must be shared remotely. Many teams implement both.
Not as a core required transport in the mainline specs discussed here. Prefer stdio and Streamable HTTP unless you intentionally build a custom transport.
Streamable HTTP simplifies the endpoint model and improves streaming flexibility while remaining HTTP-friendly (verify historical notes in the official transport docs).
Yes. Plan for long-lived streams, auth header forwarding, timeouts, and buffering behavior.
Logical JSON-RPC methods stay the same; framing and session setup differ.
Use an official client harness or your agent SDK against both local and remote endpoints with the same tool assertions.
See MCP Tunnels and outbound gateway patterns.
No. stdout is for MCP messages. Use stderr or a proper logger.
No. Unary JSON responses are valid when a single response is enough; SSE helps multi-message/streaming cases.
A2A also uses HTTP/SSE/JSON-RPC patterns for agent-to-agent work. MCP transports connect hosts to tool servers. Different layer, similar HTTP skills.
Sometimes, with care about process lifetime and package size. Many serverless designs prefer HTTP MCP services instead.
Client class names, URL shapes, session headers, and streaming expectations. Dual-run and contract tests reduce pain.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026