Skip to content

SEP-2567: Sessionless MCP via Explicit State Handles#2567

Merged
pja-ant merged 10 commits intomainfrom
sep/sessionless-mcp
May 7, 2026
Merged

SEP-2567: Sessionless MCP via Explicit State Handles#2567
pja-ant merged 10 commits intomainfrom
sep/sessionless-mcp

Conversation

@pja-ant
Copy link
Copy Markdown
Contributor

@pja-ant pja-ant commented Apr 14, 2026

Summary

Draft SEP proposing the removal of protocol-level sessions from MCP, replacing implicit session-scoped state with explicit, server-minted state handles. Builds on SEP-1442 (stateless-by-default) but argues the opt-in stateful path should not exist at all.

Core claims:

  • Application state is better served by explicit identifiers
  • The mere possibility of session-scoped tools/list forces O(subagents × servers) re-fetches on everyone, even when ~zero servers actually use it
  • Session cardinality of exactly-one prevents mixed shared/isolated state (e.g., subagents sharing a cart but isolating browser state)
  • Explicit handles are strictly more expressive and make list endpoints cacheable at (deployment, auth) granularity

What changes:

  • No session/create, session/destroy, or Mcp-Session-Id header
  • tools/list / resources/list / prompts/list MUST NOT depend on per-connection or prior-tool-call state
  • Stateful workflows use create_*() -> handle + threaded parameters (guidance, not a protocol construct)

Imported from modelcontextprotocol/transports-wg#25.

@pja-ant pja-ant requested review from a team as code owners April 14, 2026 12:43
@pja-ant pja-ant changed the title SEP-XXXX: Sessionless MCP via Explicit State Handles SEP-2567: Sessionless MCP via Explicit State Handles Apr 14, 2026
@pja-ant pja-ant added SEP draft SEP proposal with a sponsor. labels Apr 14, 2026
@kurtisvg kurtisvg self-assigned this Apr 14, 2026
@kurtisvg kurtisvg added the transport Related to MCP transports label Apr 14, 2026
@dsp-ant dsp-ant added the roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) label Apr 15, 2026
@kurtisvg
Copy link
Copy Markdown
Contributor

tools/list / resources/list / prompts/list MUST NOT depend on per-connection or prior-tool-call state

Should this be "prior request call state"? I don't think we want other requests to effect the outcome as well right?

Comment thread docs/seps/2567-sessionless-mcp.mdx Outdated
Comment thread docs/seps/2567-sessionless-mcp.mdx Outdated
Comment thread docs/seps/2567-sessionless-mcp.mdx Outdated
Comment thread docs/seps/2567-sessionless-mcp.mdx Outdated

**Clients.** Clients become simpler: they no longer track or resend session identifiers, or need to determine whether a given server is stateful. List-endpoint caching becomes safe.

Rollout is a clean break: sessions are removed in the next spec version, with no deprecation window. Servers that currently rely on session-scoped state stay on the current protocol version until they have migrated to explicit handles. Protocol version negotiation already handles mixed-version deployments — a client that supports both versions speaks the old protocol to an unmigrated server and the new one to everyone else. This avoids shipping a version where clients support both modes simultaneously, which would prevent the caching benefit (a client cannot cache list endpoints if any connected server might be session-scoped).
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.

Rollout is a clean break: sessions are removed in the next spec version, with no deprecation window. Servers that currently rely on session-scoped state stay on the current protocol version until they have migrated to explicit handles.

Somewhere in this SEP we should provide an example of how SDKs should handle this. I think we are essentially saying that the session functionality become a no-op.

@CaitieM20
Copy link
Copy Markdown
Contributor

This looks good to me. Supportive of this!

Comment thread docs/seps/2567-sessionless-mcp.mdx
@CaitieM20 CaitieM20 added this to the 2026-06-30-RC milestone Apr 17, 2026
@pja-ant
Copy link
Copy Markdown
Contributor Author

pja-ant commented Apr 20, 2026

This was reviewed by Core Maintainers: 6 Accepted, 2 Accept with Changes.

@pja-ant pja-ant added accepted SEP accepted by core maintainers, but still requires final wording and reference implementation. and removed draft SEP proposal with a sponsor. labels Apr 20, 2026
@mcp-commander mcp-commander Bot removed the accepted SEP accepted by core maintainers, but still requires final wording and reference implementation. label Apr 20, 2026
@mcp-commander
Copy link
Copy Markdown

mcp-commander Bot commented Apr 20, 2026

New commits were pushed — removed the accepted label. Re-approve with /lgtm.

@briankrug
Copy link
Copy Markdown

briankrug commented Apr 27, 2026

tools/list / resources/list / prompts/list MUST NOT depend on per-connection or prior-tool-call state

This means that MCP Servers cannot filter tools, resources, or prompts based on authorization. Seems like a step backwards. Why list an entity the client / user can't use?

Actually, I guess you could do an auth to entity permission look-up on every call. It just means greater burden on the server

@dawid-nowak
Copy link
Copy Markdown

dawid-nowak commented Apr 28, 2026

Continuing from #2575 (comment)

After:

create_counter() // returns counter_id
increase_counter(counter_id)
get_counter(counter_id)

  1. It looks like the server logic needs to tweaked to suit MCP Protocol. And MCP server needs to introduce their own sessions handling if necessary.
  2. Is there a mechanism to pass information about the principal of a user who made these calls. For example from the security/audit perspective if create_counter is created by user A and that counter id is leaked then any other user can call increase_counter and thus hijack the session.

Even if all transport calls are authenticated/authorized, there is a danger that the user with lower permissions could potentially hijack the session of a super user by using their handle id.

@pja-ant
Copy link
Copy Markdown
Contributor Author

pja-ant commented Apr 28, 2026

This means that MCP Servers cannot filter tools, resources, or prompts based on authorization. Seems like a step backwards. Why list an entity the client / user can't use?

You can still filter based on auth. I should clarify that sentence as I can see why it looks like it implies the opposite. "Per-connection state" means relying on information sent in previous messages on the connection. The auth headers are on every request, so it is stateless.

pja-ant added 7 commits May 6, 2026 18:22
… example, Future Work)

- Replace enable_admin_tools with connect_database/connection_id as the
  list-mutation example (non-auth scenario), and broaden the prohibition
  from "tool calls" to "other requests"
- Drop the "rarely used" claim; the constraint follows from removing
  sessions regardless of current usage
- Add SHOULD NOT for stdio process-lifetime state, citing undefined
  scope and lack of HTTP parity
- Add Future Work section noting protocol-level handle marking
  ($defs/$ref, annotations) as a follow-up
- Wording: "not fully precise" -> "imprecise"
Removes sessions and Mcp-Session-Id from the draft spec (transports,
architecture, lifecycle, etc.), rescopes request-ID/SSE-event-ID/list
clauses, and adds a non-normative Stateful Tools section to tools.mdx.
Expands the SEP's Consequential spec edits to match.
"MUST NOT vary per-connection" was being read as forbidding auth-based
filtering. Make explicit that credentials are per-request input, not
connection state, so servers may return different sets to different
principals.
@pja-ant pja-ant force-pushed the sep/sessionless-mcp branch from dada908 to 8cb5b8b Compare May 6, 2026 18:10
@pja-ant pja-ant added accepted SEP accepted by core maintainers, but still requires final wording and reference implementation. and removed accepted-with-changes labels May 6, 2026
Comment thread seps/2567-sessionless-mcp.md Outdated
Comment thread docs/docs.json Outdated
Comment thread docs/docs.json Outdated
Copy link
Copy Markdown
Contributor

@CaitieM20 CaitieM20 left a comment

Choose a reason for hiding this comment

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

Mostly LGTM a few minor issues around merge conflicts, and the SEP should be marked as Accepted not Draft

@kurtisvg kurtisvg assigned pja-ant and unassigned kurtisvg May 6, 2026
Addresses review feedback: updates SEP status from Draft to Accepted and
resets docs.json against main to restore nav entries (client-best-practices,
mrtr, working-group charters) that were dropped during a prior merge.
CaitieM20
CaitieM20 previously approved these changes May 7, 2026
@pja-ant pja-ant removed the accepted SEP accepted by core maintainers, but still requires final wording and reference implementation. label May 7, 2026
@pja-ant
Copy link
Copy Markdown
Contributor Author

pja-ant commented May 7, 2026

Update SEP status to final as reference implementation and conformance tests are not needed here: servers that don't return session IDs are already part of the spec and something that all SDKs already support.

@pja-ant pja-ant added the final SEP finalized. label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

final SEP finalized. roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) SEP transport Related to MCP transports

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

10 participants