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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 611ceb54904a193a5ac06d7fc7d223d835067a3d2232b05fc8a46dd1b14b96ac
4
- data.tar.gz: 8d368c37165bf816104cb32345f7576b95e6e36ff5a01e3b2ecf7a07e497172a
3
+ metadata.gz: ac6effb14117c29ebe4aab9f0178aa7ded445b448c80f7438956cbfc088c1934
4
+ data.tar.gz: 052b0c6053db07aee0ebe0991949bae91ec268d9911b5512527b54fb2fb7c503
5
5
  SHA512:
6
- metadata.gz: 1c0528601bea68540a356a143abc104267e3b3bd8972c38544f13d0a1dd49696ab2d62d571ca6f51a9bdc0b5088e8f0eac4bebd18cef307759babfeaadc1e4d0
7
- data.tar.gz: 183338a617d68e0e7fd963d627439e62cfdf66045f80f621b778cd12294ab34bf015f2ccf813ca3b747ce74c7bf1ef01e193e785423f6e94e4fac2e8b7918804
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
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
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
- ## [Unreleased]
8
+ ## [2.0.1](https://github.com/nagstler/mcp_on_ruby/compare/v2.0.0...v2.0.1) (2026-10-31)
9
9
 
10
- ## [2.0.0] - 2026-10-31
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
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2024
3
+ Copyright (c) 2024-present Nagendra Dhanakeerthi
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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
- MCP client (Claude, Cursor, …)
112
- │ Streamable HTTP (/mcp) or stdio (bin/rails mcp:stdio)
113
- ▼
114
- official mcp gem ──────── protocol, version negotiation, schema validation
115
- │ tools/call orders_index { "status": "pending" }
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 |
@@ -20,10 +20,15 @@ module McpOnRuby
20
20
  McpOnRuby.registry.reset!
21
21
  end
22
22
 
23
- # Fail at boot, not on the first agent request, when declarations do not match routes.
24
- config.after_initialize do |app|
23
+ config.after_initialize do
25
24
  McpOnRuby::WardenHook.install!
26
- McpOnRuby.registry.tools if app.config.eager_load
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
- specs = served_specs
51
+ key = [registry.tools, configuration.allow_writes]
51
52
  @mutex.synchronize do
52
- @cache = [specs, specs.map { |spec| spec.to_mcp_tool(handler) }] unless @cache&.first.equal?(specs)
53
- @cache.last
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module McpOnRuby
4
- VERSION = "2.0.0"
4
+ VERSION = "2.0.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mcp_on_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nagendra Dhanakeerthi