Skip to content

Implement SEP-2260: Server requests must associate with a client request #873

@alexhancock

Description

@alexhancock

SEP-2260: Require Server requests to be associated with a Client request — rust-sdk implementation

Spec PR: modelcontextprotocol/modelcontextprotocol#2260
Track: Specification · Stage: final · Priority: P0 · Theme: Transport Evolution and Scalability
Needs code changes: Yes (Medium) — Breaking (forbids unsolicited server→client requests)

Summary

Tightens scoping so that server→client requests must be associated with an in-flight client
request, and serves notice that "unsolicited" server-to-client requests will not be supported by
future stateless transports. Spec-only text change, but it changes allowed runtime behavior.

Why this needs code changes in rust-sdk

Server→client requests in rmcp go through the Peer API (the send_request machinery in
service.rs), exposed on the server side via service/server.rs (e.g. create_message for
sampling, create_elicitation, list_roots, ping). Today these can be invoked from a server
ServerHandler at any time — including outside the handling of a specific client request — because
the Peer doesn't carry an "originating client request" context. To conform, that context needs to
be threaded into the server's outbound request path.

The RequestContext passed to handler methods is the natural carrier for the originating request
id; the issue is that the free-standing Peer handle outlives any single request, so unsolicited
sends are currently possible.

Proposed work

  • Enumerate the server→client request entry points on the server Peer / service/server.rs (create_message, elicitation, list_roots, ping, and any notification-vs-request paths).
  • Thread the originating client request id (available in RequestContext) through to outbound server→client requests so each is associated with an in-flight client request.
  • When no originating request exists (a bare Peer send outside request handling), guard it: under V_2026_07_28 return/log an error; under older versions keep the legacy behavior.
  • Carry the association over the wire using the SEP-2322 MRTR framing (don't invent a second mechanism).
  • Gate the stricter behavior behind ProtocolVersion::V_2026_07_28.
  • Update examples/docs that rely on unsolicited server-initiated requests.

Affected areas

crates/rmcp/src/service.rs (Peer send-request path, RequestContext), service/server.rs
(sampling/elicitation/roots/ping helpers), transport/streamable_http_* (association on the wire).

Notes / risks

  • Depends on / pairs with SEP-2322 (MRTR), which defines how requests are associated. Implement after MRTR framing exists.
  • Breaking for servers that send unsolicited requests — document clearly. The bare-Peer ergonomics may need rethinking (the handle currently implies "send any time").

Related existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High: significant functionality gap or spec violationT-enhancementNew features and enhancementsT-serviceService layer changesT-transportTransport layer changes

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions