Skip to content

sep-2322 client scenario never sends requestState without inputRequests #547

Description

@SergeevDmitry

The requirement

docs/specification/2026-07-28/basic/patterns/mrtr.mdx, server and client requirements:

Servers MUST include at least one of inputRequests or requestState in every InputRequiredResult response.

If the InputRequiredResult does not contain the inputRequests field, the client MAY retry the original request immediately.

If an InputRequiredResult contains the requestState field, the client MUST echo back the exact value of that field when retrying the original request.

So an InputRequiredResult with only requestState is valid, and when the client retries it, the echo requirement still applies.

The gap

sep-2322-client-request-state never sends that shape. test_mrtr_echo_state and test_mrtr_no_state both send inputRequests, and the other two tools return complete results.

Clients handle the requestState-only case in a separate branch: go-sdk clientMultiRoundTripMiddleware, csharp-sdk McpClientImpl.SendRequestAsync, rust-sdk prepare_input_required_retry, and the requestState-only legs in typescript-sdk's inputRequiredDriver. The suite never runs that branch.

This has already happened in practice. The go-sdk client returned a requestState-only result to the caller as if it were final, instead of retrying (modelcontextprotocol/go-sdk#1364, fixed in modelcontextprotocol/go-sdk#1365), and it still passed this scenario.

Proposed shape

One more tool and one more check in the existing scenario, no new scenario:

  • test_mrtr_state_only: the first call returns { "resultType": "input_required", "requestState": ... } with no inputRequests, and the next call is treated as the retry.
  • sep-2322-client-request-state-only-echoed: MUST, so FAILURE when the retry has no requestState or a different one.
  • Retrying is a MAY, so a client that never retries gets the check as not testable under Standardize how scenarios report setup/execution failures #248, not as a violation.
  • A sep-2322.yaml row, written as a variant of the existing echo requirement, like the elicitation, sampling and list-roots variants.
  • The everything-client calls the new tool. Three inline clients in mrtr-client.test.ts cover dropping the state, rewriting it, and never retrying.

I have this implemented and have run it against go-sdk and typescript-sdk. A PR follows.

AI assistance: I used Claude Code to help investigate this.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions