diff --git a/rfcs/THV-0083-stateless-vmcp.md b/rfcs/THV-0083-stateless-vmcp.md
new file mode 100644
index 0000000..c7a249d
--- /dev/null
+++ b/rfcs/THV-0083-stateless-vmcp.md
@@ -0,0 +1,423 @@
+# RFC-0083: Stateless vMCP Support (MCP 2026-07-28)
+
+- **Status**: Draft
+- **Author(s)**: Jakub Hrozek (@jhrozek)
+- **Created**: 2026-07-21
+- **Last Updated**: 2026-07-21
+- **Target Repository**: toolhive
+- **Related Issues**: [toolhive#5756](https://github.com/stacklok/toolhive/issues/5756) (this),
+ [toolhive#5743](https://github.com/stacklok/toolhive/issues/5743) (epic)
+
+## Summary
+
+The MCP 2026-07-28 revision removes protocol sessions, the `initialize` handshake, and all
+server-initiated requests, replacing them with per-request `_meta`, a `server/discover` RPC, and
+Multi Round-Trip Requests (MRTR). This RFC proposes making the Virtual MCP Server (vMCP) serve both
+the current (2025-11-25, "Legacy") and the stateless (2026-07-28, "Modern") revision on the same
+endpoint, discriminating **per request** — and, because vMCP is an aggregating gateway that
+terminates the client connection and re-originates backend calls, acting as the **cross-generation
+bridge** so a client on either revision can reach backends on either revision.
+
+This is the decision-level counterpart to the vMCP stateless design work tracked in toolhive#5756,
+which carries the implementation detail. It
+is the vMCP sibling of [RFC-0081](THV-0081-stateless-transport-proxies.md) (transport proxies,
+toolhive#5755), which explicitly **defers the era-mismatched bridge cells to vMCP**.
+
+## Problem Statement
+
+The 2026-07-28 revision removes the mechanisms vMCP's session layer is built around: the
+`initialize` handshake, protocol sessions and `Mcp-Session-Id`, the standalone GET SSE stream and
+resumability, server-initiated requests (→ MRTR), and `ping`/`logging/setLevel`. The ecosystem will
+straddle both revisions for a long time — SDKs serve both on one endpoint and peers upgrade
+independently — so vMCP cannot do a flag-day cutover.
+
+Crucially, vMCP's stateful machinery — the two-phase `SessionIdManager`, per-session `MultiSession`
+objects, the 1,000-entry per-pod session cache, Redis session metadata, identity binding, and
+cross-pod tool rehydration — exists for **one reason**: to bridge vMCP's already-stateless core to a
+*session-ful protocol*. `coreVMCP` re-derives its advertised, per-principal view on every
+`List`/`Lookup`/`Call` from `(identity, backend registry, health)` and holds no MCP-session state.
+When the protocol stops being session-ful, that bridge is no longer needed on the Modern path — the
+design is mostly about **bypassing it on the Modern path**, not rebuilding it.
+
+RFC-0081 established per-request revision classification for the transport proxies and, in its
+compatibility matrix, marked the era-mismatched cells "Fails" for a pass-through proxy and deferred
+them to vMCP. vMCP is the component that can bridge them precisely because it terminates and
+re-originates on both edges.
+
+## Goals
+
+- Serve Legacy and Modern client traffic on the same vMCP endpoint, chosen per request.
+- Handle each backend according to its own negotiated revision (per-backend dual protocol).
+- Bridge all four client×backend era combinations, including the two RFC-0081 defers here.
+- Zero behavior change for existing 2025-11-25 traffic.
+- Add the minimum new machinery: reuse the existing `pkg/mcp` classifier; bypass the session bridge
+ on the Modern path rather than reimplement it.
+- Do **not** hard-gate the work on the go-sdk v1.7 bump.
+- Preserve every security invariant (auth per request, admission, rate limiting, audit) across the
+ Modern path, and relocate — not drop — the cross-request binding invariant onto workflow handles.
+
+## Non-Goals
+
+- go-sdk v1.7 adoption / `mcpcompat` stateless plumbing ([toolhive#5754]) — an optional later
+ simplification of the Modern dispatcher, not a dependency (see Alternatives).
+- MRTR-based elicitation/sampling passthrough ([toolhive#5759]); request-scoped streaming and
+ `subscriptions/listen` delivery — designed but deferred.
+- Caching metadata semantics beyond emitting schema-valid `ttlMs`/`cacheScope` ([toolhive#5761]).
+- CIMD-first registration / RFC 9207 issuer validation ([toolhive#5760]).
+- The transport proxies themselves ([toolhive#5755] / RFC-0081).
+
+## Proposed Solution
+
+### High-Level Design
+
+Two independent classification edges. On the **client edge**, each request is classified Modern or
+Legacy via the existing `mcp.ClassifyRevision` (`pkg/mcp/revision.go`, added in #5834, modified in
+#5839). On the
+**backend edge**, each backend is classified once by its negotiated revision and that era is cached
+in the health/probe subsystem. vMCP translates between the two edges.
+
+```mermaid
+flowchart LR
+ C[Client request] --> K{ClassifyRevision}
+ K -->|Legacy| L[initialize → MultiSession
today's path, unchanged]
+ K -->|Modern| M[Stateless dispatcher
direct core calls, no session]
+ L --> R[core.VMCP
already stateless, per-identity]
+ M --> R
+ R --> B{Per-backend era}
+ B -->|Legacy| BL[session-ful backend.Session]
+ B -->|Modern| BM[stateless calls, no Mcp-Session-Id]
+```
+
+The Modern client path **bypasses the entire Serve session layer** and dispatches straight to the
+core, which already performs per-principal projection and admission. The Legacy path is untouched.
+
+### Detailed Design
+
+Full implementation detail is tracked in toolhive#5756. The load-bearing decisions:
+
+- **D1 — Bypass the bridge on the Modern path, don't rebuild it.** The core is already stateless; the Modern path
+ invokes none of the two-phase session hook, `MultiSession`, the 1,000-session cap, Redis session metadata,
+ identity binding, and cross-pod rehydration. This matches ToolHive's own `.claude/rules/security.md`
+ ("Prefer Stateless Routing Over Stored Routing").
+- **D2 — Hand-rolled Modern dispatcher at a known seam; don't hard-gate on go-sdk v1.7.** The Serve
+ path already dispatches directly to the core, so a Modern handler that classifies and calls
+ `core.CallTool`/`List*`/`ReadResource`/`GetPrompt` is low-friction. The seam is a single line
+ (`server.go:607`, `var mcpHandler http.Handler = streamableServer`). Most of the dispatcher is
+ *assembly of parts that already exist*: the classifier (`ClassifyRevision`), the authz call-gate
+ (`authzCallGate()` is already a standalone context-reading closure — the dispatcher calls it and
+ writes HTTP 403 on a `Denial` so audit records `outcome:"denied"` rather than a 200 tool-error),
+ the domain→wire converters (`pkg/vmcp/conversion`), and header-forward application. Rate limiting
+ and admission survive automatically because they decorate the *core*, not the SDK server. The **one
+ genuinely new piece is the JSON-RPC response envelope** (the `resultType`-shaped result + error
+ framing that `NewStreamableHTTPServer` produces today). That marshaling is **not liftable today**
+ (a code investigation, tracked in #5756, settled the earlier "lift where possible" framing): go-sdk
+ v1.6.1 (current dep) has no Modern wire shapes — its `Stateless` option is only a session-lifecycle
+ knob (close-after-request), still 2025-11-25 format — and v1.7's `resultType` is an **unexported**
+ type set only by the SDK's own `MarshalJSON`, so external code cannot hand-construct it. The
+ envelope is therefore a **from-scratch implementation**, kept thin by (a) reusing `mcpcompat`'s
+ existing `dispatch`/`successResponse`/`errorResponse` skeleton, error-code mapping, and
+ `JSONRPCResponse`/`JSONRPCError` shells (already battle-tested against mcp-go), and (b) matching
+ v1.7's wire shape byte-for-byte so the eventual v1.7 swap is a **delete-and-repoint**, validated
+ against the `v1.7.0-pre.1` conformance testdata (`server/discover.txtar`). Retiring into v1.7 (see
+ Alternative 2) is thus an **adoption/replacement**, not a migration of lifted code. This is the main
+ new-code and correctness surface; keeping it thin is a deliberate goal, not an afterthought.
+- **D3 — vMCP owns the off-diagonal bridge.** Legacy-client→Modern-backend is straightforward (vMCP
+ owns the client session, the backend needs none). Modern-client→Legacy-backend is the one hard
+ cell: vMCP synthesizes and holds a backend session, initialized with the **calling principal's**
+ per-request outgoing auth — vMCP's *existing* backend-auth strategies (OBO / header injection /
+ token exchange), not new to this design and orthogonal to statelessness — partitioned by
+ `(principal, backend)` (never shared across principals). In the MVP that held session is
+ **single-request-scoped on one pod** (composites
+ run synchronously — see Alternative 3), so it needs no cross-request handle or durable state; the
+ server-minted-handle keying below matters only once workflows suspend and resume (MRTR, #5759).
+- **D4 — `server/discover` is an admission-filtered capability envelope.** Per the draft schema it
+ carries capability *flags only* (no descriptor arrays), so the risk is a per-identity topology
+ leak, not enumeration; the envelope MUST be computed from the post-admission projection, and its
+ authz-map entry lands together with that filtered response (it is default-denied today). Cost
+ caveat (tracked in #5756): computing flags post-admission means `server/discover` runs the same
+ aggregation + admission fan-out as `tools/list`, yet the spec frames discover as a cheap, cacheable
+ probe a client MAY call before every session — so on the Modern path (which already pays a
+ per-request backend fan-out) discover risks becoming the *most frequent* expensive call. Caching
+ metadata is deferred to #5761; the frequency/cost reconciliation is noted here, not solved in this RFC.
+- **D5 — Workflow handles are server-minted, owner-bound capabilities (design now, enforce with
+ MRTR).** The composer store is already keyed on `WorkflowID`, so nothing is re-keyed. The target
+ design makes the handle a ≥128-bit opaque token with an owner field on `WorkflowStatus`, an
+ `identity == owner` check on resume, a TTL, and audit redaction, backed by a Redis store injected on
+ `core.Config`. The owner is the authenticated `(iss, sub)` pair (issuer + subject — `sub` is unique
+ only within an issuer, so both are needed), stored **plaintext exactly as the existing identity
+ binding does** (`pkg/vmcp/session/binding` `Format(iss, sub)` → `iss + "\x00" + sub`); no separate
+ hashing, so the two owner-binding mechanisms stay consistent. (Handle owner-binding then inherits
+ the same token-refresh caveat #5306 tracks for session binding — a refreshed token that changes
+ `sub` breaks the bound identity; it becomes relevant only when the resume path lands with MRTR.)
+ **None of that enforcement machinery has an MVP trigger:** `WorkflowID` is
+ process-ephemeral today (minted per `ExecuteWorkflow`, deleted on return, never persisted or
+ returned to the client), and there is no resume path until MRTR (#5759). So this RFC *documents* the
+ handle-as-capability design (the tracking issue's stated direction for cross-call state) but
+ **sequences its implementation — durable store, injection seam, owner check, redaction — with MRTR**,
+ not the MVP. Corollary: **no handle migration is needed** — changing the `WorkflowID` format/entropy
+ has no on-disk or cross-request compatibility surface, because nothing persists or exposes it today.
+- **D6 — Backend connections: per-request first, shared pool next.** Correctness before
+ optimization; the pooled object must hold zero credential state (auth applied per-call; any
+ exchanged tokens cached by `(subject, backend, scope)`).
+
+### API Changes
+
+Internal only; no user-facing or CRD API changes for the MVP. New internal seams (MVP): a Modern
+dispatcher at the `server.go` handler seam, and a negotiated-era field in the health/probe subsystem
+keyed by backend ID. Deferred to MRTR (#5759): a `WorkflowStateStore` (or store factory) injected on
+`core.Config`, and an owner field on `WorkflowStatus` (see D5).
+
+### Configuration Changes
+
+None required for classification (auto-detected from request content). Two additive knobs are
+expected: a Redis wiring for the workflow-handle store (MRTR-era; see D5), and a **dedicated
+Modern-path kill-switch flag** defaulting to Modern-off until the dispatcher is proven. The flag is
+deliberately a real config knob rather than relying on the implicit "absence of Modern wiring": an
+operator must be able to force every request down the Legacy path in production. For the MVP it is a
+**startup-time config flag** — disabling the Modern path is a flag flip plus a rolling restart, not
+a code change or image rebuild; a hot/runtime reload is a possible later refinement, not required
+here. Because it ships Modern-off, activating the Modern path is a deliberate operator opt-in (the
+feature ships dark by design — Phase 1 is already safe-by-construction, so nothing regresses while
+it stays off). The kill switch is an asymmetry with
+RFC-0081, which needs none: the proxies forward to an SDK-backed backend, whereas vMCP hand-rolls
+security-relevant wire behavior on the Modern path (the JSON-RPC envelope, the re-homed authz
+call-gate, header-forward), so a defect there is a wire-behavior/security risk rather than a
+forwarding glitch. The switch is nearly free because "classify Legacy by default" is already the
+routing baseline at the `server.go:607` seam.
+
+### Data Model Changes
+
+Negotiated-era cached per backend ID in the health subsystem (not on the immutable registry entry,
+which has no writer). The owner field on `WorkflowStatus` is MRTR-era (see D5). No change to the
+transport session manager, which is unused on the Modern path.
+
+### Middleware and Observability
+
+The external middleware chain (recovery, body-limit, header-validation, header-capture, auth,
+audit, MCP parsing, telemetry, SSE write-deadline) wraps the handler seam and survives the bypass
+by construction. New signals: classification outcome and per-era distribution, synthesized-session
+counts/lifetime, workflow-handle resume outcomes (owner-mismatch is a security signal), and the
+per-request aggregation/backend-fan-out latency. `mcp.session.id` is absent under Modern; W3C trace
+context in `_meta` is the correlation mechanism.
+
+## Security Considerations
+
+### Threat Model
+
+- **Attacker**: an authenticated vMCP client attempting to (a) resume or read another principal's
+ workflow, (b) ride another principal's synthesized backend session, or (c) enumerate capabilities
+ it is not admitted to.
+
+### Authentication and Authorization
+
+- Authentication is per-request in the middleware chain and is unaffected by removing sessions.
+ Per-request `_meta` fields are client-controlled telemetry/labels, **never a security principal**;
+ admission continues to key off the authenticated identity (`core.admission.FilterTools`).
+- The identity-binding/hijack-prevention invariant does not disappear — it **relocates** from the
+ session id to the workflow handle, which must be owner-bound.
+- Rate limiting and admission survive the Modern path because they decorate the core, not the SDK
+ server.
+
+### Data Security
+
+- Workflow handles are bearer capabilities: ≥128-bit opaque, owner-bound, TTL'd, revocable, and
+ redacted from audit/telemetry (a build item — `pkg/audit` has no field-level redaction today).
+ This is the *design*; its enforcement machinery is triggered by the resume path and sequenced with
+ MRTR (#5759), since the MVP exposes no client-visible handle (see D5).
+- The Redis workflow-handle store persists logical handle + workflow state only (never backend
+ URLs/addresses), with keyspace separation from Legacy session metadata and TTL-at-write. (MRTR-era;
+ the MVP uses the existing pod-local in-memory store.)
+
+### Input Validation
+
+- The Modern dispatcher owns raw JSON parsing (no SDK layer): it MUST reject JSON-RPC batch arrays
+ with a defined error, treat notifications (no `id`) as `202`/drop, and return `404`/`-32601` for
+ unimplemented methods. `Mcp-Method`/`Mcp-Name`/`MCP-Protocol-Version` are validated against the
+ body (base64-sentinel-decoded where needed); the shipped classifier's `-3202x`/`-32602` code
+ mapping is normative.
+
+### Secrets Management
+
+The shared backend connection pool must hold **zero** retained credential state; auth is applied per
+call via vMCP's existing outgoing-auth strategies (OBO / header injection / token exchange) with no
+client-level default, and any exchanged tokens are cached by `(subject, backend, scope)` — never by
+backend alone — so no principal's credentials bleed onto another's pooled call.
+
+### Audit and Logging
+
+Denied Modern `tools/call`s must produce an audit `outcome:"denied"` — the dispatcher's re-invoked
+call-gate must emit HTTP 403, not surface the denial as a 200 tool-error. Handles must be redacted.
+
+### Mitigations
+
+- Synthesized Legacy-backend sessions partitioned by `(principal, backend)`, initialized with the
+ calling principal's outgoing auth; never shared unless the backend's session state is provably
+ identity-independent.
+- `server/discover` envelope computed post-admission; authz-map entry gated on that.
+- Backend-era detection & misclassification: for a genuinely unclassified backend, **probe
+ Modern-first** — the draft's own dual-era guidance is to attempt `server/discover` (or a
+ modern-shaped request) and fall back to `initialize` only on a non-modern error, because
+ Legacy→Modern is unconditionally "Fails" (a Modern-only backend has removed `initialize`/`ping`, so
+ a Legacy handshake against it is a guaranteed reject, **not** a compatibility-safe superset). If a
+ cached era goes stale mid-flight, any backend-edge `-32601`/`404`/handshake rejection is a
+ **re-classification trigger** (re-probe and retry under the corrected era). The re-classification —
+ not any default — is the correctness guarantee; the only cost is at most one wasted round-trip per
+ newly-seen backend.
+
+## Alternatives Considered
+
+### Alternative 1: Reimplement the session layer statelessly
+
+- Description: keep a session-like abstraction on the Modern path, minted per request.
+- Why not: the core is already stateless and does per-principal projection per request; a stateless
+ "session" would be a no-op wrapper. Bypassing the bridge on the Modern path is the smaller, safer change.
+
+### Alternative 2: Gate the work on go-sdk v1.7's stateless server mode
+
+- Description: rely on go-sdk v1.7 `StreamableHTTPOptions.Stateless` instead of a hand-rolled path.
+- Why not (as a *gate*): unlike the transport proxies (which are SDK-independent — RFC-0081
+ Alternative 2), vMCP's Serve path *is* built on `mcpcompat`. But because Serve already dispatches
+ straight to the core, a hand-rolled Modern dispatcher unblocks the work now, without waiting on a
+ prerelease SDK.
+- But v1.7 IS the intended end state for the one hard part. The hand-rolled JSON-RPC/`resultType`
+ envelope (D2) is explicitly a **bridge**, not a destination: it exists only to avoid gating the
+ whole effort on the SDK bump. It is written from scratch — v1.6.1 has no Modern wire shapes and
+ v1.7's are unexported (see D2) — but kept thin by reusing `mcpcompat`'s dispatch/error skeleton and
+ by mirroring v1.7's wire shape byte-for-byte, so that once v1.7 lands the hand-rolled envelope is
+ **deleted and repointed** at the SDK's stateless server mode. So the SDK is a **deferred dependency
+ for the envelope specifically**, not a rejected alternative — we decline only to *block* on it.
+
+### Alternative 3: Exclude composite tools from the Modern surface (or pull the store seam into Phase 2)
+
+- Description: reject composite tool names on the Modern path until the durable handle store lands.
+- Why not: composite workflows execute **synchronously within a single `tools/call`**, so the
+ pod-local in-memory store is correct and "any pod can serve any request" holds. A durable
+ cross-pod store is only required once workflows *suspend and resume* across requests (MRTR,
+ #5759). Excluding composites removes working functionality for no benefit.
+
+### Alternative 4: Shared backend connection pool from day one
+
+- Description: build the pooled-transport backend layer immediately.
+- Why not: correctness before optimization. Per-request open/close is correct and simplest; the pool
+ (with its zero-credential-state invariant) is a measured follow-up.
+
+### Alternative 5: Store negotiated backend era on the registry entry
+
+- Description: add a `Revision` field to `vmcp.Backend`/`BackendTarget`.
+- Why not: the immutable registry (static/CLI mode) is build-once and returns copies — no write
+ path — and only the operator writes the dynamic registry. Era belongs in the health/probe
+ subsystem that already re-probes backends and tracks out-of-band status keyed by backend ID.
+
+## Compatibility
+
+### Backward Compatibility
+
+Fully backward compatible. All traffic classifies Legacy unless a request carries a Modern signal,
+so 2025-11-25 clients, servers, and backends behave exactly as today. No CRD change is required, so
+a rolling upgrade is safe: old and new pods share one Service, and Modern traffic adds no session
+writes.
+
+### Forward Compatibility
+
+The binary Modern/Legacy classification suffices while there is a single Modern revision.
+`ClassifyRevision` is the single extension point when a second ships (the `Revision` enum would grow
+to carry a negotiated version string) — a signature-level change, not a rewrite.
+
+## Implementation Plan
+
+Scope mirrors RFC-0081: **unary + correctness first; streaming, subscriptions, and MRTR
+designed-deferred.** Everything classifies Legacy by default, so each phase is safe to ship
+incrementally.
+
+- **Phase 1 — Classifier wiring + parser vocabulary (no routing change).** Wire `ClassifyRevision`
+ at the client-edge decode seam (header + `Mcp-Method`/`Mcp-Name` validation, per-case error
+ codes); label `server/discover` in the parser; source `clientInfo`/`protocolVersion` for
+ telemetry. Do **not** allow-list `server/discover` in the authz map yet.
+- **Phase 2 — Server-side Modern stateless path.** The dispatcher at the handler seam; hand-rolled
+ `resultType:"complete"` envelope; re-homed call-gate and header-forward; `server/discover` served
+ as a post-admission envelope with its authz-map entry. Composite tools work here with the
+ in-memory store (single-request-scoped).
+- **Phase 3 — Client-side per-backend dual protocol.** Detect/cache backend era in the health
+ subsystem (probe Modern-first per the Mitigations bullet); give the backend `Session`
+ (`pkg/vmcp/session/internal/backend`) a no-session mode for Modern backends; per-request
+ connections first.
+- **Phase 4 — Off-diagonal bridge cells.** Legacy-client→Modern-backend (terminate client session,
+ re-originate stateless) and Modern-client→Legacy-backend (synthesize and hold a backend session for
+ the duration of the single request — pod-local, since composites execute synchronously; ephemeral
+ for a bare call). Depends on Phases 2–3. **No durable store required** — both sub-cases are
+ single-request-scoped on one pod.
+- **Deferred (designed, built separately):** request-scoped streaming; `subscriptions/listen`;
+ `x-mcp-header`/`Mcp-Param-{Name}` (SEP-2243) on both edges; MRTR elicitation/sampling (#5759) —
+ which is also when the durable workflow-handle store, its `core.Config` injection seam, and the
+ handle owner-check/redaction first have a trigger; and go-sdk v1.7's stateless server mode, which
+ **retires the hand-rolled JSON-RPC envelope** (D2) rather than merely simplifying it.
+
+### Dependencies
+
+None blocking. Independent of the go-sdk v1.7 bump ([toolhive#5754], see Alternative 2). The durable
+workflow-handle store and its `core.Config` injection seam are required **only** for cross-request
+workflow suspend/resume (MRTR, [toolhive#5759]), a Non-Goal here — the MVP bridge, including the
+synthesized Legacy-backend session, uses the existing pod-local in-memory store.
+
+## Testing Strategy
+
+- **Unit**: `ClassifyRevision` truth table and the vMCP decode seam (`Mcp-Method`/`Mcp-Name`,
+ base64-sentinel `Mcp-Name`, per-case error codes).
+- **Dispatcher**: per-method dispatch, `resultType:"complete"` envelope, `404`/`-32601`,
+ notification `202`/drop, batch rejection, and the re-homed call-gate (a denied `tools/call` yields
+ HTTP 403 **and** audit `outcome:"denied"`, not a 200 tool-error).
+- **Dual-era matrix**: e2e per cell, including the `(principal, backend)` partition and the
+ calling-principal's outgoing auth on a synthesized Legacy-backend session.
+- **Workflow handle (MRTR-era, #5759):** owner-binding enforcement (B cannot resume A's workflow),
+ TTL expiry, and Redis-unavailable fail-closed behavior — tested when the resume path lands, not in
+ the MVP (which has no client-visible handle).
+
+## Documentation
+
+- vMCP stateless design work (toolhive#5756) — this RFC is its decision-level counterpart.
+- Update `docs/arch/10-virtual-mcp-architecture.md` and `13-vmcp-scalability.md` when the Modern
+ path lands.
+
+## Open Questions
+
+None. The four questions raised in earlier drafts are resolved:
+
+- **Modern-path kill switch** — a dedicated config flag (Modern-off default); see Configuration
+ Changes.
+- **Workflow-handle owner binding** — plaintext `(iss, sub)` reusing the existing
+ `pkg/vmcp/session/binding` `Format` encoding (not a hash); see D5.
+- **`server/discover` post-admission envelope** — the invariant (computed from the post-admission
+ projection through the same seam as `core.List*`) is fixed by D4; the code location is an
+ implementation detail tracked in #5756, not a decision-level tradeoff.
+- **Implementation timing** — a scheduling matter, not an RFC decision; see the Implementation Plan
+ (each phase is Legacy-by-default and independently shippable, so the work is not gated on the spec
+ or go-sdk v1.7 going final).
+
+## References
+
+- vMCP stateless design work ([toolhive#5756]) — this RFC is its decision-level counterpart.
+- [RFC-0081](THV-0081-stateless-transport-proxies.md) (transport proxies, [toolhive#5755]) — defers
+ the bridge here.
+- MCP draft specification: `basic/versioning`, `server/discover`, `basic/transports/streamable-http`,
+ `basic/patterns/mrtr`, and the draft changelog.
+- SEP-2322 (MRTR), SEP-2243 (HTTP header standardization), SEP-2549 (cacheable results).
+- Prior art — agentgateway `stateless_send_and_initialize` (synthesize-handshake pattern for a
+ Legacy backend behind a Modern/dual-era client).
+- Related: [toolhive#5743] (epic), [toolhive#5754] (go-sdk v1.7), [toolhive#5759] (MRTR),
+ [toolhive#5761] (caching), [toolhive#5760] (CIMD/RFC 9207).
+
+---
+
+## RFC Lifecycle
+
+### Review History
+
+| Date | Reviewer | Decision | Notes |
+|------|----------|----------|-------|
+| 2026-07-21 | — | Draft | Initial submission; counterpart to the arch doc (#5756), refined through multiple independent design reviews |
+
+### Implementation Tracking
+
+| Repository | PR | Status |
+|------------|-----|--------|
+| toolhive | — | Not started |