InputRequiredResult: servers request client input inside a reply
In MCP 2026-07-28, servers request client input (sampling, elicitation, roots) by returning an `InputRequiredResult` within a reply rather than by sending a server-initiated request. The flow is: client sends a request; if the server requires client input it responds with an InputRequiredResult (for example naming `sampling/createMessage`); the client forwards it to the host/AI, obtains the response, then re-sends the original request with the input included; the server then returns the final response.
Multi Round-Trip Requests: InputRequiredResult and inputResponses retry
When a server needs client input (sampling, elicitation, or roots) to complete a request, it answers the request with an `InputRequiredResult` containing `inputRequests`. The client then retries the request as a NEW request with a new id, sending the original params plus the matching `inputResponses`; the server then returns the normal response. Example flow: client request id:1 -> server InputRequiredResult(inputRequests) -> client request id:2 (original params + inputResponses) -> server response.
InputResponses object shape
An `InputResponses` object is a JSON map of client responses to the server's requests. Its keys correspond exactly to the keys in the `InputRequests` map; values are the client's result for each request, e.g. `ElicitResult`, `CreateMessageResult`, or `ListRootsResult`.
InputRequests object shape
An `InputRequests` object is a JSON map of server-to-client requests. Keys are server-assigned string identifiers; values are request objects such as `ElicitRequest`, `CreateMessageRequest`, or `ListRootsRequest`, each having `method` (e.g. "elicitation/create", "sampling/createMessage") and `params`.
MRTR replaces server-initiated requests (breaking change)
Multi Round-Trip Requests (MRTR) was introduced in MCP specification version 2026-07-28. Servers MUST send server-to-client requests (such as `roots/list`, `sampling/createMessage`, or `elicitation/create`) using the MRTR pattern. The previous pattern of server-initiated requests is no longer supported; this is a breaking change.
MRTR four-step flow
The multi round-trip request flow is: (1) the client sends an initial request with the parameters needed for the operation; (2) the server determines additional information is required and responds requesting more information; (3) the client gathers the requested information from the user or other sources and retries the original request including the additional information; (4) the server, now having sufficient information, responds with the final result. The pattern avoids requiring shared storage across server instances or stateful load balancing.
InputRequiredResult fields: resultType, inputRequests, requestState
An `InputRequiredResult` is a kind of `Result` indicating additional input is needed before the request can be completed. It carries `resultType: "input_required"`, an optional `inputRequests` map of server-initiated requests the client must fulfill, and an optional `requestState` opaque string meaningful only to the server. Clients MUST NOT inspect, parse, modify, or make assumptions about `requestState` contents.
Example InputRequiredResult JSON-RPC response
Example: {"jsonrpc":"2.0","id":1,"result":{"resultType":"input_required","inputRequests":{"github_login":{"method":"elicitation/create","params":{"mode":"form","message":"Please provide your GitHub username","requestedSchema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}},"capital_of_france":{"method":"sampling/createMessage","params":{"messages":[{"role":"user","content":{"type":"text","text":"What is the capital of France?"}}],"modelPreferences":{"hints":[{"name":"claude-3-sonnet"}],"intelligencePriority":0.8,"speedPriority":0.5},"systemPrompt":"You are a helpful assistant.","maxTokens":100}}},"requestState":"AEAD-protected blob"}}
Example InputResponses payload
Example InputResponses map: {"github_login":{"action":"accept","content":{"name":"octocat"}},"capital_of_france":{"role":"assistant","content":{"type":"text","text":"The capital of France is Paris."},"model":"claude-3-sonnet-20240307","stopReason":"endTurn"}}. Keys match the InputRequests keys; an ElicitResult has `action` and `content`, a CreateMessageResult has `role`, `content`, `model`, and `stopReason`.
Which client requests may return InputRequiredResult
Servers MAY send `InputRequiredResult` responses only on these three client requests: `prompts/get`, `resources/read`, and `tools/call`. Servers MUST NOT send `InputRequiredResult` responses on any other client request.
InputRequests values must be one of three request types
Values in the `inputRequests` map MUST be one of `ElicitRequest`, `CreateMessageRequest`, or `ListRootsRequest`. The keys are server-assigned identifiers and MUST be unique within the scope of the request.
InputRequiredResult MUST contain inputRequests or requestState
Servers MUST include at least one of `inputRequests` or `requestState` in every `InputRequiredResult` response. Both fields are individually optional (MAY), but an empty result carrying neither is invalid.
Servers must not assume clients retry
Servers MUST NOT assume that clients will fulfill the `inputRequests` or retry the original request. Servers MAY return an `InputRequiredResult` on multiple attempts at the same request to repeatedly prompt the user until they have enough information.
requestState format is server's choice
The `requestState` field is an opaque string meaningful only to the server. Servers are free to encode the state in any format, e.g. base64-encoded JSON, an encrypted JWT, or serialized binary. Encoding the context into `requestState` lets servers request additional information without maintaining server-side state.
Client MUST construct requested inputs before retrying
If a client receives an `InputRequiredResult` containing the `inputRequests` field, the client MUST construct the requested inputs before retrying the original request. If the `InputRequiredResult` does not contain `inputRequests`, the client MAY retry the original request immediately.
Client MUST echo requestState exactly on retry
If an `InputRequiredResult` contains `requestState`, the client MUST echo back the exact value when retrying the original request, and MUST NOT inspect, parse, modify, or assume anything about its contents. If the `InputRequiredResult` does not contain a `requestState` field, the client MUST NOT include one in the retry.
inputRequests and requestState scoped to the single retry
Both `inputRequests` and `requestState` affect only the client's retry of the original request. They MUST NOT be used for any other request the client may be sending in parallel.
MRTR basic workflow sequence with tools/call
Typical MRTR sequence: client sends `tools/call` with id 1; server needs more info via elicitation and responds with an `InputRequiredResult` (id 1) containing an ElicitRequest and requestState, terminating the initial request; the client prompts the user, gathers responses, and retries `tools/call` with id 2 including the ElicitResult in inputResponses plus the echoed requestState; the server reconstitutes state, completes execution, and returns the final Result (id 2) with the tool call result. Each request is independent: the retry contains everything the server needs.
Missing requested input: re-request rather than error
If the client fails to send all information requested in a previous `InputRequests` and the missing information is necessary for the server to process the request, the server SHOULD respond with a new `InputRequiredResult` requesting the missing information again, rather than returning an error.
stdio: server MUST NOT write JSON-RPC requests to stdout
The server MUST NOT write JSON-RPC requests to stdout on the stdio transport. Server-to-client interactions are instead carried in InputRequiredResult replies (Multi Round-Trip Requests pattern).
MRTR replaces server-initiated requests (roots/list, sampling, elicitation)
The Multi Round-Trip Requests (MRTR) pattern replaces server-initiated requests such as `roots/list`, `sampling/createMessage`, and `elicitation/create`. Instead, servers return an `InputRequiredResult` with `resultType: "input_required"` whose `inputRequests` field carries the requests for additional information. Clients respond with `inputResponses` on a retry of the original request (SEP-2322).
notifications/elicitation/complete and elicitationId removed
The `notifications/elicitation/complete` notification and the `elicitationId` field of URL mode elicitation requests (both introduced in 2025-11-25) were removed. Under the Multi Round-Trip Requests pattern the client learns the outcome of an out-of-band interaction by retrying the original request; servers needing to correlate an elicitation across retries encode their own identifier in `requestState`.
elicitation/create request shape and required params
Elicitation is requested by the server sending an `InputRequiredResult` containing an `elicitation/create` request. All elicitation requests MUST include: `mode` (string, one of `form` or `url`; optional for form mode, defaults to "form" if omitted) and `message` (string, human-readable explanation of why the interaction is needed). Clients MUST treat requests without a `mode` field as form mode.
Form mode elicitation request parameters
Form mode elicitation requests MUST either specify `mode: "form"` or omit the `mode` field, and include `requestedSchema` (object): a JSON Schema defining the structure of the expected response. Form mode collects structured data in-band and the data is exposed to the client.
URL mode elicitation request parameters
URL mode elicitation requests MUST specify `mode: "url"`, a `message`, and a `url` (string) parameter that the user should navigate to. The `url` parameter MUST contain a valid URL. In URL mode the data (other than the URL itself) is NOT exposed to the client. URL mode was introduced in the 2025-11-25 version of the MCP specification.
requestedSchema restricted to flat objects with primitive properties
The `requestedSchema` of a form mode elicitation uses a restricted subset of JSON Schema: flat objects with primitive properties only. Allowed types are String (with title, description, minLength, maxLength, format, default), Number/Integer (title, description, minimum, maximum, default), Boolean (title, description, default), and Enum forms. Supported string formats are `email`, `uri`, `date`, `date-time`. Nested structures, arrays of objects (beyond enums), and other advanced JSON Schema features are intentionally not supported.
Elicitation enum schema forms (single- and multi-select)
Single-select enum without titles: {"type":"string","enum":["Red","Green","Blue"],"default":"Red"}. Single-select with titles uses `oneOf` with entries like {"const":"#FF0000","title":"Red"}. Multi-select without titles: {"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":[...]},"default":["Red","Green"]}. Multi-select with titles uses items.anyOf with {"const":..., "title":...} entries. Clients that support defaults SHOULD pre-populate form fields with the default values.
Example elicitation/create form request and accept result
Example input request delivered inside InputRequiredResult.inputRequests: {"method":"elicitation/create","params":{"mode":"form","message":"Please provide your GitHub username","requestedSchema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}. The client result, returned inside `inputResponses` on the retried request, is {"action":"accept","content":{"name":"octocat"}}.
Example URL mode elicitation request and result
Example URL mode input request: {"method":"elicitation/create","params":{"mode":"url","url":"https://mcp.example.com/ui/set_api_key","message":"Please provide your API key to continue."}}. The client result is simply {"action":"accept"} with no `content` field.
Elicitation three-action response model: accept, decline, cancel
Elicitation responses use a three-action model applying to both form and URL modes. `action: "accept"` means the user explicitly approved and submitted; for form mode `content` holds data matching the requested schema, for URL mode `content` is omitted. `action: "decline"` means the user explicitly declined and `content` is typically omitted. `action: "cancel"` means the user dismissed without an explicit choice (closed dialog, pressed Escape, browser failed to load) and `content` is typically omitted.
URL mode accept does not mean the interaction completed
A URL mode response with action "accept" indicates the user consented to the interaction, not that the interaction is complete. The interaction occurs out of band and the client is not directly informed of the outcome. When the client retries the original request, the server uses the echoed `requestState` (or its own stored state) to decide whether to return the final result or another InputRequiredResult. Clients SHOULD provide manual controls letting the user retry or cancel the original request.
Elicitation message flow with retried tools/call
Form mode flow: client sends tools/call (id 1); server replies with InputRequiredResult containing elicitation/create (mode: form); the client presents UI, gathers user input, then retries with tools/call (id 2) including the user response; the server returns the final Result for id 2. URL mode flow adds a requestState created by the server encoding URL info, the client obtains consent, opens the URL in the user agent, and sends tools/call (id 2) with the accept response and requestState; the server may block until the out-of-band interaction completes.
roots/list requested via InputRequiredResult
To retrieve roots during processing of a client request, servers send an InputRequiredResult containing a `roots/list` request. The input request delivered inside InputRequiredResult.inputRequests is simply {"method": "roots/list"}, with no params.
roots/list client result shape
The client result for roots/list is returned inside `inputResponses` on the retried request and has the shape {"roots": [{"uri": "file:///home/user/projects/myproject", "name": "My Project"}]} — an array of Root objects.
Roots message flow with request retry
Roots flow: the client calls tools/call (id: 1); the server responds with InputRequiredResult(roots/list); the client re-issues tools/call (id: 2) carrying inputResponses keyed for roots plus requestState.
Roots error handling: no replay needed
If an error occurs while gathering roots, the client does not need to replay the initial call with an error message, because with the InputRequiredResult pattern the server is not waiting for a response.
Sampling error handling under InputRequiredResult
If an error occurs or the user declines the sampling request, the client does not need to replay the initial call with an error message, because the server is not waiting for a response under the InputRequiredResult pattern.
sampling/createMessage is delivered via InputRequiredResult.inputRequests
To request a language model generation during the processing of a client request, servers send an InputRequiredResult containing a `sampling/createMessage` request inside `InputRequiredResult.inputRequests`. The client returns the result inside `inputResponses` on the retried request rather than as a normal JSON-RPC response.
Client feature: elicitation
Clients may offer Elicitation to servers, which are server-initiated requests for additional information from users.
prompts/get may return InputRequiredResult (MRTR)
Servers MAY respond to `prompts/get` with an `InputRequiredResult` to indicate that additional input is needed before the prompt can be resolved, following the multi round-trip requests (MRTR) mechanism. When retrying the request, clients include `inputResponses` and, if provided by the server, `requestState` in the request params.
resources/read may return InputRequiredResult
Servers MAY respond to `resources/read` with an InputRequiredResult indicating additional input is needed before the resource can be read, following the multi round-trip requests (MRTR) mechanism. When retrying, clients include `inputResponses` and, if provided by the server, `requestState` in the request parameters.
InputRequiredResult for tools/call
Servers MAY respond to `tools/call` with an InputRequiredResult, following the multi round-trip requests (MRTR) mechanism. Its result has "resultType":"input_required", an "inputRequests" map keyed by an id (e.g. "github_login") whose value has "method" (e.g. "elicitation/create") and "params" (e.g. mode "form", message, requestedSchema), and an optional opaque "requestState" string.
Retrying tools/call with inputResponses and requestState
When retrying a tools/call after an input_required result, clients include `inputResponses` (a map keyed by the same input request id, each with e.g. {"action":"accept","content":{...}}) and, if the server provided it, `requestState` in the request params, alongside the original name and arguments. The JSON-RPC `id` MUST be different between the initial request and the retry.
Interim input_required results are not cacheable
Interim results with `resultType: "input_required"` (part of the multi round-trip requests / MRTR pattern) are not cacheable and carry no caching hints.
MRTR retry results MUST NOT be cached
Results produced by retrying a request through the multi round-trip requests mechanism — that is, requests carrying `inputResponses` or `requestState` — MUST NOT be cached, because they depend on inputs that are not part of the cache key.
Server-to-client interactions use InputRequiredResult, not server requests
In 2026-07-28 Streamable HTTP, server-to-client interactions (sampling, elicitation, list-roots) are embedded as input requests inside an InputRequiredResult per Multi Round-Trip Requests (MRTR, SEP-2322), not delivered as separate JSON-RPC requests on any stream. This changes behaviour from protocol versions 2025-03-26 through 2025-11-25, where servers could send such requests on SSE streams.
MRTR flow: InputRequiredResult then retry with inputResponses
When a server needs input from the client (sampling, elicitation, or roots), it returns an InputRequiredResult containing inputRequests (e.g. elicitation/create) in response to the original POST (e.g. tools/call with id 1). The client gathers the requested input and POSTs the original request again with a new id (e.g. id 2) carrying the original params plus inputResponses; the server then returns the final result.
ElicitResult action semantics: accept, decline, cancel
In ElicitResult, `"accept"` means the user submitted the form or confirmed the action, `"decline"` means the user explicitly declined the action, and `"cancel"` means the user dismissed without making an explicit choice.
ResultType values: complete and input_required
`ResultType` is `"complete" | "input_required" | string`. `complete` means the request completed successfully and the result contains the final content. `input_required` means the request requires additional input and the result contains an `InputRequiredResult` object with instructions for the client to provide additional input before retrying the original request.
InputResponseRequestParams shape
`InputResponseRequestParams` is `{ _meta: RequestMetaObject; inputResponses?: InputResponses; requestState?: string }`, used when a client retries a request supplying the input that an `input_required` result asked for.
elicitation/create request shape
ElicitRequest is a server-to-client request with method:"elicitation/create" and params of type ElicitRequestParams, used to elicit additional information from the user via the client. ElicitRequestParams is a union of ElicitRequestFormParams and ElicitRequestURLParams.
elicitation/create form-mode example
Example elicitation request: {"method":"elicitation/create","params":{"mode":"form","message":"Please provide your GitHub username","requestedSchema":{"type":"object","properties":{"name":{"type":"string","title":"GitHub Username","description":"Your GitHub username"}},"required":["name"]}}}. The `mode` field distinguishes form elicitation from URL elicitation.
ElicitResult shape: action and content
ElicitResult (the client's reply to an `elicitation/create` request) has: `action: "accept" | "decline" | "cancel"` (required) and optional `content?: { [key: string]: string | number | boolean | string[] }`. Example: {"action": "accept", "content": {"name": "octocat"}}.
ElicitResult content only present for accept + form mode
The `content` field of ElicitResult contains the submitted form data and is only present when `action` is `"accept"` and the elicitation mode was `"form"`. It contains values matching the requested schema and is omitted for out-of-band (URL) mode responses. A URL-mode acceptance is just {"action": "accept"}.
ElicitRequestFormParams shape (mode form)
ElicitRequestFormParams has: optional `mode?: "form"`, required `message: string` (the message describing what information is requested), and required `requestedSchema: { $schema?: string; type: "object"; properties: { [key: string]: PrimitiveSchemaDefinition }; required?: string[] }`.
Elicitation requestedSchema is a restricted flat JSON Schema subset
The `requestedSchema` of a form-mode elicitation request is a restricted subset of JSON Schema: only top-level properties are allowed, without nesting. Property values must be PrimitiveSchemaDefinition (StringSchema, NumberSchema, BooleanSchema, or EnumSchema) — no nested objects or arrays other than the enum multi-select form.
Elicitation form request example JSON
Example form-mode elicitation params: {"mode": "form", "message": "Please provide your contact information", "requestedSchema": {"type": "object", "properties": {"name": {"type": "string", "description": "Your full name"}, "email": {"type": "string", "format": "email", "description": "Your email address"}, "age": {"type": "number", "minimum": 18, "description": "Your age"}}, "required": ["name", "email"]}}.
ElicitRequestURLParams shape (mode url)
ElicitRequestURLParams has three required fields: `mode: "url"`, `message: string` (explains why the interaction is needed), and `url: string` (the URL the user should navigate to). Example: {"mode": "url", "url": "https://mcp.example.com/ui/set_api_key", "message": "Please provide your API key to continue."} — URL mode is used to elicit sensitive data out of band.
PrimitiveSchemaDefinition union for elicitation
PrimitiveSchemaDefinition = StringSchema | NumberSchema | BooleanSchema | EnumSchema. These are restricted schema definitions that only allow primitive types without nested objects or arrays.
StringSchema fields for elicitation
StringSchema has `type: "string"` (required) plus optional `title`, `description`, `minLength?: number`, `maxLength?: number`, `format?: "uri" | "email" | "date" | "date-time"`, and `default?: string`.