Commit graph ruby-sdk/test
Author SHA1 Message Date
Koichi ITO
99cbefc610 Allow $ref in Tool::Schema for protocol version 2025-11-25
`Tool::Schema` rejected `$ref` with an `ArgumentError`.
Earlier MCP spec versions (2024-11-05 through 2025-06-18) did not define
a JSON Schema dialect or reference the `$ref` keyword. `inputSchema` was described
only as "JSON Schema defining expected parameters" with no further constraints:

- https://modelcontextprotocol.io/specification/2024-11-05/server/tools
- https://modelcontextprotocol.io/specification/2025-06-18/server/tools

The MCP spec 2025-11-25 introduced a "JSON Schema Usage" section that adopts
JSON Schema 2020-12 as the default dialect. Since `$ref` is a core keyword in 2020-12,
it is now allowed for protocol version 2025-11-25 and later.

- https://modelcontextprotocol.io/specification/2025-11-25/basic#json-schema-usage
- https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- https://json-schema.org/draft/2020-12/release-notes

For backward compatibility with older protocol versions (2025-06-18 and earlier),
`Server#validate!` continues to raise `ArgumentError` when a tool input schema contains `$ref`.
This preserves the existing behavior for servers targeting those spec versions.
2026-02-27 14:33:36 +09:00
Koichi ITO
a05da399ba
Merge pull request #235 from koic/fix_property_field_names_in_resource_contents
Fix `Resource::Contents#to_h` to use correct property names per MCP spec
2026-02-20 11:51:34 +09:00
Koichi ITO
08832c6b43 Fix Resource::Contents#to_h to use correct property names per MCP spec
This PR fixes thr following fields with the MCP specification which requires:

- Text resources use `text` and `mimeType` fields
- Binary resources use `blob` (base64-encoded) and `mimeType` fields

https://modelcontextprotocol.io/specification/2025-11-25/server/resources#resource-contents

Fixes #234.
2026-02-19 13:50:10 +09:00
Koichi ITO
15710ef0aa Return JSON-RPC protocol errors for unknown tool calls
Per the MCP specification, an unknown tool call is a protocol-level error, not a tool execution error.
Return JSON-RPC -32602 (Invalid params) instead of successful responses with `isError: true`.
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#error-handling

Fixes #228.
2026-02-19 02:53:39 +09:00
Koichi ITO
4dc2a8eb4a Fix logging/setLevel to return empty hash per MCP specification
This PR fixes `logging/setLevel` to return empty hash per MCP specification.
The MCP specification requires `logging/setLevel` to return an empty result
on success, not nil or the `LoggingMessageNotification` object.

Specification reference:
https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging

Fixes #229.
2026-02-17 01:00:15 +09:00
Koichi ITO
c11393f4c4
Merge pull request #224 from koic/extract_annotations_from_mcp
Extract `MCP::Annotations` into a dedicated file
2026-02-10 02:30:42 +09:00
Koichi ITO
0e30dff80b
Merge pull request #225 from sjrct/add-client-resource-templates
Add resource_templates to MCP::Client
2026-02-07 02:58:52 +09:00
Chris Harding
c145fe39df Add resource_templates to MCP::Client
Includes relevant README addition and tests
2026-02-05 16:02:07 -05:00
Mikhail Dubov
077a5cf15a Add protocol version negotiation to server initialization
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:43:59 +00:00
Koichi ITO
4a71fa8ec4
Merge pull request #221 from chattermill/md-client-instrumentation
Add client info to instrumentation callback
2026-02-05 11:28:14 +09:00
Mikhail Dubov
2d926ab386 Add client info to instrumentation callback 2026-02-04 12:03:03 +00:00
Koichi ITO
248c1ec532
Merge pull request #220 from koic/fix_resource_embedded_not_setting_resource_in_initialize
Fix `Resource::Embedded` not setting `@resource` in `initialize`
2026-02-04 10:58:49 +09:00
Koichi ITO
a85fa028f7 Extract MCP::Annotations into a dedicated file
This PR moves `MCP::Annotations` from lib/mcp.rb to lib/mcp/annotations.rb for better organization,
following the pattern used for other classes such as `Tool::Annotations`.

This PR also adds the missing `last_modified` attribute to `MCP::Annotations`:
https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts#L1701-L1736

It also adds a `to_h` method for serialization and includes comprehensive test coverage.

NOTE: This code is unused within the ruby-sdk repository, but it is kept for compatibility, as it may be used by users.
2026-02-03 15:38:04 +09:00
Koichi ITO
0ab77c318f
Merge pull request #103 from dak2/support-logging
Add `logging` support
2026-01-30 12:29:29 +09:00
dak2
afa2fb4077 Add logging support
A server can send structured logging messages to the client.
https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging#logging

Logging was specified in the 2024-11-05 specification, but since it was not supported in ruby-sdk, I implemented it.
https://modelcontextprotocol.io/specification/2024-11-05/server/utilities/logging

I also made it possible to output a simple notification message in the examples.
2026-01-26 22:23:46 +09:00
Koichi ITO
05c0119e53 Fix Resource::Embedded not setting @resource in initialize
The `initialize` method was missing the assignment of `@resource`,
causing the resource method to always return `nil` and `to_h` to return
an incorrect hash with an empty resource value.

Added comprehensive tests to verify the fix and prevent regression.
2026-01-26 11:37:33 +09:00
Mikhail Dubov
7412197e52 feat: add tool_arguments to instrumentation data
Include the tool arguments in instrumentation callback data when
tools/call is invoked. This allows consumers to track which arguments
were passed to each tool call for analytics and debugging purposes.
2026-01-21 17:18:28 +00:00
Koichi ITO
bd416c7a5f Omit icons from responses when empty or nil
Previously, the `icons` parameter was always included in responses (as an empty array)
even when not configured. This differs from the response representation in MCP Ruby SDK 0.4.0.

Since `icons` is optional, it should be omitted from responses when unused to reduce
unnecessary context window usage.
https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation

This fix applies to `Tool#to_h`, `Prompt#to_h`, `Resource#to_h`, `ResourceTemplate#to_h`,
and `Server#server_info`.

It doesn't seem critical, but if there are no other issues, it would be good to cut 0.5.1 bugfix release soon.
2026-01-12 09:46:45 +09:00
Koichi ITO
248b4d2dad Fix ReDoS vulnerability in StringUtils#underscore
## Summary

Replace regex patterns with lookahead/lookbehind assertions to prevent
catastrophic backtracking on Ruby 3.1 and earlier.

This issue only affects Ruby 3.1 and earlier. Since it does not occur on Ruby 3.2+,
it is not an issue in the current stable release (0.4.0), which does not include #206.

## Regression Testing

Ensure the regex patterns complete within 1 second for a 50,000-character input
that would otherwise trigger superlinear backtracking.
2026-01-09 01:14:52 +09:00
Koichi ITO
b92dbe4c28
Merge pull request #207 from keisku/add-Accept-header-validation
Add Accept header validation
2026-01-08 02:49:19 +09:00
Keisuke Umegaki
ab8f53c5b7
Add Accept header validation
- Set Accept header to request JSON or SSE responses
- Validate response Content-Type and raise error for non-JSON responses
- Add Accept header to test fixtures
- Use explicit hash syntax for Ruby 2.7 compatibility
2026-01-07 14:55:19 +09:00
Koichi ITO
aa8bbad491 Support Ruby 2.7 - Ruby 3.1
## Summary

Unlike applications, libraries provide value by remaining usable for a broad range of users,
even when that means supporting older Ruby versions beyond Ruby's own EOL timeline.

I maintain RuboCop, a Ruby linter. Because linters need to work across the ecosystem,
they often need to keep compatibility with older Ruby versions to some extent.

The trade-off is that the MCP Ruby SDK must remain compatible with Ruby 2.7.
However, given the ecosystem impact, supporting Ruby 2.7 is still worthwhile.

For example, bundled gems such as `csv` (Ruby >= 2.5), `bigdecimal` (Ruby >= 2.5), `json` (Ruby >= 2.7),
and `language_server-protocol` (Ruby >= 2.5) tend to keep compatibility with older Ruby versions.

Unlike dropping support, which imposes restrictions on users,
this change broadens compatibility and does not introduce breaking changes.

## Development Note

`rubocop-shopify` (2.18) supports Ruby 3.1+, and this PR does not change that.
Since RuboCop can configure the runtime Ruby version and the target Ruby version for analysis independently,
CI continues to run RuboCop on Ruby 4.0, while analyzing code with `TargetRubyVersion: 2.7`.

When setting `TargetRubyVersion: 2.7`, several RuboCop offenses were resolved.

Additionally, Sorbet-related libraries support Ruby 3.0+. Since these are not dependencies of the MCP Ruby SDK itself,
they are versioned and tested in the development Gemfile.
2026-01-06 10:38:56 +09:00
Koichi ITO
4968d9cffc
Merge pull request #204 from koic/make_tool_names_stricter
Make tool names stricter
2026-01-04 06:58:20 +09:00
Koichi ITO
ab4f0807d4
Merge pull request #205 from koic/add_icons
Support `icons` parameter
2026-01-03 01:46:43 +09:00
Koichi ITO
b29d522d27 Show exception messages for tool call errors
Claude Code sometimes only shows `Error: MCP error -32603: Internal error`
when an unexpected exception occurs during a tool call.

This change broadens the exception handling scope so the server can surface
the exception message more often, making failures easier to diagnose.
2025-12-31 19:38:14 +09:00
Koichi ITO
ca934456de
Merge pull request #189 from koic/update_specification_url_to_latest
[Docs] Update specification URL to `latest`
2025-12-31 08:11:20 +09:00
Koichi ITO
028c5f3291 Support icons parameter
This PR adds support for the optional `icons` parameter in prompt, resource,
resource template, and server info.

The specifications for `icons` are as follows.
https://modelcontextprotocol.io/specification/2025-11-25/schema#icon

Resolves https://github.com/modelcontextprotocol/ruby-sdk/issues/127.
2025-12-30 05:35:22 +09:00
Koichi ITO
84ff1fcba1 Make tool names stricter
Follow-up to https://github.com/modelcontextprotocol/ruby-sdk/pull/199#issuecomment-3659688807

Tool names are now validated to comply with the specification.
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names

Since the tool name is optional, `nil` value is treated as "not specified" and is ignored without validation.
2025-12-29 01:19:39 +09:00
Koichi ITO
614c016c8d
Merge pull request #192 from koic/add_missing_assertion
Add a missing assertion in `ConfigurationTest`
2025-12-25 00:33:12 +09:00
Koichi ITO
771163cc94
Merge pull request #188 from koic/add_website_url_to_server_info
Add support for the optional `websiteUrl` parameter in `serverInfo`
2025-12-24 00:49:35 +09:00
Koichi ITO
dee80d20ae Raise an error when duplicate tool names are registered
This raises an exception when duplicate tool names are registered,
instead of silently overwriting tools. Tool names are required to be
unique within a server, so this behavior aligns with the MCP specification.

> Tool names SHOULD be unique within a server.

https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names

Validation for tool names could be made more strictly spec-compliant in a separate effort.

Fixes #197
2025-12-21 22:48:43 +09:00
Koichi ITO
62615d65e4 Add support for the optional websiteUrl parameter in serverInfo
This PR adds support for the optional `websiteUrl` parameter in `serverInfo`.
This parameter has been supported since the 2025-11-25 MCP specification.

This PR also implements part of https://github.com/modelcontextprotocol/ruby-sdk/issues/127.
2025-12-21 22:44:36 +09:00
Koichi ITO
851974e454 Add support for the optional description parameter in serverInfo
This PR adds support for the optional `description` parameter in `serverInfo`.
This parameter has been supported since the 2025-11-25 MCP specification.
https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation
2025-12-20 19:12:45 +09:00
Koichi ITO
67e03d7b3d Allow stable protocol specification version "2025-11-25"
The MCP specification dated 2025-11-25 has been released:

- https://modelcontextprotocol.io/specification/2025-11-25
- https://blog.modelcontextprotocol.io/posts/2025-11-25-first-mcp-anniversary

This PR allows `'2025-11-25'` to be specified for the `:protocol_version` keyword argument
in `MCP::Configuration.new`.
2025-12-20 18:58:28 +09:00
Koichi ITO
baeb75c8d8
Merge pull request #190 from koic/avoid_draft_protocol_version
Default to the latest stable protocol version
2025-12-20 18:55:18 +09:00
Edgars Beigarts
a3c24d2bcc
Refactor schema validation to reduce duplication and add additionalProperties support
This refactoring extracts common schema validation logic into a base Schema
class, eliminating ~100 lines of duplicate code between InputSchema and
OutputSchema. It also adds support for the JSON Schema `additionalProperties`
keyword to allow fine-grained control over extra properties in tool arguments.

Previously `additionalParameters` could be set only on OutputSchema.

Key changes:

- Created MCP::Tool::Schema base class consolidating:
  - Schema validation against JSON Schema Draft 4 metaschema
  - Deep key transformation (string to symbol conversion)
  - $ref disallowance checking
  - Common validation methods

- Refactored InputSchema to inherit from Schema:
  - Simplified constructor to accept full schema hash
  - Changed required fields storage from symbols to strings
  - Removed ~40 lines of duplicated validation logic

- Refactored OutputSchema to inherit from Schema:
  - Removed ~54 lines of duplicated validation logic
  - Now shares all common functionality with InputSchema

- Updated Tool.input_schema setter:
  - Simplified to pass full hash directly to InputSchema

- Added additionalProperties support:
  - By default, tools now allow additional properties (JSON Schema default)
  - Can explicitly set `additionalProperties: false` to disallow extras
  - Added comprehensive test coverage for both behaviors
2025-12-12 12:49:52 +02:00
Koichi ITO
acf4d6025c Add a missing assertion in ConfigurationTest
This PR adds a missing assertion in `ConfigurationTest`.
2025-12-05 08:49:18 +09:00
Koichi ITO
c786a14f61 Default to the latest stable protocol version
When starting an MCP server in Claude Code with `protocol_version` set to `DRAFT-2025-v3`,
it fails with the following error:

```console
2025-12-04T02:58:01.548Z [DEBUG] MCP server "example": Connection failed after 2093ms: Server's protocol version is not supported: DRAFT-2025-v3
2025-12-04T02:58:01.548Z [ERROR] MCP server "example" Connection failed: Server's protocol version is not supported: DRAFT-2025-v3
```

This PR changes the default behavior so that if `protocol_version` is not specified,
it uses the latest stable protocol version instead of the draft version.

This PR also updates the README to note that the latest stable protocol version includes
new features from the draft version.
2025-12-04 14:58:41 +09:00
Koichi ITO
117bb426e5 [Docs] Update specification URL to latest
This PR updates the specification URL to `latest`.
This change avoids the need to update the URL whenever a new protocol version is released.
The `latest` path redirects to the latest protocol version.
2025-11-30 17:42:27 +09:00
Koichi ITO
d31c3da8f2
Merge pull request #178 from koic/add_elicitation_skeleton
Add Elicitation skeleton
2025-11-25 01:02:30 +09:00
Koichi ITO
dd458b1fb7 Add Elicitation skeleton
The MCP 2025-06-18 specification includes a feature called Elicitation:
https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation

Like Log Level, an implementation is expected to be provided in the near future.
This PR adds Elicitation as a skeleton implementation for now.
2025-11-21 02:42:20 +09:00
Koichi ITO
bf729baef2 Add "Draft" protocol version to supported protocol versions
For example, the `title` introduced in #109 is not supported in the latest stable protocol version "2025-06-18":
https://modelcontextprotocol.io/specification/2025-06-18

It is supported in the Draft of the next version:
https://modelcontextprotocol.io/specification/draft

In other words, the fact that the Ruby SDK treats "2025-06-18" as the default protocol version while `title` is
only supported in the Draft results in an inconsistency.

Because of this, a new version `"Draft"` has been added to the list of supported versions.
Its value follows the schema below and is defined as `DRAFT-2025-v3`:
14ec41c/schema/draft/schema.ts (L15)

It was also considered to continue using the latest stable version "2025-06-18" as the Ruby SDK default instead of the Draft.
However, in that case, users would need to explicitly specify `MCP::Server.new(protocol_version: 'DRAFT-2025-v3')`,
which adds extra burden. In this PR, Draft is made the default in order to provide the following benefits:

- Users are likely to prefer using the Draft version over the latest stable version
- No need to specify the `protocol_version` option when initializing `MCP::Server`
- Users generally do not need to know the internal development value `DRAFT-2025-v3`

The primary case for specifying `protocol_version` explicitly is when strict adherence to a particular version is required.
However, it seems more practical to prioritize use cases where backward-compatible features, including those from the Draft,
are desirable. This is the rationale behind making the Draft version the default.

In addition, making the Draft version the default protocol version preserves backward compatibility for `MCP::Server`.

NOTE: `DRAFT-2025-v3` is a development code, so its value cannot be set externally.
It is applied either when `protocol_version` is omitted or when `nil` is set explicitly,
such as with `MCP::Configuration.new(protocol_version: nil)`.
This prevents users from creating implementations that depend on development codes like `DRAFT-2025-v3`.
2025-11-11 15:44:36 +09:00
Hiren Hiranandani
08a84c7320
Introduce stateless mode to allow for HA
- Create failing tests for `stateless` mode
- Implement `stateless` mode by turning of SSE in Streamable HTTP,
  making the interaction a standard HTTP Req/Resp
2025-11-04 15:26:12 -08:00
Ateş Göral
3f5f6f8494
Internalize json_rpc_handler along with an XSS vulnerability fix (#175)
* Copy-paste of files from original gem

* Update copied code to match repo style

* Use the lib instead of the gem
2025-10-30 17:43:31 -04:00
Koichi ITO
61d48cd6d9
Merge pull request #165 from Jflick58/fix/make-tool-error-spec-compliant
Fix tool error handling to follow MCP spec
2025-10-22 10:58:29 +09:00
Justin Flick
389cc2e8e6 Fix tool error handling to follow MCP spec
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
2025-10-21 18:33:42 -07:00
Koichi ITO
ad87c8d805
Merge pull request #163 from dak2/add-client-prompts-support
Add `prompts/list` and `prompts/get` support to client
2025-10-19 02:24:36 +09:00
dak2
e88deb6b65 Add prompts/list and prompts/get support to client
This commit adds two new methods to `MCP::Client`:
- prompts: Lists available prompts from the server via `prompts/list`
- get_prompt: Retrieves a specific prompt by name via `prompts/get`

Both methods follow the same pattern as the existing resources support,
including comprehensive test coverage and README documentation updates.

ref. https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/server/prompts.mdx#protocol-messages
2025-10-15 13:16:41 +09:00
Koichi ITO
f312695798
Merge pull request #153 from modelcontextprotocol/prompt-spec-compliance
fix `Prompt` type gaps with 2025-06-18 spec
2025-10-15 01:22:45 +09:00
dak2
7b4ece294b Fix and add test for client tools functionality
- Add test for empty tools array response to ensure client handles empty
  results correctly
- Update call_tool test to use proper content format (array of content
  objects) instead of plain string based on
  modelcontextprotocol spec.
  https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/server/tools.mdx#calling-tools

Follow up: modelcontextprotocol#160
2025-10-13 11:14:48 +09:00