rails-ai-context 5.3.0 → 5.6.0
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 +76 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +58 -11
- data/SECURITY.md +4 -0
- data/app/controllers/rails_ai_context/mcp_controller.rb +43 -0
- data/config/routes.rb +5 -0
- data/docs/GUIDE.md +81 -33
- data/exe/rails-ai-context +44 -29
- data/lib/generators/rails_ai_context/install/install_generator.rb +42 -37
- data/lib/rails_ai_context/cli/tool_runner.rb +1 -1
- data/lib/rails_ai_context/configuration.rb +1 -1
- data/lib/rails_ai_context/doctor.rb +142 -21
- data/lib/rails_ai_context/instrumentation.rb +22 -0
- data/lib/rails_ai_context/live_reload.rb +1 -1
- data/lib/rails_ai_context/mcp_config_generator.rb +293 -0
- data/lib/rails_ai_context/resources.rb +34 -1
- data/lib/rails_ai_context/serializers/claude_rules_serializer.rb +17 -0
- data/lib/rails_ai_context/serializers/context_file_serializer.rb +19 -4
- data/lib/rails_ai_context/serializers/copilot_instructions_serializer.rb +8 -0
- data/lib/rails_ai_context/serializers/cursor_rules_serializer.rb +3 -3
- data/lib/rails_ai_context/serializers/markdown_serializer.rb +1 -1
- data/lib/rails_ai_context/serializers/tool_guide_helper.rb +3 -3
- data/lib/rails_ai_context/server.rb +30 -43
- data/lib/rails_ai_context/tasks/rails_ai_context.rake +40 -30
- data/lib/rails_ai_context/test_helper.rb +123 -0
- data/lib/rails_ai_context/tools/base_tool.rb +95 -0
- data/lib/rails_ai_context/tools/get_concern.rb +10 -3
- data/lib/rails_ai_context/tools/get_partial_interface.rb +5 -0
- data/lib/rails_ai_context/tools/query.rb +5 -5
- data/lib/rails_ai_context/tools/runtime_info.rb +4 -0
- data/lib/rails_ai_context/tools/search_code.rb +6 -1
- data/lib/rails_ai_context/version.rb +1 -1
- data/lib/rails_ai_context/vfs.rb +162 -0
- data/lib/rails_ai_context.rb +1 -1
- data/server.json +3 -3
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b89e4a41169c9ddd8a649833f96c6792b6c75ec24101ac220d9c3f431c6126e2
|
|
4
|
+
data.tar.gz: b2e4c8d0fa16d62b8fd2b67e0dddcd6f9754eb085a1b0cbae59d7b6e0d6898d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 670a61dd4524c7cae544b3277947191fe4e8ab6f0de54eca4e14eb27c8255e1b1b36c6ad10c99e76e9eac46bc4954676fae9f4680d7108dbc3134422ab9e5d13
|
|
7
|
+
data.tar.gz: f6ca688b6ae4e2c1c41cde1fdba672596cc25815f72d32cd85f039e64596c8c61f30cd24ff2d0996cd7acacb8217abace18eee32ae5ea1d0569d2376d217fad8
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,82 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [5.6.0] — 2026-04-09
|
|
9
|
+
|
|
10
|
+
### Added — Auto-Registration, TestHelper & Bug Fixes
|
|
11
|
+
|
|
12
|
+
Developer experience improvements inspired by action_mcp patterns, plus 5 security/correctness bug fixes.
|
|
13
|
+
|
|
14
|
+
- **Auto-registration via `inherited` hook** — Tools are now auto-discovered from `BaseTool` subclasses. No manual list to maintain — drop a file in `tools/` and it's registered. `Server.builtin_tools` is the new public API. Thread-safe via `@registry_mutex` with deadlock-free design (const_get runs outside mutex to avoid recursive locking from inherited). `Server::TOOLS` preserved as deprecated `const_missing` shim for backwards compatibility.
|
|
15
|
+
|
|
16
|
+
- **`abstract!` pattern** — `BaseTool.abstract!` excludes a class from the registry. `BaseTool` itself is abstract. Subclasses are concrete by default.
|
|
17
|
+
|
|
18
|
+
- **TestHelper module** (`lib/rails_ai_context/test_helper.rb`) — Reusable test helper for custom_tools users. Methods: `execute_tool` (by name, short name, or class), `execute_tool_with_error`, `assert_tool_findable`, `assert_tool_response_includes`, `assert_tool_response_excludes`, `extract_response_text`. Works with both RSpec and Minitest. Supports fuzzy name resolution (`schema` → `rails_get_schema`).
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **SQL comment stripping validation bypass** (HIGH) — `#` comment stripping now restricted to line-start only, preventing validation bypass via hash characters in string literals. PostgreSQL JSONB operators (`#>>`) preserved.
|
|
23
|
+
|
|
24
|
+
- **SHARED_CACHE read outside mutex** (MEDIUM) — `redact_results` now uses `cached_context` for thread-safe access to encrypted column data.
|
|
25
|
+
|
|
26
|
+
- **McpController double-checked locking** (MEDIUM) — Removed unsynchronized read outside mutex, fixing unsafe pattern on non-GVL Rubies (JRuby/TruffleRuby).
|
|
27
|
+
|
|
28
|
+
- **PG EXPLAIN parser bare rescue** (LOW) — Changed from `rescue` to `rescue JSON::ParserError`, preventing silent swallowing of bugs in `extract_pg_nodes`.
|
|
29
|
+
|
|
30
|
+
- **GetConcern `class_methods` block closing** (LOW) — Indent-based tracking to detect the closing `end`, so `def self.` methods after the block are no longer lost.
|
|
31
|
+
|
|
32
|
+
- **Query spec graceful degradation** — Replaced permanently-pending spec (sqlite3 2.x removed `set_progress_handler`) with a spec that verifies queries execute correctly without it.
|
|
33
|
+
|
|
34
|
+
## [5.5.0] — 2026-04-08
|
|
35
|
+
|
|
36
|
+
### Added — Universal MCP Auto-Discovery & Per-Tool Context Optimization (#51-#56)
|
|
37
|
+
|
|
38
|
+
Every AI tool now gets its own MCP config file — auto-detected on project open. No manual setup needed for any supported tool.
|
|
39
|
+
|
|
40
|
+
- **McpConfigGenerator** (`lib/rails_ai_context/mcp_config_generator.rb`) — Shared infrastructure for per-tool MCP config generation. Writes `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (GitHub Copilot), `opencode.json` (OpenCode), `.codex/config.toml` (Codex CLI). Merge-safe — only manages the `rails-ai-context` entry, preserves other servers. Supports standalone mode and CLI skip.
|
|
41
|
+
|
|
42
|
+
- **Codex CLI support** (#51) — 5th supported AI tool. Reuses `AGENTS.md` (shared with OpenCode) and `OpencodeRulesSerializer` for directory-level split rules. Config via `.codex/config.toml` (TOML format) with `[mcp_servers.rails-ai-context.env]` subsection that snapshots Ruby environment variables at install time — required because Codex CLI `env_clear()`s the process before spawning MCP servers. Works with all Ruby version managers (rbenv, rvm, asdf, mise, chruby, system). Added to all 3 install paths (generator, CLI, rake), doctor checks, and search exclusions.
|
|
43
|
+
|
|
44
|
+
- **Cursor improvements** (#52) — `.cursor/mcp.json` auto-generated for MCP auto-discovery. MCP tools rule changed from `alwaysApply: true` to `alwaysApply: false` with descriptive text for agent-requested (Type 3) loading.
|
|
45
|
+
|
|
46
|
+
- **OpenCode improvements** (#53) — `opencode.json` auto-generated for MCP auto-discovery.
|
|
47
|
+
|
|
48
|
+
- **Claude Code improvements** (#54) — `paths:` YAML frontmatter added to `.claude/rules/` schema, models, and components rules for conditional loading. Context and mcp-tools rules remain unconditional.
|
|
49
|
+
|
|
50
|
+
- **Copilot improvements** (#55) — `.vscode/mcp.json` auto-generated for MCP auto-discovery. `name:` and `description:` YAML frontmatter added to all `.github/instructions/` files. Updated `excludeAgent` spec to validate `code-review`, `coding-agent`, and `workspace` per GitHub Copilot docs.
|
|
51
|
+
|
|
52
|
+
- **All 3 install paths updated** — Install generator, standalone CLI (`rails-ai-context init`), and rake task (`rails ai:setup`) all delegate to McpConfigGenerator. Codex added as option "5" in interactive tool selection.
|
|
53
|
+
|
|
54
|
+
- **Doctor expanded** — `check_mcp_json` now validates per-tool MCP configs based on configured `ai_tools` (JSON parse validation + TOML existence check).
|
|
55
|
+
|
|
56
|
+
- **Search exclusions** — `.codex/`, `.vscode/mcp.json`, `opencode.json` added to `search_code` tool exclusions.
|
|
57
|
+
|
|
58
|
+
## [5.4.0] — 2026-04-08
|
|
59
|
+
|
|
60
|
+
### Added — Phase 3: Dynamic VFS & Live Resource Architecture (Ground Truth Engine Blueprint #39)
|
|
61
|
+
|
|
62
|
+
Live Virtual File System replaces static resource handling. Every MCP resource is introspected fresh on every request — zero stale data.
|
|
63
|
+
|
|
64
|
+
- **VFS URI Dispatcher** (`lib/rails_ai_context/vfs.rb`) — Pattern-matched routing for `rails-ai-context://` URIs. Resolves models, controllers, controller actions, views, and routes. Each call introspects fresh. Path traversal protection for view reads.
|
|
65
|
+
|
|
66
|
+
- **4 new MCP Resource Templates:**
|
|
67
|
+
- `rails-ai-context://controllers/{name}` — controller details with actions, filters, strong params
|
|
68
|
+
- `rails-ai-context://controllers/{name}/{action}` — action source code and applicable filters
|
|
69
|
+
- `rails-ai-context://views/{path}` — view template content (path traversal protected)
|
|
70
|
+
- `rails-ai-context://routes/{controller}` — live route map filtered by controller name
|
|
71
|
+
|
|
72
|
+
- **MCP Controller** (`app/controllers/rails_ai_context/mcp_controller.rb`) — Native Rails controller for Streamable HTTP transport. Alternative to Rack middleware — integrates with Rails routing, authentication, and middleware stack. Mount via `mount RailsAiContext::Engine, at: "/mcp"`.
|
|
73
|
+
|
|
74
|
+
- **output_schema on all 38 tools** — Default `MCP::Tool::OutputSchema` set via `BaseTool.inherited` hook. Every tool now declares its output format in the MCP protocol. Individual tools can override with custom schemas.
|
|
75
|
+
|
|
76
|
+
- **Instrumentation** (`lib/rails_ai_context/instrumentation.rb`) — Bridges MCP gem instrumentation to `ActiveSupport::Notifications`. Events: `rails_ai_context.tools.call`, `rails_ai_context.resources.read`, etc. Subscribe with standard Rails notification patterns.
|
|
77
|
+
|
|
78
|
+
- **Server instructions** — MCP server now includes `instructions:` field describing the ground truth engine capabilities.
|
|
79
|
+
|
|
80
|
+
- **Enhanced LiveReload** — Full cache sweep on file changes via `reset_all_caches!` (includes AST, tool, and fingerprint caches).
|
|
81
|
+
|
|
82
|
+
- **82 new specs** covering VFS resolution (models, controllers, actions, views, routes), instrumentation callback, McpController (thread safety, delegation, subclass isolation), resource templates (5 total), output_schema on all 38 tools, and server configuration.
|
|
83
|
+
|
|
8
84
|
## [5.3.0] — 2026-04-07
|
|
9
85
|
|
|
10
86
|
### Added — Phase 2: Cross-Tool Semantic Hydration (Ground Truth Engine Blueprint #38)
|
data/CONTRIBUTING.md
CHANGED
|
@@ -41,7 +41,7 @@ lib/rails_ai_context/
|
|
|
41
41
|
1. Create `lib/rails_ai_context/tools/your_tool.rb` inheriting from `BaseTool` (auto-loaded by Zeitwerk)
|
|
42
42
|
2. Define `tool_name`, `description`, `input_schema`, and `annotations`
|
|
43
43
|
3. Implement `def self.call(...)` returning `text_response(string)`
|
|
44
|
-
4.
|
|
44
|
+
4. Auto-registered — no manual list to update (BaseTool.inherited tracks it)
|
|
45
45
|
5. Write specs in `spec/lib/rails_ai_context/tools/your_tool_spec.rb`
|
|
46
46
|
|
|
47
47
|
## Adding a Prism Listener
|
data/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<a href="https://cursor.com"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor"></a>
|
|
10
10
|
<a href="https://github.com/features/copilot"><img src="https://img.shields.io/badge/GitHub_Copilot-000000?style=for-the-badge&logo=githubcopilot&logoColor=white" alt="GitHub Copilot"></a>
|
|
11
11
|
<a href="https://opencode.ai"><img src="https://img.shields.io/badge/OpenCode-4285F4?style=for-the-badge&logoColor=white" alt="OpenCode"></a>
|
|
12
|
+
<a href="https://codex.openai.com"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI"></a>
|
|
12
13
|
<a href="#-cli--works-everywhere"><img src="https://img.shields.io/badge/Any_Terminal-4EAA25?style=for-the-badge&logo=gnubash&logoColor=white" alt="Any Terminal"></a>
|
|
13
14
|
|
|
14
15
|
|
|
@@ -17,9 +18,10 @@
|
|
|
17
18
|
[](https://rubygems.org/gems/rails-ai-context)
|
|
18
19
|
[](https://github.com/crisnahine/rails-ai-context/actions)
|
|
19
20
|
[](https://registry.modelcontextprotocol.io)
|
|
21
|
+
<br>
|
|
20
22
|
[](https://github.com/crisnahine/rails-ai-context)
|
|
21
23
|
[](https://github.com/crisnahine/rails-ai-context)
|
|
22
|
-
[](https://github.com/crisnahine/rails-ai-context/actions)
|
|
23
25
|
[](LICENSE)
|
|
24
26
|
|
|
25
27
|
</div>
|
|
@@ -66,7 +68,7 @@ rails-ai-context serve # start MCP server
|
|
|
66
68
|
|
|
67
69
|
</div>
|
|
68
70
|
|
|
69
|
-
Now your AI doesn't guess — it **asks your app directly.** 38 tools that query your schema, models, routes, controllers, views, and conventions on demand. Model introspection uses Prism AST parsing — every result carries a `[VERIFIED]` or `[INFERRED]` confidence tag so AI knows what's ground truth and what needs runtime checking.
|
|
71
|
+
Now your AI doesn't guess — it **asks your app directly.** 38 tools and 5 resource templates that query your schema, models, routes, controllers, views, and conventions on demand. Model introspection uses Prism AST parsing — every result carries a `[VERIFIED]` or `[INFERRED]` confidence tag so AI knows what's ground truth and what needs runtime checking.
|
|
70
72
|
|
|
71
73
|
<br>
|
|
72
74
|
|
|
@@ -122,15 +124,15 @@ Compare what AI outputs with and without these tools wired in. The difference is
|
|
|
122
124
|
|
|
123
125
|
<br>
|
|
124
126
|
|
|
125
|
-
##
|
|
127
|
+
## Three ways to use it
|
|
126
128
|
|
|
127
129
|
<table>
|
|
128
130
|
<tr>
|
|
129
|
-
<td width="
|
|
131
|
+
<td width="33%">
|
|
130
132
|
|
|
131
|
-
### MCP Server
|
|
133
|
+
### MCP Server (stdio)
|
|
132
134
|
|
|
133
|
-
AI calls tools directly via the protocol.
|
|
135
|
+
AI calls tools directly via the protocol. Each AI tool gets its own config file — auto-detected on project open.
|
|
134
136
|
|
|
135
137
|
```
|
|
136
138
|
rails ai:serve
|
|
@@ -143,7 +145,21 @@ rails ai:serve
|
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
</td>
|
|
146
|
-
<td width="
|
|
148
|
+
<td width="33%">
|
|
149
|
+
|
|
150
|
+
### MCP Server (HTTP)
|
|
151
|
+
|
|
152
|
+
Mount inside your Rails app — inherits routing, auth, and middleware.
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
# config/routes.rb
|
|
156
|
+
mount RailsAiContext::Engine, at: "/mcp"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Native Rails controller transport. No separate process needed.
|
|
160
|
+
|
|
161
|
+
</td>
|
|
162
|
+
<td width="33%">
|
|
147
163
|
|
|
148
164
|
### CLI
|
|
149
165
|
|
|
@@ -342,6 +358,22 @@ Every tool is **read-only** and returns data verified against your actual app
|
|
|
342
358
|
|
|
343
359
|
<br>
|
|
344
360
|
|
|
361
|
+
## Live Resources (VFS)
|
|
362
|
+
|
|
363
|
+
AI clients can also read structured data through **resource templates** — `rails-ai-context://` URIs that introspect fresh on every request. Zero stale data.
|
|
364
|
+
|
|
365
|
+
| Resource Template | What it returns |
|
|
366
|
+
|:------------------|:---------------|
|
|
367
|
+
| `rails-ai-context://controllers/{name}` | Actions, inherited filters, strong params |
|
|
368
|
+
| `rails-ai-context://controllers/{name}/{action}` | Action source code with applicable filters |
|
|
369
|
+
| `rails-ai-context://views/{path}` | View template content (path traversal protected) |
|
|
370
|
+
| `rails-ai-context://routes/{controller}` | Live route map filtered by controller |
|
|
371
|
+
| `rails://models/{name}` | Per-model details: associations, validations, schema |
|
|
372
|
+
|
|
373
|
+
Plus 9 static resources (schema, routes, conventions, gems, controllers, config, tests, migrations, engines) that AI clients read directly.
|
|
374
|
+
|
|
375
|
+
<br>
|
|
376
|
+
|
|
345
377
|
## Anti-Hallucination Protocol
|
|
346
378
|
|
|
347
379
|
Every generated context file ships with **6 rules that force AI verification** before writing code. The protocol targets the exact cognitive failures that produce confident-wrong code: statistical priors overriding observed facts, pattern completion beating verification, stale context lies.
|
|
@@ -376,14 +408,15 @@ Enabled by default. Disable with `config.anti_hallucination_rules = false` if yo
|
|
|
376
408
|
┌─────────────────────────────────────────────────────────┐
|
|
377
409
|
│ rails-ai-context │
|
|
378
410
|
│ Prism AST parsing. Cached. Confidence-tagged results. │
|
|
411
|
+
│ VFS: rails-ai-context:// URIs introspected fresh. │
|
|
379
412
|
└────────┬──────────────────┬──────────────┬──────────────┘
|
|
380
413
|
│ │ │
|
|
381
414
|
▼ ▼ ▼
|
|
382
415
|
┌──────────────────┐ ┌────────────┐ ┌────────────────────┐
|
|
383
416
|
│ Static Files │ │ MCP Server │ │ CLI Tools │
|
|
384
417
|
│ CLAUDE.md │ │ 38 tools │ │ Same 38 tools │
|
|
385
|
-
│ .cursor/rules/ │ │
|
|
386
|
-
│ .github/instr... │ │
|
|
418
|
+
│ .cursor/rules/ │ │ 5 templates│ │ No server needed │
|
|
419
|
+
│ .github/instr... │ │ stdio/HTTP │ │ rails 'ai:tool[X]' │
|
|
387
420
|
└──────────────────┘ └────────────┘ └────────────────────┘
|
|
388
421
|
```
|
|
389
422
|
|
|
@@ -406,7 +439,7 @@ cd your-rails-app
|
|
|
406
439
|
rails-ai-context init
|
|
407
440
|
```
|
|
408
441
|
|
|
409
|
-
Both paths ask which AI tools you use and whether you want MCP or CLI mode.
|
|
442
|
+
Both paths ask which AI tools you use (Claude Code, Cursor, GitHub Copilot, OpenCode, Codex CLI) and whether you want MCP or CLI mode. Each tool gets its own MCP config file — auto-detected on project open.
|
|
410
443
|
|
|
411
444
|
<br>
|
|
412
445
|
|
|
@@ -458,6 +491,20 @@ end
|
|
|
458
491
|
|
|
459
492
|
<br>
|
|
460
493
|
|
|
494
|
+
## Observability
|
|
495
|
+
|
|
496
|
+
Every MCP tool call and resource read fires an `ActiveSupport::Notifications` event. Subscribe with standard Rails patterns:
|
|
497
|
+
|
|
498
|
+
```ruby
|
|
499
|
+
ActiveSupport::Notifications.subscribe("rails_ai_context.tools.call") do |event|
|
|
500
|
+
Rails.logger.info "[MCP] #{event.payload[:method]} — #{event.duration}ms"
|
|
501
|
+
end
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Events: `rails_ai_context.tools.call`, `rails_ai_context.resources.read`, and more. All 38 tools declare `output_schema` in the MCP protocol, so clients know the response format before calling.
|
|
505
|
+
|
|
506
|
+
<br>
|
|
507
|
+
|
|
461
508
|
## Requirements
|
|
462
509
|
|
|
463
510
|
- **Ruby** >= 3.2 **Rails** >= 7.1
|
|
@@ -472,7 +519,7 @@ end
|
|
|
472
519
|
## About
|
|
473
520
|
|
|
474
521
|
Built by a Rails developer with 10+ years of production experience.<br>
|
|
475
|
-
|
|
522
|
+
1889 tests. 38 tools. 5 resource templates. 31 introspectors. Standalone or in-Gemfile.<br>
|
|
476
523
|
MIT licensed. [Contributions welcome.](CONTRIBUTING.md)
|
|
477
524
|
|
|
478
525
|
<br>
|
data/SECURITY.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
|---------|--------------------|
|
|
7
|
+
| 5.5.x | :white_check_mark: |
|
|
8
|
+
| 5.4.x | :white_check_mark: |
|
|
9
|
+
| 5.3.x | :white_check_mark: |
|
|
10
|
+
| 5.2.x | :white_check_mark: |
|
|
7
11
|
| 5.1.x | :white_check_mark: |
|
|
8
12
|
| 5.0.x | :white_check_mark: |
|
|
9
13
|
| 4.7.x | :white_check_mark: |
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAiContext
|
|
4
|
+
# Rails controller for serving MCP over Streamable HTTP.
|
|
5
|
+
# Alternative to the Rack middleware — integrates with Rails routing,
|
|
6
|
+
# authentication, and middleware stack.
|
|
7
|
+
#
|
|
8
|
+
# Mount in routes: mount RailsAiContext::Engine, at: "/mcp"
|
|
9
|
+
class McpController < ActionController::API
|
|
10
|
+
def handle
|
|
11
|
+
rack_response = self.class.mcp_transport.handle_request(request)
|
|
12
|
+
self.status = rack_response[0]
|
|
13
|
+
rack_response[1].each { |k, v| response.headers[k] = v }
|
|
14
|
+
self.response_body = rack_response[2]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Class-level memoization — transport persists across requests.
|
|
19
|
+
# Thread-safe: MCP::Server and transport are stateless for reads.
|
|
20
|
+
def mcp_transport
|
|
21
|
+
@transport_mutex.synchronize do
|
|
22
|
+
@mcp_transport ||= begin
|
|
23
|
+
server = RailsAiContext::Server.new(Rails.application, transport: :http).build
|
|
24
|
+
MCP::Server::Transports::StreamableHTTPTransport.new(server)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def reset_transport!
|
|
30
|
+
@transport_mutex.synchronize { @mcp_transport = nil }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def inherited(subclass)
|
|
36
|
+
super
|
|
37
|
+
subclass.instance_variable_set(:@transport_mutex, Mutex.new)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@transport_mutex = Mutex.new
|
|
42
|
+
end
|
|
43
|
+
end
|
data/config/routes.rb
ADDED
data/docs/GUIDE.md
CHANGED
|
@@ -47,7 +47,7 @@ rails ai:context
|
|
|
47
47
|
This creates:
|
|
48
48
|
1. `config/initializers/rails_ai_context.rb` — configuration file
|
|
49
49
|
2. `.rails-ai-context.yml` — standalone config (enables switching later)
|
|
50
|
-
3.
|
|
50
|
+
3. Per-tool MCP config files — auto-discovery for Claude Code, Cursor, Copilot, OpenCode, and Codex
|
|
51
51
|
4. Context files — tailored for each AI assistant
|
|
52
52
|
|
|
53
53
|
### Option B: Standalone (no Gemfile entry needed)
|
|
@@ -60,16 +60,16 @@ rails-ai-context init
|
|
|
60
60
|
|
|
61
61
|
This creates:
|
|
62
62
|
1. `.rails-ai-context.yml` — configuration file
|
|
63
|
-
2.
|
|
63
|
+
2. Per-tool MCP config files — auto-discovery (if MCP mode selected)
|
|
64
64
|
3. Context files — tailored for each AI assistant
|
|
65
65
|
|
|
66
66
|
No Gemfile entry, no initializer, no files in your project besides config and context.
|
|
67
67
|
|
|
68
68
|
### What the install generator does
|
|
69
69
|
|
|
70
|
-
1. Creates `.mcp.json
|
|
70
|
+
1. Creates per-tool MCP config files (`.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json`, `.codex/config.toml`)
|
|
71
71
|
2. Creates `config/initializers/rails_ai_context.rb` with commented defaults
|
|
72
|
-
3. Asks which AI tools you use (Claude, Cursor, Copilot, OpenCode)
|
|
72
|
+
3. Asks which AI tools you use (Claude, Cursor, Copilot, OpenCode, Codex)
|
|
73
73
|
4. Asks whether to enable MCP server (`tool_mode: :mcp`) or use CLI-only mode (`tool_mode: :cli`)
|
|
74
74
|
5. Adds `.ai-context.json` to `.gitignore` (JSON cache — markdown files should be committed)
|
|
75
75
|
6. Generates all context files
|
|
@@ -159,7 +159,7 @@ end
|
|
|
159
159
|
| `.cursor/rules/rails-project.mdc` | Project overview | `alwaysApply: true` — loaded in every conversation. |
|
|
160
160
|
| `.cursor/rules/rails-models.mdc` | Model reference | `globs: app/models/**/*.rb` — auto-attaches when editing models. |
|
|
161
161
|
| `.cursor/rules/rails-controllers.mdc` | Controller reference | `globs: app/controllers/**/*.rb` — auto-attaches when editing controllers. |
|
|
162
|
-
| `.cursor/rules/rails-mcp-tools.mdc` | MCP tool reference | `alwaysApply:
|
|
162
|
+
| `.cursor/rules/rails-mcp-tools.mdc` | MCP tool reference | `alwaysApply: false` — agent-requested when relevant. |
|
|
163
163
|
|
|
164
164
|
### GitHub Copilot (5 files)
|
|
165
165
|
|
|
@@ -193,6 +193,7 @@ Commit **all files except `.ai-context.json`** (which is gitignored). This gives
|
|
|
193
193
|
| `rails ai:context:full` | full | all | Generate all files in full mode |
|
|
194
194
|
| `rails ai:context:claude` | compact | Claude | CLAUDE.md + .claude/rules/ |
|
|
195
195
|
| `rails ai:context:opencode` | compact | OpenCode | AGENTS.md + per-directory AGENTS.md |
|
|
196
|
+
| `rails ai:context:codex` | compact | Codex | AGENTS.md + .codex/config.toml |
|
|
196
197
|
| `rails ai:context:cursor` | compact | Cursor | .cursor/rules/ |
|
|
197
198
|
| `rails ai:context:copilot` | compact | Copilot | copilot-instructions.md + .github/instructions/ |
|
|
198
199
|
| `rails ai:context:json` | — | JSON | .ai-context.json |
|
|
@@ -212,7 +213,7 @@ Commit **all files except `.ai-context.json`** (which is gitignored). This gives
|
|
|
212
213
|
|
|
213
214
|
| Command | Transport | Description |
|
|
214
215
|
|---------|-----------|-------------|
|
|
215
|
-
| `rails ai:serve` | stdio | Start MCP server
|
|
216
|
+
| `rails ai:serve` | stdio | Start MCP server. Auto-discovered by each AI tool via its own config file. |
|
|
216
217
|
| `rails ai:serve_http` | HTTP | Start MCP server at `http://127.0.0.1:6029/mcp`. For remote clients. |
|
|
217
218
|
|
|
218
219
|
### Utilities
|
|
@@ -228,7 +229,7 @@ Commit **all files except `.ai-context.json`** (which is gitignored). This gives
|
|
|
228
229
|
The gem ships a `rails-ai-context` executable that works **without adding the gem to your Gemfile**. Install globally with `gem install rails-ai-context`, then run from any Rails app directory.
|
|
229
230
|
|
|
230
231
|
```bash
|
|
231
|
-
rails-ai-context init # Interactive setup (creates .rails-ai-context.yml +
|
|
232
|
+
rails-ai-context init # Interactive setup (creates .rails-ai-context.yml + MCP configs)
|
|
232
233
|
rails-ai-context serve # Start MCP server (stdio)
|
|
233
234
|
rails-ai-context serve --transport http # Start MCP server (HTTP, port 6029)
|
|
234
235
|
rails-ai-context serve --transport http --port 8080 # Custom port
|
|
@@ -1010,6 +1011,17 @@ In addition to tools, the gem registers static MCP resources that AI clients can
|
|
|
1010
1011
|
| `rails://engines` | Mounted engines with paths and descriptions (JSON) |
|
|
1011
1012
|
| `rails://models/{name}` | Per-model details (resource template) |
|
|
1012
1013
|
|
|
1014
|
+
### Dynamic Resource Templates (VFS)
|
|
1015
|
+
|
|
1016
|
+
Live resources introspected fresh on every request — zero stale data:
|
|
1017
|
+
|
|
1018
|
+
| Resource Template | Description |
|
|
1019
|
+
|-------------------|-------------|
|
|
1020
|
+
| `rails-ai-context://controllers/{name}` | Controller details with actions, filters, strong params |
|
|
1021
|
+
| `rails-ai-context://controllers/{name}/{action}` | Specific action source code and applicable filters |
|
|
1022
|
+
| `rails-ai-context://views/{path}` | View template content (path traversal protected) |
|
|
1023
|
+
| `rails-ai-context://routes` | Live route map (optionally filter by controller) |
|
|
1024
|
+
|
|
1013
1025
|
---
|
|
1014
1026
|
|
|
1015
1027
|
## MCP Server Setup
|
|
@@ -1025,9 +1037,19 @@ curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=rails-ai-cont
|
|
|
1025
1037
|
|
|
1026
1038
|
### Auto-discovery (recommended)
|
|
1027
1039
|
|
|
1028
|
-
The install generator (or `rails-ai-context init`) creates
|
|
1040
|
+
The install generator (or `rails-ai-context init`) creates per-tool MCP config files based on your selected AI tools:
|
|
1041
|
+
|
|
1042
|
+
| AI Tool | Config File | Root Key | Format |
|
|
1043
|
+
|---------|------------|----------|--------|
|
|
1044
|
+
| Claude Code | `.mcp.json` | `mcpServers` | JSON |
|
|
1045
|
+
| Cursor | `.cursor/mcp.json` | `mcpServers` | JSON |
|
|
1046
|
+
| GitHub Copilot | `.vscode/mcp.json` | `servers` | JSON |
|
|
1047
|
+
| OpenCode | `opencode.json` | `mcp` | JSON |
|
|
1048
|
+
| Codex CLI | `.codex/config.toml` | `[mcp_servers]` | TOML |
|
|
1029
1049
|
|
|
1030
|
-
|
|
1050
|
+
Each file is merge-safe — only the `rails-ai-context` entry is managed, other servers are preserved.
|
|
1051
|
+
|
|
1052
|
+
**Example: `.mcp.json` (Claude Code)**
|
|
1031
1053
|
```json
|
|
1032
1054
|
{
|
|
1033
1055
|
"mcpServers": {
|
|
@@ -1039,19 +1061,20 @@ The install generator (or `rails-ai-context init`) creates `.mcp.json` in your p
|
|
|
1039
1061
|
}
|
|
1040
1062
|
```
|
|
1041
1063
|
|
|
1042
|
-
**
|
|
1043
|
-
```
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1064
|
+
**Example: `.codex/config.toml` (Codex CLI)**
|
|
1065
|
+
```toml
|
|
1066
|
+
[mcp_servers.rails-ai-context]
|
|
1067
|
+
command = "bundle"
|
|
1068
|
+
args = ["exec", "rails", "ai:serve"]
|
|
1069
|
+
|
|
1070
|
+
[mcp_servers.rails-ai-context.env]
|
|
1071
|
+
PATH = "/home/user/.rbenv/shims:/usr/local/bin:/usr/bin"
|
|
1072
|
+
GEM_HOME = "/home/user/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0"
|
|
1052
1073
|
```
|
|
1053
1074
|
|
|
1054
|
-
|
|
1075
|
+
> **Why the `[env]` section?** Codex CLI `env_clear()`s the process before spawning MCP servers, stripping Ruby version manager paths. The install generator snapshots your current Ruby environment (PATH, GEM\_HOME, GEM\_PATH, GEM\_ROOT, RUBY\_VERSION, BUNDLE\_PATH) so the MCP server can find gems regardless of version manager (rbenv, rvm, asdf, mise, chruby, or system Ruby).
|
|
1076
|
+
|
|
1077
|
+
Each AI tool auto-detects its own config file. No manual config needed — just open your project.
|
|
1055
1078
|
|
|
1056
1079
|
### Claude Code
|
|
1057
1080
|
|
|
@@ -1085,7 +1108,7 @@ Or for standalone: replace `"command": "bundle"` / `"args": ["exec", "rails", "a
|
|
|
1085
1108
|
|
|
1086
1109
|
### Cursor
|
|
1087
1110
|
|
|
1088
|
-
Auto-discovered via `.mcp.json`. Or add manually in **Cursor Settings > MCP**:
|
|
1111
|
+
Auto-discovered via `.cursor/mcp.json`. Or add manually in **Cursor Settings > MCP**:
|
|
1089
1112
|
|
|
1090
1113
|
```json
|
|
1091
1114
|
{
|
|
@@ -1126,6 +1149,17 @@ end
|
|
|
1126
1149
|
|
|
1127
1150
|
Both transports are **read-only** — they expose the same 38 tools and never modify your app.
|
|
1128
1151
|
|
|
1152
|
+
### Controller Transport (Alternative)
|
|
1153
|
+
|
|
1154
|
+
For tighter Rails integration (authentication, routing, middleware stack), mount the engine instead of using Rack middleware:
|
|
1155
|
+
|
|
1156
|
+
```ruby
|
|
1157
|
+
# config/routes.rb
|
|
1158
|
+
mount RailsAiContext::Engine, at: "/mcp"
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
This provides a native Rails controller (`RailsAiContext::McpController`) that delegates to the Streamable HTTP transport.
|
|
1162
|
+
|
|
1129
1163
|
---
|
|
1130
1164
|
|
|
1131
1165
|
## Configuration — All Options
|
|
@@ -1260,7 +1294,7 @@ end
|
|
|
1260
1294
|
| `custom_tools` | Array | `[]` | Additional MCP tool classes to register alongside built-in tools |
|
|
1261
1295
|
| `skip_tools` | Array | `[]` | Built-in tool names to exclude (e.g. `%w[rails_security_scan]`) |
|
|
1262
1296
|
| `tool_mode` | Symbol | `:mcp` | `:mcp` (MCP primary + CLI fallback) or `:cli` (CLI only, no MCP server needed) |
|
|
1263
|
-
| `ai_tools` | Array | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot opencode]`. Selected during install. |
|
|
1297
|
+
| `ai_tools` | Array | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot opencode codex]`. Selected during install. |
|
|
1264
1298
|
| `excluded_models` | Array | internal Rails models | Models to skip |
|
|
1265
1299
|
| `excluded_paths` | Array | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
1266
1300
|
| `sensitive_patterns` | Array | `.env`, `.key`, `.pem`, credentials | File patterns blocked from search and read tools |
|
|
@@ -1386,13 +1420,13 @@ config.introspectors = %i[schema models routes gems auth api]
|
|
|
1386
1420
|
|
|
1387
1421
|
**Context files loaded:**
|
|
1388
1422
|
- `CLAUDE.md` — read at conversation start
|
|
1389
|
-
- `.claude/rules/*.md` — auto-loaded alongside CLAUDE.md
|
|
1423
|
+
- `.claude/rules/*.md` — auto-loaded alongside CLAUDE.md (schema, models, and components rules use `paths:` frontmatter for conditional loading)
|
|
1390
1424
|
|
|
1391
1425
|
**MCP tools:** Available immediately via `.mcp.json`.
|
|
1392
1426
|
|
|
1393
1427
|
### Cursor
|
|
1394
1428
|
|
|
1395
|
-
**Auto-discovery:** Opens `.mcp.json` automatically. No setup needed.
|
|
1429
|
+
**Auto-discovery:** Opens `.cursor/mcp.json` automatically. No setup needed.
|
|
1396
1430
|
|
|
1397
1431
|
**Context files loaded:**
|
|
1398
1432
|
- `.cursor/rules/*.mdc` — loaded based on `alwaysApply` and `globs` settings
|
|
@@ -1400,13 +1434,13 @@ config.introspectors = %i[schema models routes gems auth api]
|
|
|
1400
1434
|
**MDC rule activation modes:**
|
|
1401
1435
|
| Mode | When it activates |
|
|
1402
1436
|
|------|-------------------|
|
|
1403
|
-
| `alwaysApply: true` | Every conversation (project overview
|
|
1437
|
+
| `alwaysApply: true` | Every conversation (project overview) |
|
|
1404
1438
|
| `globs: ["app/models/**/*.rb"]` | When editing files matching the glob pattern |
|
|
1405
|
-
| `alwaysApply: false` + `description` |
|
|
1439
|
+
| `alwaysApply: false` + `description` | Agent-requested — loaded when AI decides it's relevant (MCP tools rule) |
|
|
1406
1440
|
|
|
1407
1441
|
### OpenCode
|
|
1408
1442
|
|
|
1409
|
-
**
|
|
1443
|
+
**Auto-discovery:** `opencode.json` is auto-generated by the install generator. Or add manually:
|
|
1410
1444
|
|
|
1411
1445
|
```json
|
|
1412
1446
|
{
|
|
@@ -1440,13 +1474,15 @@ For standalone: use `"command": ["rails-ai-context", "serve"]` instead.
|
|
|
1440
1474
|
|
|
1441
1475
|
OpenCode uses **per-directory lazy-loading**: when the agent reads a file, it walks up the directory tree and auto-loads any `AGENTS.md` it finds. This is how split rules work — no globs or frontmatter needed.
|
|
1442
1476
|
|
|
1443
|
-
**MCP tools:** Available via `opencode.json` config above.
|
|
1477
|
+
**MCP tools:** Available via `opencode.json` (auto-generated or manual config above).
|
|
1444
1478
|
|
|
1445
1479
|
### GitHub Copilot
|
|
1446
1480
|
|
|
1481
|
+
**Auto-discovery:** `.vscode/mcp.json` is auto-generated by the install generator.
|
|
1482
|
+
|
|
1447
1483
|
**Context files loaded:**
|
|
1448
1484
|
- `.github/copilot-instructions.md` — repo-wide instructions
|
|
1449
|
-
- `.github/instructions/*.instructions.md` — path-specific, activated by `applyTo` glob
|
|
1485
|
+
- `.github/instructions/*.instructions.md` — path-specific, activated by `applyTo` glob (with `name:` and `description:` frontmatter)
|
|
1450
1486
|
|
|
1451
1487
|
**applyTo patterns:**
|
|
1452
1488
|
| Pattern | When it activates |
|
|
@@ -1455,6 +1491,17 @@ OpenCode uses **per-directory lazy-loading**: when the agent reads a file, it wa
|
|
|
1455
1491
|
| `app/controllers/**/*.rb` | Editing controller files |
|
|
1456
1492
|
| `**/*` | All files (MCP tool reference) |
|
|
1457
1493
|
|
|
1494
|
+
### Codex CLI
|
|
1495
|
+
|
|
1496
|
+
**Auto-discovery:** `.codex/config.toml` is auto-generated by the install generator, including an `[env]` subsection that snapshots your Ruby environment for sandbox compatibility.
|
|
1497
|
+
|
|
1498
|
+
**Context files loaded:**
|
|
1499
|
+
- `AGENTS.md` — project overview + MCP tool guide (shared with OpenCode)
|
|
1500
|
+
- `app/models/AGENTS.md` — model listing, auto-loaded when agent reads model files
|
|
1501
|
+
- `app/controllers/AGENTS.md` — controller listing, auto-loaded when agent reads controller files
|
|
1502
|
+
|
|
1503
|
+
**MCP tools:** Available via `.codex/config.toml`.
|
|
1504
|
+
|
|
1458
1505
|
---
|
|
1459
1506
|
|
|
1460
1507
|
## Stack Compatibility
|
|
@@ -1606,11 +1653,12 @@ Works in:
|
|
|
1606
1653
|
|
|
1607
1654
|
## Troubleshooting
|
|
1608
1655
|
|
|
1609
|
-
### MCP server not detected by
|
|
1656
|
+
### MCP server not detected by your AI tool
|
|
1610
1657
|
|
|
1611
|
-
1.
|
|
1612
|
-
2. Verify
|
|
1613
|
-
3.
|
|
1658
|
+
1. Run `rails ai:doctor` — it checks per-tool MCP config files
|
|
1659
|
+
2. Verify the correct config file exists for your tool (`.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json`, `.codex/config.toml`)
|
|
1660
|
+
3. Re-run install (`rails generate rails_ai_context:install` or `rails-ai-context init`) to regenerate configs
|
|
1661
|
+
4. Restart your AI tool
|
|
1614
1662
|
|
|
1615
1663
|
### Context files are too large
|
|
1616
1664
|
|