The Model Context Protocol's 2026-07-28 revision removed protocol-level
sessions entirely. No initialize handshake, no Mcp-Session-Id header,
no held-open bidirectional stream. Every request is now self-describing
and can land on any server instance behind a plain load balancer.
That's a real win for scaling. It's also a real problem if your server
needs to remember anything between calls, which most useful ones do.
The pattern: explicit state handles
Instead of a hidden session living in the transport layer, a tool mints
a handle and hands it back to the model:
create_cart() → "cart_7f3a9c2e5b1d"
add_item(cart="cart_7f3a9c2e5b1d", sku="MUG-01", quantity=2)
view_cart(cart="cart_7f3a9c2e5b1d")
Four HTTP requests. Four separate server instances, potentially. The
only thread connecting them is a twelve-character string the model can
see, hold onto, and pass around.
Why a visible handle actually beats a hidden session
- The model can hold more than one at once. Two carts isn't a protocol problem anymore, it's just two strings.
- It shows up in the transcript. When something breaks, you can read the handle and go look at exactly the state that caused it.
- Scope is explicit. A tool that wasn't handed a handle can't touch that cart. There's no ambient "current cart" to reach for by accident.
- Any instance can serve any request. No sticky routing, no shared session table, no session affinity to configure.
The cost: handles are now part of your tool's contract, so getting their
error cases right matters. Expired, malformed, and unknown all need to
be distinct, readable messages, not one generic 500.
I wrote a generator for this pattern
I kept rebuilding the same scaffolding, a pluggable state store, handle
minting and validation, a working multi-turn example, so I turned it
into a CLI:
npm create stateforge@latest my-server
It generates a TypeScript + Express server with:
- A swappable
StateStore(in-memory for dev, Redis for production/serverless) - A working shopping-cart example built entirely on explicit handles
- A visual inspector, live tool list, call forms, editable state browser
- Deploy configs for Vercel and Docker
MIT licensed, zero runtime dependencies in the CLI itself.
Repo: https://github.com/JRTrippett/mcp-stateforge
Would genuinely like to hear if anyone's solving this differently, the
2026-07-28 spec is new enough that I don't think there's a "standard"
answer yet.
Top comments (0)