Persistence (Advanced)
- Build your first harness
- Host options
- Send and show media
- Connect clients
- Write a client in any language
- Access and tenants
- Run in the terminal
- Deploy a harness
- Send inputs safely
- Run a tool without a model
- Durable sessions
- Run background work on workers
- List, rename, and fork sessions
- Lifecycle and retention
- Run side effects once
- Wait for a person
- Build on the session log
- Control how a turn ends
- Store settings per thread
- Compact a long session
- Fork and reset a thread
- One log for a session tree
- Write a plugin
- Track usage and cost
- Ask before risky tool calls
- Give your agent coding tools
- Sandbox and extend the coding tools
- Run the coding tools for many threads
- Undo a turn
- Build a coding agent
- Delegate to coding agents
- Switch between agent profiles
- Auth and connectors
- Share a thread between people
- Connect model providers
- Build your own UI
- Code mode in a harness
- Work until a goal is met
- Run agents from a harness
- Hand off a conversation
- Add skills
- Use MCP servers
- Give your agent a computer
- Use from any MCP client
- Use a harness from an editor (ACP)
- Overview
- Quick Start
- Providers
- Harnesses
- Harness Auth
- Workspace
- Tools
- Policy
- Lifecycle & Snapshots
- Portable Snapshots
- Keep Files After Reload
- Save a Named Version
- Branch From a Version
- Send a Frozen File
- Let the Agent Save and Fork
- Pick Which Files to Keep
- What a Snapshot Stores
- Instance Durability
- Durable Runs
- Events
Sandboxes (Advanced)
- Runtime Context
- Bring Your Own Key
- Keep Keys on the Server
- Debug Logging
- Multimodal Content
- Files API
- Per-Model Type Safety
- Runtime Adapter Switching
- Tree-Shaking
- Extend Adapter
- Extend Adapter: Advanced
- Typed Pre-Configured Options
- Test with a Fake Model
- Prompt Caching
- Mid-Conversation Changes
- Approval Flow Processing
MCP Server Sessions
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.
Quick setup#
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.
How it works#
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:
- ctx.context.requestInput throws an error that names the sessions option.
- ctx.context.sample calls the sample option of the server. Without that option, it throws.
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.
Turn spec 2025 off#
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',
})Advanced#
Route each session to one instance#
A spec 2025 session keeps a live connection object. That object stays in the process that opened the session. Another process cannot read it.
- The client sends the session id on the mcp-session-id header.
- A request with an unknown session id gets 404 Session not found.
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.
When a session closes#
A session closes in two cases:
- The client sends DELETE with its session id.
- The session gets no request for 30 minutes.
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.
Sessions and auth#
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.