Consolidates four identical constructions of error `Tool::Response` in
`handle_call_tool_request` into a single private `error_tool_response` method,
reducing duplication and improving maintainability. No behavior change.
- Create failing tests for `stateless` mode
- Implement `stateless` mode by turning of SSE in Streamable HTTP,
making the interaction a standard HTTP Req/Resp
Tool execution errors now return successful responses with isError: true
instead of JSON-RPC protocol errors, per the MCP specification.
This allows clients to distinguish between protocol-level errors and
tool execution errors, providing better error context.
Fixes#159
Follow-up to https://github.com/modelcontextprotocol/ruby-sdk/pull/147.
According to the specification schema, `content` is not optional and therefore cannot be omitted:
```typescript
interface CallToolResult {
_meta?: { [key: string]: unknown };
content: ContentBlock[];
isError?: boolean;
structuredContent?: { [key: string]: unknown };
[key: string]: unknown;
}
```
https://modelcontextprotocol.io/specification/2025-06-18/schema#calltoolresult
Instead of `nil`, an empty array is set as the default value.
There may be a better value for `content`, but at the very least it should not be missing.
* Add support for _meta field on tool schema
* use `meta` naming for `_meta` field on tool schema
* apply suggestions to fix `_meta` tests
Co-authored-by: Ateş Göral <ates@magnetiq.com>
* Update lib/mcp/tool.rb
Co-authored-by: Ateş Göral <ates@magnetiq.com>
* Update lib/mcp/tool.rb
Co-authored-by: Ateş Göral <ates@magnetiq.com>
---------
Co-authored-by: Topher Bullock <topherbullock@users.noreply.github.com>
Co-authored-by: Ateş Göral <ates@magnetiq.com>
I noticed through the existing tests that `MCP::Configuration#protocol_version=`
allows setting an arbitrary protocol version.
Since the official MCP Ruby SDK is an implementation of the MCP specification,
it should not support arbitrary protocol versions. This change adds validation
to the setter, consistent with `Configuration#initialize`.
The same validation has also been added to `MCP::Configuration#validate_tool_call_arguments=`.
There are some unused block variables. This change removes block parameters
that consist solely of unused block parameters.
Where `Hash#values` suffices instead of ignoring unused variables,
replace such code with `Hash#values`.
This commit implements optional JSON Schema validation for tool outputs according to the MCP specification:
- Add MCP::Tool::OutputSchema class mirroring InputSchema functionality
- Support output_schema in class definitions, Tool.define, and OutputSchema objects
- Include validate_result method for runtime validation
- Update MCP::Client::Tool to track output schemas
- Add comprehensive test coverage with 249 passing tests
- Update README with dedicated Tool Output Schemas section
- Follow MCP spec requirements for server/client validation
Since the optional `title` becomes `title: null` when not provided, the following error occurs.
This occurs with Claude Code 1.0.100.
```console
[DEBUG] MCP server "example": Connection failed after 1591ms: [
{
"code": "invalid_type",
"expected": "string",
"received": "null",
"path": [
"serverInfo",
"title"
],
"message": "Expected string, received null"
}
]
```
By adding `compact`, the `title` key will be removed if the optional `title` keyword argument is not specified.
According to the specification, `destructive_hint`, `idempotent_hint`, `open_world_hint`,
and `read_only_hint` of `ToolAnnotations` are optional with default values:
https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations
This PR sets their default values in accordance with the specification.
Additionally, for readability, the hints have been reordered to follow the specification.
Both the combination of positional argument and naming does not feel
like Ruby.
This change makes `is_error` argument a keyword argument called `error`.
Thanks to this, the usage is more self-explanatory:
```ruby
response = Response.new([], error: true)
```
When defining a tool without any arguments taken, it should be allowed
to not have to define the `input_schema` at all, and the default value
for such a scenario should be `{ type: "object" }` as per the schema.
16d91abb68/schema/2025-06-18/schema.ts (L896-L900)
Update send_notification method to properly construct JSON-RPC notification objects with jsonrpc version and method fields.
This ensures notifications conform to the JSON-RPC 2.0 specification when sent over HTTP transport.
https://www.jsonrpc.org/specification#notification
Another goal is to standardise the `send_notification` interface.
Before the revision, it was sufficient to pass the method and parameters in the case of stdio.
However, in the case of Streamable, a hash based on the JSON-RPC specification must be passed.