Skip to content

Ask upstream whether rmcp intends supported-pre-2026 + both _meta keys to reach the stateless path #204

Description

@plusky

Carried forward from #34, which closes without it having a home.

The question

In rmcp 3.1.4, is_legacy_request (tower.rs) routes a POST to the
handshake-free stateless path when the request's revision is >= 2026-07-28 or
when a non-initialize request carries both io.modelcontextprotocol/protocolVersion
and …/clientCapabilities.

That second arm means a revision rmcp does support and that predates 2026-07-28
— 2025-11-25, say — reaches serve_negotiated_request_directly and gets a peer
synthesized with client_info: Implementation::default(), i.e. rmcp's own build
identity, purely because the request carried both keys.

Is that intended, or is the both-keys shape meant to imply the 2026-07-28
lifecycle?
If intended, the discover-shape check is doing double duty. If not,
it is a routing hole that hands a server a placeholder identity for a client that
never asked for the handshake-free lifecycle.

Why bugwarden cares, and why it is not urgent for us

bugwarden is unaffected: lifecycle_of decides on the request's own _meta
revision and refuses anything below 2026-07-28 as out of contract, so that shape
gets mixed_lifecycle_refused rather than a placeholder-identity record. The
question is whether the SDK should be closing it, and whether our refusal is
defending against a bug or against a design.

The answer changes one thing for us: if upstream calls it a bug and fixes it, the
contains(&v) guard in lifecycle_of and part of the DESIGN.md trap prose become
belt-and-braces rather than load-bearing, and should be re-labelled as such rather
than left implying a hazard that no longer exists.

Suggested direction

Ask on modelcontextprotocol/rust-sdk — an issue, not a PR; this is a question
about intent, and the answer determines whether a patch is even wanted.
Filing it is outward-facing and needs Martin's go-ahead, which is why this
issue exists on our side rather than there.

Include the concrete trace: routing predicate, the synthesized-peer call site, and
the observation that validate_request_protocol_version_meta does not close it
because it only enforces header/_meta agreement once a _meta version is
present.

Re-verify against whatever rmcp version is pinned when this is picked up — the
routing description in this repo was wrong once already (bd674e7), and the
pinned version may have moved.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-assistedAuthored or substantially written with an AI coding agentquestionFurther information is requested

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions