rails-ai-context 2.0.2 → 2.0.3
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 +7 -0
- data/README.md +139 -327
- data/docs/GUIDE.md +3 -2
- data/lib/rails_ai_context/tools/search_code.rb +109 -22
- data/lib/rails_ai_context/version.rb +1 -1
- data/server.json +2 -2
- 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: 582aebf4849cdb8617b33dff88f3822009b8960e1334bbd1aa2eb6a3f6a03350
|
|
4
|
+
data.tar.gz: 03c8eedbf4989f07a75f878fe86380b809dd4ae1e2afd0020836a848da99b5c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a2abfe4dc7c9c123dacd427354789810197c478fab741ac88e9aa0d8c95fcccc5cac2b5005f01615cf678f7229362d3e4ea5838d7c76d2210b28a8531edd9da
|
|
7
|
+
data.tar.gz: 3f04bb928f49325badb6a956a54c1adb9dec73ac2f73b9d7f81831f5da5931ac0ef1f4494a5c71780cdabcfa159c38ff11a4bd6f7fbcbb7ac79272aaf5de4e3b
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ 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
|
+
## [2.0.3] - 2026-03-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Trace mode 100%** — `match_type:"trace"` now shows 7 sections: definition with class/module context, source code, internal calls, sibling methods (same file), app callers with route chain hints, and test coverage (separated from app code). Zero follow-up calls needed.
|
|
13
|
+
- **README rewrite** — neuro marketing techniques: loss aversion hook, measured token savings table, trace output inline, architecture diagram. 456→261 lines.
|
|
14
|
+
|
|
8
15
|
## [2.0.2] - 2026-03-25
|
|
9
16
|
|
|
10
17
|
### Added
|
data/README.md
CHANGED
|
@@ -1,273 +1,182 @@
|
|
|
1
1
|
# rails-ai-context
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
### Your AI is guessing. This gem makes it know.
|
|
4
4
|
|
|
5
5
|
[](https://rubygems.org/gems/rails-ai-context)
|
|
6
6
|
[](https://registry.modelcontextprotocol.io)
|
|
7
7
|
[](https://github.com/crisnahine/rails-ai-context/actions)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**Works with:** Claude Code • Cursor • GitHub Copilot • Windsurf • OpenCode
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## The Problem
|
|
15
|
-
|
|
16
|
-
AI agents working on Rails apps operate blind. They read files one at a time but never see the full picture — how your schema connects to your models, which callbacks fire on save, what filters apply to a controller action, which Stimulus controllers exist, or what your UI conventions are.
|
|
17
|
-
|
|
18
|
-
The result: **guess-and-check coding.** The agent writes code, it breaks, it reads more files, fixes it, breaks again. Each iteration wastes tokens and erodes trust.
|
|
19
|
-
|
|
20
|
-
## The Solution
|
|
21
|
-
|
|
22
|
-
**rails-ai-context** gives your AI agent what a senior Rails developer has naturally: a structured mental model of the entire application.
|
|
12
|
+
> Built by a Rails developer with 10 years of production experience. Yes, AI helped write this gem — the same way AI helps me ship features at work. I designed the architecture, made every decision, reviewed every line, and wrote 575 tests. The gem exists because I understand Rails deeply enough to know what AI agents get wrong and what context they need to get it right.
|
|
23
13
|
|
|
24
14
|
```bash
|
|
25
|
-
|
|
15
|
+
gem "rails-ai-context", group: :development
|
|
26
16
|
rails generate rails_ai_context:install
|
|
27
|
-
rails ai:context
|
|
28
17
|
```
|
|
29
18
|
|
|
30
|
-
|
|
19
|
+
That's it. Your AI now has 25 live MCP tools that understand your entire Rails app. Zero config.
|
|
31
20
|
|
|
32
|
-
|
|
21
|
+
---
|
|
33
22
|
|
|
34
|
-
|
|
23
|
+
## What AI gets wrong without this
|
|
35
24
|
|
|
36
|
-
|
|
25
|
+
Right now, your AI agent:
|
|
37
26
|
|
|
38
|
-
|
|
27
|
+
- **Reads all 2,000 lines of schema.rb** to find one column type
|
|
28
|
+
- **Misses encrypted columns** — doesn't know `gemini_api_key` is encrypted
|
|
29
|
+
- **Shows 25 Devise methods** as if they're your code
|
|
30
|
+
- **Doesn't see inherited filters** — misses `authenticate_user!` from ApplicationController
|
|
31
|
+
- **Uses underscores in Stimulus HTML** — `data-cook_status` instead of `data-cook-status`
|
|
32
|
+
- **Breaks Turbo Stream wiring** — broadcasts to channels nobody subscribes to
|
|
33
|
+
- **Permits wrong params** — doesn't cross-check against your schema
|
|
34
|
+
- **Guesses your UI patterns** — invents new button styles instead of matching yours
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
**Every wrong guess = a wasted iteration.** You fix it, re-run, it breaks something else.
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
---
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
## What AI knows with this
|
|
45
41
|
|
|
46
|
-
|
|
42
|
+
One call. Full picture.
|
|
47
43
|
|
|
48
44
|
```
|
|
49
|
-
|
|
50
|
-
Agent: rails_get_model_details(model:"Cook") → associations, validations, scopes, callbacks, concern methods
|
|
51
|
-
Agent: rails_get_controllers(controller:"cooks", action:"create") → source code + applicable filters + strong params body
|
|
52
|
-
Agent: rails_validate(files:["app/models/cook.rb"], level:"rails") → catches column/route/partial errors before execution
|
|
45
|
+
rails_search_code(pattern: "can_cook?", match_type: "trace")
|
|
53
46
|
```
|
|
54
47
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
```
|
|
49
|
+
# Trace: can_cook?
|
|
50
|
+
|
|
51
|
+
## Definition
|
|
52
|
+
app/models/concerns/plan_limitable.rb:8
|
|
53
|
+
def can_cook?
|
|
54
|
+
p = effective_plan
|
|
55
|
+
return true if p.unlimited_cooks?
|
|
56
|
+
(cooks_this_month || 0) < p.cooks_per_month
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
## Calls internally
|
|
60
|
+
- unlimited_cooks?
|
|
61
|
+
|
|
62
|
+
## Called from (8 sites)
|
|
63
|
+
### app/controllers/cooks_controller.rb (Controller)
|
|
64
|
+
24: unless current_user.can_cook?
|
|
65
|
+
### app/views/cooks/new.html.erb (View)
|
|
66
|
+
7: <% unless current_user.can_cook? %>
|
|
67
|
+
### test/models/concerns/plan_limitable_test.rb (Test)
|
|
68
|
+
24: assert @user.can_cook?
|
|
69
|
+
29: assert_not @user.can_cook?
|
|
70
|
+
```
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
Definition + source code + every caller grouped by type + what it calls internally. **One tool call replaces 6 file reads.**
|
|
68
73
|
|
|
69
74
|
---
|
|
70
75
|
|
|
71
|
-
##
|
|
76
|
+
## Measured token savings
|
|
72
77
|
|
|
73
|
-
|
|
74
|
-
|-------|--------|---------------|
|
|
75
|
-
| **rails-ai-context (full)** | **28,834** | 25 MCP tools + generated docs + split rules |
|
|
76
|
-
| rails-ai-context CLAUDE.md only | 33,106 | Generated docs + rules, no MCP tools |
|
|
77
|
-
| Normal Claude `/init` | 40,700 | Generic CLAUDE.md only |
|
|
78
|
-
| No rails-ai-context | 45,477 | Nothing — discovers everything from scratch |
|
|
78
|
+
Tested on a real Rails 8 app (5 models, 19 controllers, 95 routes):
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```
|
|
80
|
+
| Task | Without gem | With gem | Saved |
|
|
81
|
+
|------|-------------|----------|-------|
|
|
82
|
+
| Trace a method across the codebase | ~9,080 tokens (read 5 files) | ~198 tokens (1 MCP call) | **98%** |
|
|
83
|
+
| Understand a feature (schema + model + controller) | ~5,200 tokens (read 3 files) | ~1,500 tokens (2 MCP calls) | **71%** |
|
|
84
|
+
| Check all table columns | ~2,573 tokens (read schema.rb) | ~908 tokens (1 MCP call) | **65%** |
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
"Without" = AI reads files it would realistically need. "With" = MCP tools return only what's relevant.
|
|
88
87
|
|
|
89
|
-
>
|
|
88
|
+
> Savings scale with app size. A 50-model app reads more files per task — MCP calls stay the same size.
|
|
90
89
|
|
|
91
|
-
But
|
|
90
|
+
But tokens are the side effect. The real value:
|
|
92
91
|
|
|
93
|
-
- **
|
|
94
|
-
- **Cross-file
|
|
95
|
-
- **
|
|
96
|
-
- **No stale context** — live reload invalidates caches when files change mid-session
|
|
92
|
+
- **First attempt is correct** — AI understands associations, callbacks, and constraints before writing code
|
|
93
|
+
- **Cross-file validation** — catches wrong columns, missing partials, broken routes in one call
|
|
94
|
+
- **Matches your patterns** — your button classes, your test style, your flash messages
|
|
97
95
|
|
|
98
96
|
---
|
|
99
97
|
|
|
100
98
|
## 25 Live MCP Tools
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| Tool |
|
|
105
|
-
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `rails_get_service_pattern` | Service objects — interface, dependencies, side effects, error handling, calling convention |
|
|
126
|
-
| `rails_get_job_pattern` | Background jobs — queue, retries, guard clauses, service calls, Turbo broadcasts, schedules |
|
|
100
|
+
Every tool is **read-only** and returns structured, token-efficient data. Start with `detail:"summary"`, drill into specifics.
|
|
101
|
+
|
|
102
|
+
| Tool | One-liner |
|
|
103
|
+
|------|-----------|
|
|
104
|
+
| `rails_search_code` | **Trace mode**: definition + class context + source + internal calls + sibling methods + callers with route chain + test coverage. Also: `"definition"`, `"call"`, `"class"` filters, smart pagination |
|
|
105
|
+
| `rails_get_context` | **Composite**: schema + model + controller + routes + views in one call |
|
|
106
|
+
| `rails_analyze_feature` | **Full-stack**: everything about a feature — models, controllers, routes, services, jobs, views, Stimulus, tests |
|
|
107
|
+
| `rails_validate` | **Syntax + semantic + security** in one call. Catches wrong columns, missing partials, broken routes, Brakeman vulnerabilities |
|
|
108
|
+
| `rails_get_controllers` | Action source code + inherited filters + render map + side effects + private methods inline |
|
|
109
|
+
| `rails_get_schema` | Columns with `[indexed]`, `[unique]`, `[encrypted]`, `[default: value]` hints + model name inline |
|
|
110
|
+
| `rails_get_model_details` | Associations, validations, scopes with lambda body, enum backing types, macros, delegations, constants |
|
|
111
|
+
| `rails_get_routes` | Code-ready helpers (`cook_path(@record)`), controller filters inline, required params |
|
|
112
|
+
| `rails_get_view` | Templates with ivars, Turbo wiring, Stimulus refs, partial locals — pipe-separated, scannable |
|
|
113
|
+
| `rails_get_stimulus` | Copy-paste HTML data-attributes (dashes, not underscores) + reverse view lookup |
|
|
114
|
+
| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |
|
|
115
|
+
| `rails_get_test_info` | Fixture contents with relationships + test template matching your app's patterns |
|
|
116
|
+
| `rails_get_conventions` | Your app's actual patterns — auth checks, flash messages, create action template, test patterns |
|
|
117
|
+
| `rails_get_turbo_map` | Broadcast → subscription wiring with mismatch warnings |
|
|
118
|
+
| `rails_get_partial_interface` | Partial locals contract — what to pass, what methods are called on each local |
|
|
119
|
+
| `rails_get_concern` | Public methods, signatures, which models include it |
|
|
120
|
+
| `rails_get_callbacks` | Callbacks in Rails execution order with source code |
|
|
121
|
+
| `rails_get_service_pattern` | Interface, dependencies, side effects, error handling, who calls it |
|
|
122
|
+
| `rails_get_job_pattern` | Queue, retries, guard clauses, Turbo broadcasts, schedules |
|
|
127
123
|
| `rails_get_env` | Environment variables, credentials keys (not values), external service dependencies |
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
124
|
+
| `rails_get_helper_methods` | App + framework helpers with view usage cross-references |
|
|
125
|
+
| `rails_get_config` | Database adapter, auth framework, assets stack, Action Cable, middleware |
|
|
126
|
+
| `rails_get_gems` | Notable gems with versions, categories, and config file locations |
|
|
127
|
+
| `rails_get_edit_context` | Method-aware code extraction with class/method context header |
|
|
128
|
+
| `rails_security_scan` | Brakeman static analysis — SQL injection, XSS, mass assignment |
|
|
131
129
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Schema, routes, models, and controllers tools support a `detail` parameter — critical for large apps:
|
|
135
|
-
|
|
136
|
-
| Level | Returns | Default limit |
|
|
137
|
-
|-------|---------|---------------|
|
|
138
|
-
| `summary` | Names + counts | 50 |
|
|
139
|
-
| `standard` | Names + key details *(default)* | 25 |
|
|
140
|
-
| `full` | Everything (indexes, FKs, constraints) | 10 |
|
|
141
|
-
|
|
142
|
-
```ruby
|
|
143
|
-
rails_get_schema(detail: "summary") # → all tables with column counts
|
|
144
|
-
rails_get_schema(table: "users") # → full detail for one table
|
|
145
|
-
rails_get_routes(controller: "users") # → routes for one controller
|
|
146
|
-
rails_get_model_details(model: "User") # → associations, validations, scopes
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
A safety net (`max_tool_response_chars`, default 200K) truncates oversized responses with hints to use filters.
|
|
130
|
+
> **[Full parameter documentation →](docs/GUIDE.md)**
|
|
150
131
|
|
|
151
132
|
---
|
|
152
133
|
|
|
153
|
-
##
|
|
154
|
-
|
|
155
|
-
`rails ai:context` generates context files tailored to each AI assistant:
|
|
134
|
+
## How It Works
|
|
156
135
|
|
|
157
136
|
```
|
|
158
|
-
|
|
159
|
-
│
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
│
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
│
|
|
166
|
-
│
|
|
167
|
-
|
|
168
|
-
│
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
│
|
|
172
|
-
│
|
|
173
|
-
│
|
|
174
|
-
│
|
|
175
|
-
│
|
|
176
|
-
|
|
177
|
-
├── ⚡ OpenCode
|
|
178
|
-
│ ├── AGENTS.md native OpenCode context
|
|
179
|
-
│ ├── app/models/AGENTS.md auto-loaded when editing models
|
|
180
|
-
│ └── app/controllers/AGENTS.md auto-loaded when editing controllers
|
|
181
|
-
│
|
|
182
|
-
├── 🔵 Windsurf
|
|
183
|
-
│ ├── .windsurfrules ≤5,800 chars (6K limit)
|
|
184
|
-
│ └── .windsurf/rules/
|
|
185
|
-
│ ├── rails-context.md project overview
|
|
186
|
-
│ ├── rails-ui-patterns.md CSS component patterns
|
|
187
|
-
│ └── rails-mcp-tools.md tool reference
|
|
188
|
-
│
|
|
189
|
-
├── 🟠 GitHub Copilot
|
|
190
|
-
│ ├── .github/copilot-instructions.md ≤500 lines (compact)
|
|
191
|
-
│ └── .github/instructions/
|
|
192
|
-
│ ├── rails-context.instructions.md applyTo: **/*
|
|
193
|
-
│ ├── rails-models.instructions.md applyTo: app/models/**
|
|
194
|
-
│ ├── rails-controllers.instructions.md applyTo: app/controllers/**
|
|
195
|
-
│ ├── rails-ui-patterns.instructions.md applyTo: app/views/**
|
|
196
|
-
│ └── rails-mcp-tools.instructions.md applyTo: **/*
|
|
197
|
-
│
|
|
198
|
-
├── 📋 .ai-context.json full JSON (programmatic)
|
|
199
|
-
└── .mcp.json MCP auto-discovery
|
|
137
|
+
┌─────────────────────────────────────────────────────────┐
|
|
138
|
+
│ Your Rails App │
|
|
139
|
+
│ models + schema + routes + controllers + views + jobs │
|
|
140
|
+
└────────────────────────┬────────────────────────────────┘
|
|
141
|
+
│ introspects
|
|
142
|
+
▼
|
|
143
|
+
┌─────────────────────────────────────────────────────────┐
|
|
144
|
+
│ rails-ai-context (29 introspectors) │
|
|
145
|
+
│ Parses everything. Caches results. Zero config. │
|
|
146
|
+
└────────┬─────────────────────────────┬──────────────────┘
|
|
147
|
+
│ │
|
|
148
|
+
▼ ▼
|
|
149
|
+
┌────────────────────┐ ┌───────────────────────────────┐
|
|
150
|
+
│ Static Files │ │ Live MCP Server (25 tools) │
|
|
151
|
+
│ CLAUDE.md │ │ Real-time queries on demand │
|
|
152
|
+
│ .cursor/rules/ │ │ Schema, models, routes, etc. │
|
|
153
|
+
│ .github/instr... │ │ Trace, validate, analyze │
|
|
154
|
+
│ .windsurfrules │ │ Auto-discovered via .mcp.json │
|
|
155
|
+
└────────────────────┘ └───────────────────────────────┘
|
|
200
156
|
```
|
|
201
157
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## What Your AI Learns
|
|
207
|
-
|
|
208
|
-
| Category | What's introspected |
|
|
209
|
-
|----------|-------------------|
|
|
210
|
-
| **Database** | Every table, column, index, foreign key, and migration |
|
|
211
|
-
| **Models** | Associations, validations, scopes, enums, callbacks, concerns, macros |
|
|
212
|
-
| **Routing** | Every route with HTTP verbs, paths, controller actions, API namespaces |
|
|
213
|
-
| **Controllers** | Actions, filters, strong params, concerns, API controllers |
|
|
214
|
-
| **Views** | Layouts, templates, partials, helpers, template engines, view components |
|
|
215
|
-
| **Frontend** | Stimulus controllers (targets, values, actions, outlets), Turbo Frames/Streams |
|
|
216
|
-
| **Background** | ActiveJob classes, mailers, Action Cable channels |
|
|
217
|
-
| **Gems** | 70+ notable gems categorized (Devise = auth, Sidekiq = jobs, Pundit = authorization) |
|
|
218
|
-
| **Auth** | Devise modules, Pundit policies, CanCanCan, has_secure_password, CORS, CSP |
|
|
219
|
-
| **API** | Serializers, GraphQL, versioning, rate limiting, API-only mode |
|
|
220
|
-
| **Testing** | Framework, factories/fixtures, CI config, coverage, system tests |
|
|
221
|
-
| **Config** | Cache store, session store, middleware, initializers, timezone |
|
|
222
|
-
| **DevOps** | Puma, Procfile, Docker, deployment tools, asset pipeline |
|
|
223
|
-
| **Architecture** | Service objects, STI, polymorphism, state machines, multi-tenancy, engines |
|
|
224
|
-
|
|
225
|
-
29 introspectors total. The `:full` preset runs 28 by default; use `:standard` for 13 core only (`database_stats` is opt-in, PostgreSQL only).
|
|
158
|
+
The install generator asks which AI tools you use and only generates files for those.
|
|
226
159
|
|
|
227
160
|
---
|
|
228
161
|
|
|
229
|
-
##
|
|
230
|
-
|
|
231
|
-
The install generator creates `.mcp.json` — **Claude Code and Cursor auto-detect it**. No manual config needed.
|
|
162
|
+
## Install
|
|
232
163
|
|
|
233
|
-
|
|
164
|
+
```bash
|
|
165
|
+
# Add to Gemfile
|
|
166
|
+
gem "rails-ai-context", group: :development
|
|
234
167
|
|
|
235
|
-
|
|
168
|
+
# Install (picks your AI tools, generates context)
|
|
169
|
+
rails generate rails_ai_context:install
|
|
236
170
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
|
|
241
|
-
|
|
242
|
-
```json
|
|
243
|
-
{
|
|
244
|
-
"mcpServers": {
|
|
245
|
-
"rails-ai-context": {
|
|
246
|
-
"command": "bundle",
|
|
247
|
-
"args": ["exec", "rails", "ai:serve"],
|
|
248
|
-
"cwd": "/path/to/your/rails/app"
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
171
|
+
# Or generate context directly
|
|
172
|
+
rails ai:context
|
|
252
173
|
```
|
|
253
|
-
</details>
|
|
254
|
-
|
|
255
|
-
<details>
|
|
256
|
-
<summary><strong>HTTP transport (for remote clients)</strong></summary>
|
|
257
174
|
|
|
258
|
-
|
|
259
|
-
rails ai:serve_http # Starts at http://127.0.0.1:6029/mcp
|
|
260
|
-
```
|
|
175
|
+
Both commands ask which AI tools you use (Claude, Cursor, Copilot, Windsurf, OpenCode) and only generate what you need.
|
|
261
176
|
|
|
262
|
-
|
|
177
|
+
MCP auto-discovery: `.mcp.json` is detected automatically by Claude Code and Cursor. No manual config.
|
|
263
178
|
|
|
264
|
-
|
|
265
|
-
RailsAiContext.configure do |config|
|
|
266
|
-
config.auto_mount = true
|
|
267
|
-
config.http_path = "/mcp"
|
|
268
|
-
end
|
|
269
|
-
```
|
|
270
|
-
</details>
|
|
179
|
+
> **[Full Guide →](docs/GUIDE.md)** — every command, parameter, and configuration option.
|
|
271
180
|
|
|
272
181
|
---
|
|
273
182
|
|
|
@@ -276,31 +185,17 @@ end
|
|
|
276
185
|
```ruby
|
|
277
186
|
# config/initializers/rails_ai_context.rb
|
|
278
187
|
RailsAiContext.configure do |config|
|
|
279
|
-
#
|
|
280
|
-
config.
|
|
281
|
-
|
|
282
|
-
# Cherry-pick on top of a preset
|
|
283
|
-
# config.introspectors += %i[views turbo auth api]
|
|
188
|
+
# Which AI tools to generate context for (selected during install)
|
|
189
|
+
# config.ai_tools = %i[claude cursor]
|
|
284
190
|
|
|
285
|
-
#
|
|
286
|
-
# config.
|
|
191
|
+
# Presets: :full (28 introspectors, default) or :standard (13 core)
|
|
192
|
+
# config.preset = :full
|
|
287
193
|
|
|
288
194
|
# Exclude models from introspection
|
|
289
|
-
config.excluded_models += %w[AdminUser
|
|
290
|
-
|
|
291
|
-
# Exclude paths from code search
|
|
292
|
-
config.excluded_paths += %w[vendor/bundle]
|
|
293
|
-
|
|
294
|
-
# Cache TTL for MCP tool responses (seconds)
|
|
295
|
-
config.cache_ttl = 60
|
|
195
|
+
# config.excluded_models += %w[AdminUser]
|
|
296
196
|
|
|
297
|
-
#
|
|
298
|
-
#
|
|
299
|
-
# config.live_reload = :auto
|
|
300
|
-
|
|
301
|
-
# Skip root files (CLAUDE.md, .windsurfrules, etc.) — only generate split rules
|
|
302
|
-
# Lets you manage root files yourself while still getting .claude/rules/, .cursor/rules/, etc.
|
|
303
|
-
# config.generate_root_files = false
|
|
197
|
+
# Skip specific MCP tools
|
|
198
|
+
# config.skip_tools = %w[rails_security_scan]
|
|
304
199
|
end
|
|
305
200
|
```
|
|
306
201
|
|
|
@@ -316,122 +211,39 @@ end
|
|
|
316
211
|
| `context_mode` | `:compact` | `:compact` (≤150 lines) or `:full` (dump everything) |
|
|
317
212
|
| `claude_max_lines` | `150` | Max lines for CLAUDE.md in compact mode |
|
|
318
213
|
| `generate_root_files` | `true` | Generate root files (CLAUDE.md, etc.) — set `false` for split rules only |
|
|
319
|
-
| `
|
|
214
|
+
| `ai_tools` | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot windsurf opencode]` |
|
|
320
215
|
| **MCP Server** | | |
|
|
321
|
-
| `server_name` | `"rails-ai-context"` | MCP server name |
|
|
322
|
-
| `server_version` | gem version | MCP server version |
|
|
323
|
-
| `auto_mount` | `false` | Auto-mount HTTP MCP endpoint |
|
|
324
|
-
| `http_path` | `"/mcp"` | HTTP endpoint path |
|
|
325
|
-
| `http_port` | `6029` | HTTP server port |
|
|
326
|
-
| `http_bind` | `"127.0.0.1"` | HTTP server bind address |
|
|
327
216
|
| `cache_ttl` | `60` | Cache TTL in seconds |
|
|
328
217
|
| `max_tool_response_chars` | `200_000` | Safety cap for MCP tool responses |
|
|
329
218
|
| `live_reload` | `:auto` | `:auto`, `true`, or `false` — MCP live reload |
|
|
330
|
-
| `
|
|
331
|
-
| **Filtering & Exclusions** | | |
|
|
332
|
-
| `excluded_models` | internal Rails models | Models to skip during introspection |
|
|
333
|
-
| `excluded_paths` | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
334
|
-
| `sensitive_patterns` | `.env .env.* config/master.key config/credentials.yml.enc config/credentials/*.yml.enc *.pem *.key` | File patterns blocked from search and read tools |
|
|
335
|
-
| `excluded_controllers` | `DeviseController` etc. | Controller classes hidden from listings |
|
|
336
|
-
| `excluded_route_prefixes` | `action_mailbox/ active_storage/ rails/` etc. | Route controller prefixes hidden with app_only |
|
|
337
|
-
| `excluded_concerns` | Rails/Devise/framework patterns | Regex patterns for concerns to hide |
|
|
338
|
-
| `excluded_filters` | `verify_authenticity_token` etc. | Framework filter names hidden from controller output |
|
|
339
|
-
| `excluded_middleware` | standard Rack/Rails middleware | Default middleware hidden from config output |
|
|
219
|
+
| `auto_mount` | `false` | Auto-mount HTTP MCP endpoint |
|
|
340
220
|
| **File Size Limits** | | |
|
|
341
|
-
| `max_file_size` | `5_000_000` | Per-file read limit
|
|
342
|
-
| `max_test_file_size` | `1_000_000` | Test file read limit (bytes) |
|
|
343
|
-
| `max_schema_file_size` | `10_000_000` | schema.rb / structure.sql parse limit (bytes) |
|
|
344
|
-
| `max_view_total_size` | `10_000_000` | Total aggregated view content for UI patterns (bytes) |
|
|
345
|
-
| `max_view_file_size` | `1_000_000` | Per-view file during aggregation (bytes) |
|
|
221
|
+
| `max_file_size` | `5_000_000` | Per-file read limit (bytes) |
|
|
346
222
|
| `max_search_results` | `200` | Max search results per call |
|
|
347
223
|
| `max_validate_files` | `50` | Max files per validate call |
|
|
348
|
-
| **Search & Discovery** | | |
|
|
349
|
-
| `search_extensions` | `rb js erb yml yaml json ts tsx vue svelte haml slim` | File extensions for Ruby fallback search |
|
|
350
|
-
| `concern_paths` | `app/models/concerns app/controllers/concerns` | Where to look for concern source files |
|
|
351
224
|
| **Extensibility** | | |
|
|
352
|
-
| `custom_tools` | `[]` | Additional MCP tool classes
|
|
353
|
-
| `skip_tools` | `[]` | Built-in tool names to exclude
|
|
354
|
-
| `ai_tools` | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot windsurf opencode]` |
|
|
225
|
+
| `custom_tools` | `[]` | Additional MCP tool classes |
|
|
226
|
+
| `skip_tools` | `[]` | Built-in tool names to exclude |
|
|
355
227
|
</details>
|
|
356
228
|
|
|
357
229
|
---
|
|
358
230
|
|
|
359
231
|
## Commands
|
|
360
232
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
| Command | Description |
|
|
233
|
+
| Command | What it does |
|
|
364
234
|
|---------|-------------|
|
|
365
|
-
| `rails ai:context` | Generate
|
|
366
|
-
| `rails ai:context:full` | Generate all files in full mode (dumps everything) |
|
|
367
|
-
| `rails ai:context:claude` | Generate Claude Code files only |
|
|
368
|
-
| `rails ai:context:opencode` | Generate OpenCode files only |
|
|
369
|
-
| `rails ai:context:cursor` | Generate Cursor files only |
|
|
370
|
-
| `rails ai:context:windsurf` | Generate Windsurf files only |
|
|
371
|
-
| `rails ai:context:copilot` | Generate Copilot files only |
|
|
372
|
-
| `rails ai:context:json` | Generate JSON context file only |
|
|
235
|
+
| `rails ai:context` | Generate context files for your AI tools |
|
|
373
236
|
| `rails ai:serve` | Start MCP server (stdio) |
|
|
374
|
-
| `rails ai:
|
|
375
|
-
| `rails ai:
|
|
376
|
-
| `rails ai:
|
|
377
|
-
| `rails ai:inspect` | Print introspection summary to stdout |
|
|
378
|
-
|
|
379
|
-
### Standalone CLI
|
|
380
|
-
|
|
381
|
-
The gem also ships a `rails-ai-context` executable — an alternative to rake tasks.
|
|
382
|
-
|
|
383
|
-
| Command | Equivalent rake task |
|
|
384
|
-
|---------|---------------------|
|
|
385
|
-
| `rails-ai-context serve` | `rails ai:serve` |
|
|
386
|
-
| `rails-ai-context serve --transport http` | `rails ai:serve_http` |
|
|
387
|
-
| `rails-ai-context context` | `rails ai:context` |
|
|
388
|
-
| `rails-ai-context context --format claude` | `rails ai:context:claude` |
|
|
389
|
-
| `rails-ai-context doctor` | `rails ai:doctor` |
|
|
390
|
-
| `rails-ai-context watch` | `rails ai:watch` |
|
|
391
|
-
| `rails-ai-context inspect` | `rails ai:inspect` |
|
|
392
|
-
| `rails-ai-context version` | — |
|
|
393
|
-
|
|
394
|
-
Run from your Rails app root. Use `rails-ai-context help` for all options.
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## Stack Compatibility
|
|
399
|
-
|
|
400
|
-
Works with every Rails architecture — auto-detects what's relevant:
|
|
401
|
-
|
|
402
|
-
| Setup | Coverage | Notes |
|
|
403
|
-
|-------|----------|-------|
|
|
404
|
-
| Rails full-stack (ERB + Hotwire) | 29/29 | All introspectors relevant |
|
|
405
|
-
| Rails + Inertia.js (React/Vue) | ~22/29 | Views/Turbo partially useful, backend fully covered |
|
|
406
|
-
| Rails API + React/Next.js SPA | ~20/29 | Schema, models, routes, API, auth, jobs — all covered |
|
|
407
|
-
| Rails API + mobile app | ~20/29 | Same as SPA — backend introspection is identical |
|
|
408
|
-
| Rails engine (mountable gem) | ~15/29 | Core introspectors (schema, models, routes, gems) work |
|
|
409
|
-
|
|
410
|
-
Frontend introspectors (views, Turbo, Stimulus, assets) degrade gracefully — they report nothing when those features aren't present.
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
## Works Without a Database
|
|
415
|
-
|
|
416
|
-
The gem parses `db/schema.rb` as text when no database is connected. Works in CI, Docker build stages, and Claude Code sessions without a running DB.
|
|
237
|
+
| `rails ai:doctor` | Diagnostics + AI readiness score |
|
|
238
|
+
| `rails ai:watch` | Auto-regenerate on file changes |
|
|
239
|
+
| `rails ai:inspect` | Print introspection summary |
|
|
417
240
|
|
|
418
241
|
---
|
|
419
242
|
|
|
420
243
|
## Requirements
|
|
421
244
|
|
|
422
245
|
- Ruby >= 3.2, Rails >= 7.1
|
|
423
|
-
-
|
|
424
|
-
- Optional: `listen` gem for watch mode, `ripgrep` for fast code search
|
|
425
|
-
|
|
426
|
-
---
|
|
427
|
-
|
|
428
|
-
## vs. Other Ruby MCP Projects
|
|
429
|
-
|
|
430
|
-
| Project | Approach | rails-ai-context |
|
|
431
|
-
|---------|----------|-----------------|
|
|
432
|
-
| [Official Ruby SDK](https://github.com/modelcontextprotocol/ruby-sdk) | Low-level protocol library | We **use** this as our foundation |
|
|
433
|
-
| [fast-mcp](https://github.com/yjacquin/fast-mcp) | Generic MCP framework | We're a **product** — zero-config Rails introspection |
|
|
434
|
-
| [rails-mcp-server](https://github.com/maquina-app/rails-mcp-server) | Manual config (`projects.yml`) | We auto-discover everything |
|
|
246
|
+
- Optional: `brakeman` for security scanning, `listen` for watch mode, `ripgrep` for fast search
|
|
435
247
|
|
|
436
248
|
---
|
|
437
249
|
|
|
@@ -440,7 +252,7 @@ The gem parses `db/schema.rb` as text when no database is connected. Works in CI
|
|
|
440
252
|
```bash
|
|
441
253
|
git clone https://github.com/crisnahine/rails-ai-context.git
|
|
442
254
|
cd rails-ai-context && bundle install
|
|
443
|
-
bundle exec rspec #
|
|
255
|
+
bundle exec rspec # 575 examples
|
|
444
256
|
bundle exec rubocop # Lint
|
|
445
257
|
```
|
|
446
258
|
|
|
@@ -448,7 +260,7 @@ Bug reports and pull requests welcome at [github.com/crisnahine/rails-ai-context
|
|
|
448
260
|
|
|
449
261
|
## Sponsorship
|
|
450
262
|
|
|
451
|
-
If rails-ai-context
|
|
263
|
+
If rails-ai-context saves you time, consider [becoming a sponsor](https://github.com/sponsors/crisnahine).
|
|
452
264
|
|
|
453
265
|
## License
|
|
454
266
|
|
data/docs/GUIDE.md
CHANGED
|
@@ -564,7 +564,7 @@ Ripgrep-powered regex search across the codebase.
|
|
|
564
564
|
| `pattern` | string | **Required.** Regex pattern or method name to search for. |
|
|
565
565
|
| `path` | string | Subdirectory to search in (e.g. `app/models`, `config`). Default: entire app. |
|
|
566
566
|
| `file_type` | string | Filter by file extension (e.g. `rb`, `erb`, `js`). Alphanumeric only. |
|
|
567
|
-
| `match_type` | string | `any` (default), `definition` (def lines), `class` (class/module lines), `call` (call sites only), `trace` (**full picture** — definition + source + callers +
|
|
567
|
+
| `match_type` | string | `any` (default), `definition` (def lines), `class` (class/module lines), `call` (call sites only), `trace` (**full picture** — definition with class context + source code + internal calls + sibling methods + callers with route chain + test coverage separated). |
|
|
568
568
|
| `exact_match` | boolean | Match whole words only (wraps pattern in `\b` boundaries). Default: false. |
|
|
569
569
|
| `exclude_tests` | boolean | Exclude test/spec/features directories. Default: false. |
|
|
570
570
|
| `group_by_file` | boolean | Group results by file with match counts. Default: false. |
|
|
@@ -577,7 +577,8 @@ Smart result limiting: <10 results shows all, 10-100 shows half, >100 caps at 10
|
|
|
577
577
|
|
|
578
578
|
```
|
|
579
579
|
rails_search_code(pattern: "can_cook?", match_type: "trace")
|
|
580
|
-
→ FULL PICTURE: definition
|
|
580
|
+
→ FULL PICTURE: definition with class context + source code + internal calls
|
|
581
|
+
+ sibling methods + app callers with route chain + test coverage (separated)
|
|
581
582
|
|
|
582
583
|
rails_search_code(pattern: "create", match_type: "definition")
|
|
583
584
|
→ Only `def create` / `def self.create` lines
|
|
@@ -306,15 +306,18 @@ module RailsAiContext
|
|
|
306
306
|
if def_results.any?
|
|
307
307
|
lines << "## Definition"
|
|
308
308
|
def_results.each do |r|
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
# Class/module context
|
|
310
|
+
class_context = extract_class_context(File.join(root, r[:file]), r[:line_number])
|
|
311
|
+
lines << "**#{r[:file]}:#{r[:line_number]}**#{class_context ? " in `#{class_context}`" : ""}"
|
|
312
|
+
|
|
313
|
+
# Full method body
|
|
311
314
|
body = extract_method_body(File.join(root, r[:file]), r[:line_number])
|
|
312
315
|
if body
|
|
313
316
|
lines << "```ruby"
|
|
314
317
|
lines << body
|
|
315
318
|
lines << "```"
|
|
316
319
|
|
|
317
|
-
#
|
|
320
|
+
# What does this method call?
|
|
318
321
|
internal_calls = body.scan(/\b([a-z_]\w*[!?]?)(?:\s*[\(])/).flatten.uniq
|
|
319
322
|
internal_calls += body.scan(/\b([A-Z]\w+(?:::\w+)*)\.(new|call|perform_later|perform_async|find|where|create)/).map { |c| "#{c[0]}.#{c[1]}" }
|
|
320
323
|
internal_calls.reject! { |c| %w[if else elsif unless return end def class module do begin rescue ensure raise puts print].include?(c) }
|
|
@@ -325,6 +328,14 @@ module RailsAiContext
|
|
|
325
328
|
internal_calls.first(15).each { |c| lines << "- `#{c}`" }
|
|
326
329
|
end
|
|
327
330
|
end
|
|
331
|
+
|
|
332
|
+
# Sibling methods in the same file
|
|
333
|
+
siblings = extract_sibling_methods(File.join(root, r[:file]), r[:line_number], cleaned)
|
|
334
|
+
if siblings.any?
|
|
335
|
+
lines << "" << "## Sibling methods (same file)"
|
|
336
|
+
siblings.first(10).each { |s| lines << "- `#{s}`" }
|
|
337
|
+
end
|
|
338
|
+
|
|
328
339
|
lines << ""
|
|
329
340
|
end
|
|
330
341
|
else
|
|
@@ -346,28 +357,46 @@ module RailsAiContext
|
|
|
346
357
|
callers.reject! { |r| def_locations.include?("#{r[:file]}:#{r[:line_number]}") }
|
|
347
358
|
|
|
348
359
|
if callers.any?
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
360
|
+
# Separate app code from tests
|
|
361
|
+
app_callers = callers.reject { |r| r[:file].match?(/\A(test|spec)\//) }
|
|
362
|
+
test_callers = callers.select { |r| r[:file].match?(/\A(test|spec)\//) }
|
|
363
|
+
|
|
364
|
+
if app_callers.any?
|
|
365
|
+
lines << "## Called from (#{app_callers.size} sites)"
|
|
366
|
+
grouped = app_callers.group_by { |r| r[:file] }
|
|
367
|
+
grouped.each do |file, matches|
|
|
368
|
+
category = case file
|
|
369
|
+
when /controller/i then "Controller"
|
|
370
|
+
when /model/i then "Model"
|
|
371
|
+
when /view|\.erb/i then "View"
|
|
372
|
+
when /job/i then "Job"
|
|
373
|
+
when /service/i then "Service"
|
|
374
|
+
when /\.js$|\.ts$/i then "JavaScript"
|
|
375
|
+
else "Other"
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# Route chain for controller callers
|
|
379
|
+
route_hint = ""
|
|
380
|
+
if category == "Controller" && file.match?(/app\/controllers\/(.+)_controller\.rb/)
|
|
381
|
+
ctrl_path = $1
|
|
382
|
+
route_actions = extract_controller_actions_from_matches(matches)
|
|
383
|
+
routes = find_routes_for_controller(ctrl_path, route_actions, root)
|
|
384
|
+
route_hint = " → #{routes}" if routes
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
lines << "### #{file} (#{category})#{route_hint}"
|
|
388
|
+
matches.first(5).each do |r|
|
|
389
|
+
lines << " #{r[:line_number]}: #{r[:content].strip}"
|
|
390
|
+
end
|
|
391
|
+
lines << " _(#{matches.size - 5} more)_" if matches.size > 5
|
|
364
392
|
end
|
|
393
|
+
end
|
|
365
394
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
395
|
+
if test_callers.any?
|
|
396
|
+
lines << "" << "## Tested by (#{test_callers.size} references)"
|
|
397
|
+
test_callers.group_by { |r| r[:file] }.each do |file, matches|
|
|
398
|
+
lines << "- `#{file}` (#{matches.size} references)"
|
|
369
399
|
end
|
|
370
|
-
lines << " _(#{matches.size - 5} more)_" if matches.size > 5
|
|
371
400
|
end
|
|
372
401
|
else
|
|
373
402
|
lines << "## Called from"
|
|
@@ -388,6 +417,64 @@ module RailsAiContext
|
|
|
388
417
|
end
|
|
389
418
|
end
|
|
390
419
|
|
|
420
|
+
# Extract class/module context for a line
|
|
421
|
+
private_class_method def self.extract_class_context(file_path, line_num)
|
|
422
|
+
return nil unless File.exist?(file_path)
|
|
423
|
+
lines = File.readlines(file_path)
|
|
424
|
+
# Walk backwards from the method to find the enclosing class/module
|
|
425
|
+
(line_num - 2).downto(0) do |i|
|
|
426
|
+
if lines[i]&.match?(/\A\s*(class|module)\s+(\S+)/)
|
|
427
|
+
return lines[i].strip.sub(/\s*<.*/, "")
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
nil
|
|
431
|
+
rescue
|
|
432
|
+
nil
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
# Extract sibling methods in the same file (other public methods)
|
|
436
|
+
private_class_method def self.extract_sibling_methods(file_path, def_line, exclude_method)
|
|
437
|
+
return [] unless File.exist?(file_path)
|
|
438
|
+
return [] if File.size(file_path) > RailsAiContext.configuration.max_file_size
|
|
439
|
+
source = File.read(file_path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
440
|
+
methods = []
|
|
441
|
+
in_private = false
|
|
442
|
+
source.each_line do |line|
|
|
443
|
+
in_private = true if line.match?(/\A\s*private\s*$/)
|
|
444
|
+
next if in_private
|
|
445
|
+
if (m = line.match(/\A\s*def\s+((?:self\.)?\w+[?!]?)/))
|
|
446
|
+
name = m[1]
|
|
447
|
+
methods << name unless name == exclude_method || name.start_with?("initialize")
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
methods
|
|
451
|
+
rescue
|
|
452
|
+
[]
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
# Extract which action a controller caller is in
|
|
456
|
+
private_class_method def self.extract_controller_actions_from_matches(matches)
|
|
457
|
+
actions = []
|
|
458
|
+
matches.each do |m|
|
|
459
|
+
# Look for the method name from indentation context
|
|
460
|
+
actions << $1 if m[:content].match?(/\b(create|index|show|new|edit|update|destroy|[a-z_]+)\b/)
|
|
461
|
+
end
|
|
462
|
+
actions.uniq.first(3)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# Find routes for a controller
|
|
466
|
+
private_class_method def self.find_routes_for_controller(ctrl_path, _actions, _root)
|
|
467
|
+
routes = cached_context[:routes]
|
|
468
|
+
return nil unless routes
|
|
469
|
+
by_controller = routes[:by_controller] || {}
|
|
470
|
+
ctrl_routes = by_controller[ctrl_path]
|
|
471
|
+
return nil unless ctrl_routes&.any?
|
|
472
|
+
# Show the first 2 routes as hints
|
|
473
|
+
ctrl_routes.first(2).map { |r| "`#{r[:verb]} #{r[:path]}`" }.join(", ")
|
|
474
|
+
rescue
|
|
475
|
+
nil
|
|
476
|
+
end
|
|
477
|
+
|
|
391
478
|
# Extract a method body from a file given the def line number
|
|
392
479
|
private_class_method def self.extract_method_body(file_path, def_line)
|
|
393
480
|
return nil unless File.exist?(file_path)
|
data/server.json
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
"url": "https://github.com/crisnahine/rails-ai-context",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.3",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "mcpb",
|
|
14
|
-
"identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v2.0.
|
|
14
|
+
"identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v2.0.3/rails-ai-context-mcp.mcpb",
|
|
15
15
|
"fileSha256": "dd711a0ad6c4de943ae4da94eaf59a6dc9494b9d57f726e24649ed4e2f156990",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|