Summary
Request to track support for MCP protocol revision 2026-07-28, which makes the protocol core stateless. This revision has unusually large implications for a gateway/proxy like MCPX — larger than for a plain MCP server — so it seems worth planning for early even though the upstream SDK is not there yet.
Current state (as far as I can tell from the code)
packages/mcpx-server/package.json depends on @modelcontextprotocol/sdk ^1.29.0
packages/mcpx-server/src/server/mcp-gateway.ts:40 — MIN_PROTOCOL_VERSION_FOR_KEEPALIVE = "2025-11-25"
packages/mcpx-server/src/server/metadata.ts:14 — client icon schema is annotated version 2025-11-25
Upstream dependency: @modelcontextprotocol/sdk@1.30.0 (latest, published 2026-07-27) still declares LATEST_PROTOCOL_VERSION = '2025-11-25', so this is presumably blocked on the TypeScript SDK first. Filing this mainly so the gateway-specific work is visible early.
Please correct me if any of the above is out of date.
Why this matters for MCPX specifically
1. It would fix the multi-pod problem in #55.
In #55 a user hit Session not found when MCPX ran with 2 pods, and asked "Is the gateway exposed as a stateful mcp server to the clients?". Under 2026-07-28 that question disappears: initialize and the Mcp-Session-Id header are removed, and every request carries its own protocol version and client capabilities in _meta. A gateway becomes horizontally scalable behind an ordinary round-robin load balancer, with no sticky routing and no shared session store.
2. Cross-era traffic fails hard, with no fallback.
Per the spec's compatibility matrix, a modern client talking to a legacy server fails outright — legacy clients have no fall-forward mechanism and modern clients have no automatic downgrade. A gateway sitting between them is exactly where this breaks first: whichever side upgrades first, MCPX becomes the blocker unless it can serve both eras. Dual-era support (accept both initialize and server/discover; connect to both legacy and modern upstreams) is likely the practical target rather than a hard cutover.
Gateway-specific work items in this revision
Beyond the usual protocol updates, these land squarely on a proxy:
- MRTR (SEP-2322) — server-initiated requests (
sampling/createMessage, elicitation/create, roots/list) are gone. Servers now return an InputRequiredResult carrying inputRequests + an opaque requestState, and the client retries with inputResponses and a new JSON-RPC id. A gateway must wrap the upstream's requestState in its own envelope so the retry routes back to the same upstream, and the spec requires treating incoming requestState as attacker-controlled (integrity protection, principal binding, TTL, originating-request digest).
subscriptions/listen replaces the HTTP GET stream and resources/subscribe/unsubscribe. A gateway needs to fan out to N upstreams and multiplex their notifications onto one downstream stream, re-stamping io.modelcontextprotocol/subscriptionId.
resultType on every result ("complete" / "input_required"), with absent-means-"complete" for older upstreams.
- Required request headers
Mcp-Method and Mcp-Name on Streamable HTTP POSTs, plus mandatory header/body consistency validation (-32020 HeaderMismatch). Relevant to MCPX both as a server and as a client. Also x-mcp-header → Mcp-Param-* mirroring, which clients MUST support.
server/discover — servers MUST implement it; useful for MCPX to expose aggregated capabilities in one call.
- Caching fields —
ttlMs and cacheScope are now required on tools/list, prompts/list, resources/list, resources/read, resources/templates/list. For an aggregating gateway the natural merge is min-ttlMs and private if any upstream is private.
- Deterministic
tools/list ordering (SHOULD) — the spec calls this out explicitly to keep client caches and LLM prompt-prefix caches warm. For an aggregator this matters more than for a single server, since fan-out order is non-deterministic by default.
- Deprecations — Roots, Sampling and Logging are now Deprecated (12-month minimum window), as is
resources/subscribe, DCR, and the HTTP+SSE transport. ping and logging/setLevel are removed.
Suggested phasing
- Track the TypeScript SDK's
2026-07-28 support and pin to it when available.
- Dual-era on the downstream side first (keep serving
initialize clients, additionally accept per-request _meta + server/discover).
- Dual-era on the upstream side (probe
server/discover, fall back to initialize on any non-modern error — the spec's stdio backward-compatibility rules).
- MRTR
requestState wrapping/routing and subscriptions/listen multiplexing — these are the two genuinely new pieces of gateway logic.
References
Summary
Request to track support for MCP protocol revision
2026-07-28, which makes the protocol core stateless. This revision has unusually large implications for a gateway/proxy like MCPX — larger than for a plain MCP server — so it seems worth planning for early even though the upstream SDK is not there yet.Current state (as far as I can tell from the code)
packages/mcpx-server/package.jsondepends on@modelcontextprotocol/sdk ^1.29.0packages/mcpx-server/src/server/mcp-gateway.ts:40—MIN_PROTOCOL_VERSION_FOR_KEEPALIVE = "2025-11-25"packages/mcpx-server/src/server/metadata.ts:14— client icon schema is annotatedversion 2025-11-25Upstream dependency:
@modelcontextprotocol/sdk@1.30.0(latest, published 2026-07-27) still declaresLATEST_PROTOCOL_VERSION = '2025-11-25', so this is presumably blocked on the TypeScript SDK first. Filing this mainly so the gateway-specific work is visible early.Please correct me if any of the above is out of date.
Why this matters for MCPX specifically
1. It would fix the multi-pod problem in #55.
In #55 a user hit
Session not foundwhen MCPX ran with 2 pods, and asked "Is the gateway exposed as a stateful mcp server to the clients?". Under2026-07-28that question disappears:initializeand theMcp-Session-Idheader are removed, and every request carries its own protocol version and client capabilities in_meta. A gateway becomes horizontally scalable behind an ordinary round-robin load balancer, with no sticky routing and no shared session store.2. Cross-era traffic fails hard, with no fallback.
Per the spec's compatibility matrix, a modern client talking to a legacy server fails outright — legacy clients have no fall-forward mechanism and modern clients have no automatic downgrade. A gateway sitting between them is exactly where this breaks first: whichever side upgrades first, MCPX becomes the blocker unless it can serve both eras. Dual-era support (accept both
initializeandserver/discover; connect to both legacy and modern upstreams) is likely the practical target rather than a hard cutover.Gateway-specific work items in this revision
Beyond the usual protocol updates, these land squarely on a proxy:
sampling/createMessage,elicitation/create,roots/list) are gone. Servers now return anInputRequiredResultcarryinginputRequests+ an opaquerequestState, and the client retries withinputResponsesand a new JSON-RPC id. A gateway must wrap the upstream'srequestStatein its own envelope so the retry routes back to the same upstream, and the spec requires treating incomingrequestStateas attacker-controlled (integrity protection, principal binding, TTL, originating-request digest).subscriptions/listenreplaces the HTTP GET stream andresources/subscribe/unsubscribe. A gateway needs to fan out to N upstreams and multiplex their notifications onto one downstream stream, re-stampingio.modelcontextprotocol/subscriptionId.resultTypeon every result ("complete"/"input_required"), with absent-means-"complete"for older upstreams.Mcp-MethodandMcp-Nameon Streamable HTTP POSTs, plus mandatory header/body consistency validation (-32020 HeaderMismatch). Relevant to MCPX both as a server and as a client. Alsox-mcp-header→Mcp-Param-*mirroring, which clients MUST support.server/discover— servers MUST implement it; useful for MCPX to expose aggregated capabilities in one call.ttlMsandcacheScopeare now required ontools/list,prompts/list,resources/list,resources/read,resources/templates/list. For an aggregating gateway the natural merge is min-ttlMsandprivateif any upstream isprivate.tools/listordering (SHOULD) — the spec calls this out explicitly to keep client caches and LLM prompt-prefix caches warm. For an aggregator this matters more than for a single server, since fan-out order is non-deterministic by default.resources/subscribe, DCR, and the HTTP+SSE transport.pingandlogging/setLevelare removed.Suggested phasing
2026-07-28support and pin to it when available.initializeclients, additionally accept per-request_meta+server/discover).server/discover, fall back toinitializeon any non-modern error — the spec's stdio backward-compatibility rules).requestStatewrapping/routing andsubscriptions/listenmultiplexing — these are the two genuinely new pieces of gateway logic.References
2026-07-28