Why MCP uses JSON RPC
MCP is completely agnostic to HTTP (and its versions).

✅ MCP is not tied to HTTP or any version (1.1, 2, 3)
✅ It’s often used over stdin, WebSocket, or raw TCP
✅ It borrows JSON-RPC-style structure, not REST or HTTP conventions
✅ You can use HTTP — but it’s entirely optional
MCP doesn’t require HTTP at all.
✅ MCP Is Transport-Agnostic
MCP is fundamentally about structured message passing, not the transport. It can work over:
stdin
/stdout
(most common, e.g. in language servers or CLI tools)- Named pipes / UNIX sockets
- TCP or WebSocket
- Embedded channels (e.g., Tauri
invoke
, FFI) - Optionally: HTTP (any version, 1.1, 2, 3…) — if you choose
🧠 Why MCP Skips HTTP
HTTP comes with baggage MCP doesn’t need, like:
HTTP Concern | Needed in MCP? | Why Not? |
---|---|---|
Verb (GET/POST/PUT/…) | ❌ | MCP uses "method" in JSON instead |
URI routing | ❌ | MCP calls are like functions, not resources |
Headers (Content-Type) | ❌ | Fixed format: usually always JSON |
Status codes (200, 404) | ❌ | Replaced by "result" or "error" in JSON |
Version negotiation | ❌ | MCP is versioned at the protocol/tool level |
✅ You Can Use HTTP — but it’s Optional
If you do run an MCP server over HTTP, you’re just using HTTP as a transport. MCP still defines:
- The structure of the request/response JSON
- The methods and parameters
- The semantics
Example: you can send JSON like this via HTTP 1.1, HTTP/2, WebSocket, or stdin:
{
"method": "generate_image",
"params": { "prompt": "a frog in a hat" },
"id": 7
}
But MCP itself doesn’t care how it gets delivered.
✅ Summary
- ✅ MCP is not tied to HTTP or any version (1.1, 2, 3)
- ✅ It’s often used over stdin, WebSocket, or raw TCP
- ✅ It borrows JSON-RPC-style structure, not REST or HTTP conventions
- ✅ You can use HTTP — but it’s entirely optional
Let me know if you want a no-HTTP MCP server stub in Rust that speaks over stdin or pipes.
Conclusion – Why MCP Skips HTTP
HTTP comes with baggage MCP doesn’t need, like:
HTTP Concern | Needed in MCP? | Why Not? |
---|---|---|
Verb (GET/POST/PUT/…) | ❌ | MCP uses "method" in JSON instead |
URI routing | ❌ | MCP calls are like functions, not resources |
Headers (Content-Type) | ❌ | Fixed format: usually always JSON |
Status codes (200, 404) | ❌ | Replaced by "result" or "error" in JSON |
Version negotiation | ❌ | MCP is versioned at the protocol/tool level |