Follow-up to #109.
The introduction of `title` in #109 is still a draft and is not supported in the latest specification, `Version 2025-06-18 (latest)`.
In this PR, the README.md will be updated to mention this point and restore the references to the removed `annotations.title`.
This aims to inform users that, as of `Version 2025-06-18 (latest)`, the use of `annotations.title` is considered stable.
Additionally, separate validation for these parameters could be added.
Please refer to the following comment regarding `annotations.title` and `title`:
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/663#issuecomment-2963519737
In Ruby, it is generally not customary to add parentheses to methods without arguments.
This PR removes such redundant parentheses from the documentation.
`MCP::Server` does not have a `protocol_version=` method.
```console
$ bin/console
irb(main):001> MCP::Server.protocol_version = "2024-11-05"
(irb):1:in '<main>': undefined method 'protocol_version=' for class MCP::Server (NoMethodError)
from bin/console:15:in '<main>'
```
This PR fixes an incorrect example that causes the above error.
Currently, MCP has three versions: 2024-11-05, 2025-03-26, and 2025-06-18.
- https://modelcontextprotocol.io/specification/2024-11-05/basic/transports (stdio and HTTP with SSE)
- https://modelcontextprotocol.io/specification/2025-03-26/basic/transports (stdio and Streamable HTTP)
- https://modelcontextprotocol.io/specification/2025-06-18/basic/transports (stdio and Streamable HTTP)
The newer specification supports stdio and Streamable HTTP as transport mechanisms.
Only the oldest version, 2024-11-05, supports stdin and HTTP with SSE,
but that version is now considered legacy.
Given the current behavior of the Ruby SDK, it likely makes more sense to set
the default protocol version to the latest one, 2025-06-18, rather than the oldest, 2024-11-05.
Ideally, the implementation should adjust its behavior based on the version,
but this PR is limited to updating the default protocol version only.
## Motivation and Context
Currently, MCP supports the following three protocol versions:
"2025-06-18", "2025-03-26", and "2024-11-05".
https://modelcontextprotocol.io/introduction
As shown in the changes to `test/mcp/configuration_test.rb`,
the `protocol_version` value is not currently being validated,
which allows unexpected `protocol_version` values to be accepted.
This PR ensures that only supported protocol versions are accepted.
## How Has This Been Tested?
Existing tests have been updated and new tests have been added.
## Breaking Changes
None. If it becomes an issue, it means a value that was not originally intended has been used.
## Additional context
While one possible approach might be to fall back to a default protocol version
when an invalid `protocol_version` value is provided,
this PR opts to reject invalid `protocol_version` values explicitly.
The reasoning is that encouraging users to provide intentional,
valid input is preferable to silently falling back to a default,
which could lead to unexpected behavior.
Since the example files are not executable binaries, this PR removes the shebangs.
This ensures that all examples are consistently executed via `ruby` command.
It also removes the executable permission from `examples/stdio_server.rb` using `chmod 444`,
bringing it in line with the other example files.
This PR adds links to the following two badges:
1. RubyGems badge: A link to the `mcp` gem will be added. The repository name is `ruby-sdk`,
following the modelcontextprotocol org's naming convention. Since the repository name and
the gem name are different, the link will help make it clear which gem it refers to.
2. MIT license badge: This will link to the MIT license file in the repository.
NOTE: Separately from this PR, the copyright notice in the MIT license should probably be addressed.
It currently says `Copyright (c) 2025 TODO: Write your name`, so the TODO should be resolved:
https://github.com/modelcontextprotocol/ruby-sdk/blob/v0.1.0/LICENSE.txt#L3
Other language SDKs seem to list `Anthropic, PBC` as the copyright holder,
though I would defer that decision to someone more knowledgeable.
`MCP::Resource` doesn't have `text` attribute:
https://github.com/modelcontextprotocol/ruby-sdk/blob/v0.1.0/lib/mcp/resource.rb#L8-L13
I've replaced it with attributes that it actually supports.
Also, the use of `text: "Hello, world!"` in the example of `server.resources_read_handler` implementation resulted in
an unexpected response the first time I worked with `Resource`. While it may not be the best (but better),
in my experience using Resources with Cline, `text: params[:uri]` served as a clearer response when interacting with an LLM,
making it easier to understand.
Follow-up to #27.
This PR fixes the following build error:
```console
$ bundle exec rake
/Users/koic/.rbenv/versions/3.5-dev/lib/ruby/3.5.0+1/bundled_gems.rb:59:in 'Kernel.require': cannot load such file -- mcp/transports/stdio (LoadError)
Did you mean? mcp/transports/stdio_transport_test
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/3.5.0+1/bundled_gems.rb:59:in 'block (2 levels) in Kernel#replace_require'
from /Users/koic/src/github.com/modelcontextprotocol/ruby-sdk/test/mcp/transports/stdio_transport_test.rb:4:in '<top (required)>'
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/3.5.0+1/bundled_gems.rb:59:in 'Kernel.require'
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/3.5.0+1/bundled_gems.rb:59:in 'block (2 levels) in Kernel#replace_require'
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/gems/3.5.0+1/gems/rake-13.3.0/lib/rake/rake_test_loader.rb:21:in 'block in <main>'
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/gems/3.5.0+1/gems/rake-13.3.0/lib/rake/rake_test_loader.rb:6:in 'Array#select'
from /Users/koic/.rbenv/versions/3.5-dev/lib/ruby/gems/3.5.0+1/gems/rake-13.3.0/lib/rake/rake_test_loader.rb:6:in '<main>'
rake aborted!
Command failed with status (1)
/Users/koic/.rbenv/versions/3.5-dev/bin/bundle:25:in 'Kernel#load'
/Users/koic/.rbenv/versions/3.5-dev/bin/bundle:25:in '<main>'
Tasks: TOP => default => test
(See full trace by running task with --trace)
```
https://github.com/modelcontextprotocol/ruby-sdk/actions/runs/15428236624/job/43420346011
The following is stated in #27.
> Breaking Changes
> `MCP::Transports::StdioTransport` is now `MCP::Server::Transports::StdioTransport`
What is shown here is the new name `MCP::Server::Transports::StdioTransport`, not `MCP::Server::Transports::Stdio`.
Therefore, the file path has been updated from `lib/mcp/server/transports/stdio.rb` to `lib/mcp/server/transports/stdio_transport.rb` to
match the module name. If `MCP::Server::Transports::Stdio` is preferred instead, please let me know and I will open a separate PR.
The example code is located at `./examples/stdio_server.rb`.
Also, the content provided as input via stdio has been updated to avoid returning an error data.
Using ping pong as an example, here's the difference:
## Before
An error data is returned.
```console
$ ./examples/stdio_server.rb
{"jsonrpc":"2.0","id":"1","result":"pong"}
{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"Invalid Request","data":"Method name must be a string and not start with \"rpc.\""}}
```
This error message is generated in the following location:
https://github.com/Shopify/json-rpc-handler/blob/v0.1.1/lib/json_rpc_handler.rb#L70
## After
The expected result is returned without error data.
```console
$ ./examples/stdio_server.rb
{"jsonrpc":"2.0","id":"1","method":"ping"}
{"jsonrpc":"2.0","id":"1","result":{}}
```
The other stdin example has been updated to use data that does not cause errors.
With this document update, users can verify the behavior of the MCP server via stdin without using an MCP client.
- add support for resource templates
- improve capability negotiation on handlers
- clean up readme
- reduce default protocol version to "2024-11-05"
- address spec compliance of resources
- add debug gem to development
- alias ModelContextProtocol to MCP
- move prompt subclasses to subdir
- improve tool and prompt definition
- improve passing of server context to tools
- improve tool input schema validation
- Allow protocol version to be set at the server level through configuration instead of a class method, providing more flexibility in protocol version management [#43](https://github.com/Shopify/mcp-ruby/pull/43) @topherbullock
- Fixed instrumentation handling to ensure accurate timing information and proper error reporting [#42](https://github.com/Shopify/mcp-ruby/pull/42) @tobiasbales
- Improved error handling and reporting in the server
- Fixed timing information collection in instrumentation
- Added proper error types for different failure scenarios
- Enhanced test coverage for error cases
- [Allow protocol version to be set at the server level #43](https://github.com/Shopify/mcp-ruby/pull/43) @topherbullock
- [Fix instrumentation handling #42](https://github.com/Shopify/mcp-ruby/pull/42) @tobiasbales
Bump protocol version to 2025-03-26
Provide fallback value for tool_name
Make configuration per server
Add support for tool annotations
document tool annotations
- Added support for handle_json method from JSON RPC gem to allow consumers to pass JSON strings
- Added context parameter to prompt templating system
- Updated tool and prompt registration to use class references instead of instances
- Changed tool response is_error to isError to match protocol specification
Add configurable exception reporter
Avoid leaking tool exceptions by sending them to a configurable exception reporter
Add optional context to pass to tools
Add basic instrumentation data/labels
- remove activesupport as a runtime dependency
- use alternative to activesupport/inflector methods
- use `json_rpc_handler` gem
- add json_rpc_handler to gem dependencies
- fix `lib/mcp-ruby` auto-import path
- implement server resources
- add basic listing of resources to Server
- allow setting handlers on Server
- wrap handler method results
- make tool definition more declarative
- make prompt definition more declarative
- bump dependency versions