Skip to content

feat(mcp)!: migrate to the stateless MCP 2026-07-28 protocol - #297

Open
antfubot wants to merge 2 commits into
mainfrom
feat/mcp-stateless-2026
Open

feat(mcp)!: migrate to the stateless MCP 2026-07-28 protocol#297
antfubot wants to merge 2 commits into
mainfrom
feat/mcp-stateless-2026

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

What & why

Migrates devframe's MCP surface to the stateless MCP 2026-07-28 protocol, as tracked in #293, as a clean break for v0.10.0. It retires devframe's hand-rolled Mcp-Session-Id lifecycle in favor of the SDK's stateless serving entry points, so requests reach any server instance without session affinity and modern MCP clients are first-class.

Per the agreed posture, the endpoints keep serving 2025-era clients through the SDK's default stateless legacy path — the custom session registry is gone either way, but today's clients keep working.

Changes

  • HTTP (createMcpFetchHandler) moves to the SDK's createMcpHandler, building a fresh server per request. No session registry, no session-local routing; a GET/DELETE (2025 session ops) is answered 405. The loopback origin gate is unchanged.
  • stdio (createMcpServer) moves to serveStdio, pinning one server per connection.
  • devframe connect negotiates the modern era via server/discover, falling back to the 2025 handshake for a 2025-only instance.
  • list_changed events bridge onto modern subscriptions/listen streams — over HTTP through the handler's notify bus, on stdio through the pinned server's send*ListChanged calls.
  • The pure server factory (buildMcpServerFromContext) is split from the notification bridge (bridgeListChanged) so it's safe to call per request / per connection.
  • transports.ts (the old startStdioTransport wrapper) is removed.

The authored devframe API — createMcpServer, createMcpFetchHandler, mountMcpHttp, cli.mcp, the agent host — is unchanged, so the Vite/Next bridges and custom hosts need no code changes.

Docs

  • Rewrites the MCP adapter page's serving model (stateless, per-request).
  • Adds a "Migrating to 0.10" guide (renumbering the migration series).

Notes

  • No package versions were bumped — releasing v0.10.0 is left for a human-approved release.

Closes #293

This PR was created with the help of an agent.

Serve the MCP surface through the SDK's stateless 2026-07-28 entry points,
retiring devframe's custom Mcp-Session-Id lifecycle:

- HTTP moves to `createMcpHandler`, building a fresh server per request
  (no session registry, no session-local routing, GET/DELETE -> 405).
  2025-era clients are still served through the SDK's stateless legacy path.
- stdio moves to `serveStdio`, pinning one server per connection.
- `devframe connect` negotiates the modern era via `server/discover`,
  falling back to the 2025 handshake for a 2025-only instance.
- `list_changed` events bridge onto modern `subscriptions/listen` streams
  (HTTP via the handler's notify bus; stdio via the pinned server's
  send*ListChanged calls).

The devframe API surface (createMcpServer, createMcpFetchHandler,
mountMcpHttp, cli.mcp) and the origin gate are unchanged.

Closes #293
@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
devframe Skipped Skipped Aug 26, 2026 4:45am

@antfu antfu changed the title feat(mcp): migrate to the stateless MCP 2026-07-28 protocol feat(mcp)!: migrate to the stateless MCP 2026-07-28 protocol Aug 26, 2026
The hub aggregate-MCP and Next handler tests still exercised the 2025
initialize/Mcp-Session-Id handshake. Serve them statelessly: the hub test
lists tools with a single per-request POST, and both assert no session id
is issued.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Investigate migration to stateless MCP 2026-07-28

1 participant