ask-rails-harness-mcp 0.2.0 → 0.2.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: 10bdd0fdd7f2b5ad18f3953a8d87474c5df24a4c21ae3e5bfbd9945c2e21bb67
4
- data.tar.gz: 50fb399f513255f82626819688d5afc898b6fcab709adf7126a5a93b57c7176a
3
+ metadata.gz: 557e26401f98e088d56827ac4c52341bffd6cff9226ccd1495bfb925da0b6068
4
+ data.tar.gz: c6d51e57bdc815908e58c973efe84ef123fa9e11b4f04b9517f8c294206d0a86
5
5
  SHA512:
6
- metadata.gz: '0383729111ae526ea38c8a7a12e13310bb4c705c876f55b2a4b0ba2afacc65ff330be644bd5e134dc4fc77568200092f48546e2f8ed81663c697742782634f96'
7
- data.tar.gz: 5c1791fdc69510e5fd48acf49b764a73129b5bbe37e0cf47877ef147386191bf5df3b7bdcf612760e6c0f7f63e3d782fab859b81358a99446ebe8d274250fc7c
6
+ metadata.gz: 0fc972965204065aea34a061fd29678b6addb1f079bc04ed503e9c307fc0e30b12f5f421811da77854f36a928ce169797824654816ba650d9643897d30cd92ed
7
+ data.tar.gz: 79231eb99d2e958bf1517633b3e2e20e047bf54b604cc1b52d1c49ee46cc8381b595cbf2c425d60264cad06d88eecfefb4fcc702b6b60715f9f203797aa228a5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.2.1] — 2026-08-08
2
+
3
+ ### Fixed
4
+
5
+ - **Boot under the app's Bundler context** — the `ask-rails-harness-mcp` binary now requires `bundler/setup` before loading the gem, so gem versions resolve against the host app's `Gemfile.lock` instead of whatever is newest on the system. Without this, loading the harness could activate conflicting gem versions (e.g. two `securerandom` releases) and abort the app boot with a misleading "config/environment.rb not found" error. The gem must be present in the app's Gemfile (`bundle add ask-rails-harness-mcp`); a clear hint is printed if it isn't.
6
+
1
7
  ## [0.2.0] — 2026-07-23
2
8
 
3
9
  ### Added
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # ask-rails-harness-mcp
2
2
 
3
- MCP server for Rails app introspection. Exposes all [ask-rails-harness](https://github.com/ask-rb/ask-rails-harness) tools over the [Model Context Protocol](https://modelcontextprotocol.io/).
3
+ [![Gem Version](https://badge.fury.io/rb/ask-rails-harness-mcp.svg)](https://badge.fury.io/rb/ask-rails-harness-mcp)
4
4
 
5
- Coding agents like Claude Code, Cursor, or any MCP-compatible client can connect to inspect your Rails schema, query your database, read models, and more — all through the same tools ask-rails-harness uses internally.
5
+ MCP server for Rails app introspection. Exposes all [ask-rails-harness](https://github.com/ask-rb/ask-rails-harness) tools over the [Model Context Protocol](https://modelcontextprotocol.io/), so coding agents like Claude Code and Cursor can inspect your Rails schema, query your database, read models, and more.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,18 +10,16 @@ Coding agents like Claude Code, Cursor, or any MCP-compatible client can connect
10
10
  bundle add ask-rails-harness-mcp
11
11
  ```
12
12
 
13
- ## Usage
13
+ ## Quick Start
14
14
 
15
- ### Option 1: stdio (local developmentrecommended)
16
-
17
- Run from your Rails app root:
15
+ Add the gem to your Rails app, then run the server from the app root via Bundler this pins gem versions to the app's `Gemfile.lock`, which is required (loading the harness against the newest installed gems can activate conflicting versions and abort the boot):
18
16
 
19
17
  ```bash
20
- cd my-rails-app
21
- ask-rails-harness-mcp
18
+ bundle add ask-rails-harness-mcp
19
+ bundle exec ask-rails-harness-mcp
22
20
  ```
23
21
 
24
- This boots your Rails app and starts an MCP stdio server. Configure in your agent's MCP config:
22
+ Configure it in your agent's MCP config, pointing `cwd` at your Rails app root (add `timeoutMs` if the app is slow to boot):
25
23
 
26
24
  ```json
27
25
  {
@@ -29,72 +27,56 @@ This boots your Rails app and starts an MCP stdio server. Configure in your agen
29
27
  "servers": {
30
28
  "ask-rails-harness-mcp": {
31
29
  "type": "stdio",
32
- "command": "ask-rails-harness-mcp",
33
- "args": []
30
+ "command": "bundle",
31
+ "args": ["exec", "ask-rails-harness-mcp"],
32
+ "cwd": "/path/to/my-rails-app",
33
+ "timeoutMs": 60000
34
34
  }
35
35
  }
36
36
  }
37
37
  }
38
38
  ```
39
39
 
40
- ### Option 2: HTTP endpoint (remote/production)
41
-
42
- Mount in `config/routes.rb` behind your existing auth:
43
-
44
- ```ruby
45
- Rails.application.routes.draw do
46
- authenticate :user, ->(u) { u.admin? } do
47
- post "ask/mcp", to: "ask/rails/mcp#handle"
48
- end
49
- end
50
- ```
40
+ stdio is the only shipped transport.
51
41
 
52
- Then configure any MCP-compatible agent:
53
-
54
- ```json
55
- {
56
- "mcp": {
57
- "servers": {
58
- "ask-rails-harness-mcp": {
59
- "type": "http",
60
- "url": "https://myapp.com/ask/mcp"
61
- }
62
- }
63
- }
64
- }
65
- ```
42
+ ## Tools
66
43
 
67
- The agent discovers 9 tools automatically:
44
+ The agent discovers 7 tools:
68
45
 
69
46
  | Tool | What it does |
70
47
  |---|---|
71
- | `schema_graph` | Full schema introspection — all models, tables, columns, associations, validations |
48
+ | `schema_graph` | Full schema introspection: models, tables, columns, associations |
72
49
  | `query_database` | Read-only SQL queries with safety guards |
73
50
  | `read_model` | Introspect a single ActiveRecord model |
74
51
  | `route_inspector` | Parsed route table with filters |
75
- | `read_log` | Read Rails log files with level/search filtering |
76
- | `search_codebase` | Full-text grep search |
77
- | `read_file` | Read any file from `Rails.root` |
52
+ | `read_log` | Read log files with level/search filtering |
78
53
  | `run_command` | Run shell commands in the app root |
79
- | `read_routes` | Read the raw `config/routes.rb` |
54
+ | `run_tests` | Structured test results with failure reruns (minitest/rspec) |
80
55
 
81
- ### Authentication
56
+ The six generic tools come from `ask-ruby-harness` (usable in any Ruby
57
+ project — see the [Ruby Harness MCP guide](https://ask-rb.github.io/ask-docs/ruby/mcp));
58
+ `route_inspector` is Rails-native.
82
59
 
83
- The MCP endpoint uses the same `Ask::Rails::Harness::Auth` system as the chat UI:
60
+ ## Essential API
61
+
62
+ `Ask::Rails::MCP` exposes four entry points:
63
+
64
+ - `start`: start the stdio server (what the `ask-rails-harness-mcp` binary runs)
65
+ - `handle(json_string)`: handle a raw JSON-RPC message string
66
+ - `process_message(msg)`: handle a parsed JSON-RPC message hash
67
+ - `tools`: the harness tools as MCP tool instances
68
+
69
+ To serve MCP from your own endpoint, parse the request body and return the response hash:
84
70
 
85
71
  ```ruby
86
- Ask::Rails::Harness::Auth.check = -> {
87
- redirect_to main_app.login_path unless current_user&.admin?
88
- }
72
+ render json: Ask::Rails::MCP.process_message(JSON.parse(request.body.read))
89
73
  ```
90
74
 
91
- ### Safety
75
+ All ask-rails-harness safety features apply: environment permission modes, `allowed_commands`/`denied_commands`, read-only query guards, and audit logging of every tool call.
76
+
77
+ ## Full documentation
92
78
 
93
- All ask-rails-harness safety features apply automatically:
94
- - **Permissions** — access modes (`:read_only`, `:ask_before_changes`, `:full_access`)
95
- - **Command allowlists** — `allowed_commands` / `denied_commands` for `RunCommand`
96
- - **Write guards** — `INSERT`/`UPDATE`/`DELETE` blocked by `QueryDatabase`
97
- - **Audit log** — every tool call recorded in `ask_audit_logs`
79
+ The full ask-rb documentation lives at https://ask-rb.github.io/ask-docs. [Rails MCP](https://ask-rb.github.io/ask-docs/rails/mcp) covers ask-rails-harness-mcp in depth. API reference: https://ask-rb.github.io/ask-docs/reference/api.
98
80
 
99
81
  ## Development
100
82
 
@@ -1,6 +1,29 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "ask-rails-harness-mcp"
4
+ # Boot the host Rails app's Bundler environment BEFORE loading the gem, so
5
+ # gem versions (rails, securerandom, ...) resolve against the app's
6
+ # Gemfile.lock instead of whatever is newest on the system. Loading the
7
+ # harness against the newest gems can activate conflicting versions and
8
+ # break the app boot with a misleading "config/environment.rb not found"
9
+ # error. Requires the gem to be present in the app's Gemfile.
10
+ begin
11
+ require "bundler/setup"
12
+ rescue StandardError => e
13
+ # The rubygems bin stub activates the gem's newest dependencies before
14
+ # this script runs, which can conflict with the app's pinned versions.
15
+ # Prefer running via `bundle exec`; fall back to plain resolution and
16
+ # let Ask::Rails::MCP.start report the missing app root.
17
+ warn "ask-rails-harness-mcp: bundler/setup failed (#{e.class}: #{e.message})"
18
+ warn "If you're inside a Rails app, run: bundle exec ask-rails-harness-mcp"
19
+ end
20
+
21
+ begin
22
+ require "ask-rails-harness-mcp"
23
+ rescue LoadError => e
24
+ warn "ask-rails-harness-mcp: cannot load the gem (#{e.message})"
25
+ warn "If you're inside a Rails app, add it to your Gemfile first: bundle add ask-rails-harness-mcp"
26
+ exit 1
27
+ end
5
28
 
6
29
  Ask::Rails::MCP.start
@@ -3,7 +3,7 @@
3
3
  module Ask
4
4
  module Rails
5
5
  module MCP
6
- VERSION = "0.2.0"
6
+ VERSION = "0.2.1"
7
7
  end
8
8
  end
9
9
  end
data/lib/ask/rails/mcp.rb CHANGED
@@ -100,7 +100,8 @@ module Ask
100
100
  # }
101
101
  # }
102
102
  def start
103
- load_rails_app
103
+ load_rails_app_quietly
104
+ silence_stdout_loggers
104
105
 
105
106
  Ask::MCP::Server.start_stdio(
106
107
  name: "ask-rails-harness-mcp",
@@ -119,11 +120,41 @@ module Ask
119
120
 
120
121
  private
121
122
 
123
+ # Boot the app with stdout pointed at stderr: Rails/OTel loggers
124
+ # default to STDOUT in development, and boot-time output would
125
+ # corrupt the JSON-RPC stream the server writes to stdout.
126
+ def load_rails_app_quietly
127
+ real_stdout = STDOUT.dup
128
+ STDOUT.reopen(STDERR)
129
+ begin
130
+ load_rails_app
131
+ ensure
132
+ STDOUT.reopen(real_stdout)
133
+ end
134
+ end
135
+
136
+ # Point app loggers at stderr so tool calls (AR queries, shell
137
+ # commands, ...) can't interleave with JSON-RPC responses.
138
+ def silence_stdout_loggers
139
+ require "logger"
140
+ $stderr.sync = true
141
+ stderr_logger = ::Logger.new($stderr)
142
+ stderr_logger.level = ::Logger::INFO
143
+ if defined?(OpenTelemetry) && OpenTelemetry.respond_to?(:logger=)
144
+ OpenTelemetry.logger = stderr_logger
145
+ end
146
+ return unless defined?(Rails)
147
+
148
+ Rails.logger = stderr_logger if Rails.respond_to?(:logger=)
149
+ ActiveRecord::Base.logger = stderr_logger if defined?(ActiveRecord::Base)
150
+ end
151
+
122
152
  def load_rails_app
123
153
  return if defined?(::Rails) && ::Rails.application
124
154
  require File.expand_path("config/environment")
125
- rescue LoadError
126
- warn "ask-rails-harness-mcp: must be run from your Rails app root (config/environment.rb not found)"
155
+ rescue LoadError => e
156
+ warn "ask-rails-harness-mcp: failed to boot the Rails app: #{e.message}"
157
+ warn "Run it from your Rails app root with the gem in the Gemfile (bundle add ask-rails-harness-mcp)."
127
158
  exit 1
128
159
  end
129
160
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-rails-harness-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto