mcptest docs GitHub

InputRequiredResult elicitation flow

MCP 2026-07-28 (SEP-2322) replaces the experimental Tasks-shaped elicitation flow with a stateless multi-round-trip exchange. When a server cannot finish a call without more input, it returns an InputRequiredResult carrying one or more input requests and an opaque continuation token. The client re-issues the original method with the user's answers and the echoed token; any server instance can pick the retry up because the state travels in the request, not in a per-session table.

This page is the operator-level reference: the wire shapes, the recognition rule, and the v1 / v2 scope split.

Wire shapes

The server's response carries an InputRequiredResult inside its result field:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "inputRequests": [
      {
        "id": "city",
        "kind": "string",
        "description": "What city?",
        "required": true
      }
    ],
    "requestState": "opaque-token-abc-123",
    "description": "Need the city before I can fetch the forecast."
  }
}

The client's retry is the original method call with two added fields: inputResponses (the user's answers, keyed by the matching request's id) and requestState (the echoed token):

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "weather",
    "arguments": { "loc": "SFO" },
    "inputResponses": [
      { "id": "city", "value": "San Francisco" }
    ],
    "requestState": "opaque-token-abc-123"
  }
}

The original args stay intact so the server treats the retry as the same logical call.

Recognition rule

A response is an InputRequiredResult when its result field deserializes as one and:

  1. inputRequests is a non-empty array.
  2. requestState is a non-empty string.

Both conditions must hold; a half-shaped response (inputRequests present but empty, or requestState missing or empty) is treated as a normal result so the client does not loop on a server bug.

The library function is mcptest_core::protocol::recognize_input_required(envelope) -> Option<InputRequiredResult>.

Library

mcptest_core::protocol::elicitation exposes:

Type / FunctionPurpose
InputRequestOne requested field: id, kind, description, required.
InputResponseOne user answer: id matches a prior request.
InputRequiredResultThe server-side result shape.
RequestStateOpaque continuation token wrapper.
recognize_input_required(envelope)Detect and parse an InputRequiredResult off a response.
build_retry_params(original, state, responses)Construct the retry params object.

All wire types use camelCase serde renames so they match the spec on the wire. InputRequest.required defaults to true when the server omits the field (matches the SEP-2322 default).

What's shipped

Planned follow-up

Cross-references