rails-ai-context 2.0.4 → 2.0.5
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/lib/rails_ai_context/serializers/claude_rules_serializer.rb +74 -128
- data/lib/rails_ai_context/serializers/claude_serializer.rb +73 -42
- data/lib/rails_ai_context/serializers/copilot_instructions_serializer.rb +71 -33
- data/lib/rails_ai_context/serializers/cursor_rules_serializer.rb +71 -32
- data/lib/rails_ai_context/serializers/opencode_serializer.rb +72 -30
- data/lib/rails_ai_context/serializers/windsurf_rules_serializer.rb +68 -31
- data/lib/rails_ai_context/tools/get_concern.rb +8 -1
- 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: e17feb99495b6f8328eedaa95020ca097aa4ee7df658ed0a51a925cd6961cdee
|
|
4
|
+
data.tar.gz: 8b5dc406788cc2af104813e0711887bfc6a5ef0e97ddc79464291b0da74ad7df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8b7ff36197da72c8b1d3ca1c7199da2333015fda502a37c83d819a95394732449b2d26f20084a14687b59c6fcde10445dda5fbf4705890793ae213bda2cba33
|
|
7
|
+
data.tar.gz: 22e5d0ae93d2af2c01f383197a10e454667f0d24af0bb463a191922913702d3c976f04fb918e7716833af874ee1913d86182d234e36c65bb568469a8ead8f116
|
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.5] - 2026-03-25
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Task-based MCP tool instructions** — all 6 serializers (Claude, Cursor, Copilot, Windsurf, OpenCode) rewritten from tool-first to task-first: "What are you trying to do?" → exact tool call. 7 task categories: understand a feature, trace a method, add a field, fix a controller, build a view, write tests, find code. Every AI agent now understands which tool to use for any task.
|
|
13
|
+
- **Concern detail:"full" bug fix** — `\b` after `?`/`!` prevented 13 of 15 method bodies from being extracted. All methods now show source code.
|
|
14
|
+
|
|
8
15
|
## [2.0.4] - 2026-03-25
|
|
9
16
|
|
|
10
17
|
### Added
|
|
@@ -297,134 +297,80 @@ module RailsAiContext
|
|
|
297
297
|
lines = [
|
|
298
298
|
"# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
|
|
299
299
|
"",
|
|
300
|
-
"
|
|
301
|
-
"
|
|
302
|
-
"
|
|
303
|
-
"",
|
|
304
|
-
"
|
|
305
|
-
"",
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"
|
|
315
|
-
"",
|
|
316
|
-
"
|
|
317
|
-
"
|
|
318
|
-
"
|
|
319
|
-
"",
|
|
320
|
-
"
|
|
321
|
-
"
|
|
322
|
-
"
|
|
323
|
-
"
|
|
324
|
-
"",
|
|
325
|
-
"
|
|
326
|
-
"
|
|
327
|
-
"
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
"
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"",
|
|
338
|
-
"
|
|
339
|
-
"
|
|
340
|
-
"
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"
|
|
344
|
-
"",
|
|
345
|
-
"
|
|
346
|
-
"",
|
|
347
|
-
"
|
|
348
|
-
"
|
|
349
|
-
"
|
|
350
|
-
"",
|
|
351
|
-
"
|
|
352
|
-
"
|
|
353
|
-
"
|
|
354
|
-
"",
|
|
355
|
-
"
|
|
356
|
-
"
|
|
357
|
-
"
|
|
358
|
-
"",
|
|
359
|
-
"
|
|
360
|
-
"
|
|
361
|
-
"
|
|
362
|
-
"",
|
|
363
|
-
"
|
|
364
|
-
"
|
|
365
|
-
"
|
|
366
|
-
"",
|
|
367
|
-
"
|
|
368
|
-
"
|
|
369
|
-
"
|
|
370
|
-
"",
|
|
371
|
-
"
|
|
372
|
-
"
|
|
373
|
-
"
|
|
374
|
-
"- `rails_get_test_info(model:\"Cook\", detail:\"summary\")` — test names only (saves tokens)",
|
|
375
|
-
"- `rails_get_test_info(controller:\"Cooks\")` — existing controller tests",
|
|
376
|
-
"",
|
|
377
|
-
"**rails_get_edit_context** — surgical edit helper with line numbers",
|
|
378
|
-
"- `rails_get_edit_context(file:\"app/models/cook.rb\", near:\"scope\")` — returns code around match with line numbers",
|
|
379
|
-
"",
|
|
380
|
-
"**rails_validate** — syntax checker for edited files",
|
|
381
|
-
"- `rails_validate(files:[\"app/models/cook.rb\"])` — checks Ruby, ERB, JS syntax in one call",
|
|
382
|
-
"",
|
|
383
|
-
"**rails_analyze_feature** — combined schema + models + controllers + routes for a feature area",
|
|
384
|
-
"- `rails_analyze_feature(feature:\"authentication\")` — one call gets everything related to a feature, including inherited filters from parent controllers and code-ready route helpers",
|
|
385
|
-
"",
|
|
386
|
-
"**rails_get_design_system** — color palette, component patterns, canonical page examples",
|
|
387
|
-
"- `rails_get_design_system(detail:\"standard\")` — colors + components + real HTML examples + design rules",
|
|
388
|
-
"- `rails_get_design_system(detail:\"full\")` — + typography, responsive, dark mode, layout, spacing",
|
|
389
|
-
"",
|
|
390
|
-
"**rails_get_config** — cache store, session, timezone, middleware, initializers",
|
|
391
|
-
"**rails_get_gems** — notable gems categorized by function",
|
|
392
|
-
"**rails_get_conventions** — architecture patterns, directory structure",
|
|
393
|
-
"**rails_search_code** — regex search with trace mode for deep call-chain analysis",
|
|
394
|
-
"- `rails_search_code(pattern:\"regex\", file_type:\"rb\")` — basic regex search across files",
|
|
395
|
-
"- `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — trace mode: definition + class context + source + siblings + callers with route chain + test coverage",
|
|
396
|
-
"- `rails_search_code(pattern:\"cook\", exclude_tests: true)` — search app code only, skip test files",
|
|
397
|
-
"",
|
|
398
|
-
"**rails_security_scan** — Brakeman security analysis",
|
|
399
|
-
"- `rails_security_scan` — run security scan, returns warnings by confidence",
|
|
400
|
-
"",
|
|
401
|
-
"**rails_get_concern** — concern methods and includers",
|
|
402
|
-
"- `rails_get_concern(name:\"Searchable\")` — methods, included modules, includers",
|
|
403
|
-
"- `rails_get_concern(name:\"Searchable\", detail:\"full\")` — + method source code",
|
|
404
|
-
"",
|
|
405
|
-
"**rails_get_callbacks** — model callbacks in execution order",
|
|
406
|
-
"- `rails_get_callbacks(model:\"User\")` — before/after/around callbacks by type",
|
|
407
|
-
"",
|
|
408
|
-
"**rails_get_helper_methods** — app + framework helpers",
|
|
409
|
-
"- `rails_get_helper_methods` — all helper methods across app and framework",
|
|
410
|
-
"",
|
|
411
|
-
"**rails_get_service_pattern** — service object patterns and interfaces",
|
|
412
|
-
"- `rails_get_service_pattern` — service objects with call signatures and dependencies",
|
|
413
|
-
"",
|
|
414
|
-
"**rails_get_job_pattern** — background job patterns and schedules",
|
|
415
|
-
"- `rails_get_job_pattern` — job classes, queues, retry policies, schedules",
|
|
416
|
-
"",
|
|
417
|
-
"**rails_get_env** — environment variables and credentials keys",
|
|
418
|
-
"- `rails_get_env` — ENV vars referenced in code + credentials structure",
|
|
419
|
-
"",
|
|
420
|
-
"**rails_get_partial_interface** — partial locals contract",
|
|
421
|
-
"- `rails_get_partial_interface(path:\"shared/_form\")` — required/optional locals for a partial",
|
|
422
|
-
"",
|
|
423
|
-
"**rails_get_turbo_map** — Turbo Streams/Frames wiring",
|
|
424
|
-
"- `rails_get_turbo_map` — Turbo Frame IDs, Stream channels, broadcast sources",
|
|
425
|
-
"",
|
|
426
|
-
"**rails_get_context** — composite cross-layer context",
|
|
427
|
-
"- `rails_get_context(model:\"User\")` — schema + model + controllers + views in one call"
|
|
300
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
301
|
+
"Read files ONLY when you are about to Edit them.",
|
|
302
|
+
"",
|
|
303
|
+
"## What Are You Trying to Do?",
|
|
304
|
+
"",
|
|
305
|
+
"**Understand a feature or area:**",
|
|
306
|
+
"→ `rails_analyze_feature(feature:\"cook\")` — models + controllers + routes + services + jobs + views + tests in one call",
|
|
307
|
+
"→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
|
|
308
|
+
"",
|
|
309
|
+
"**Understand a method (who calls it, what it calls):**",
|
|
310
|
+
"→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
|
|
311
|
+
"",
|
|
312
|
+
"**Add a field or modify a model:**",
|
|
313
|
+
"→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
|
|
314
|
+
"→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
|
|
315
|
+
"",
|
|
316
|
+
"**Fix a controller bug:**",
|
|
317
|
+
"→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
|
|
318
|
+
"",
|
|
319
|
+
"**Build or modify a view:**",
|
|
320
|
+
"→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
|
|
321
|
+
"→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
|
|
322
|
+
"→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
|
|
323
|
+
"",
|
|
324
|
+
"**Write tests:**",
|
|
325
|
+
"→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
|
|
326
|
+
"→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
|
|
327
|
+
"",
|
|
328
|
+
"**Find code:**",
|
|
329
|
+
"→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
|
|
330
|
+
"→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
|
|
331
|
+
"→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
|
|
332
|
+
"",
|
|
333
|
+
"**After editing (EVERY time):**",
|
|
334
|
+
"→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
|
|
335
|
+
"",
|
|
336
|
+
"## Rules",
|
|
337
|
+
"",
|
|
338
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
339
|
+
"2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
|
|
340
|
+
"3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
|
|
341
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
342
|
+
"5. Start with `detail:\"summary\"` to orient, then drill into specifics",
|
|
343
|
+
"",
|
|
344
|
+
"## All 25 Tools",
|
|
345
|
+
"",
|
|
346
|
+
"| Tool | What it does |",
|
|
347
|
+
"|------|-------------|",
|
|
348
|
+
"| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
|
|
349
|
+
"| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
|
|
350
|
+
"| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
|
|
351
|
+
"| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
|
|
352
|
+
"| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
|
|
353
|
+
"| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
|
|
354
|
+
"| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
|
|
355
|
+
"| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
|
|
356
|
+
"| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
|
|
357
|
+
"| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
|
|
358
|
+
"| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
|
|
359
|
+
"| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
|
|
360
|
+
"| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
|
|
361
|
+
"| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
|
|
362
|
+
"| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
|
|
363
|
+
"| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
|
|
364
|
+
"| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
|
|
365
|
+
"| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
|
|
366
|
+
"| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
|
|
367
|
+
"| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
|
|
368
|
+
"| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
|
|
369
|
+
"| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
|
|
370
|
+
"| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
|
|
371
|
+
"| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
|
|
372
|
+
"| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
|
|
373
|
+
"| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
|
|
428
374
|
]
|
|
429
375
|
|
|
430
376
|
lines.join("\n")
|
|
@@ -196,43 +196,84 @@ module RailsAiContext
|
|
|
196
196
|
render_design_system(context, max_lines: 30)
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
def render_mcp_guide # rubocop:disable Metrics/MethodLength
|
|
199
|
+
def render_mcp_guide # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
200
200
|
[
|
|
201
|
-
"## MCP Tools (25) —
|
|
201
|
+
"## MCP Tools (25) — MANDATORY, Use Before Read/Grep",
|
|
202
202
|
"",
|
|
203
|
-
"This project has live MCP tools. You MUST use them instead of reading
|
|
204
|
-
"
|
|
203
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
204
|
+
"Read files ONLY when you are about to Edit them.",
|
|
205
205
|
"",
|
|
206
|
-
"###
|
|
207
|
-
"1. **Before exploring a feature**: `rails_analyze_feature(feature:\"...\")` — NOT Explore agents or Grep",
|
|
208
|
-
"2. **Before writing migrations**: `rails_get_schema(table:\"...\")` — NOT reading db/schema.rb",
|
|
209
|
-
"3. **Before modifying a model**: `rails_get_model_details(model:\"...\")` — NOT reading the model file",
|
|
210
|
-
"4. **Before adding routes**: `rails_get_routes(controller:\"...\")` — Read routes.rb only when you will edit it",
|
|
211
|
-
"5. **Before creating views**: `rails_get_design_system` — match existing patterns",
|
|
212
|
-
"6. **After editing ANY file**: `rails_validate(files:[...])` — no exceptions, no ruby -c / erb / node -c",
|
|
206
|
+
"### What Are You Trying to Do?",
|
|
213
207
|
"",
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"| Column types | `rails_get_schema(table:\"x\")` — includes orphaned table warnings | Read db/schema.rb |",
|
|
218
|
-
"| Model associations | `rails_get_model_details(model:\"X\")` | Read app/models/x.rb |",
|
|
219
|
-
"| Route paths | `rails_get_routes(controller:\"x\")` | Read config/routes.rb |",
|
|
220
|
-
"| Feature overview | `rails_analyze_feature(feature:\"x\")` — models + controllers (inherited filters) + routes (code-ready helpers) + services + jobs + views + tests + gaps | Explore agent / Grep |",
|
|
221
|
-
"| Find code | `rails_search_code(pattern:\"x\", match_type:\"trace\")` | Grep tool |",
|
|
222
|
-
"| Validate edits | `rails_validate(files:[...])` | ruby -c / erb / node |",
|
|
223
|
-
"| Controller logic | `rails_get_controllers(controller:\"X\", action:\"y\")` | Read controller file |",
|
|
224
|
-
"| UI patterns | `rails_get_design_system` | Read view files |",
|
|
225
|
-
"| Stimulus API | `rails_get_stimulus(controller:\"x\")` | Read JS files |",
|
|
226
|
-
"| Test patterns | `rails_get_test_info(model:\"X\")` | Read test files |",
|
|
227
|
-
"| Full context | `rails_get_context(model:\"X\")` | Multiple Read calls |",
|
|
208
|
+
"**Understand a feature or area:**",
|
|
209
|
+
"→ `rails_analyze_feature(feature:\"cook\")` — models + controllers + routes + services + jobs + views + tests in one call",
|
|
210
|
+
"→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
|
|
228
211
|
"",
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
212
|
+
"**Understand a method (who calls it, what it calls):**",
|
|
213
|
+
"→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
|
|
214
|
+
"",
|
|
215
|
+
"**Add a field or modify a model:**",
|
|
216
|
+
"→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
|
|
217
|
+
"→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
|
|
218
|
+
"",
|
|
219
|
+
"**Fix a controller bug:**",
|
|
220
|
+
"→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
|
|
221
|
+
"",
|
|
222
|
+
"**Build or modify a view:**",
|
|
223
|
+
"→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
|
|
224
|
+
"→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
|
|
225
|
+
"→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
|
|
226
|
+
"",
|
|
227
|
+
"**Write tests:**",
|
|
228
|
+
"→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
|
|
229
|
+
"→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
|
|
230
|
+
"",
|
|
231
|
+
"**Find code:**",
|
|
232
|
+
"→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
|
|
233
|
+
"→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
|
|
234
|
+
"→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
|
|
235
|
+
"",
|
|
236
|
+
"**After editing (EVERY time):**",
|
|
237
|
+
"→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
|
|
238
|
+
"",
|
|
239
|
+
"### Rules",
|
|
240
|
+
"",
|
|
241
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
242
|
+
"2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
|
|
243
|
+
"3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
|
|
244
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
245
|
+
"5. Start with `detail:\"summary\"` to orient, then drill into specifics",
|
|
246
|
+
"",
|
|
247
|
+
"### All 25 Tools",
|
|
248
|
+
"",
|
|
249
|
+
"| Tool | What it does |",
|
|
250
|
+
"|------|-------------|",
|
|
251
|
+
"| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
|
|
252
|
+
"| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
|
|
253
|
+
"| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
|
|
254
|
+
"| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
|
|
255
|
+
"| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
|
|
256
|
+
"| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
|
|
257
|
+
"| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
|
|
258
|
+
"| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
|
|
259
|
+
"| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
|
|
260
|
+
"| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
|
|
261
|
+
"| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
|
|
262
|
+
"| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
|
|
263
|
+
"| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
|
|
264
|
+
"| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
|
|
265
|
+
"| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
|
|
266
|
+
"| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
|
|
267
|
+
"| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
|
|
268
|
+
"| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
|
|
269
|
+
"| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
|
|
270
|
+
"| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
|
|
271
|
+
"| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
|
|
272
|
+
"| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
|
|
273
|
+
"| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
|
|
274
|
+
"| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
|
|
275
|
+
"| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
|
|
276
|
+
"| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |",
|
|
236
277
|
""
|
|
237
278
|
]
|
|
238
279
|
end
|
|
@@ -267,18 +308,8 @@ module RailsAiContext
|
|
|
267
308
|
"- Follow existing patterns and conventions",
|
|
268
309
|
"- Match existing code style",
|
|
269
310
|
"- Run tests after changes",
|
|
270
|
-
"- After editing, ALWAYS use `rails_validate(files:[...])` — do NOT use separate ruby -c / erb / node -c calls",
|
|
271
311
|
"- Do NOT re-read files to verify edits — trust your Edit, validate syntax only",
|
|
272
312
|
"- Stimulus controllers auto-register — no manual import in controllers/index.js needed",
|
|
273
|
-
"",
|
|
274
|
-
"## MCP-First Rule — Do NOT Bypass",
|
|
275
|
-
"- Do NOT read db/schema.rb — use `rails_get_schema`",
|
|
276
|
-
"- Do NOT read config/routes.rb for reference — use `rails_get_routes`",
|
|
277
|
-
"- Do NOT read model files for associations/scopes — use `rails_get_model_details`",
|
|
278
|
-
"- Do NOT use Grep to search code — use `rails_search_code`",
|
|
279
|
-
"- Do NOT launch Explore agents for context — use `rails_analyze_feature`",
|
|
280
|
-
"- Do NOT read test files for patterns — use `rails_get_test_info`",
|
|
281
|
-
"- Read files ONLY when you are about to Edit them",
|
|
282
313
|
""
|
|
283
314
|
]
|
|
284
315
|
end
|
|
@@ -213,50 +213,88 @@ module RailsAiContext
|
|
|
213
213
|
lines.join("\n")
|
|
214
214
|
end
|
|
215
215
|
|
|
216
|
-
def render_mcp_tools_instructions # rubocop:disable Metrics/MethodLength
|
|
216
|
+
def render_mcp_tools_instructions # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
217
217
|
lines = [
|
|
218
218
|
"---",
|
|
219
219
|
"applyTo: \"**/*\"",
|
|
220
220
|
"---",
|
|
221
221
|
"",
|
|
222
|
-
"# Rails MCP Tools
|
|
222
|
+
"# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
|
|
223
223
|
"",
|
|
224
|
-
"
|
|
225
|
-
"Read files ONLY when you are about to
|
|
226
|
-
"Start with `detail:\"summary\"`, then drill into specifics.",
|
|
224
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
225
|
+
"Read files ONLY when you are about to Edit them.",
|
|
227
226
|
"",
|
|
228
|
-
"##
|
|
229
|
-
"1. Gathering context → use MCP tools (NOT file reads, NOT grep)",
|
|
230
|
-
"2. Reading files → ONLY files you will edit",
|
|
231
|
-
"3. After editing → `rails_validate(files:[...])` every time, no exceptions",
|
|
227
|
+
"## What Are You Trying to Do?",
|
|
232
228
|
"",
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
244
|
-
"
|
|
229
|
+
"**Understand a feature or area:**",
|
|
230
|
+
"→ `rails_analyze_feature(feature:\"cook\")` — models + controllers + routes + services + jobs + views + tests in one call",
|
|
231
|
+
"→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
|
|
232
|
+
"",
|
|
233
|
+
"**Understand a method (who calls it, what it calls):**",
|
|
234
|
+
"→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
|
|
235
|
+
"",
|
|
236
|
+
"**Add a field or modify a model:**",
|
|
237
|
+
"→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
|
|
238
|
+
"→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
|
|
239
|
+
"",
|
|
240
|
+
"**Fix a controller bug:**",
|
|
241
|
+
"→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
|
|
242
|
+
"",
|
|
243
|
+
"**Build or modify a view:**",
|
|
244
|
+
"→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
|
|
245
|
+
"→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
|
|
246
|
+
"→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
|
|
247
|
+
"",
|
|
248
|
+
"**Write tests:**",
|
|
249
|
+
"→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
|
|
250
|
+
"→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
|
|
251
|
+
"",
|
|
252
|
+
"**Find code:**",
|
|
253
|
+
"→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
|
|
254
|
+
"→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
|
|
255
|
+
"→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
|
|
256
|
+
"",
|
|
257
|
+
"**After editing (EVERY time):**",
|
|
258
|
+
"→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
|
|
259
|
+
"",
|
|
260
|
+
"## Rules",
|
|
261
|
+
"",
|
|
262
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
263
|
+
"2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
|
|
264
|
+
"3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
|
|
265
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
266
|
+
"5. Start with `detail:\"summary\"` to orient, then drill into specifics",
|
|
245
267
|
"",
|
|
246
268
|
"## All 25 Tools",
|
|
247
|
-
"- `rails_get_schema` | `rails_get_model_details` | `rails_get_routes` | `rails_get_controllers`",
|
|
248
|
-
"- `rails_get_view` | `rails_get_stimulus` | `rails_get_test_info` | `rails_analyze_feature`",
|
|
249
|
-
"- `rails_get_design_system` | `rails_get_edit_context` | `rails_validate` | `rails_search_code`",
|
|
250
|
-
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
|
|
251
|
-
"- `rails_get_concern` | `rails_get_callbacks` | `rails_get_helper_methods` | `rails_get_service_pattern`",
|
|
252
|
-
"- `rails_get_job_pattern` | `rails_get_env` | `rails_get_partial_interface` | `rails_get_turbo_map`",
|
|
253
|
-
"- `rails_get_context(model:\"X\")` — composite cross-layer context in one call",
|
|
254
269
|
"",
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"
|
|
258
|
-
"
|
|
259
|
-
"
|
|
270
|
+
"| Tool | What it does |",
|
|
271
|
+
"|------|-------------|",
|
|
272
|
+
"| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
|
|
273
|
+
"| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
|
|
274
|
+
"| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
|
|
275
|
+
"| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
|
|
276
|
+
"| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
|
|
277
|
+
"| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
|
|
278
|
+
"| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
|
|
279
|
+
"| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
|
|
280
|
+
"| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
|
|
281
|
+
"| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
|
|
282
|
+
"| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
|
|
283
|
+
"| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
|
|
284
|
+
"| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
|
|
285
|
+
"| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
|
|
286
|
+
"| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
|
|
287
|
+
"| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
|
|
288
|
+
"| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
|
|
289
|
+
"| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
|
|
290
|
+
"| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
|
|
291
|
+
"| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
|
|
292
|
+
"| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
|
|
293
|
+
"| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
|
|
294
|
+
"| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
|
|
295
|
+
"| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
|
|
296
|
+
"| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
|
|
297
|
+
"| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
|
|
260
298
|
]
|
|
261
299
|
|
|
262
300
|
lines.join("\n")
|
|
@@ -253,50 +253,89 @@ module RailsAiContext
|
|
|
253
253
|
end
|
|
254
254
|
|
|
255
255
|
# Always-on MCP tool reference — strongest enforcement point for Cursor
|
|
256
|
-
def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength
|
|
256
|
+
def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
257
257
|
lines = [
|
|
258
258
|
"---",
|
|
259
259
|
"description: \"Rails MCP tools (25) — MANDATORY, use before reading any reference files\"",
|
|
260
260
|
"alwaysApply: true",
|
|
261
261
|
"---",
|
|
262
262
|
"",
|
|
263
|
-
"# Rails MCP Tools
|
|
263
|
+
"# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
|
|
264
264
|
"",
|
|
265
|
-
"
|
|
266
|
-
"Read files ONLY when you are about to
|
|
265
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
266
|
+
"Read files ONLY when you are about to Edit them.",
|
|
267
267
|
"",
|
|
268
|
-
"##
|
|
269
|
-
"1. Gathering context → use MCP tools (NOT file reads, NOT grep)",
|
|
270
|
-
"2. Reading files → ONLY files you will edit (Read is required before Edit)",
|
|
271
|
-
"3. After editing → `rails_validate(files:[...])` every time, no exceptions",
|
|
268
|
+
"## What Are You Trying to Do?",
|
|
272
269
|
"",
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
276
|
-
"
|
|
277
|
-
"
|
|
278
|
-
"
|
|
279
|
-
"
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"
|
|
284
|
-
"
|
|
270
|
+
"**Understand a feature or area:**",
|
|
271
|
+
"→ `rails_analyze_feature(feature:\"cook\")` — models + controllers + routes + services + jobs + views + tests in one call",
|
|
272
|
+
"→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
|
|
273
|
+
"",
|
|
274
|
+
"**Understand a method (who calls it, what it calls):**",
|
|
275
|
+
"→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
|
|
276
|
+
"",
|
|
277
|
+
"**Add a field or modify a model:**",
|
|
278
|
+
"→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
|
|
279
|
+
"→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
|
|
280
|
+
"",
|
|
281
|
+
"**Fix a controller bug:**",
|
|
282
|
+
"→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
|
|
283
|
+
"",
|
|
284
|
+
"**Build or modify a view:**",
|
|
285
|
+
"→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
|
|
286
|
+
"→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
|
|
287
|
+
"→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
|
|
288
|
+
"",
|
|
289
|
+
"**Write tests:**",
|
|
290
|
+
"→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
|
|
291
|
+
"→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
|
|
292
|
+
"",
|
|
293
|
+
"**Find code:**",
|
|
294
|
+
"→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
|
|
295
|
+
"→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
|
|
296
|
+
"→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
|
|
297
|
+
"",
|
|
298
|
+
"**After editing (EVERY time):**",
|
|
299
|
+
"→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
|
|
300
|
+
"",
|
|
301
|
+
"## Rules",
|
|
302
|
+
"",
|
|
303
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
304
|
+
"2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
|
|
305
|
+
"3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
|
|
306
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
307
|
+
"5. Start with `detail:\"summary\"` to orient, then drill into specifics",
|
|
285
308
|
"",
|
|
286
309
|
"## All 25 Tools",
|
|
287
|
-
"- `rails_get_schema` | `rails_get_model_details` | `rails_get_routes` | `rails_get_controllers`",
|
|
288
|
-
"- `rails_get_view` | `rails_get_stimulus` | `rails_get_test_info` | `rails_analyze_feature`",
|
|
289
|
-
"- `rails_get_design_system` | `rails_get_edit_context` | `rails_validate` | `rails_search_code`",
|
|
290
|
-
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
|
|
291
|
-
"- `rails_get_concern` | `rails_get_callbacks` | `rails_get_helper_methods` | `rails_get_service_pattern`",
|
|
292
|
-
"- `rails_get_job_pattern` | `rails_get_env` | `rails_get_partial_interface` | `rails_get_turbo_map`",
|
|
293
|
-
"- `rails_get_context(model:\"X\")` — composite cross-layer context in one call",
|
|
294
310
|
"",
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
"
|
|
299
|
-
"
|
|
311
|
+
"| Tool | What it does |",
|
|
312
|
+
"|------|-------------|",
|
|
313
|
+
"| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
|
|
314
|
+
"| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
|
|
315
|
+
"| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
|
|
316
|
+
"| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
|
|
317
|
+
"| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
|
|
318
|
+
"| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
|
|
319
|
+
"| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
|
|
320
|
+
"| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
|
|
321
|
+
"| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
|
|
322
|
+
"| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
|
|
323
|
+
"| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
|
|
324
|
+
"| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
|
|
325
|
+
"| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
|
|
326
|
+
"| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
|
|
327
|
+
"| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
|
|
328
|
+
"| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
|
|
329
|
+
"| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
|
|
330
|
+
"| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
|
|
331
|
+
"| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
|
|
332
|
+
"| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
|
|
333
|
+
"| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
|
|
334
|
+
"| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
|
|
335
|
+
"| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
|
|
336
|
+
"| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
|
|
337
|
+
"| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
|
|
338
|
+
"| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
|
|
300
339
|
]
|
|
301
340
|
|
|
302
341
|
lines.join("\n")
|
|
@@ -163,42 +163,84 @@ module RailsAiContext
|
|
|
163
163
|
render_design_system(context, max_lines: 30)
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
def render_mcp_guide # rubocop:disable Metrics/MethodLength
|
|
166
|
+
def render_mcp_guide # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
167
167
|
[
|
|
168
|
-
"## MCP Tools (25) — MANDATORY, Use Before Read",
|
|
168
|
+
"## MCP Tools (25) — MANDATORY, Use Before Read/Grep",
|
|
169
169
|
"",
|
|
170
|
-
"
|
|
171
|
-
"Read files ONLY when you are about to
|
|
172
|
-
"Start with `detail:\"summary\"`, then drill into specifics.",
|
|
170
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
171
|
+
"Read files ONLY when you are about to Edit them.",
|
|
173
172
|
"",
|
|
174
|
-
"###
|
|
175
|
-
"1. **Before exploring a feature**: `rails_analyze_feature(feature:\"...\")` — models + controllers (inherited filters) + routes (code-ready helpers) + services + jobs + views + tests + gaps",
|
|
176
|
-
"2. **Before writing migrations**: `rails_get_schema(table:\"...\")` — NOT reading db/schema.rb",
|
|
177
|
-
"3. **Before modifying a model**: `rails_get_model_details(model:\"...\")` — NOT reading the model file",
|
|
178
|
-
"4. **Before adding routes**: `rails_get_routes(controller:\"...\")` — Read only when you will edit",
|
|
179
|
-
"5. **Before creating views**: `rails_get_design_system` — match existing patterns",
|
|
180
|
-
"6. **After editing ANY file**: `rails_validate(files:[...])` — no exceptions",
|
|
173
|
+
"### What Are You Trying to Do?",
|
|
181
174
|
"",
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
185
|
-
"
|
|
186
|
-
"
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"
|
|
190
|
-
"
|
|
191
|
-
"
|
|
175
|
+
"**Understand a feature or area:**",
|
|
176
|
+
"→ `rails_analyze_feature(feature:\"cook\")` — models + controllers + routes + services + jobs + views + tests in one call",
|
|
177
|
+
"→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
|
|
178
|
+
"",
|
|
179
|
+
"**Understand a method (who calls it, what it calls):**",
|
|
180
|
+
"→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
|
|
181
|
+
"",
|
|
182
|
+
"**Add a field or modify a model:**",
|
|
183
|
+
"→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
|
|
184
|
+
"→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
|
|
185
|
+
"",
|
|
186
|
+
"**Fix a controller bug:**",
|
|
187
|
+
"→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
|
|
188
|
+
"",
|
|
189
|
+
"**Build or modify a view:**",
|
|
190
|
+
"→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
|
|
191
|
+
"→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
|
|
192
|
+
"→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
|
|
193
|
+
"",
|
|
194
|
+
"**Write tests:**",
|
|
195
|
+
"→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
|
|
196
|
+
"→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
|
|
197
|
+
"",
|
|
198
|
+
"**Find code:**",
|
|
199
|
+
"→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
|
|
200
|
+
"→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
|
|
201
|
+
"→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
|
|
202
|
+
"",
|
|
203
|
+
"**After editing (EVERY time):**",
|
|
204
|
+
"→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
|
|
205
|
+
"",
|
|
206
|
+
"### Rules",
|
|
207
|
+
"",
|
|
208
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
209
|
+
"2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
|
|
210
|
+
"3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
|
|
211
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
212
|
+
"5. Start with `detail:\"summary\"` to orient, then drill into specifics",
|
|
192
213
|
"",
|
|
193
214
|
"### All 25 Tools",
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
"
|
|
198
|
-
"
|
|
199
|
-
"
|
|
200
|
-
"
|
|
201
|
-
"
|
|
215
|
+
"",
|
|
216
|
+
"| Tool | What it does |",
|
|
217
|
+
"|------|-------------|",
|
|
218
|
+
"| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
|
|
219
|
+
"| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
|
|
220
|
+
"| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
|
|
221
|
+
"| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
|
|
222
|
+
"| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
|
|
223
|
+
"| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
|
|
224
|
+
"| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
|
|
225
|
+
"| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
|
|
226
|
+
"| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
|
|
227
|
+
"| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
|
|
228
|
+
"| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
|
|
229
|
+
"| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
|
|
230
|
+
"| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
|
|
231
|
+
"| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
|
|
232
|
+
"| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
|
|
233
|
+
"| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
|
|
234
|
+
"| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
|
|
235
|
+
"| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
|
|
236
|
+
"| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
|
|
237
|
+
"| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
|
|
238
|
+
"| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
|
|
239
|
+
"| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
|
|
240
|
+
"| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
|
|
241
|
+
"| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
|
|
242
|
+
"| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
|
|
243
|
+
"| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |",
|
|
202
244
|
""
|
|
203
245
|
]
|
|
204
246
|
end
|
|
@@ -65,43 +65,80 @@ module RailsAiContext
|
|
|
65
65
|
lines.join("\n")
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength
|
|
68
|
+
def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
69
69
|
lines = [
|
|
70
|
-
"# Rails MCP Tools
|
|
70
|
+
"# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
|
|
71
71
|
"",
|
|
72
|
-
"
|
|
73
|
-
"Read files ONLY when you are about to
|
|
72
|
+
"This project has 25 live MCP tools. You MUST use them instead of reading files.",
|
|
73
|
+
"Read files ONLY when you are about to Edit them.",
|
|
74
74
|
"",
|
|
75
|
-
"
|
|
76
|
-
"1. Gathering context → use MCP tools (NOT file reads)",
|
|
77
|
-
"2. Reading files → ONLY files you will edit",
|
|
78
|
-
"3. After editing → rails_validate(files:[...]) every time",
|
|
75
|
+
"What Are You Trying to Do?",
|
|
79
76
|
"",
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"- Reading model files → rails_get_model_details(model:\"Name\")",
|
|
84
|
-
"- Grep for code → rails_search_code(pattern:\"regex\")",
|
|
85
|
-
"- Reading test files → rails_get_test_info(model:\"Name\")",
|
|
86
|
-
"- Reading controller → rails_get_controllers(controller:\"Name\", action:\"x\")",
|
|
87
|
-
"- Reading JS for Stimulus → rails_get_stimulus(controller:\"name\")",
|
|
88
|
-
"- Multiple reads for feature → rails_analyze_feature(feature:\"keyword\")",
|
|
89
|
-
"- ruby -c / erb / node -c → rails_validate(files:[...])",
|
|
77
|
+
"Understand a feature or area:",
|
|
78
|
+
" rails_analyze_feature(feature:\"cook\") — models + controllers + routes + services + jobs + views + tests in one call",
|
|
79
|
+
" rails_get_context(model:\"Cook\") — schema + model + controller + views assembled together",
|
|
90
80
|
"",
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
81
|
+
"Understand a method (who calls it, what it calls):",
|
|
82
|
+
" rails_search_code(pattern:\"can_cook?\", match_type:\"trace\") — definition + source + siblings + all callers + test coverage",
|
|
83
|
+
"",
|
|
84
|
+
"Add a field or modify a model:",
|
|
85
|
+
" rails_get_schema(table:\"cooks\") — columns, types, indexes, defaults, encrypted hints",
|
|
86
|
+
" rails_get_model_details(model:\"Cook\") — associations, validations, scopes, enums, callbacks, macros",
|
|
87
|
+
"",
|
|
88
|
+
"Fix a controller bug:",
|
|
89
|
+
" rails_get_controllers(controller:\"CooksController\", action:\"create\") — source + inherited filters + render map + side effects + private methods",
|
|
90
|
+
"",
|
|
91
|
+
"Build or modify a view:",
|
|
92
|
+
" rails_get_design_system(detail:\"standard\") — canonical HTML/ERB patterns to copy",
|
|
93
|
+
" rails_get_view(controller:\"cooks\") — templates with ivars, Turbo wiring, Stimulus refs",
|
|
94
|
+
" rails_get_partial_interface(partial:\"shared/status_badge\") — what locals to pass",
|
|
95
|
+
"",
|
|
96
|
+
"Write tests:",
|
|
97
|
+
" rails_get_test_info(detail:\"standard\") — framework + fixtures + test template to copy",
|
|
98
|
+
" rails_get_test_info(model:\"Cook\") — existing tests for a model",
|
|
99
99
|
"",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
100
|
+
"Find code:",
|
|
101
|
+
" rails_search_code(pattern:\"has_many\") — regex search with 2 lines of context",
|
|
102
|
+
" rails_search_code(pattern:\"create\", match_type:\"definition\") — only def lines",
|
|
103
|
+
" rails_search_code(pattern:\"can_cook\", match_type:\"call\") — only call sites",
|
|
104
|
+
"",
|
|
105
|
+
"After editing (EVERY time):",
|
|
106
|
+
" rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\") — syntax + semantics + security",
|
|
107
|
+
"",
|
|
108
|
+
"Rules:",
|
|
109
|
+
"1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
|
|
110
|
+
"2. NEVER use Grep for code search — use rails_search_code",
|
|
111
|
+
"3. NEVER run ruby -c, erb, or node -c — use rails_validate",
|
|
112
|
+
"4. Read files ONLY when you are about to Edit them",
|
|
113
|
+
"5. Start with detail:\"summary\" to orient, then drill into specifics",
|
|
114
|
+
"",
|
|
115
|
+
"All 25 Tools:",
|
|
116
|
+
"rails_analyze_feature(feature:\"X\") — Full-stack: models + controllers + routes + services + jobs + views + tests + gaps",
|
|
117
|
+
"rails_get_context(model:\"X\") — Composite: schema + model + controller + routes + views in one call",
|
|
118
|
+
"rails_search_code(pattern:\"X\", match_type:\"trace\") — Trace: definition + source + siblings + callers + test coverage",
|
|
119
|
+
"rails_get_controllers(controller:\"X\", action:\"Y\") — Action source + inherited filters + render map + side effects",
|
|
120
|
+
"rails_validate(files:[...], level:\"rails\") — Syntax + semantic validation + Brakeman security",
|
|
121
|
+
"rails_get_schema(table:\"X\") — Columns with indexed/unique/encrypted/default + orphaned table warnings",
|
|
122
|
+
"rails_get_model_details(model:\"X\") — Associations, validations, scopes, enums, macros, delegations",
|
|
123
|
+
"rails_get_routes(controller:\"X\") — Routes with code-ready helpers and controller filters inline",
|
|
124
|
+
"rails_get_view(controller:\"X\") — Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals",
|
|
125
|
+
"rails_get_design_system — Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals",
|
|
126
|
+
"rails_get_stimulus(controller:\"X\") — Targets, values, actions + copy-paste HTML data-attributes",
|
|
127
|
+
"rails_get_test_info(model:\"X\") — Existing tests + fixture contents + test template",
|
|
128
|
+
"rails_get_concern(name:\"X\", detail:\"full\") — Concern methods with full source code + includers",
|
|
129
|
+
"rails_get_callbacks(model:\"X\") — Callbacks in Rails execution order with source",
|
|
130
|
+
"rails_get_edit_context(file:\"X\", near:\"Y\") — Code around a match with class/method context + line numbers",
|
|
131
|
+
"rails_search_code(pattern:\"X\") — Regex search with smart limiting + exclude_tests + group_by_file",
|
|
132
|
+
"rails_get_service_pattern — Service objects: interface, dependencies, side effects, callers",
|
|
133
|
+
"rails_get_job_pattern — Jobs: queue, retries, guard clauses, broadcasts, schedules",
|
|
134
|
+
"rails_get_env — Environment variables + credentials keys (not values) + external services",
|
|
135
|
+
"rails_get_partial_interface(partial:\"X\") — Partial locals contract: what to pass + usage examples",
|
|
136
|
+
"rails_get_turbo_map — Turbo Stream/Frame wiring: broadcasts to subscriptions + mismatch warnings",
|
|
137
|
+
"rails_get_helper_methods — App + framework helper methods with view cross-references",
|
|
138
|
+
"rails_get_config — Database adapter, auth framework, assets stack, cache, queue, Action Cable",
|
|
139
|
+
"rails_get_gems — Notable gems with versions, categories, config file locations",
|
|
140
|
+
"rails_get_conventions — App patterns: auth checks, flash messages, create action template, test patterns",
|
|
141
|
+
"rails_security_scan — Brakeman static analysis: SQL injection, XSS, mass assignment"
|
|
105
142
|
]
|
|
106
143
|
|
|
107
144
|
lines.join("\n")
|
|
@@ -386,7 +386,14 @@ module RailsAiContext
|
|
|
386
386
|
# Extract method source from raw source string using indentation-based matching
|
|
387
387
|
private_class_method def self.extract_method_source(source, method_name)
|
|
388
388
|
source_lines = source.lines
|
|
389
|
-
|
|
389
|
+
escaped = Regexp.escape(method_name.to_s)
|
|
390
|
+
# Don't use \b after ? or ! — they ARE word boundaries
|
|
391
|
+
pattern = if method_name.to_s.end_with?("?") || method_name.to_s.end_with?("!")
|
|
392
|
+
/\A\s*def\s+#{escaped}/
|
|
393
|
+
else
|
|
394
|
+
/\A\s*def\s+#{escaped}\b/
|
|
395
|
+
end
|
|
396
|
+
start_idx = source_lines.index { |l| l.match?(pattern) }
|
|
390
397
|
return nil unless start_idx
|
|
391
398
|
|
|
392
399
|
def_indent = source_lines[start_idx][/\A\s*/].length
|
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.5",
|
|
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.5/rails-ai-context-mcp.mcpb",
|
|
15
15
|
"fileSha256": "dd711a0ad6c4de943ae4da94eaf59a6dc9494b9d57f726e24649ed4e2f156990",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|