github-repo-stats
by Sonichigo
README.md
# mcp-transport-talk
Code companion for my MCP Dev Summit Bengaluru 2026 talk:
**"From SSE to Streamable HTTP: What Actually Changed in MCP's Transport Layer and Why Your Servers Need to Catch Up"**
— Animesh Pathak ([@sonichigo](https://github.com/sonichigo)), Developer Relations Engineer, Harness Inc
## A note on terminology (important — read this first)
The talk title uses community shorthand. People say "SSE → Streamable HTTP" when what they actually mean is *"the dual-endpoint HTTP+SSE architecture → the single-endpoint Streamable HTTP architecture."*
Three things people conflate:
| Term | What it is | Status |
|---|---|---|
| **HTTP+SSE transport** | The deprecated MCP transport. Two endpoints: `GET /sse` (persistent) + `POST /message`. Required sticky sessions. | **Deprecated** (spec 2025-03-26) |
| **Streamable HTTP transport** | The current MCP transport. Single endpoint that supports both POST and GET, with optional SSE streaming for responses. | **Current spec** |
| **SSE (the format)** | The W3C `text/event-stream` content type. Used *inside* Streamable HTTP for streaming server messages. | **Still alive — actively used** |
**The deprecation was architectural, not protocol-level.** Streamable HTTP still uses SSE format when it needs to stream multiple messages — it's just no longer a separate persistent endpoint. Throughout this repo, when I use the shorthand "SSE deprecated" I mean the two-endpoint architecture.
## What's in here
The same MCP server (a GitHub repo stats tool) implemented three ways. You can run them side by side and watch how each architecture behaves under different conditions.
```
src/
├── stdio-server/ # Local-only transport (still recommended for Claude Desktop / Code)
├── http-sse-server-deprecated/ # The dual-endpoint HTTP+SSE pattern (deprecated March 2025)
└── streamable-http-server/ # The current spec (uses SSE format internally when streaming)
clients/ # A minimal MCP client to test each server
scripts/
├── load-test-dual-endpoint.sh # Watch the deprecated architecture break behind a load balancer
└── load-test-streamable.sh # Watch Streamable HTTP scale horizontally
```
## The tool we're implementing
A single MCP tool — `github_repo_stats` — that fetches public stats for any GitHub repo. Picked deliberately:
- **Real I/O** (calls the GitHub API), so transport behavior is observable.
- **Stateless** (no auth, no session needed), so we can fairly compare architectures.
- **Small enough** to fit on a slide.
## Quick start
```bash
pnpm install
# Run all three servers in parallel
pnpm dev:all
# Or one at a time:
pnpm dev:stdio # → connects via stdin/stdout
pnpm dev:http-sse # → http://localhost:3001 (deprecated dual-endpoint pattern)
pnpm dev:streamable # → http://localhost:3002 (current spec)
```
## The demo that lands the point
```bash
# Start the load-balancer simulator (round-robin across 3 instances of each server)
pnpm demo:lb
# Hit the dual-endpoint server through it — watch it fail intermittently
pnpm demo:lb:dual-endpoint
# Hit the Streamable HTTP server through it — watch it just work
pnpm demo:lb:streamable
```
The deprecated dual-endpoint server fails roughly 2 out of every 3 requests because the POST `/message` lands on a different process than the GET `/sse` that initiated the session. The Streamable HTTP server is stateless and doesn't care which instance handles each request.
This is the live version of the architectural contrast in the slides.
## The real-world failure I keep referencing
The intermittent-failure scenario in `scripts/load-test-dual-endpoint.sh` is a synthetic version of an actual incident from the Harness MCP Server's staging environment. We had a load balancer with default round-robin behavior in front of three pods. About 60% of MCP tool calls failed silently because the POST request landed on the wrong pod. Logs showed nothing because each pod treated it as a missing session and returned 404 to the SSE stream that wasn't there.
Three days of debugging produced a one-line architectural fix: switch transports. That experience is what this talk is built on.
## Where SSE format still lives in the current architecture
This is the bit that confuses people. The current Streamable HTTP transport **still uses SSE format** — but as a response mode, not a separate endpoint. When a client POSTs to the single `/mcp` endpoint, the server can respond with either:
1. **A plain JSON body** (`Content-Type: application/json`) — for simple one-shot requests
2. **An SSE stream** (`Content-Type: text/event-stream`) — when the server needs to stream progress, notifications, or multiple messages
See `src/streamable-http-server/index.ts` — the SDK's `handleRequest()` picks the response mode automatically based on what the server is doing.
## Migration cheat sheet
If you have an existing dual-endpoint server and want to migrate, the diff is roughly:
```diff
- import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
- app.get("/sse", async (req, res) => {
- const transport = new SSEServerTransport("/message", res);
- await server.connect(transport);
- });
- app.post("/message", async (req, res) => {
- await transport.handlePostMessage(req, res);
- });
+ app.post("/mcp", async (req, res) => {
+ const transport = new StreamableHTTPServerTransport({
+ sessionIdGenerator: () => randomUUID(),
+ });
+ await server.connect(transport);
+ await transport.handleRequest(req, res, req.body);
+ });
```
Plus a 405 shim for the old `/sse` endpoint — see `src/streamable-http-server/index.ts`.
## Real-world deprecation deadlines
This isn't theoretical — major MCP server providers are pulling the old endpoints:
| Vendor | Deadline | Notes |
|---|---|---|
| Keboola | April 1, 2026 | Removing dual-endpoint SSE |
| Atlassian Rovo | June 30, 2026 | `mcp.atlassian.com/v1/sse` → `/v1/mcp` |
If your server still uses the dual-endpoint pattern, your integrations will start breaking in 2026.
## Resources & References
- [Talk: From SSE to Streamable HTTP — MCP Dev Summit Bengaluru 2026](https://mcpbengaluru26.sched.com/event/2NLM1/from-sse-to-streamable-http-what-actually-changed-in-mcps-transport-layer-and-why-you-should-care-animesh-pathak-harness-inc)
- [Blog: Model Context Protocol — Stateless Architecture Explained](https://sonichigo.com/posts/model-context-protocol-stateless-architecture-explained)
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues