h3-mcp logoh3-mcp

Sessions

Opt-in Mcp-Session-Id lifecycle, legacy only.

Note

Protocol-level sessions were removed in 2026-07-28. Modern servers are stateless; carry cross-call state in explicit handles passed as ordinary tool arguments.

Sessions are off by default. Enable them and initialize starts issuing session ids that clients must return on every subsequent request:

defineMcpHandler({
  name: "my-server",
  version: "1.0.0",

  // Simple — uses crypto.randomUUID()
  session: true,

  // Or configured
  session: {
    generateId: (event) => `session-${Date.now()}`,
    maxSessions: 1000,
  },

  tools: [/* ... */],
});

#Lifecycle

initialize creates a session and returns it in the mcp-session-id response header.
Every later POST, GET, and DELETE must carry that header.
DELETE removes it from the store.
SituationResponse
Missing mcp-session-id400
Unknown session id404
maxSessions exceeded503

Session ids are format-checked before they are looked up or stored — bounded length, alphanumerics plus - and _. A custom generateId must stay inside that alphabet.

#The Store Is In-Memory

The built-in store is a bounded Map in the handler's closure. That has consequences worth being explicit about:

  • It does not survive a restart. Clients get 404 and must re-initialize.
  • It is per-process. Behind a load balancer without sticky sessions, requests will land on a process that has never seen the id.
  • maxSessions is unset by default. The store is a client-growable, server-lifetime collection: without a cap, anything that can reach initialize can grow it. Set maxSessions on any endpoint that is not fully trusted — exceeding it returns 503 rather than consuming more memory.

For anything multi-process, prefer keeping real state in your own store keyed by the session id, so losing the id costs a handshake rather than data.

#Reading the Session

defineMcpTool({
  name: "remember",
  handler: (event) => {
    const sessionId = event.context.mcp?.sessionId;
    return { content: [{ type: "text", text: `session: ${sessionId ?? "none"}` }] };
  },
});

Important

A session id is a bearer credential: whoever holds it continues that session. It is not an authentication mechanism — pair sessions with transport auth rather than treating the id as proof of identity.

h3-mcp logo

h3-mcp  MCP servers, built on H3.