Class: MCP::Server::InputRequiredResult
- Inherits:
-
Object
- Object
- MCP::Server::InputRequiredResult
- Defined in:
- lib/mcp/server/input_required_result.rb
Overview
A multi round-trip input_required result (SEP-2322, MCP 2026-07-28).
Handlers for tools/call, prompts/get, and resources/read may return one instead of
their normal result to ask the client for additional input: input_requests maps server-assigned keys
to embedded request shapes (elicitation/create, sampling/createMessage, or roots/list),
and request_state is an opaque continuation string the client echoes back byte-exactly when it retries
the original request with inputResponses under the same keys.
The server holds no memory between rounds: handlers re-run from the start on every retry and read
the answers via server_context.input_responses / server_context.request_state
(deterministic replay, matching the Python SDK). At least one of the two fields must be present;
a request_state-only result is the load-shedding form ("retry later").
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322
Constant Summary collapse
- EMBEDDABLE_METHODS =
[ Methods::ELICITATION_CREATE, Methods::SAMPLING_CREATE_MESSAGE, Methods::ROOTS_LIST, ].freeze
Instance Attribute Summary collapse
-
#input_requests ⇒ Object
readonly
Returns the value of attribute input_requests.
-
#request_state ⇒ Object
readonly
Returns the value of attribute request_state.
Instance Method Summary collapse
-
#initialize(input_requests: nil, request_state: nil) ⇒ InputRequiredResult
constructor
A new instance of InputRequiredResult.
-
#missing_client_capabilities(declared) ⇒ Object
The subset of #required_client_capabilities the request did not declare.
-
#required_client_capabilities ⇒ Object
The client capabilities required to fulfill every embedded request, merged into one nested hash.
- #to_h ⇒ Object
Constructor Details
#initialize(input_requests: nil, request_state: nil) ⇒ InputRequiredResult
Returns a new instance of InputRequiredResult.
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/mcp/server/input_required_result.rb', line 29 def initialize(input_requests: nil, request_state: nil) if (input_requests.nil? || input_requests.empty?) && request_state.nil? raise ArgumentError, "at least one of input_requests or request_state is required" end unless request_state.nil? || request_state.is_a?(String) raise ArgumentError, "request_state must be a String" end @input_requests = normalize_input_requests(input_requests) @request_state = request_state freeze end |
Instance Attribute Details
#input_requests ⇒ Object (readonly)
Returns the value of attribute input_requests.
27 28 29 |
# File 'lib/mcp/server/input_required_result.rb', line 27 def input_requests @input_requests end |
#request_state ⇒ Object (readonly)
Returns the value of attribute request_state.
27 28 29 |
# File 'lib/mcp/server/input_required_result.rb', line 27 def request_state @request_state end |
Instance Method Details
#missing_client_capabilities(declared) ⇒ Object
The subset of #required_client_capabilities the request did not declare.
Per SEP-2575, servers MUST NOT rely on capabilities the client has not declared,
so a non-empty return means the result must not be sent (-32021).
68 69 70 71 |
# File 'lib/mcp/server/input_required_result.rb', line 68 def missing_client_capabilities(declared) missing = missing_subtree(required_client_capabilities, declared) prune_implied_form_elicitation(missing, declared) end |
#required_client_capabilities ⇒ Object
The client capabilities required to fulfill every embedded request, merged into one nested hash.
The mapping matches the TypeScript SDK's requiredClientCapabilitiesForInputRequest:
elicitation/create with mode: "url" requires elicitation.url, any other elicitation/create
requires elicitation.form, sampling/createMessage with tools/toolChoice requires sampling.tools
(plain sampling otherwise), and roots/list requires roots.
59 60 61 62 63 |
# File 'lib/mcp/server/input_required_result.rb', line 59 def required_client_capabilities (@input_requests || {}).values.reduce({}) do |merged, entry| deep_merge(merged, entry_capability(entry)) end end |
#to_h ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/mcp/server/input_required_result.rb', line 42 def to_h serialized_requests = @input_requests&.transform_values do |entry| { method: entry[:method], params: entry[:params] }.compact end { resultType: ResultType::INPUT_REQUIRED, inputRequests: serialized_requests, requestState: @request_state, }.compact end |