## Motivation and Context
The MCP specification defines `completion/complete` for providing autocompletion
suggestions for prompt arguments and resource template URIs.
The Ruby SDK previously had only a no-op handler that returned empty results,
with no way for users to define custom completion logic.
This aligns the Ruby SDK with the Python and TypeScript SDKs,
both of which support user-defined completion handlers.
## How Has This Been Tested?
Server tests cover: default handler, custom handler for `ref/prompt` and `ref/resource`,
context argument passing, 100-item truncation, and error responses for nonexistent prompts,
nonexistent resource templates, and invalid ref types.
Client tests cover: request structure, context parameter inclusion,
and fallback when result is missing.
## Breaking Changes
None. The existing default no-op handler behavior is preserved.
The `completion_handler` method is purely additive. The only behavioral change
is that `completion/complete` requests now validate that the referenced prompt
or resource template exists before calling the handler,
returning an `invalid_params` error for unknown references.
## Motivation and Context
Client methods (`tools`, `resources`, `resource_templates`, `prompts`, `read_resource`, `get_prompt`, `call_tool`)
silently swallowed JSON-RPC error responses by falling back to empty defaults. This did not conform to JSON-RPC 2.0,
which clearly distinguishes error responses from success responses.
Both the Python SDK (`MCPError`) and TypeScript SDK (`ProtocolError`) raise exceptions on error responses.
The Ruby SDK was the only one silently discarding them.
Introduces a common `request` method that handles JSON-RPC request construction and error checking in one place,
replacing the duplicated `transport.send_request` calls across all client methods.
## How Has This Been Tested?
Added tests for each affected method verifying that `ServerError` is raised with the correct `code`, `message`,
and `data` attributes.
## Breaking Changes
The previous behavior of silently returning empty defaults on server errors did not conform to JSON-RPC 2.0.
Error responses should be surfaced to callers, not swallowed.
Callers that relied on the silent fallback behavior will need to rescue `MCP::Client::ServerError`.
## Motivation and Context
`Client#call_tool` previously required an `MCP::Client::Tool` object to call a tool.
This made the API harder to use compared to other MCP SDK implementations,
which accept a tool name string directly:
- Python SDK: `session.call_tool(name, arguments)` accepts a name string.
https://github.com/modelcontextprotocol/python-sdk/blob/v1.26.0/src/mcp/client/session.py#L370
- TypeScript SDK: `client.callTool({ name, arguments })` accepts a name string.
ccb78f2/packages/client/src/client/client.ts (L834)
## How Has This Been Tested?
Updated existing tests and added new tests.
## Breaking Change
No. This change adds a `name:` parameter so callers can pass a tool name string
directly without looking up a `Tool` object first. The existing `tool:` parameter
continues to work for backward compatibility.
## Motivation and Context
The `MCP::Client` currently only supports HTTP transport (`MCP::Client::HTTP`).
To achieve parity with other MCP SDKs (Python, TypeScript, C#) which provide
stdio client transports for spawning and communicating with server subprocesses,
the Ruby SDK needs a stdio client transport.
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#stdio
This enables building MCP clients that launch server processes and communicate
via stdin/stdout using newline-delimited JSON-RPC 2.0 messages.
## How Has This Been Tested?
Added tests for process spawning, protocol initialization handshake,
notification handling, error handling, and transport close lifecycle.
## Additional context
Enabled the `Lint/IncompatibleIoSelectWithFiberScheduler` cop in `.rubocop.yml`
to detect accidental use of `IO.select` instead of `IO#wait_readable`.
## Motivation and Context
`lib/mcp.rb` currently declares all `require_relative` statements in one place.
As a result, Server and Client are both loaded, the stdio and Streamable HTTP
transports are both loaded, and Tool, Prompt, and Resource are all loaded,
regardless of which components are actually used.
These components are selected by the user depending on their use case,
so loading everything upfront is unnecessary.
Using `autoload` for selected constants defers loading until the constant
is actually referenced, so only the subsystems required by the user are loaded.
## How Has This Been Tested?
All existing tests pass unchanged.
## Breaking Change
None. This change only defers loading of unused components.
## Motivation and Context
The MCP specification defines `notifications/progress` for reporting incremental progress
during long-running tool operations. The Ruby SDK did not yet support this, so tools had no way to
send progress updates to clients. This caused the `tools-call-with-progress` conformance test to fail.
This adds an `MCP::ServerContext` wrapper that provides a `report_progress` method on
`server_context`. Tools call `server_context.report_progress(value, total:, message:)` to send
notifications back to the client. The method is a no-op when no `progressToken` was provided,
so tools can call it unconditionally without checking for a token.
This design is consistent with the TypeScript and Python SDKs, which provide progress
reporting through a context object rather than a separate parameter.
On the client side, `Client#call_tool` now accepts a `progress_token:` parameter that sets
`_meta.progressToken` in the request.
Ref: https://modelcontextprotocol.io/specification/latest/server/utilities/progress
## How Has This Been Tested?
Added comprehensive tests in `test/mcp/server_progress_test.rb` covering `notify_progress`,
tool integration with progress, block-defined tools, `**kwargs` tools, and no-op behavior
without a token.
Added client tests for `progress_token:` parameter inclusion and omission.
Added `test/mcp/server_context_test.rb` test for non-Hash `server_context` preservation
when `_meta` is present.
Conformance: `tools-call-with-progress` removed from expected failures.
## Breaking Change
`server_context` is now always an `MCP::ServerContext` instance when passed to tools,
even if the server has no context configured. Code that checks `server_context ?` to
detect a nil context will need to be updated, as `ServerContext` is always truthy.
`ServerContext` delegates method calls to the underlying context object via
`method_missing`, so `server_context[:key]` and other accessor patterns continue to work.
In practice, this is unlikely to affect users. A tool that declares `server_context:`
is opting in to use the context; if the server has no context configured, that is a
server configuration issue rather than something the tool should handle with a nil check.