Introducing Stateless MCP to NitroStack

MCP just went stateless by default. The initialize handshake and session IDs are gone, replaced by self-describing requests that any server replica can answer. NitroStack's decorator-and-DI architecture was already built request-scoped, so it lines up with the new spec naturally. This post walks through what changed and what it means for servers you're building or running on NitroStack today.

Sharvari Raut
Sharvari Raut
Introducing Stateless MCP to NitroStack

On July 28, 2026, the Model Context Protocol shipped its largest revision since launch, and it's a big one: MCP is now stateless by default. No more initialize handshake, no more session IDs, no more sticky connections. Today, we're bringing that shift into NitroStack 🎉

The problem with sessions

Every MCP server built against the 2025-era spec (2025-06-18) started the same way. A client POSTs initialize, the server negotiates a protocol version and capabilities, the client confirms with notifications/initialized, and from then on every request rides that same session, tracked by an Mcp-Session-Id header.

That worked, but it meant your MCP server carried state that had to live somewhere. Scale to multiple replicas and you needed sticky routing or a shared session store, or you risked breaking a client mid-conversation. It's the kind of infrastructure tax that shouldn't exist for something that's really just HTTP underneath.

What changes with 2026-07-28

The new spec removes that tax at the protocol level:

  • No handshake. initialize/initialized are gone. Capability discovery is now a single, optional, cacheable server/discover call, and a client can skip it entirely and go straight to tools/list or tools/call.
  • No session state. Every request is self-describing. Instead of relying on state pinned at connection time, each request carries its own envelope right in _meta: protocol version, client capabilities, and client info. Any server replica behind a load balancer can answer any request, because there's nothing to pin.
  • Standard routing headers. Streamable HTTP requests now carry MCP-Protocol-Version, Mcp-Method, Mcp-Name, and optional Mcp-Param-* headers that mirror the JSON-RPC body. Gateways and proxies can route and rate-limit MCP traffic without ever parsing the request body, and if a header disagrees with the body, that's now a hard rejection before the tool even runs.
  • Multi-round-trip requests instead of push. A stateless HTTP request has no open channel for a server to call back to the client mid-flight. So server-to-client interactions like elicitation and sampling are now modeled as a request/response pair: the handler returns an input_required result with an opaque requestState, the client gathers the answer, and reissues the original call with inputResponses attached. The server keeps nothing in memory between the two calls.
  • Cache hints, built in. Cacheable results like tools/list, resources/read, and server/discover can now declare a ttlMs and a cacheScope (public or private). "Skip discovery, cache the tool list" becomes a standardized behavior instead of a client-specific guess.
  • Capabilities become extensions. Things that used to be baked into the core spec, like MCP Apps and Tasks, are now named, independently versioned extensions negotiated at server/discover. The core protocol stays small, and extensions move at their own pace.

Alongside all of that, there's full JSON Schema 2020-12 support for tool schemas (composition, $ref, unrestricted output schemas), tightened OAuth flows including issuer-bound credentials and a shift from Dynamic Client Registration toward Client ID Metadata Documents, and the formal deprecation of Roots, Sampling, and MCP-level logging in favor of tool parameters, your host's own LLM APIs, and standard observability tooling.

What this means if you're building on NitroStack

The headline is simple: an MCP server can now be a plain, horizontally scalable HTTP handler. No sticky sessions, no shared session store, no coordination problem when you add a second replica.

That maps naturally onto how NitroStack servers are already structured. Tools, resources, and prompts are declared with decorators and resolved through dependency injection per request, so there was never really an architectural reason for your server to hold connection-scoped state, and now the protocol doesn't ask it to either. Scale out behind a load balancer the same way you'd scale any stateless service, cache what's cacheable at the edge, and let your gateway route on Mcp-Method and Mcp-Name without unpacking JSON-RPC bodies.

If you rely on server-to-client interactions today, like elicitation or sampling, those now follow the request/resume pattern above instead of a long-lived push channel. That's a much more forgiving shape for HTTP infrastructure (proxies, gateways, load balancers) than a persistent stream ever was.

Where this goes next

We don't think of stateless MCP as a one-time migration to check off. It's the direction the whole protocol is heading: a small, stable core with capabilities like Apps and Tasks moving out into independently versioned extensions, each able to evolve on its own schedule. That's the same bet a lot of good infrastructure makes, keep the core boring and let the edges innovate.

For NitroStack, that means the framework's job isn't just to support 2026-07-28 today. It's to keep tracking the spec as new extensions land, so the servers you build now don't need a rewrite every time MCP adds a capability. Request-scoped, horizontally scalable, and boring in the best way, that's what we're building toward.

Get started

Stateless MCP is a protocol-level change, and NitroStack is built to track the spec closely as it evolves. If you're starting a new server, this is the shape to build for from day one. And if you're running an existing one, the good news is that the architecture NitroStack already encourages, request-scoped resolution with no server-held session state, is exactly what the new spec expects.

Explore the docs at nitrostack.ai or drop into Discord with questions as you migrate.

Sharvari Raut

Sharvari Raut

Author

A blog poet ✍🏻

Popular tags