MCP spec 2025 sessions live in one process. A multi-instance deploy needs sticky routing for those clients.
The sessions option of createMCPServer sets how the server treats spec 2025 clients. By default, it keeps no session. Change it only for one of the cases below.
Pick one value for sessions:
| Value | What you get | Use it when |
|---|---|---|
| 'stateless' (default) | No session. Any instance can answer any request. | You deploy to serverless or to many instances. |
| 'memory' | Sessions in the process. The server can ask a spec 2025 client for input or a sample. | A tool calls requestInput or sample for spec 2025 clients. |
| 'reject' | Spec 2026 only. | You do not want to serve spec 2025 clients. |
To keep sessions, set sessions to 'memory':
import { createMCPServer } from '@tanstack/ai-mcp/server'
const server = createMCPServer({
name: 'weather',
version: '1.0.0',
sessions: 'memory',
})Now a spec 2025 client opens a session, and a tool can ask that client for input or a sample.
With the default 'stateless' value, a new server answers each spec 2025 request, and no session stays in memory. A spec 2026 client sends no session id either, so any instance can serve both.
Without a session, the server cannot send a request back to a spec 2025 client. For that client:
A spec 2026 client gets requestInput and sample with no session.
serveMCPStdio uses 'memory' when you do not set sessions. A stdio process serves one client, so a session costs nothing there.
To serve spec 2026 only, set sessions to 'reject'. A spec 2025 request then gets the SDK rejection. A client that speaks only spec 2025 cannot use that server.
import { createMCPServer } from '@tanstack/ai-mcp/server'
const server = createMCPServer({
name: 'weather',
version: '1.0.0',
sessions: 'reject',
})A spec 2025 session keeps a live connection object. That object stays in the process that opened the session. Another process cannot read it.
On a deploy with more than one instance, a later request can reach an instance that did not open the session. That request gets 404. Use the mcp-session-id header as the key for sticky routing on your load balancer.
A session closes in two cases:
The server looks for idle sessions when a request comes in. After a session closes, the client must open a new session.
The server has no limit on the number of open sessions. Each session stays in memory until it closes, and that can take 30 minutes. On a public server, set auth, or limit new sessions at your proxy.
When the server has auth, the session belongs to the caller that opened it: the clientId of the token plus its sub claim. A request from another caller gets 404, the same as an unknown id. MCP Server Auth shows how the verifier sets these values.