ruby-sdk/test/mcp
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO 48d4fb9272 Return tool argument validation failures as tool execution errors
## Motivation and Context

MCP 2025-11-25 (SEP-1303) clarifies that input validation errors for `tools/call`
should be returned as Tool Execution Errors (`{ content: [...], isError: true }`)
rather than as JSON-RPC `-32602` protocol errors, so models can observe
the validation message and self-correct on a follow-up call.
https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1303

This is a clarification rather than a brand-new requirement: the 2024-11-05, 2025-03-26,
and 2025-06-18 specifications all defined two error categories with overlapping language
("Invalid arguments" listed under Protocol Errors *and* "Invalid input data" listed under
Tool Execution Errors), leaving the routing of JSON-Schema validation failures ambiguous.
The Ruby SDK had selected the "Protocol Errors / Invalid arguments" interpretation,
while the TypeScript SDK (`packages/server/src/server/mcp.ts`, which wraps
`validateToolInput` errors via `createToolError`) and Python SDK's FastMCP
(which routes through the generic `is_error=True` path) had selected the other.
SEP-1303 in 2025-11-25 disambiguates this by replacing the bullets with
"Malformed requests (requests that fail to satisfy CallToolRequest schema)"
under Protocol Errors and "Input validation errors (e.g., date in wrong format,
value out of range)" under Tool Execution Errors, and explicitly states that the latter
"contain actionable feedback that language models can use to self-correct".

`tool_not_found` continues to be returned as a JSON-RPC `-32602` protocol error since
the spec change only covers input validation.

## How Has This Been Tested?

Updated existing tests that previously asserted `-32602` and "Invalid arguments" /
"Missing required arguments" in the JSON-RPC error data to instead
assert `result[:isError] == true` with the same text in the `content` block.
Added new regression tests covering:

- Instrumentation still records `:missing_required_arguments` and
  `:invalid_schema` on the new non-raising path
- Nested schema validation failure (deep arrays of objects with
  required fields) returns a tool execution error rather than a
  protocol error
- `tool_not_found` continues to return JSON-RPC `-32602` (regression
  guard against accidentally widening the change)

`bundle exec rake test` and `bundle exec rake rubocop` both pass.

## Breaking Changes

Yes. Clients that detect tool argument validation errors via `error.code == -32602`
will need to switch to inspecting `result.isError == true` and reading `result.content[].text`.

Note that the Ruby SDK's previous behavior was a defensible reading of the 2024-11-05 /
2025-03-26 / 2025-06-18 spec wording. The 2025-11-25 disambiguation is what makes
the previous behavior non-conforming; the TypeScript and Python SDKs already shipped
the new behavior.
2026-05-01 03:18:29 +09:00
..
client Add HTTP client close for explicit session termination 2026-04-20 13:58:41 -04:00
prompt Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
resource Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
server Support JSON response mode for StreamableHTTPTransport 2026-04-22 08:30:28 +09:00
tool Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
annotations_test.rb Replace assert_empty with assert_equal using explicit literals 2026-02-24 16:09:34 +09:00
client_test.rb Support ping client API per MCP specification 2026-04-19 23:14:50 +09:00
configuration_test.rb Add around_request hook for request instrumentation 2026-04-11 13:54:47 +09:00
content_test.rb Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
icon_test.rb Replace assert_empty with assert_equal using explicit literals 2026-02-24 16:09:34 +09:00
instrumentation_test.rb Add around_request hook for request instrumentation 2026-04-11 13:54:47 +09:00
logging_message_notification_test.rb Add logging support 2026-01-26 22:23:46 +09:00
methods_test.rb Add roots/list and notifications/roots/list_changed support 2026-04-15 02:39:14 +09:00
progress_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
prompt_test.rb Fix Prompt#validate_arguments! crash when arguments are nil 2026-03-01 17:21:41 +09:00
resource_template_test.rb Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
resource_test.rb Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
server_context_test.rb Support resource subscriptions per MCP specification 2026-04-19 03:48:46 +09:00
server_elicitation_test.rb Support elicitation/create per MCP specification 2026-04-13 15:21:45 +09:00
server_notification_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
server_progress_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
server_roots_test.rb Add roots/list and notifications/roots/list_changed support 2026-04-15 02:39:14 +09:00
server_sampling_test.rb Remove Server#create_sampling_message direct call 2026-04-12 17:05:46 +09:00
server_test.rb Return tool argument validation failures as tool execution errors 2026-05-01 03:18:29 +09:00
string_utils_test.rb Fix ReDoS vulnerability in StringUtils#underscore 2026-01-09 01:14:52 +09:00
tool_test.rb Allow $ref in Tool::Schema for protocol version 2025-11-25 2026-02-27 14:33:36 +09:00
transport_test.rb Remove redundant require statements 2025-08-02 00:57:31 +09:00