mcp_on_ruby 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -8
- data/LICENSE.txt +1 -1
- data/README.md +7 -16
- data/lib/mcp_on_ruby/engine.rb +8 -3
- data/lib/mcp_on_ruby/server_factory.rb +8 -4
- data/lib/mcp_on_ruby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac6effb14117c29ebe4aab9f0178aa7ded445b448c80f7438956cbfc088c1934
|
|
4
|
+
data.tar.gz: 052b0c6053db07aee0ebe0991949bae91ec268d9911b5512527b54fb2fb7c503
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: deafb7ff0545ab491e495fba46d21d27ff66e9c397d7466c1800b74206c98aa19569855148f4b0015e9cd5ce3a78bdc29b591a7599ca95b2afdf97d191b54054
|
|
7
|
+
data.tar.gz: 5da7f45bc3087d683a1f17283709f14b3e020b8f69ab270fa00156953abec498593e843c01278644ee57bf08fca227e2df1a9745ea9e747cb9b79974e1727a9e
|
data/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Entries from 2.0.0 onward
|
|
6
|
+
are generated by [release-please](https://github.com/googleapis/release-please) from Conventional Commit PR titles.
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [2.0.1](https://github.com/nagstler/mcp_on_ruby/compare/v2.0.0...v2.0.1) (2026-10-31)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* reuse tool classes when writes are disabled ([#33](https://github.com/nagstler/mcp_on_ruby/issues/33)) ([44be48c](https://github.com/nagstler/mcp_on_ruby/commit/44be48cafcb508a559b718f676e27990277bd41b))
|
|
14
|
+
* validate declarations once routes are loaded ([#32](https://github.com/nagstler/mcp_on_ruby/issues/32)) ([bf96834](https://github.com/nagstler/mcp_on_ruby/commit/bf968346f9131c6f898bdcf152726973079f3429))
|
|
15
|
+
|
|
16
|
+
## [2.0.0](https://github.com/nagstler/mcp_on_ruby/compare/v1.0.0...v2.0.0) (2026-10-31)
|
|
11
17
|
|
|
12
18
|
MCP on Ruby is now a Rails engine that exposes existing controller actions as MCP tools,
|
|
13
19
|
built on the official [`mcp`](https://github.com/modelcontextprotocol/ruby-sdk) gem.
|
|
@@ -99,7 +105,3 @@ built on the official [`mcp`](https://github.com/modelcontextprotocol/ruby-sdk)
|
|
|
99
105
|
- Resource management
|
|
100
106
|
- Prompt handling
|
|
101
107
|
- Root filesystem access
|
|
102
|
-
|
|
103
|
-
[Unreleased]: https://github.com/nagstler/mcp_on_ruby/compare/v2.0.0...HEAD
|
|
104
|
-
[2.0.0]: https://github.com/nagstler/mcp_on_ruby/compare/v1.0.0...v2.0.0
|
|
105
|
-
[1.0.0]: https://github.com/nagstler/mcp_on_ruby/releases/tag/v1.0.0
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -107,21 +107,12 @@ Then ask: *"Which of my products cost more than $50?"*
|
|
|
107
107
|
|
|
108
108
|
## How it works
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
▼
|
|
117
|
-
MCP on Ruby
|
|
118
|
-
Registry which controller actions are exposed, with their routes and schemas
|
|
119
|
-
Dispatcher builds an in-process request: GET /orders?status=pending
|
|
120
|
-
Identity the caller's Authorization header and cookies, or the stdio user
|
|
121
|
-
Result 2xx JSON → structured result; 4xx/5xx → readable tool error
|
|
122
|
-
▼
|
|
123
|
-
Your Rails app: middleware → routes → before_action → controller → render json
|
|
124
|
-
```
|
|
110
|
+
<p align="center">
|
|
111
|
+
<picture>
|
|
112
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/how-it-works-dark.svg">
|
|
113
|
+
<img src="docs/assets/how-it-works.svg" width="960" alt="An MCP client sends a tool call over HTTP or stdio to the official mcp gem, which hands it to MCP on Ruby. MCP on Ruby runs it as an ordinary Rails request through your app, as the caller, and the JSON response comes back as the tool result.">
|
|
114
|
+
</picture>
|
|
115
|
+
</p>
|
|
125
116
|
|
|
126
117
|
Each tool call becomes an ordinary request through your full middleware stack. Anything that protects your API, including `rate_limit`, Rack::Attack, tenant scoping, and audit logging, protects agent traffic too.
|
|
127
118
|
|
|
@@ -396,7 +387,7 @@ end
|
|
|
396
387
|
|
|
397
388
|
| | Supported |
|
|
398
389
|
|---|---|
|
|
399
|
-
| Ruby | 3.2, 3.3, 3.4 |
|
|
390
|
+
| Ruby | 3.2, 3.3, 3.4, 4.0 |
|
|
400
391
|
| Rails | 7.1, 7.2, 8.0, 8.1 |
|
|
401
392
|
| MCP protocol | Every version the official `mcp` gem supports, negotiated per client |
|
|
402
393
|
| Transports | Streamable HTTP (stateless), stdio |
|
data/lib/mcp_on_ruby/engine.rb
CHANGED
|
@@ -20,10 +20,15 @@ module McpOnRuby
|
|
|
20
20
|
McpOnRuby.registry.reset!
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
config.after_initialize do |app|
|
|
23
|
+
config.after_initialize do
|
|
25
24
|
McpOnRuby::WardenHook.install!
|
|
26
|
-
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Fail at boot, not on the first agent request, when declarations do not match routes.
|
|
28
|
+
# Rails runs after_initialize before it loads routes, so validate once routes are loaded,
|
|
29
|
+
# which happens during boot (after eager loading) when eager_load is on.
|
|
30
|
+
initializer "mcp_on_ruby.validate_declarations" do |app|
|
|
31
|
+
app.config.after_routes_loaded { McpOnRuby.registry.tools } if app.config.eager_load
|
|
27
32
|
end
|
|
28
33
|
end
|
|
29
34
|
end
|
|
@@ -45,12 +45,16 @@ module McpOnRuby
|
|
|
45
45
|
@dispatcher ||= Dispatcher.new
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
# Tool classes are rebuilt only when the registry is (on boot and code reload)
|
|
48
|
+
# Tool classes are rebuilt only when the registry is (on boot and code reload) or when
|
|
49
|
+
# `allow_writes` changes, never per request.
|
|
49
50
|
def mcp_tools
|
|
50
|
-
|
|
51
|
+
key = [registry.tools, configuration.allow_writes]
|
|
51
52
|
@mutex.synchronize do
|
|
52
|
-
@cache
|
|
53
|
-
|
|
53
|
+
unless @cache && @cache[:registry].equal?(key.first) && @cache[:allow_writes] == key.last
|
|
54
|
+
@cache = { registry: key.first, allow_writes: key.last,
|
|
55
|
+
tools: served_specs.map { |spec| spec.to_mcp_tool(handler) } }
|
|
56
|
+
end
|
|
57
|
+
@cache[:tools]
|
|
54
58
|
end
|
|
55
59
|
end
|
|
56
60
|
|
data/lib/mcp_on_ruby/version.rb
CHANGED