## Motivation and Context SEP-2322 (modelcontextprotocol/modelcontextprotocol#2322, merged for the 2026-07-28 spec release) introduces Multi Round-Trip Requests: instead of issuing in-flight server-to-client JSON-RPC requests, a server answers with a result whose `resultType` is `"input_required"`, carrying an `inputRequests` map (of `sampling/createMessage`, `roots/list`, and `elicitation/create` request shapes) and an opaque `requestState`; the client fulfills the requests and re-issues the original request with `inputResponses` and the echoed `requestState`. The wire contract (the `resultType` discriminator and the `inputRequests`/`requestState` shape) stayed stable across all three closed TypeScript prototype iterations (typescript-sdk#2062/#2065, the v2-stateless stack, and #2251) and the Python draft (python-sdk#2322), but the server-side suspend/resume mechanism is still unsettled in both SDKs (typescript-sdk#2251 was put on hold on 2026-06-08). This change therefore implements only the stable, additive vocabulary and the client-side recognition, leaving server emission and automatic resumption for a follow-up once the reference design lands: - New `MCP::ResultType` module with `COMPLETE` and `INPUT_REQUIRED` constants documenting the `resultType` values. - `MCP::Client` raises the new `MCP::Client::InputRequiredError` (exposing `input_requests`, `request_state`, and the raw `result`) when any response carries `resultType: "input_required"`, instead of silently returning a non-final result as if it were the answer. The check lives in the shared request path, so every client method is covered. Servers on stable protocol versions never emit `resultType`, so default behavior is unchanged. Part of #382. ## How Has This Been Tested? New tests in `test/mcp/client_test.rb`: - `call_tool` raises `InputRequiredError` for an `input_required` result and exposes `input_requests`, `request_state`, and the full raw result - `call_tool` returns normally when `resultType` is `"complete"` and when it is absent (wire-compat regression for stable-protocol servers) - `list_tools` also raises for `input_required` results, proving the recognition covers the shared request path `bundle exec rake` (tests, RuboCop, and conformance baseline) passes. ## Breaking Changes None for spec-compliant stable servers, which never send `resultType`. A response that does carry `resultType: "input_required"` now raises `MCP::Client::InputRequiredError` instead of being returned as a final result, which was always a misinterpretation of the draft semantics.
34 lines
927 B
Ruby
34 lines
927 B
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "json_rpc_handler"
|
|
require_relative "mcp/configuration"
|
|
require_relative "mcp/string_utils"
|
|
require_relative "mcp/transport"
|
|
require_relative "mcp/version"
|
|
|
|
module MCP
|
|
autoload :Annotations, "mcp/annotations"
|
|
autoload :Cancellation, "mcp/cancellation"
|
|
autoload :CancelledError, "mcp/cancelled_error"
|
|
autoload :Client, "mcp/client"
|
|
autoload :Content, "mcp/content"
|
|
autoload :Icon, "mcp/icon"
|
|
autoload :Prompt, "mcp/prompt"
|
|
autoload :Resource, "mcp/resource"
|
|
autoload :ResourceTemplate, "mcp/resource_template"
|
|
autoload :ResultType, "mcp/result_type"
|
|
autoload :Server, "mcp/server"
|
|
autoload :ServerSession, "mcp/server_session"
|
|
autoload :Tool, "mcp/tool"
|
|
autoload :TraceContext, "mcp/trace_context"
|
|
|
|
class << self
|
|
def configure
|
|
yield(configuration)
|
|
end
|
|
|
|
def configuration
|
|
@configuration ||= Configuration.new
|
|
end
|
|
end
|
|
end
|