rails-ai-context 5.4.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 +50 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +5 -4
- data/SECURITY.md +4 -0
- data/app/controllers/rails_ai_context/mcp_controller.rb +1 -1
- data/docs/GUIDE.md +59 -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/mcp_config_generator.rb +293 -0
- 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 +23 -42
- 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 +69 -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/server.json +3 -3
- metadata +5 -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,56 @@ 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
|
+
|
|
8
58
|
## [5.4.0] — 2026-04-08
|
|
9
59
|
|
|
10
60
|
### Added — Phase 3: Dynamic VFS & Live Resource Architecture (Ground Truth Engine Blueprint #39)
|
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
|
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
<br>
|
|
21
22
|
[](https://github.com/crisnahine/rails-ai-context)
|
|
22
23
|
[](https://github.com/crisnahine/rails-ai-context)
|
|
23
|
-
[](https://github.com/crisnahine/rails-ai-context/actions)
|
|
24
25
|
[](LICENSE)
|
|
25
26
|
|
|
26
27
|
</div>
|
|
@@ -131,7 +132,7 @@ Compare what AI outputs with and without these tools wired in. The difference is
|
|
|
131
132
|
|
|
132
133
|
### MCP Server (stdio)
|
|
133
134
|
|
|
134
|
-
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.
|
|
135
136
|
|
|
136
137
|
```
|
|
137
138
|
rails ai:serve
|
|
@@ -438,7 +439,7 @@ cd your-rails-app
|
|
|
438
439
|
rails-ai-context init
|
|
439
440
|
```
|
|
440
441
|
|
|
441
|
-
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.
|
|
442
443
|
|
|
443
444
|
<br>
|
|
444
445
|
|
|
@@ -518,7 +519,7 @@ Events: `rails_ai_context.tools.call`, `rails_ai_context.resources.read`, and mo
|
|
|
518
519
|
## About
|
|
519
520
|
|
|
520
521
|
Built by a Rails developer with 10+ years of production experience.<br>
|
|
521
|
-
|
|
522
|
+
1889 tests. 38 tools. 5 resource templates. 31 introspectors. Standalone or in-Gemfile.<br>
|
|
522
523
|
MIT licensed. [Contributions welcome.](CONTRIBUTING.md)
|
|
523
524
|
|
|
524
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: |
|
|
@@ -18,7 +18,7 @@ module RailsAiContext
|
|
|
18
18
|
# Class-level memoization — transport persists across requests.
|
|
19
19
|
# Thread-safe: MCP::Server and transport are stateless for reads.
|
|
20
20
|
def mcp_transport
|
|
21
|
-
@
|
|
21
|
+
@transport_mutex.synchronize do
|
|
22
22
|
@mcp_transport ||= begin
|
|
23
23
|
server = RailsAiContext::Server.new(Rails.application, transport: :http).build
|
|
24
24
|
MCP::Server::Transports::StreamableHTTPTransport.new(server)
|
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
|
|
@@ -1036,9 +1037,19 @@ curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=rails-ai-cont
|
|
|
1036
1037
|
|
|
1037
1038
|
### Auto-discovery (recommended)
|
|
1038
1039
|
|
|
1039
|
-
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:
|
|
1040
1041
|
|
|
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 |
|
|
1049
|
+
|
|
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)**
|
|
1042
1053
|
```json
|
|
1043
1054
|
{
|
|
1044
1055
|
"mcpServers": {
|
|
@@ -1050,19 +1061,20 @@ The install generator (or `rails-ai-context init`) creates `.mcp.json` in your p
|
|
|
1050
1061
|
}
|
|
1051
1062
|
```
|
|
1052
1063
|
|
|
1053
|
-
**
|
|
1054
|
-
```
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}
|
|
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"
|
|
1063
1073
|
```
|
|
1064
1074
|
|
|
1065
|
-
|
|
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.
|
|
1066
1078
|
|
|
1067
1079
|
### Claude Code
|
|
1068
1080
|
|
|
@@ -1096,7 +1108,7 @@ Or for standalone: replace `"command": "bundle"` / `"args": ["exec", "rails", "a
|
|
|
1096
1108
|
|
|
1097
1109
|
### Cursor
|
|
1098
1110
|
|
|
1099
|
-
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**:
|
|
1100
1112
|
|
|
1101
1113
|
```json
|
|
1102
1114
|
{
|
|
@@ -1282,7 +1294,7 @@ end
|
|
|
1282
1294
|
| `custom_tools` | Array | `[]` | Additional MCP tool classes to register alongside built-in tools |
|
|
1283
1295
|
| `skip_tools` | Array | `[]` | Built-in tool names to exclude (e.g. `%w[rails_security_scan]`) |
|
|
1284
1296
|
| `tool_mode` | Symbol | `:mcp` | `:mcp` (MCP primary + CLI fallback) or `:cli` (CLI only, no MCP server needed) |
|
|
1285
|
-
| `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. |
|
|
1286
1298
|
| `excluded_models` | Array | internal Rails models | Models to skip |
|
|
1287
1299
|
| `excluded_paths` | Array | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
1288
1300
|
| `sensitive_patterns` | Array | `.env`, `.key`, `.pem`, credentials | File patterns blocked from search and read tools |
|
|
@@ -1408,13 +1420,13 @@ config.introspectors = %i[schema models routes gems auth api]
|
|
|
1408
1420
|
|
|
1409
1421
|
**Context files loaded:**
|
|
1410
1422
|
- `CLAUDE.md` — read at conversation start
|
|
1411
|
-
- `.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)
|
|
1412
1424
|
|
|
1413
1425
|
**MCP tools:** Available immediately via `.mcp.json`.
|
|
1414
1426
|
|
|
1415
1427
|
### Cursor
|
|
1416
1428
|
|
|
1417
|
-
**Auto-discovery:** Opens `.mcp.json` automatically. No setup needed.
|
|
1429
|
+
**Auto-discovery:** Opens `.cursor/mcp.json` automatically. No setup needed.
|
|
1418
1430
|
|
|
1419
1431
|
**Context files loaded:**
|
|
1420
1432
|
- `.cursor/rules/*.mdc` — loaded based on `alwaysApply` and `globs` settings
|
|
@@ -1422,13 +1434,13 @@ config.introspectors = %i[schema models routes gems auth api]
|
|
|
1422
1434
|
**MDC rule activation modes:**
|
|
1423
1435
|
| Mode | When it activates |
|
|
1424
1436
|
|------|-------------------|
|
|
1425
|
-
| `alwaysApply: true` | Every conversation (project overview
|
|
1437
|
+
| `alwaysApply: true` | Every conversation (project overview) |
|
|
1426
1438
|
| `globs: ["app/models/**/*.rb"]` | When editing files matching the glob pattern |
|
|
1427
|
-
| `alwaysApply: false` + `description` |
|
|
1439
|
+
| `alwaysApply: false` + `description` | Agent-requested — loaded when AI decides it's relevant (MCP tools rule) |
|
|
1428
1440
|
|
|
1429
1441
|
### OpenCode
|
|
1430
1442
|
|
|
1431
|
-
**
|
|
1443
|
+
**Auto-discovery:** `opencode.json` is auto-generated by the install generator. Or add manually:
|
|
1432
1444
|
|
|
1433
1445
|
```json
|
|
1434
1446
|
{
|
|
@@ -1462,13 +1474,15 @@ For standalone: use `"command": ["rails-ai-context", "serve"]` instead.
|
|
|
1462
1474
|
|
|
1463
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.
|
|
1464
1476
|
|
|
1465
|
-
**MCP tools:** Available via `opencode.json` config above.
|
|
1477
|
+
**MCP tools:** Available via `opencode.json` (auto-generated or manual config above).
|
|
1466
1478
|
|
|
1467
1479
|
### GitHub Copilot
|
|
1468
1480
|
|
|
1481
|
+
**Auto-discovery:** `.vscode/mcp.json` is auto-generated by the install generator.
|
|
1482
|
+
|
|
1469
1483
|
**Context files loaded:**
|
|
1470
1484
|
- `.github/copilot-instructions.md` — repo-wide instructions
|
|
1471
|
-
- `.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)
|
|
1472
1486
|
|
|
1473
1487
|
**applyTo patterns:**
|
|
1474
1488
|
| Pattern | When it activates |
|
|
@@ -1477,6 +1491,17 @@ OpenCode uses **per-directory lazy-loading**: when the agent reads a file, it wa
|
|
|
1477
1491
|
| `app/controllers/**/*.rb` | Editing controller files |
|
|
1478
1492
|
| `**/*` | All files (MCP tool reference) |
|
|
1479
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
|
+
|
|
1480
1505
|
---
|
|
1481
1506
|
|
|
1482
1507
|
## Stack Compatibility
|
|
@@ -1628,11 +1653,12 @@ Works in:
|
|
|
1628
1653
|
|
|
1629
1654
|
## Troubleshooting
|
|
1630
1655
|
|
|
1631
|
-
### MCP server not detected by
|
|
1656
|
+
### MCP server not detected by your AI tool
|
|
1632
1657
|
|
|
1633
|
-
1.
|
|
1634
|
-
2. Verify
|
|
1635
|
-
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
|
|
1636
1662
|
|
|
1637
1663
|
### Context files are too large
|
|
1638
1664
|
|
data/exe/rails-ai-context
CHANGED
|
@@ -167,8 +167,8 @@ class RailsAiContextCLI < Thor
|
|
|
167
167
|
# --- Write .rails-ai-context.yml ---
|
|
168
168
|
write_yaml_config(ai_tools, tool_mode)
|
|
169
169
|
|
|
170
|
-
# --- Write
|
|
171
|
-
|
|
170
|
+
# --- Write per-tool MCP config files (MCP mode only) ---
|
|
171
|
+
write_mcp_configs(ai_tools, tool_mode)
|
|
172
172
|
|
|
173
173
|
# --- Add .ai-context.json to .gitignore ---
|
|
174
174
|
add_to_gitignore
|
|
@@ -200,7 +200,8 @@ class RailsAiContextCLI < Thor
|
|
|
200
200
|
"1" => { key: :claude, name: "Claude Code", files: "CLAUDE.md + .claude/rules/" },
|
|
201
201
|
"2" => { key: :cursor, name: "Cursor", files: ".cursor/rules/" },
|
|
202
202
|
"3" => { key: :copilot, name: "GitHub Copilot", files: ".github/copilot-instructions.md + .github/instructions/" },
|
|
203
|
-
"4" => { key: :opencode, name: "OpenCode", files: "AGENTS.md" }
|
|
203
|
+
"4" => { key: :opencode, name: "OpenCode", files: "AGENTS.md" },
|
|
204
|
+
"5" => { key: :codex, name: "Codex CLI", files: "AGENTS.md + .codex/config.toml" }
|
|
204
205
|
}.freeze
|
|
205
206
|
|
|
206
207
|
def prompt_ai_tools
|
|
@@ -233,7 +234,7 @@ class RailsAiContextCLI < Thor
|
|
|
233
234
|
$stderr.puts ""
|
|
234
235
|
$stderr.puts "Do you also want MCP server support?"
|
|
235
236
|
$stderr.puts ""
|
|
236
|
-
$stderr.puts " 1. Yes — MCP server (generates
|
|
237
|
+
$stderr.puts " 1. Yes — MCP server (generates per-tool MCP config files)"
|
|
237
238
|
$stderr.puts " 2. No — CLI only (no server needed)"
|
|
238
239
|
$stderr.puts ""
|
|
239
240
|
$stderr.print "Enter number (default: 1): "
|
|
@@ -245,12 +246,15 @@ class RailsAiContextCLI < Thor
|
|
|
245
246
|
mode
|
|
246
247
|
end
|
|
247
248
|
|
|
248
|
-
# Files/dirs generated per AI tool format — used for cleanup on tool removal
|
|
249
|
+
# Files/dirs generated per AI tool format — used for cleanup on tool removal.
|
|
250
|
+
# MCP config files are NOT listed here — they use merge-safe removal via
|
|
251
|
+
# McpConfigGenerator.remove to preserve other servers' entries.
|
|
249
252
|
FORMAT_PATHS = {
|
|
250
253
|
claude: %w[CLAUDE.md .claude/rules],
|
|
251
254
|
cursor: %w[.cursor/rules],
|
|
252
255
|
copilot: %w[.github/copilot-instructions.md .github/instructions],
|
|
253
|
-
opencode: %w[AGENTS.md app/models/AGENTS.md app/controllers/AGENTS.md]
|
|
256
|
+
opencode: %w[AGENTS.md app/models/AGENTS.md app/controllers/AGENTS.md],
|
|
257
|
+
codex: %w[AGENTS.md app/models/AGENTS.md app/controllers/AGENTS.md]
|
|
254
258
|
}.freeze
|
|
255
259
|
|
|
256
260
|
def read_previous_ai_tools
|
|
@@ -297,10 +301,17 @@ class RailsAiContextCLI < Thor
|
|
|
297
301
|
return if to_remove.empty?
|
|
298
302
|
|
|
299
303
|
require "fileutils"
|
|
304
|
+
# Collect paths still needed by remaining tools to avoid deleting shared files
|
|
305
|
+
kept_paths = current.map(&:to_sym).flat_map { |f| FORMAT_PATHS[f] || [] }.to_set
|
|
306
|
+
|
|
300
307
|
to_remove.each do |fmt|
|
|
301
308
|
tool = AI_TOOL_OPTIONS.values.find { |t| t[:key] == fmt }
|
|
309
|
+
|
|
310
|
+
# Remove context files (skip if another selected tool still needs them)
|
|
302
311
|
paths = FORMAT_PATHS[fmt] || []
|
|
303
312
|
paths.each do |rel_path|
|
|
313
|
+
next if kept_paths.include?(rel_path)
|
|
314
|
+
|
|
304
315
|
full = File.join(Dir.pwd, rel_path)
|
|
305
316
|
if File.directory?(full)
|
|
306
317
|
FileUtils.rm_rf(full)
|
|
@@ -310,6 +321,11 @@ class RailsAiContextCLI < Thor
|
|
|
310
321
|
$stderr.puts " Removed #{rel_path}"
|
|
311
322
|
end
|
|
312
323
|
end
|
|
324
|
+
|
|
325
|
+
# Merge-safe MCP config cleanup — removes only the rails-ai-context entry
|
|
326
|
+
cleaned = RailsAiContext::McpConfigGenerator.remove(tools: [ fmt ], output_dir: Dir.pwd)
|
|
327
|
+
cleaned.each { |f| $stderr.puts " Removed MCP entry from #{File.basename(f)}" }
|
|
328
|
+
|
|
313
329
|
$stderr.puts " #{tool[:name]} files removed" if tool
|
|
314
330
|
end
|
|
315
331
|
end
|
|
@@ -339,26 +355,17 @@ class RailsAiContextCLI < Thor
|
|
|
339
355
|
$stderr.puts "Created .rails-ai-context.yml"
|
|
340
356
|
end
|
|
341
357
|
|
|
342
|
-
def
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
existing["mcpServers"]["rails-ai-context"] = server_entry
|
|
354
|
-
File.write(mcp_path, JSON.pretty_generate(existing) + "\n")
|
|
355
|
-
$stderr.puts "Updated rails-ai-context in .mcp.json"
|
|
356
|
-
end
|
|
357
|
-
else
|
|
358
|
-
content = JSON.pretty_generate({ mcpServers: { "rails-ai-context" => server_entry } }) + "\n"
|
|
359
|
-
File.write(mcp_path, content)
|
|
360
|
-
$stderr.puts "Created .mcp.json (auto-discovered by Claude Code, Cursor, etc.)"
|
|
361
|
-
end
|
|
358
|
+
def write_mcp_configs(ai_tools, tool_mode)
|
|
359
|
+
require_relative "../lib/rails_ai_context/mcp_config_generator"
|
|
360
|
+
generator = ::RailsAiContext::McpConfigGenerator.new(
|
|
361
|
+
tools: ai_tools,
|
|
362
|
+
output_dir: Dir.pwd,
|
|
363
|
+
standalone: true,
|
|
364
|
+
tool_mode: tool_mode
|
|
365
|
+
)
|
|
366
|
+
result = generator.call
|
|
367
|
+
result[:written].each { |f| $stderr.puts " Created/Updated #{f}" }
|
|
368
|
+
result[:skipped].each { |f| $stderr.puts " #{f} unchanged — skipped" }
|
|
362
369
|
end
|
|
363
370
|
|
|
364
371
|
def show_standalone_instructions(ai_tools, tool_mode)
|
|
@@ -375,7 +382,7 @@ class RailsAiContextCLI < Thor
|
|
|
375
382
|
$stderr.puts ""
|
|
376
383
|
$stderr.puts "Commands:"
|
|
377
384
|
$stderr.puts " rails-ai-context context # Regenerate context files"
|
|
378
|
-
$stderr.puts " rails-ai-context tool NAME # Run any of the
|
|
385
|
+
$stderr.puts " rails-ai-context tool NAME # Run any of the #{tool_count_str} tools"
|
|
379
386
|
if tool_mode == :mcp
|
|
380
387
|
$stderr.puts " rails-ai-context serve # Start MCP server"
|
|
381
388
|
end
|
|
@@ -383,8 +390,8 @@ class RailsAiContextCLI < Thor
|
|
|
383
390
|
$stderr.puts ""
|
|
384
391
|
if tool_mode == :mcp
|
|
385
392
|
$stderr.puts "MCP auto-discovery:"
|
|
386
|
-
$stderr.puts "
|
|
387
|
-
$stderr.puts " No manual config needed
|
|
393
|
+
$stderr.puts " Each AI tool gets its own config file — auto-detected on project open."
|
|
394
|
+
$stderr.puts " No manual config needed."
|
|
388
395
|
else
|
|
389
396
|
$stderr.puts "CLI tools:"
|
|
390
397
|
$stderr.puts " AI agents can run `rails-ai-context tool schema table=users` directly."
|
|
@@ -394,6 +401,14 @@ class RailsAiContextCLI < Thor
|
|
|
394
401
|
$stderr.puts ""
|
|
395
402
|
end
|
|
396
403
|
|
|
404
|
+
def tool_count_str
|
|
405
|
+
if defined?(::RailsAiContext::Server)
|
|
406
|
+
::RailsAiContext::Server.builtin_tools.size.to_s
|
|
407
|
+
else
|
|
408
|
+
"38"
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
|
|
397
412
|
def print_context_result(result)
|
|
398
413
|
(result[:written] || []).each { |f| $stderr.puts " Written: #{f}" }
|
|
399
414
|
(result[:skipped] || []).each { |f| $stderr.puts " Skipped: #{f} (unchanged)" }
|