RFC: Stateless Transport Proxy Support (MCP 2026-07-28)#81
Conversation
|
I compared this against the locked blocker: Please include blocker: Parser registration alone does not make the new methods usable through protected proxies. blocker: The Modern→Legacy compatibility row is incorrect as written. The draft compatibility matrix says a modern-only client talking to a Legacy server fails. A dual-era client can probe and fall back to blocker: Revision classification needs to validate a complete supported Modern request, not merely the presence of a protocol-version
I would also avoid saying the body is "authoritative": a header/body mismatch must be rejected with blocker: The proposed health-monitor signal still uses a removed method. suggestion: Add Modern message-shape and method validation before the current dispatch branches. The current streamable proxy accepts JSON-RPC batches and client-sent responses before suggestion: Correct the Kubernetes streaming language. Modern has no GET SSE stream. A POST response stream is attached to one pod for its lifetime, but it does not create session affinity for later requests; after disconnect, clients recreate subscriptions. MRTR can reasonably remain out of scope because an Tests I would add to the RFC:
The sessionless routing-token work and the distinction between protocol sessions and stdio response correlation are strong. The main issue is scope: without the POST streaming path and authz changes, this should not yet claim complete |
Proposes dual-protocol operation in the transparent and streamable transport proxies so ToolHive serves both the current (2025-11-25) and the stateless 2026-07-28 MCP revision on one endpoint, discriminating per request. Covers the revision classifier, the client x backend dual-era matrix (diagonal cells in scope, off-diagonal deferred to vMCP), security (per-request response correlation), and the relationship to the existing --stateless flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes claims found inaccurate when verified against the MCP draft spec,
ToolHive source, and agentgateway:
- Correct the agentgateway prior-art attribution: it does not assess
Legacy-client/Modern-server as unsound; cite the spec compatibility
matrix ("Fails", no client fall-forward) instead.
- Reconcile the client x backend matrix: Modern-client/Legacy-server
resolves via the client's own probe-then-fallback (no proxy work),
leaving only Legacy-client/Modern-server unbridged.
- Qualify Mcp-Name as conditionally required (tools/call, resources/read,
prompts/get) rather than universally mandatory.
- Reframe the health-monitor note: neither existing readiness trigger
fires on the Modern path, so it must gate off first backend contact.
- Correct the forward-compat note: version negotiation is a Revision
type/signature change, not drop-in.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These belong to separate proposals; keep this PR to THV-0081 only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Documents why the middleware chain and telemetry need no structural change under stateless Modern traffic (nothing keys on the MCP protocol session id), verified against source: - Cedar authz, rate limiting, and audit all reconstruct identity from the token per request; annotation cache is keyed by tool name, not session. - Telemetry gains richer per-request attribution (protocol version from the mandatory header, client name from _meta on every span, W3C trace context for correlation in place of mcp.session.id). - Distinguish the JWT tsid (upstream-token session) from the MCP protocol session; note the audit initialize target name still reflects clientInfo. - Flag vMCP per-session backend connections as the one structural dependency, deferred to vMCP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expand the RFC to the full in-scope change set (deepened classification, Modern message-shape enforcement, authz-map registration, ping-removed health readiness) plus the deferred request-scoped streaming and subscriptions designs. Restructure the implementation plan into In scope / Deferred, dropping the tier/phase labeling, and extend Testing with the conformance and test-inversion notes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1e0a75d to
fe82edd
Compare
|
Thanks for the detailed review — it reshaped the RFC. The main change is scope: rather than claim complete 2026-07-28 transport support, the RFC now draws a clear line. In scope is the stateless unary path plus the correctness work (classification, message-shape, authz, health). Request-scoped streaming and
Net: scoped to unary + correctness now, streaming and subscriptions designed and deferred, and the stdio logging limitation documented. Does that scoping work for you, or would you rather see the streaming work pulled into this round? |
Summary
Proposes making ToolHive's transparent (HTTP→HTTP) and streamable (HTTP→stdio) transport proxies serve both the current
2025-11-25(Legacy, initialize-based) and the upcoming2026-07-28(Modern, stateless) MCP revisions on the same endpoint, discriminating per request rather than at a flag-day cutover.Key points:
ClassifyRevision) wired at the proxies' existing JSON-RPC decode points; zero behavior change for existing Legacy traffic.Mcp-Session-Id, closing a response cross-delivery leak by construction.Related issue: toolhive#5755
Review status
The technical claims in this RFC were verified against the MCP draft spec (incl.
schema/draft/schema.ts), the ToolHive source, and agentgateway's implementation before submission. The second commit folds in corrections from that review (agentgateway attribution, matrix reconciliation for Modern-client/Legacy-server, conditionalMcp-Namerequirement, health-monitor and forward-compat framing).🤖 Generated with Claude Code