Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions proposals/session-track.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
**Sessions Track: Brief**

**Goal** To decouple session state from the underlying transport connection, allowing for robust, long-lived application state that survives connection drops and scales horizontally across stateless servers.

**Core Principle: Adapted Cookie Semantics**

* **RFC 6265 as a Foundation:** We will use **RFC 6265 (HTTP Cookies)** as a functional starting point to determine necessary adaptations for MCP.
* **Payload Integration:** Session data will primarily be included as a dedicated field within the JSON-RPC payload. We will look to **SEP-1655** and **SEP-1685** for inspiration on structuring this metadata.
Comment on lines +5 to +8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The payload integration is how we'll support this on stdio, right? I believe that was the plan, but wanted to verify that, as most of the discussion is (rightly) focused on HTTP servers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of my interest is WebSocket transport which has the same problem as stdio in that it doesn't have headers. I too want to see everything necessary to maintain session in the JSON-RPC payload. I also use HTTP POST transport but not SSE HTTP GET. I believe that spec is still quite difficult to implement and while I hope this work fixes that, I see WebSockets as a much better alternative to streaming with SSE HTTP.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Principle has been agreed that payload content can be duplicated to headers if wanted. STDIO would need "cookie" data in JSON-RPC

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content is required in JSON-RPC package for transports that don't have header-like side-channels (WebSockets, gRPC etc).


**Key Requirements**

* **Routing Compatibility & Size Constraints:** To allow load balancers to route requests based on session affinity, we may need to copy the session identifier/token into an HTTP header. This introduces strict **size constraints**; the session token must remain small enough to fit within standard header limits (typically \~4KB), prohibiting large state blobs from being stored directly in the token.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we impose a size limit here? This is dependent on the network infra and is typically configurable - it looks like only Nginx has a 4KB limit by default. It would likely be inadvisable to have even a 4KB header, but I believe that server operators will generally be able to determine what reasonable limits look like for their particular setups.

Copy link
Copy Markdown
Member Author

@evalstate evalstate Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolute minimum is SessionID/Version. Resumption/Last-Known-Id. <-- next layer of design.


  1. Limit to SessionId Only (minimum for supporting routing)
  2. Keep the session envelope open with an arbitrary size limit.
  3. Keep it open with no size limit

Constrained by common infrastructure limitations. Question to infra specialists -> what are the hard constraints.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the SDK experience from a Client/Server perspective.

* **Security & Integrity:** Servers utilizing cookies must encrypt or sign the data to prevent client-side tampering. We will evaluate including a standard mechanism for signing/encryption directly in the spec.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this, but I believe we need to explicitly justify why we want to go beyond RFC 6265 and require this when most applications use unsigned cookies all the time without problems. Some good reasons I can think of:

  1. Unlike a website, MCP host applications are server-agnostic, and an agent or host application has little reason to directly alter a server-provided cookie in the first place.
  2. This is (at least in isolation) privacy-preserving; it's not possible for to add fingerprinting to a signed cookie - of course, tools themselves don't have this property, so it's a bit moot, but at least it doesn't make things worse.

Copy link
Copy Markdown

@lmaccherone lmaccherone Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a stronger position against this requirement. It's added complexity. At the very least, I believe this should be no more than "MAY" with guidance on how to do it if they include it but I believe this does more harm than good. As Luca said, headers are sent unencrypted all the time, but I'll also add that the information we're talking about adding there is not particularly sensitive.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, requiring cookies to have these options: Secure, HttpOnly, SameSite=Strict|Lax makes sense. Also having a narrow path/domain restrictions is good practice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need security beyond the current specification level (e.g. signing and encryption of content). This is not an application layer concern.

* **Expert Review:** We will consult security experts to review the design for known vulnerabilities common in standard cookie implementations.

**Key Design Decision: Lifecycle Management**

> (Gabriel Z) Another key decision is around parallel tool calling. I think the decision was that parallel tool calling would just overwrite the session data nondeterministically if multiple tools decided to add session data. It could be good to at least add a warning to that effect.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that there are two distinct use-cases here: per-session state, and per-tool-call state.

I think per-session state is in scope for the session track, and I think HTTP cookies can work pretty well for this. The idea behind using cookies for session data is that the client can basically use a different cookie jar for each session, and it's totally up to the server as to how and when to update the cookies within that session. So, for example, the session/create RPC would wind up creating a cookie indicating the session ID, which the client would then store in its cookie jar and therefore send with every subsequent RPC in that session. The server can decide in its response to any of those RPCs that it wants to set an additional cookie, and that's fine -- there's a fair amount of flexibility there for server implementations. (Clients that don't support sessions would just use a single cookie jar for all RPCs.)

I don't think per-tool-call state is in scope for the session track; instead, I think that should be addressed as part of the multi round-trip requests track, and there's already some discussion about this in the multi round-trip request track's brief doc. To summarize, I don't think the HTTP cookie approach will work very well for per-tool-call state, specifically because there can be multiple tool calls in flight in parallel (either within a session or not). The server implementation would need some way to know what cookie name to use for the state for each in-flight tool call, or else the cookie data would simply conflict, so we'd need to provide some way to do that. And it also doesn't seem to scale very well to have every tool call include cookies for state for every other tool call that is in flight at the same time. I think that instead, we'll wind up wanting something more like SEP-1685 here.


* **Implicit vs. Explicit:** We must decide between allowing lazy initialization (Implicit) versus requiring a formal setup handshake (Explicit).
* *Consideration:* The need to **copy or fork** session data (e.g., branching an agent's state) strongly suggests preferring an **Explicit** mechanism (e.g., `session/create`, `session/fork`) to ensure these operations are predictable and race-free.
Copy link
Copy Markdown

@LucaButBoring LucaButBoring Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe forking sessions needs its own explicit RPC method, but that depends on our contract for cookie formats. I would expect that if I (as a client) save the current cookie at each point in the conversation, I can simply roll back to an old conversation state and do something different, and if that implies a different change to the session state, I'll just wind up receiving a new cookie instead. In other words, all cookies are always valid and immutable state objects by default.

I'm not strongly opinionated on this, however - I just don't see any obvious use cases where this would both (1) not hold true and (2) simultaneously allow forking a session. For example, if I have a single-use cookie and make a request with it, that cookie value is invalidated and I probably can't fork off it, either.

I do think explicit session creation is a good idea, however.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes to session/create and session/destroy. I too don't see a use case for session/fork


---

## Prior Art

This section is for summarising the relevant parts of how other Agent systems and specifications handle Sessions.

### Agent Client Protocol (Specification)

Sessions are created by the Client (Host) and resumable, with the option of the Agent replaying messages to rehydrate Client state. There is no "close" operation.

Sessions are well specified with a unique session identifier, multiplexing and sequences of Prompt Turns between Client and Agent. Sessions in ACP are a user level abstraction. ACP is currently STDIO only with an HTTP transport "in progress".
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ss-> interesting design, not sure how related this specifically is to MCP. It is a high level application protocol.


#### In-flight Proposals

##### Session Listing

https://agentclientprotocol.com/rfds/session-list

##### Session Forking

https://agentclientprotocol.com/rfds/session-fork

##### MCP/ACP transport (MCP over ACP)

https://agentclientprotocol.com/rfds/mcp-over-acp
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is reusing or incorporating an ACP Session Id worthwhile.


Text courtesy of https://github.com/secretiveshell

> your IDE can provide tools to the agent, for example you might install a zed extension for prettier, and the prettier zed extension can expose MCP tools to the agent
>
> previously you would have
> 1) zed spawns ACP server (fast agent) as a sub process
> 2) ACP server spawns MCP server as subprocess
> 3) MCP server talks to zed via some other side channel
> this is basically a circular dependency chain
>
> with this proposal you can have:
> 1) zed spawn ACP server (fast agent)
> 2) zed embed the MCP server into the same ACP client process
> 3) fast agent connects to the MCP server over the existing ACP transport

> which means you skip the whole extra MCP server process
> https://agentclientprotocol.com/rfds/mcp-over-acp#routing-by-id
> in fact it even lets zed handle multiple MCP servers via multiplexing, so you could have zed IDE install MCP servers similar to the vscode extension store, and then have those MCP servers configured in fast agent automatically by just connecting to all the MCP servers exposed by the MCP over ACP bridge
> its literally just a wrapper to send mcp frames over an ACP connection


### Claude Code


### Intra-Inference

#### Responses / Open Resonses

[Protocol](https://www.openresponses.org/) uses "Response Chaining" and state machines for lifecycle management. `previous_response_id`, `next_response_id` and `sequence_id` describe sequencing with `conversation_id` allowing grouping and potential persistence.

Protocol uses "Response Chaining" and state machines for lifecycle management.
`previous_response_id` and `next_response_id` describe sequencing, with conversation (object containing id) allowing grouping.

Client may set a `store` flag to persist state, reflected by the Server. No explicit guarantees apply.

#### Anthropic

#### Gemini

### `fast-agent`

Sub-agents only retain state within the tool loop.

Agents hosted as MCP Servers can have an instance type of `connection`, `request` or `shared`.

### Tool Generates association identifier.

A Tool Call returns a unique identifier, and requests that the identifier be returned in subsequent tool calls.

This pattern is potentially unreliable due to LLM generation being potentially unreliable but works in practice.

Promoting this technique to a determenistic side-channel is a possibility.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Promoting this technique to a determenistic side-channel is a possibility.
Promoting this technique to a deterministic side-channel is a possibility.


### Use Cases

#### Sandbox VM

An LLM creates a temporary sandbox compute instance, and over the course of several generations calls tools to manipulate the state of the sandbox.

In this scenario, the sandbox would normally be relatively short-lived with either a termination call or timeout quiescing or destroying it.

The sandbox will usually have an identifier that needs associating to the conversation (see `Tool Generates association identifier` or through a 1:1 connection mapping).

Each inference turn is independent of previous turns: the sandbox state is inferred from the message history. Reassociation with the sandbox needs to be either within message content or associated metadata.

Replaying messages to reproduce state in this case should be a Client responsibility (rather than a Server responsibility).