Commit graph ruby-sdk/lib/mcp/server
Author SHA1 Message Date
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
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
dak2
cd7a54a5c9 Fix to return a response code 202 if the server accepts JSON-RPC notifications and responses
If the server accepts JSON-RPC notifications and responses, it must return an HTTP status code of 202 without a body.

refs
- https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#sending-messages-to-the-server
- https://www.jsonrpc.org/specification

Follow up: https://github.com/modelcontextprotocol/ruby-sdk/issues/111
2025-09-26 00:18:01 +09:00
Siddhant Bajaj
4a65f62158 Return HTTP status code 202 for notification initialized method 2025-08-11 10:40:17 -04:00
dak2
e7fafddf94 Fix JSON-RPC notification format in Streamable HTTP transport
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.
2025-07-26 17:58:31 +09:00
dak2
dc38c9f84a Rename to MCP when handling exceptions in Streamable HTTP transport
The reason for the change is that a NameError occurs when a POST request is made while the stream is closed because ModelContextProtocol is undefined.

I have also added test cases to check the behaviour when IOError and Errno::EPIPE occurs.
2025-06-15 15:21:22 +09:00
Riley Shott
4d79263a87 Addressing feedback 2025-06-11 13:44:54 -07:00
Riley Shott
91af9ad19a Gracefully handle POST requests with nil bodies 2025-06-09 14:14:41 -07:00
Riley Shott
55b03fc7aa Add notification support
Co-authored-by: Kevin Fischer <kfischer_okarin@yahoo.co.jp>
2025-06-09 14:12:13 -07:00
Riley Shott
3e03a2af66 Implement StreamableHTTP transport
Co-authored-by: Topher Bullock <topher.bullock@shopify.com>
2025-06-09 14:12:11 -07:00
Koichi ITO
85252e0546 Suppress Interrupt exception for stdio server
This PR suppresses the following backtrace of `Interrupt` (Ctrl+c) exception for stdio server:

## Before

```console
$ ./examples/stdio_server.rb
^C/Users/koic/src/github.com/modelcontextprotocol/ruby-sdk/lib/mcp/server/transports/stdio_transport.rb:20:
in 'IO#gets': Interrupt
        from /Users/koic/src/github.com/modelcontextprotocol/ruby-sdk/lib/mcp/server/transports/stdio_transport.rb:20:
             in 'MCP::Server::Transports::StdioTransport#open'
        from ./examples/stdio_server.rb:95:in '<main>'
$ echo $?
130
```

## After

```console
$ ./examples/stdio_server.rb
^C
Exiting...
$ echo $?
130
```

This change should prevent unexpected backtrace from appearing when running the example:
https://github.com/modelcontextprotocol/ruby-sdk?tab=readme-ov-file#stdio-transport
2025-06-07 19:25:37 +09:00
Kevin Fischer
72663c0a3f
Extract server capabilities into dedicated Capabilities class
Refactor capabilities handling into MCP::Server::Capabilities to improve
code organization and separation of concerns. This provides a cleaner API
for configuring server capabilities including prompts, resources, tools,
completions, logging, and experimental features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-04 22:52:16 +09:00
Koichi ITO
70680fce88 Fix build error
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.
2025-06-04 11:48:25 +09:00
Joey Cardosi
5cc3d9d526
stop using shared dir 2025-05-30 14:33:22 -04:00
Joey Cardosi
3c8ff5a547
fix + cleanup stdio 2025-05-30 12:17:09 -04:00
Joey Cardosi
d80b13736e
just redo all of it from scratch 2025-05-30 12:15:11 -04:00