Skip to content

Investigate migration to stateless MCP 2026-07-28 #293

Description

@dvcolomban

Context

While reviewing the resource subscription work in PR #292, we noticed that Devframe still uses the 2025-era MCP protocol model.

Devframe already depends on version 2 of the TypeScript MCP SDK, but the SDK keeps hand-constructed clients and servers on the legacy protocol unless applications opt into the new serving and negotiation entry points.

The current Devframe implementation still relies on:

  • the initialize handshake
  • Mcp-Session-Id
  • session-local HTTP routing
  • GET and DELETE session operations
  • resources/subscribe and resources/unsubscribe
  • direct Server.connect() calls for stdio
  • legacy client negotiation in devframe connect

MCP 2026-07-28 replaces this with a stateless protocol based on independent requests, per-request metadata, server/discover, and subscriptions/listen.

References:

Why consider migrating

The stateless model is now the direction of the MCP specification. Existing 2025-era behavior remains supported for compatibility, but newer protocol work and client behavior will build on the 2026 model.

Unless Devframe intentionally remains a legacy-only MCP implementation, we will likely need to migrate at some point to maintain compatibility with modern MCP clients and future protocol revisions.

Migration would bring:

  • modern MCP client compatibility
  • HTTP requests that can reach any server instance without session affinity
  • no application-owned Mcp-Session-Id registry or DELETE teardown protocol
  • SDK-managed protocol discovery and per-request version validation
  • SDK-managed subscriptions/listen routing and notification filtering
  • required HTTP routing-header validation
  • automatic modern result fields such as resultType, ttlMs, and cacheScope
  • one server factory that can serve both protocol eras where compatibility is needed
  • a clearer path to future MCP extensions built on the stateless protocol

This should also let Devframe delete part of its custom HTTP session lifecycle once legacy support is no longer needed.

Likely migration cost

This is more than changing a protocol-version constant.

The server construction model would need to change from a session-owned server to an SDK factory:

  • HTTP would move to createMcpHandler.
  • Stdio would move to serveStdio.
  • devframe connect would enable modern version negotiation.
  • MCP server registration would need to work when the SDK creates instances per request or connection.

Resource notifications need particular attention. MCP 2026-07-28 replaces resources/subscribe and resources/unsubscribe with a long-lived subscriptions/listen request. Devframe would need to:

  • publish resource and list changes through the SDK notification bus
  • decide how the existing resource subscribe and unsubscribe callbacks map to listen-stream lifecycle
  • preserve correct cleanup when a listen stream closes
  • update the SharedState resource bridge
  • test concurrent listeners and resource-specific filters

Compatibility policy changes the size of the work:

  • A modern-only migration could replace the custom HTTP session handler.
  • Supporting both eras would require routing modern requests to createMcpHandler while retaining the current sessionful handler for legacy clients. The SDK's default legacy HTTP fallback is stateless and cannot preserve legacy resource subscriptions by itself.
  • Tests would need separate modern and legacy coverage. Current raw HTTP and in-memory tests exercise the legacy handshake.
  • Documentation would need to explain the supported protocol versions and any legacy compatibility window.

The public Devframe resource API may remain useful, but its subscription semantics should be reviewed before treating the current callback lifecycle as the long-term contract.

Questions

  • Should Devframe adopt MCP 2026-07-28 now, or wait for broader client adoption?
  • Should the first migration support both protocol eras or move directly to modern-only MCP?
  • If legacy support remains, how long should Devframe keep the sessionful HTTP route?
  • Should HTTP, stdio, and devframe connect migrate together?
  • How should Devframe's resource subscription callbacks map to subscriptions/listen?
  • Can the migration preserve the current public resource API, or should subscription lifecycle become an internal MCP adapter concern?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions