Skip to content

feat: multi-round-trip request implementation (SEP-2322)#950

Open
yarolegovich wants to merge 8 commits into
mainfrom
yarolegovich/mrtr
Open

feat: multi-round-trip request implementation (SEP-2322)#950
yarolegovich wants to merge 8 commits into
mainfrom
yarolegovich/mrtr

Conversation

@yarolegovich
Copy link
Copy Markdown
Member

@yarolegovich yarolegovich commented May 8, 2026

Context

Design (design/mrtr.md) and implementation proposal for Multi Round-Trip Requests (MRTR) per SEP-2322.

Changes

  • Introduce InputRequest and InputResponse sealed interfaces with corresponding InputRequestMap and InputResponseMap types for custom map JSON codec implementation.
  • Extend CallToolParams, GetPromptParams, and ReadResourceParams with InputResponses, RequestState and an unexported resultType ("complete" or "input_required") for retry round-trips. The type is set by the SDK based on input requests presence.
  • Add client-side MRTR middleware enabled by default that automatically fulfills input requests and retries.
  • Added MRTROptions on ClientOptions to allow disabling the middleware and configuring the number of retries.
  • Add server-side MRTR middleware for backward compatibility: transparently bridges input requests to direct Elicit/CreateMessage/ListRoots calls for older clients

@yarolegovich yarolegovich marked this pull request as draft May 8, 2026 11:04
@maciej-kisiel
Copy link
Copy Markdown
Contributor

I think the main question we should ask ourselves is how we would design the API for this if there was no backwards compatibility requirement.

If we have an approach that will likely be chosen for v2, sometimes it may make sense to move toward its direction, even if it has some disadvantages if they would disappear with v2 release.

Comment thread design/mrtr.md
Comment thread design/mrtr.md
Comment thread design/mrtr.md
Comment thread design/mrtr.md Outdated
Comment thread design/mrtr.md Outdated
@yarolegovich
Copy link
Copy Markdown
Member Author

I think the main question we should ask ourselves is how we would design the API for this if there was no backwards compatibility requirement.

I don't think my proposal would change significantly if we didn't need backward compatibility.

I would want a sealed interface return type for *Handler functions and separate types for complete and incomplete result. On the client side I would probably leave a handler registration API through ClientOptions.

If we make the client API return a sealed interface as well the "base case" becomes overly verbose - all clients need to unpack result to a specific type and handle it accordingly, even though most of the time retry is auto-handled by the middleware.

Now this breaks the proposed client side "manual handling" where if you disable MRTR through options you can just inspect *Result.InputRequests and take action. I don't think it's a big problem though because users can just disable the auto-middleware and write their own.

@maciej-kisiel
Copy link
Copy Markdown
Contributor

I think it's also worth adding a section on what should happen with the existing methods that are replaced with MRTR.

@yarolegovich yarolegovich marked this pull request as ready for review May 25, 2026 13:15
@yarolegovich yarolegovich changed the title design: mrtr implementation proposal feat: multi-round-trip request implementation (SEP-2322) May 26, 2026
Comment thread mcp/mrtr.go
type MRTROptions struct {
// MaxRetries is the maximum number of MRTR retry attempts after the
// initial call. Defaults to 3 if the provided value is <= 0.
MaxRetries int
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.

It looks like you're giving the client a fixed number of chances to satisfy the input requests. I'm not sure I understand why. I would say you should keep retrying as long as the client is making progress, by providing the answer to at least one request.

Comment thread mcp/mrtr.go
// middleware. The middleware is enabled by default and automatically fulfills input
// requests from the server by invoking the appropriate client handlers and
// retrying the original call.
type MRTROptions struct {
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.

Do you know if other SDKs are using "MRTR" or do they use something else? I'm not suggesting spelling out the full phrase, but maybe MultiRequest, etc. I think MRTR is fine if other SDKs don't have anything better.

Comment thread mcp/protocol.go

// ResultType indicates whether a result is complete or requires further input
// from the client via the MRTR (Multi Round-Trip Requests) protocol.
type ResultType string
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.

Does this need to be exported?

Comment thread mcp/protocol.go
// InputRequest is a sealed interface for parameters that a server can include
// in an MRTR input-required result. Implementations are [*ElicitParams],
// [*CreateMessageParams], and [*ListRootsParams].
type InputRequest interface{ isInputRequest() }
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.

We usually don't mention that something is an interface, and the word "sealed" is not a standard Go term. Just say what it is. Example:

Params is a parameter (input) type for an MCP call or notification.

Comment thread mcp/protocol.go
return nil
}

// InputResponse is a sealed interface for results that a client sends back
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.

ditto

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants