Skip to content

SEP-2322: Multi Round-Trip Requests #2322

Open
CaitieM20 wants to merge 79 commits intomodelcontextprotocol:mainfrom
CaitieM20:merge
Open

SEP-2322: Multi Round-Trip Requests #2322
CaitieM20 wants to merge 79 commits intomodelcontextprotocol:mainfrom
CaitieM20:merge

Conversation

@CaitieM20
Copy link
Copy Markdown
Contributor

@CaitieM20 CaitieM20 commented Feb 28, 2026

This is a draft SEP for Multi Round-Trip Requests (MRTR) from the Transports Working Group. It is one of the changes discussed and planned at the December 2025 Core Maintainer Meetup. Exploring the Future of MCP Transports Blog

This SEP Is still in draft, Schema changes are proposed but not locked, documentation updates, conformance tests and additional work still to come, but its ready to move out of Transports Working Group and open up to broader feedback.

Authors: Mark D. Roth (@markdroth), Caitie McCaffrey (@CaitieM20), Gabriel Zimmerman (@gjz22)

Motivation and Context

See SEP for details.

How Has This Been Tested?

Conformance Tests: modelcontextprotocol/conformance#188

Breaking Changes

Yes, see SEP for details

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally - Work In Progress
  • I have added appropriate error handling - Work In Progress
  • I have added or updated documentation as needed - Work in Progress

Additional context

CaitieM20 and others added 30 commits February 20, 2026 10:36
…uestParams — now available on any

  client-initiated request, not just tool calls
   2. Added typed InputResponse = ElicitResult | CreateMessageResult — InputResponses values are now properly typed
  instead of { result: { [key: string]: unknown } }
   3. Updated examples — removed the extra result wrapper from TaskInputResponseRequest and
  TaskInputResponseRequestParams examples to match the new typed schema

  All checks pass: ✅ TypeScript compiles, ✅ JSON schema up to date, ✅ 140/140 examples valid.

Caitie Note: Need to take a look at task-input-response-params.json looks wrong on cursory inspection.
…itRequets these should only be sent as part of IncompleteResponse Objects now
…a JSONRPCIncompleteResultResponse and add examples
…pper in the SEP because InputRequests maps keys directly to the requests so the InputResponses now follows that pattern and there is no benefit to the added wrapper. The only argument for the wrapper would be if we wanted to carry error's alongside results but we do not in these cases. If there is an error the client would retry until the necessary information was retrieved and then send back to the server.
Marking SEP as Approved with Changes

Updating SEP to make IncompleteResponses on available on specific request/response paths (CallTool, GetPrompt, ListResources) making matching schema updates as well.

Updating Backward Compatibility & Programming Model section based on Maintainer Discussions in NY
Comment thread docs/seps/2322-MRTR.mdx Outdated
Comment thread docs/seps/2322-MRTR.mdx
Comment thread docs/seps/2322-MRTR.mdx Outdated
@CaitieM20
Copy link
Copy Markdown
Contributor Author

Why Removing Protocol-Level Sessions Would Block MRTR Adoption

[snip]

@halter73 makes a good point here. For our server, we're going to have tool developers adopt MRTR and we will emulate it inside the server (with a blocking thread). However, existing tools must be refactored. This could be a large burden if there are a lot of tools and it they are complex.

Hey folks,

Appreciate the feedback on this. The core maintainers were able to look at usage data from across a variety of MCP Clients, and we don't see a large amount of elicitation usage today. Partly because of the challenges highlighted in this SEP.

Moreover many popular Agentic Clients create a new session per tool call. Or share sessions across multiple chat windows. The current way protocol sessions is defined is underspecified and not consistently implemented across the ecosystem, meaning most MCP Servers that try to leverage them will not work correctly. I had a conversation with a developer who was having to implement different variations for each Client it targeted due to inconsistencies (this is not what we want and creates fragmentation in the ecosystem).

I hear you on its a breaking change however, I would argue this works in very few cases today. The goal with MRTR is to ensure we have a consistent and supportable implementation for Elicitations and other features moving forward that is well defined and works consistently across the ecosystem

Comment thread docs/seps/2322-MRTR.mdx
if becomes a problem.

## Backward Compatibility

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@halter73, @felixweinberger, @maxisbey, @maciej-kisiel I updated this section to reflect what was discussed at the MCP Maintainer meetup in New York, can you please take a look. I'd like to close out on this by next week.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I interpret this section correctly, then it will be legal to support the old await-style syntax in the new SDK versions with the behavior of advertising the 2025-11-25 as the protocol version supported by the server (i.e. no wrapping of MRTR underneath by the SDK). Enabling 2026-06-XX would then require some manual adjustment (e.g. declaration that server-to-client communication is not used or rewriting the handlers to be MRTR-compatible).

If we're aligned on this, then the section LGTM.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I think that's correct. There is some discussion of should we flag the old await style behavior as deprecated (i.e. 2025-11-25 is the last version this is supported) just so developers understand the future path.

@CaitieM20
Copy link
Copy Markdown
Contributor Author

Posting some of the open questions from the C# SDK MRTR PR #1458 here for visibility:

Open Questions for the Spec

  1. InputRequest method field: The spec's InputRequest type is a union of CreateMessageRequest | ElicitRequest | ListRootsRequest. In practice, the method field is needed for deserialization since the params shapes can overlap. The C# SDK uses InputRequest.Method as the discriminator for typed deserialization. The spec should be explicit that method is required.

This is already required since they are not marked optional in the schema. Let me know if there is something more specific you want added here.

  1. I want to second the point @mikekistler brought up transport WG about the inability to smuggle more general JSON-RPC responses like errors back from the server to client with inputResponses. This could make the upgrade scenario for servers relying on errors from upgrading to the new protocol if they're capable of maintaining the stateful session required for such an interaction to makes sense even in stdio. While this isn't as critical as keeping sessions in the protocol in general, I strongly agree with this feedback.

Technically you can do this since the Input

  1. Can stateless servers get sampling/eliciation/roots capabilities via headers somehow in the next protocol version, so we don't degrade the experience during the transition from stateful to stateless either? I know there are other proposals for that, but I think that specifically should be packaged with the MRTR spec revision so SDKs can provide a coherent story about the upgrade to the new protocol.
  2. All new types are marked [Experimental(MCPEXP001)] and gated behind ExperimentalProtocolVersion = "2026-06-XX", so that Mcp-Protocol-Header version is what I'm doing for protocol negotiation, and naturally the initialize handshake in stateful modes. I think we have conformance tests these must match in stateful mode). Anyway, is that how we're going to do this before the next protocol version is ratified?

Posting some of the open questions from the C# SDK MRTR PR #1458 here for visibility:

Open Questions for the Spec

  1. InputRequest method field: The spec's InputRequest type is a union of CreateMessageRequest | ElicitRequest | ListRootsRequest. In practice, the method field is needed for deserialization since the params shapes can overlap. The C# SDK uses InputRequest.Method as the discriminator for typed deserialization. The spec should be explicit that method is required.

Since these aren't marked as optional in the Schema they are required. Let me know if there is something more explicit you want me to add.

  1. I want to second the point @mikekistler brought up transport WG about the inability to smuggle more general JSON-RPC responses like errors back from the server to client with inputResponses. This could make the upgrade scenario for servers relying on errors from upgrading to the new protocol if they're capable of maintaining the stateful session required for such an interaction to makes sense even in stdio. While this isn't as critical as keeping sessions in the protocol in general, I strongly agree with this feedback.

Technically you can smuggle these back in InputResponse today since its just the ElicitResult which provides a way to say elicitation declined. I don't know that I'd encourage that pattern in the ephemeral case because its implying that the two requests are somehow associated, and the whole point in MRTR is that they are not.

  1. Can stateless servers get sampling/eliciation/roots capabilities via headers somehow in the next protocol version, so we don't degrade the experience during the transition from stateful to stateless either? I know there are other proposals for that, but I think that specifically should be packaged with the MRTR spec revision so SDKs can provide a coherent story about the upgrade to the new protocol.

I think this is a comment for @kurtisvg and SEP-1442

  1. All new types are marked [Experimental(MCPEXP001)] and gated behind ExperimentalProtocolVersion = "2026-06-XX", so that Mcp-Protocol-Header version is what I'm doing for protocol negotiation, and naturally the initialize handshake in stateful modes. I think we have conformance tests these must match in stateful mode). Anyway, is that how we're going to do this before the next protocol version is ratified?

Currently Conformance tests support a draft tag, that's what the conformance tests associated with this SEP have. I'm fine with us moving to a more explicit header to mark what's on deck for the June release and make it clear what we expect SDK maintainers to support, but I think this comment is for the conformance test group

SEP Cleanup, fixing typos, adding collapsible sessions to make it easier to read.

Renamed RetryAugmentedRequestParams to InputResponseRequestParams, to better align with other type names added in this SEP.

Removed SEP wording that says ephemeral scenario does not support Elicitation Form URLs, I have a prototype of this working by leveraging request state. Also re-added URLElicitationRequiredError since this may still be necessary.
@dsp-ant dsp-ant added the roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) label Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accepted-with-changes roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) SEP transport Related to MCP transports

Projects

Status: Accepted

Development

Successfully merging this pull request may close these issues.