rails-ai-context 5.34.1 → 5.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/docs/CLI.md CHANGED
@@ -218,14 +218,28 @@ Requires the `listen` gem. `rails ai:watch` needs it in the app's Gemfile; the s
218
218
 
219
219
  ### `init` (standalone only)
220
220
 
221
- Interactive setup for standalone mode.
221
+ Setup for a standalone install, interactive or answered by flags.
222
222
 
223
223
  ```bash
224
- rails-ai-context init
225
- rails-ai-context init --mcp-only # MCP config only, no context files
224
+ rails-ai-context init # asks
225
+ rails-ai-context init --tools claude --defaults # asks nothing: Claude Code, MCP config + context files
226
+ rails-ai-context init --tools claude,cursor --cli # context files only (CLI mode)
227
+ rails-ai-context init --tools all --mcp-only # MCP config only, no context files
228
+ rails-ai-context init --tools claude --prune --defaults # remove the files of tools dropped since the last run
226
229
  ```
227
230
 
228
- Asks which AI tools to configure and what to write: MCP config and context files, context files only (CLI mode), or MCP config only. Creates `.rails-ai-context.yml`, the MCP config files (except in CLI mode) and the context files (except with MCP config only). `--mcp-only` skips the second question. Every question - including a re-run's cleanup of dropped tools, and in CLI mode whether to take the gem's entries out of existing MCP configs - is asked before the app boots and anything is written; with MCP config only, the app is not booted at all.
231
+ Asks which AI tools to configure and what to write: MCP config and context files, context files only (CLI mode), or MCP config only. Creates `.rails-ai-context.yml`, the MCP config files (except in CLI mode) and the context files (except with MCP config only).
232
+
233
+ | Flag | Answers |
234
+ |:-----|:--------|
235
+ | `--tools LIST` | Which AI tools: `claude`, `cursor`, `copilot`, `opencode`, `codex`, comma-separated, or `all`. Names only, never menu numbers |
236
+ | `--mcp` | What to write: MCP config + context files (the first install's default) |
237
+ | `--cli` | What to write: context files only (CLI mode) |
238
+ | `--mcp-only` | What to write: MCP config only |
239
+ | `--prune` | Yes to every removal question: the generated files of tools dropped since the last run, the gem's MCP entries on a switch to the CLI setup, the generated context files on a switch to the MCP-only setup, and legacy files |
240
+ | `--defaults` | Every question no flag answered, with its default: all five tools and MCP config + context files on a first run, the recorded tools and setup on a re-run; files are kept |
241
+
242
+ A flag `init` cannot read (`--tools vim`, or two of `--mcp`, `--cli` and `--mcp-only`) exits 1 before anything is asked or written. A default never removes a file; only `--prune` does. The install generator takes the same flags, plus `--hook` for its pre-commit hook question. The [copy-paste prompts](PROMPTS.md) use them so an AI tool can run the setup in its own shell, and in the MCP setup the closing summary names each tool's next step: the approval or trust step that tool needs before it starts the server. Every question - including a re-run's cleanup of dropped tools, and in CLI mode whether to take the gem's entries out of existing MCP configs - is asked before the app boots and anything is written; with MCP config only, the app is not booted at all.
229
243
 
230
244
  Run inside an app, `init` sets up that app (found the way every command finds it: the [app root](#tool) above a subdirectory, or the one `--app-path` names).
231
245
 
@@ -239,7 +253,7 @@ work/ <- run `rails-ai-context init` here
239
253
  web/ .rails-ai-context.yml, CLAUDE.md, ...
240
254
  ```
241
255
 
242
- The AI tools and the setup are asked once. Each app gets its own `.rails-ai-context.yml` and context files, because its server reads them from its own root; a child process generates them with the install that app's server will run. The folder's MCP configs get one server per app, because a client reads its project config from the folder it opened. Each entry is named `rails-ai-context-<app folder>` (the whole path where two apps share a folder name; a short hash where the name would pass 30 characters, since Cursor drops a tool whose server and tool names together pass 60) and points `--app-path` at its app:
256
+ The AI tools and the setup are asked once. On a re-run whose apps recorded different setups there is no one setup to keep, so `--defaults` without `--mcp`, `--cli` or `--mcp-only` stops with exit status 1 and asks for one. Each app gets its own `.rails-ai-context.yml` and context files, because its server reads them from its own root; a child process generates them with the install that app's server will run. The folder's MCP configs get one server per app, because a client reads its project config from the folder it opened. Each entry is named `rails-ai-context-<app folder>` (the whole path where two apps share a folder name; a short hash where the name would pass 30 characters, since Cursor drops a tool whose server and tool names together pass 60) and points `--app-path` at its app:
243
257
 
244
258
  ```json
245
259
  {
@@ -268,6 +282,40 @@ The AI tools and the setup are asked once. Each app gets its own `.rails-ai-cont
268
282
 
269
283
  Start the client in the workspace folder. A client started inside one of the apps (Claude Code, Codex and OpenCode still read a config above it) runs each workspace server from there, where the relative path misses; the server says which folder the path was written for. To open an app on its own, run `init` inside it as well. `init` warns when an app declares a Ruby other than the one the workspace runs, since every server it starts runs under that one. `doctor` inside one of the apps finds the workspace's config one or two levels up.
270
284
 
285
+ ### `uninstall`
286
+
287
+ Removes what the gem wrote: each AI tool's context files and MCP entries, `.rails-ai-context.yml`, `.ai-context.json`, the initializer, the `.gitignore` lines and the pre-commit hook it installed.
288
+
289
+ ```bash
290
+ rails-ai-context uninstall
291
+ bundle exec rails-ai-context uninstall # in-Gemfile; then bundle remove rails-ai-context
292
+ ```
293
+
294
+ What you wrote stays: your lines around the markers in a shared `CLAUDE.md` or `AGENTS.md`, your rule files, other servers in an MCP config, and a pre-commit hook you changed by hand (named, not touched). Its own config files go even when you edited them: `.rails-ai-context.yml` and the initializer configure nothing once the gem is gone. An HTTP entry under the gem's name goes too, since only the gem's endpoint answers it. A `mount RailsAiContext::Engine` line in `config/routes.rb` is named with its line number for you to delete. In a folder of apps it uninstalls every app below and the folder's MCP configs. It needs no boot. An entry you added by hand to another client's own config from `mcp-entry` (Claude Desktop and the like) lives outside the app, so remove it there. Its last lines say how to remove the gem itself: `bundle remove rails-ai-context` when the Gemfile lists it, `gem uninstall rails-ai-context` once no other app uses the installed copy. Details in the [Guide](GUIDE.md#uninstalling).
295
+
296
+ ### `mcp-entry`
297
+
298
+ Prints an MCP server entry for a client the install writes no config for: Claude Desktop, Windsurf, Zed, a JetBrains IDE.
299
+
300
+ ```bash
301
+ rails-ai-context mcp-entry
302
+ bundle exec rails-ai-context mcp-entry # in-Gemfile
303
+ ```
304
+
305
+ ```json
306
+ {
307
+ "mcpServers": {
308
+ "rails-ai-context": {
309
+ "command": "/Users/you/.rbenv/versions/3.4.1/bin/ruby",
310
+ "args": ["/Users/you/.rbenv/versions/3.4.1/bin/rails-ai-context", "serve", "--app-path", "/Users/you/work/shop"],
311
+ "env": { "PATH": "...", "GEM_HOME": "..." }
312
+ }
313
+ }
314
+ }
315
+ ```
316
+
317
+ Such a client starts its servers from its own folder with its own `PATH`, so every path is absolute. The command is the Ruby the binary runs under, by its full path, which no version manager's shim can swap for the Ruby of the client's folder; `--app-path` names the app; `env` carries the gem variables the shell had (`PATH`, `GEM_HOME`, `GEM_PATH`, `GEM_ROOT`, `RUBY_VERSION`, `BUNDLE_PATH`). For an in-Gemfile app the entry runs `bundle exec` with `BUNDLE_GEMFILE` naming the app's Gemfile. Merge it into the client's config under the key that client uses for servers, and print it again after the app moves or its Ruby changes. See [Other MCP clients](SETUP.md#other-mcp-clients).
318
+
271
319
  ### `version`
272
320
 
273
321
  ```bash
@@ -296,6 +296,13 @@ Proof sources:
296
296
  In the v5.34.1 release QA: the gem built from the release commit and its
297
297
  file list read, and the unit suite and the E2E harness on Linux, macOS and
298
298
  Windows; the code is v5.34.0's.
299
+ In the v5.35.0 release QA: every copy-paste prompt in `docs/PROMPTS.md`
300
+ pasted into Claude Code (`claude -p`) and Codex CLI (`codex exec`) and the
301
+ result checked on disk, 40 scenarios in fresh Rails 8.1 apps, an app that
302
+ cannot boot, a mountable engine, a Docker container and a copy of a
303
+ private production app; each AI tool's MCP config started the way its
304
+ client starts it; and the unit suite and the E2E harness on Linux, macOS
305
+ and Windows.
299
306
  2. Non-crash coverage for every built-in tool including `get_view` in
300
307
  `spec/e2e/in_gemfile_install_spec.rb`'s full-tool sweep; output correctness
301
308
  (ivar cross-check, render-form detection, partial interfaces) verified
@@ -60,6 +60,7 @@ server and nothing else:
60
60
 
61
61
  ```bash
62
62
  rails generate rails_ai_context:install --mcp-only # or: rails-ai-context init --mcp-only
63
+ rails generate rails_ai_context:install --tools claude --mcp-only --defaults # asks nothing
63
64
  ```
64
65
 
65
66
  That writes the MCP config for the tools you pick and records:
data/docs/FAQ.md CHANGED
@@ -18,7 +18,7 @@ It gives AI coding assistants verified, real-time access to your Rails app's str
18
18
 
19
19
  ### Which AI tools are supported?
20
20
 
21
- Claude Code, Cursor, GitHub Copilot, OpenCode, and Codex CLI. Each gets tailored context files and MCP auto-discovery config.
21
+ Claude Code, Cursor, GitHub Copilot, OpenCode, and Codex CLI. Each gets tailored context files and an MCP config it finds when it opens the project; you approve the server once in the tool.
22
22
 
23
23
  ### Do I need MCP support in my AI tool?
24
24
 
@@ -39,6 +39,14 @@ Yes. The gem gracefully degrades - it parses `db/schema.rb` as text when no data
39
39
 
40
40
  ## Installation
41
41
 
42
+ ### Can my AI tool install it for me?
43
+
44
+ Yes. [Copy-paste prompts](PROMPTS.md) has one prompt per setup: the usual install, no Gemfile change, CLI only, MCP only, every AI tool for a team, a folder of apps, a private setup with nothing committed, and a try-out that writes nothing. More cover changing the setup, upgrading, fixing and uninstalling. Each runs the install with every answer given as a flag, so it never waits on a question.
45
+
46
+ ### How do I uninstall it?
47
+
48
+ `bundle exec rails-ai-context uninstall` (or `rails-ai-context uninstall` standalone), then `bundle remove rails-ai-context` if the Gemfile lists it. It removes what the gem wrote and keeps what you wrote, such as your own lines in `CLAUDE.md`. See [Uninstalling](GUIDE.md#uninstalling).
49
+
42
50
  ### Gemfile or standalone - which should I use?
43
51
 
44
52
  **In-Gemfile** is recommended if you own the project. Gives you the install generator, rake tasks, and initializer config.
@@ -56,7 +64,7 @@ Yes. Run `rails-ai-context init` in that folder. It asks once, gives each app it
56
64
  ### Do I need to commit the generated files?
57
65
 
58
66
  **Yes, commit these:**
59
- - `.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json` - so teammates get MCP auto-discovery
67
+ - `.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json` - so teammates get the MCP server after approving it once in their AI tool
60
68
  - `CLAUDE.md`, `.claude/rules/`, `.cursor/rules/`, `.cursorrules`, `.github/copilot-instructions.md`, `.github/instructions/`, `AGENTS.md` - so AI has context
61
69
  - `config/initializers/rails_ai_context.rb`, `.rails-ai-context.yml` - so config is shared
62
70
 
@@ -70,6 +78,7 @@ Yes:
70
78
 
71
79
  ```bash
72
80
  rails generate rails_ai_context:install --mcp-only # or: rails-ai-context init --mcp-only
81
+ rails generate rails_ai_context:install --tools claude --mcp-only --defaults # asks nothing
73
82
  ```
74
83
 
75
84
  The MCP config is written, `config.context_files = false` is recorded, and no
@@ -238,7 +247,7 @@ Those are AI coding interfaces. This gem is a data layer that makes *any* of the
238
247
 
239
248
  ### My AI tool doesn't see the MCP server
240
249
 
241
- Run `rails ai:doctor` - it checks each configured tool's MCP config file, and whether the command it holds can start. See [Troubleshooting](TROUBLESHOOTING.md) for detailed steps.
250
+ Each AI tool holds a project's MCP server back until you take a step in the tool itself: approve it in Claude Code, turn it on in Cursor, trust the folder in VS Code and Codex CLI, restart OpenCode. The install's summary names the step for each tool you picked. If it is done and the tools still don't appear, run `rails ai:doctor` - it checks each configured tool's MCP config file, and whether the command it holds can start. See [Troubleshooting](TROUBLESHOOTING.md#ai-tool-doesnt-detect-the-mcp-server) for detailed steps.
242
251
 
243
252
  ### Tools return empty results
244
253
 
data/docs/GUIDE.md CHANGED
@@ -18,6 +18,7 @@
18
18
  | Guide | Description |
19
19
  |:------|:------------|
20
20
  | [Quickstart](QUICKSTART.md) | Get running in 5 minutes |
21
+ | [Copy-paste prompts](PROMPTS.md) | Let your AI tool install, change, remove or use the gem |
21
22
  | [Tools Reference](TOOLS.md) | All 45 MCP tools with parameters |
22
23
  | [Recipes](RECIPES.md) | Real-world workflows and examples |
23
24
  | [Custom Tools](CUSTOM_TOOLS.md) | Build your own MCP tools |
@@ -36,6 +37,7 @@
36
37
  ## Table of Contents
37
38
 
38
39
  - [Installation](#installation)
40
+ - [Uninstalling](#uninstalling)
39
41
  - [Context Modes](#context-modes)
40
42
  - [Generated Files](#generated-files)
41
43
  - [All Commands](#all-commands)
@@ -69,7 +71,7 @@ rails ai:context
69
71
  This creates:
70
72
  1. `config/initializers/rails_ai_context.rb` - configuration file
71
73
  2. `.rails-ai-context.yml` - standalone config (enables switching later)
72
- 3. Per-tool MCP config files - auto-discovery for Claude Code, Cursor, Copilot, OpenCode, and Codex
74
+ 3. Per-tool MCP config files - each AI tool finds its own when it opens the project, then asks you to approve the server once
73
75
  4. Context files - tailored for each AI assistant
74
76
 
75
77
  ### Option B: Standalone (no Gemfile entry needed)
@@ -82,16 +84,16 @@ rails-ai-context init
82
84
 
83
85
  This creates:
84
86
  1. `.rails-ai-context.yml` - configuration file
85
- 2. Per-tool MCP config files - auto-discovery (if MCP mode selected)
87
+ 2. Per-tool MCP config files - in the MCP and MCP-only setups
86
88
  3. Context files - tailored for each AI assistant
87
89
 
88
90
  No Gemfile entry, no initializer, no files in your project besides config and context.
89
91
 
90
92
  ### What the install generator does
91
93
 
92
- `rails generate rails_ai_context:install` runs these steps in this order. Steps 1, 2, 3, 8 and 9 can ask a question.
94
+ `rails generate rails_ai_context:install` runs these steps in this order. Steps 1, 2, 3, 4, 8 and 9 can ask a question.
93
95
 
94
- 1. **Asks which AI tools you use.** It prints this menu, then `Enter numbers separated by commas (e.g. 1,2) or 'a' for all:`
96
+ 1. **Asks which AI tools you use.** It prints this menu, then `Enter numbers separated by commas (e.g. 1,2) or 'a' for all (default: all):`, or `(default: keep the current selection):` on a re-run
95
97
 
96
98
  ```
97
99
  1. Claude Code -> CLAUDE.md + .claude/rules/
@@ -102,29 +104,34 @@ No Gemfile entry, no initializer, no files in your project besides config and co
102
104
  a. All of the above
103
105
  ```
104
106
 
105
- On a re-run the menu is followed by the selection recorded last time, as `Currently selected: 1,2 (Claude Code, Cursor)`. There is no "none" choice. An empty answer selects all five, and so does one with no valid number in it, which says so (`"9" names no tool - selecting all.`).
107
+ On a re-run the menu is followed by the selection recorded last time, as `Currently selected: 1,2 (Claude Code, Cursor)`. There is no "none" choice. An empty answer takes the default: the recorded selection on a re-run, all five on a first install. So does an answer with no valid number in it, which says so (`"9" names no tool - keeping the current selection.`).
106
108
  2. **Offers to clean up tools you dropped.** Only on a re-run, and only when the last recorded selection (the `config.ai_tools` line in the initializer, else `.rails-ai-context.yml`) has a tool you did not pick this time. It lists them and asks `Remove their generated files?` with `y` (all), `n` (keep, the default) or numbers like `1,2`. A yes removes only what the gem generated: the rule files it names inside the tool's rules directory (the directory goes too when nothing else is left in it), and the block between the `rails-ai-context` markers in a root file such as `CLAUDE.md`. A rule file you wrote by hand, your own lines around the markers, a root file with no markers and a symlink are left alone. It keeps any file shared with a tool whose files stay (`AGENTS.md`) - one still selected, or one dropped whose files you kept by leaving its number out - and says so, and takes only the `rails-ai-context` entry out of the tool's MCP config - a config left with no other entry is deleted, and named as removed. A tool's dot-directory the cleanup emptied (`.cursor/`, `.github/`, `.codex/`, `.vscode/`) goes too; one that still holds a file of yours stays.
107
- 3. **Asks what to write**, then `Enter number (default: 1):`
109
+ 3. **Asks what to write**, then `Enter number (default: 1):`. On a re-run it first prints the recorded setup (`Currently: Context files only (CLI mode, no MCP server)`), and that is the default
108
110
 
109
111
  ```
110
112
  1. MCP config + context files (default)
111
113
  2. Context files only (CLI mode, no MCP server)
112
- 3. MCP config only (leaves CLAUDE.md, AGENTS.md and rules untouched)
114
+ 3. MCP config only (writes no CLAUDE.md, AGENTS.md or rules files)
113
115
  ```
114
116
 
115
- Choices 1 and 3 set `tool_mode` to `:mcp`, choice 2 sets it to `:cli`. Choice 3 also sets `context_files` to `false`. Any other answer counts as 1.
116
- 4. **Writes the MCP config for each selected tool** (`.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json`, `.codex/config.toml`). Skipped for choice 2, which instead lists any config that still starts `rails-ai-context` and asks `Remove rails-ai-context from them? (y/N)`: CLI mode starts no MCP server. A yes takes out only the gem's entries, as step 2 does. An existing file is merged: only the `rails-ai-context` entry is added or replaced. One that does not parse as JSON, or holds comments a rewrite would drop, is left as it is, with a warning that names the entry to add by hand. Each file is read as its client reads it. VS Code's and OpenCode's take JSONC, comments and trailing commas (read under json 2.9 or later); Claude Code reads `.mcp.json` as plain JSON, and Cursor's `.cursor/mcp.json` is held to plain JSON too, so a comment or a trailing comma in either is reported as one the client cannot read, and the file left as it is. In `.codex/config.toml` the server's table is found however its name is quoted, and replaced where it stands; an entry of the gem's written as an inline table or with dotted keys is left as it is, with a warning, since a table added beside it would declare the server twice, which Codex refuses.
117
+ Choices 1 and 3 set `tool_mode` to `:mcp`, choice 2 sets it to `:cli`. Choice 3 also sets `context_files` to `false`. Any other answer takes the default.
118
+ 4. **Writes the MCP config for each selected tool** (`.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json`, `.codex/config.toml`). Skipped for choice 2, which instead lists any config that still starts `rails-ai-context` and asks `Remove rails-ai-context from them? (y/N)`: CLI mode starts no MCP server. A yes takes out only the gem's entries, as step 2 does. With choice 3 it lists instead the context files an earlier setup generated, which nothing refreshes once the install writes no context files, and asks `Remove the generated parts? Lines you wrote stay. (y/N)`; a yes removes them the way step 2 does, and `.ai-context.json` with them. An existing file is merged: only the `rails-ai-context` entry is added or replaced. One that does not parse as JSON, or holds comments a rewrite would drop, is left as it is, with a warning that names the entry to add by hand. Each file is read as its client reads it. VS Code's and OpenCode's take JSONC, comments and trailing commas (read under json 2.9 or later); Claude Code reads `.mcp.json` as plain JSON, and Cursor's `.cursor/mcp.json` is held to plain JSON too, so a comment or a trailing comma in either is reported as one the client cannot read, and the file left as it is. In `.codex/config.toml` the server's table is found however its name is quoted, and replaced where it stands; an entry of the gem's written as an inline table or with dotted keys is left as it is, with a warning, since a table added beside it would declare the server twice, which Codex refuses.
117
119
  5. **Creates or updates `config/initializers/rails_ai_context.rb`.** A new file gets your three answers as live lines (`config.ai_tools`, `config.tool_mode`, `config.context_files`) and every other option commented out at its default, wrapped in `if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)`; it passes the omakase Rubocop a new Rails app runs. In an existing file it rewrites those three lines where the value changed - keeping the line's indentation and any note of your own after it - appends any config section the file lacks, adds the guard if it is missing, and leaves the rest alone.
118
120
  6. **Writes `.rails-ai-context.yml`** with `ai_tools`, `tool_mode` and `context_files`. Only a key whose value changed is rewritten, where it stands; your comments and other keys are kept, and a run that changes no value leaves the file as it was.
119
121
  7. **Adds lines to `.gitignore`**, if the file exists: `.ai-context.json` (not for choice 3) and `.codex/config.toml` (always, because it holds this machine's Ruby paths). A line that is already there is not added again.
120
122
  8. **Asks about a pre-commit hook:** `Install a pre-commit hook that checks staged Ruby, ERB and JavaScript files for syntax errors? (y/N)`. Only `y` installs it. The hook runs `bundle exec rails-ai-context tool validate` (`rails-ai-context tool validate` in a standalone install) on the staged `.rb`, `.erb`, `.js`, `.mjs` and `.cjs` files and stops a commit whose files do not parse (JavaScript is parsed by `node`, as [`rails_validate`](TOOLS.md#rails_validate) describes); the Rails-reference checks (`level=rails`) are left to the tool, as Brakeman would slow every commit. An app that cannot boot (an initializer that needs a variable the shell lacks, say) is still checked, from its source, and the hook shows why it did not boot; it shows whatever else the check prints to stderr too, so a check that cannot run says why. Every staged name is read whole, one with characters outside ASCII included; a name holding a comma, which the files list cannot carry, is named and left unchecked. It goes where git runs hooks (`git rev-parse --git-path hooks`), so an app checked out as a submodule, an app inside a monorepo and a repo with `core.hooksPath` set all get it where git will run it. The hook names the apps it covers and validates each one's staged files (deleted ones aside) from inside that app; installing in a second app of the same monorepo adds it to the hook, unless the hook was changed by hand, which it says, and for an app below the top of the repository the question names the repository. A hook an earlier version wrote, and nobody changed since, is brought up to date without asking again: the oldest handed validate the files a commit deletes too, and the commit failed on them, and later ones ran `rails 'ai:tool[validate]'`, which has to boot the app, with its errors thrown away, so an app that could not boot failed every commit with no reason given. Any other hook that runs `rails-ai-context` - one changed by hand, or a team's own that calls it among other checks - is left as it is, with a message. No hook is offered for an app the repository does not track yet (an app under a dotfiles repository at `$HOME`, say), nor into a `core.hooksPath` outside the repository, which every repository using it shares; both say why. No question is asked outside a git repository or when the hook already covers the app. When another `pre-commit` hook exists there it prints `Skipped pre-commit hook (existing hook found - add manually)` and moves on.
121
- 9. **Generates the context files** for the selected tools. Skipped for choice 3. If files that v5.0.0 stopped generating are still there (`.claude/rules/rails-ui-patterns.md`, `.claude/rules/rails-accessibility.md`, `.cursor/rules/rails-ui-patterns.mdc`, `.github/instructions/rails-ui-patterns.instructions.md`), it lists them first and asks `Delete them? [y/N]:`. Without a terminal, or under `--defaults`, it prints the `rm` command and does not ask.
122
- 10. **Prints a summary:** the files each selected tool got and the commands to run next.
123
+ 9. **Generates the context files** for the selected tools. Skipped for choice 3. If files that v5.0.0 stopped generating are still there (`.claude/rules/rails-ui-patterns.md`, `.claude/rules/rails-accessibility.md`, `.cursor/rules/rails-ui-patterns.mdc`, `.github/instructions/rails-ui-patterns.instructions.md`), it lists them first and asks `Delete them? [y/N]:`. Without a terminal, or under `--defaults`, it prints the `rm` command and does not ask; under `--prune` it deletes them without asking.
124
+ 10. **Prints a summary:** the files each selected tool got, the commands to run next, and, in the MCP setup, each tool's next step: the approval or trust step that tool asks for before it starts a project's MCP server (approve the server in Claude Code, turn it on in Cursor, trust the folder in VS Code and Codex CLI, restart OpenCode).
123
125
 
124
- Two flags change the prompts:
126
+ Every question has a flag, so an AI tool or a script can run the install to the end with nobody at the keyboard (the [copy-paste prompts](PROMPTS.md) are built on them):
125
127
 
126
- - `--defaults` answers every prompt with its default: all five tools, keep dropped tools' files, choice 1, no hook, keep legacy files. Piping an empty stdin does the same.
127
- - `--mcp-only` skips the step 3 question and acts as choice 3. Steps 1, 2 and 8 still ask.
128
+ - `--tools claude,cursor` answers step 1. It takes the tool names `claude`, `cursor`, `copilot`, `opencode` and `codex`, comma-separated, or `all`; never the menu numbers, which would pick another tool once one is added.
129
+ - `--mcp` answers step 3 with choice 1, `--cli` with choice 2, `--mcp-only` with choice 3. Only one of them can be given.
130
+ - `--prune` answers yes to every removal question: step 2 (dropped tools' generated files), step 4's in the CLI setup (the gem's MCP entries) and in the MCP-only setup (the context files an earlier setup generated), and step 9's (legacy files).
131
+ - `--hook` answers yes to step 8.
132
+ - `--defaults` answers every question no flag answered with its default. On a first install that is all five tools and choice 1; on a re-run it is the recorded tools and setup, so running the install again with `--defaults` repairs it without switching anything. Every removal question defaults to keep, and the hook to no. Piping an empty stdin does the same. A default never removes a file; only `--prune` does.
133
+
134
+ A flag the install cannot read (a name that is no tool, two setup flags at once, or a flag it does not have, such as a mistyped one) stops it with exit status 1 before anything is asked or written. [ADR-0007](adr/0007-every-install-question-has-a-flag.md) records the design.
128
135
 
129
136
  Run from a mountable engine's root, where `bin/rails` boots `test/dummy`, the install goes into the engine's root - the folder an editor is opened at, and the one every `rails-ai-context` command run there reads: the MCP configs, `.rails-ai-context.yml`, the `.gitignore` lines and the context files, which are generated from the engine's source the way its MCP server reads it there. No initializer is written, since Rails runs an engine's `config/initializers` in every app that mounts it and the gemspec ships them; one an earlier install left there is named, with a note to delete it. Step 8 offers no hook at the engine's root (its rake tasks run in the dummy app, as `app:ai:*`), and the summary lists the commands that work at the engine's root, `bundle exec rails-ai-context ...`. The context files written there name the same commands for their CLI fallback and the server, as do the tools' own hints. `bundle exec rails-ai-context doctor` at the engine's root diagnoses the dummy app and reads this install, as `bin/rails app:ai:doctor` does.
130
137
 
@@ -132,11 +139,30 @@ A team that wants no AI tool files in the repo can skip the generator. The gem n
132
139
 
133
140
  Two other entry points ask the same step 1 and step 3 questions:
134
141
 
135
- - `rails-ai-context init` (standalone) asks both, then the step 2 cleanup question, step 4's question about MCP configs when the answer was CLI mode, and the step 9 question. Only then does it boot the app, so that every gem the app locks loads at the app's pin, and write: the cleanup, `.rails-ai-context.yml`, the MCP configs, the `.gitignore` lines and the context files. An MCP-only run skips the step 9 question, as the generator does, and boots nothing. It never creates the initializer (in one that exists it updates `config.ai_tools`, `config.tool_mode` and `config.context_files`), never offers the pre-commit hook, and has `--mcp-only` but no `--defaults`. Typed outside the app (`init --app-path ../shop`), it names the files it wrote from there, as `../shop/.mcp.json`. Run in a folder that holds several apps, it asks once and sets them all up: each app's own `.rails-ai-context.yml` and context files, and one MCP server per app in the folder's configs ([`init`](CLI.md#init-standalone-only)).
142
+ - `rails-ai-context init` (standalone) asks both, then the step 2 cleanup question, step 4's question about MCP configs when the answer was the CLI setup or about generated context files when it was MCP only, and the step 9 question. Only then does it boot the app, so that every gem the app locks loads at the app's pin, and write: the cleanup, `.rails-ai-context.yml`, the MCP configs, the `.gitignore` lines and the context files. An MCP-only run skips the step 9 question, as the generator does, and boots nothing. It never creates the initializer (in one that exists it updates `config.ai_tools`, `config.tool_mode` and `config.context_files`), never offers the pre-commit hook, and takes the same flags as the generator but `--hook`: `--tools`, `--mcp`, `--cli`, `--mcp-only`, `--prune` and `--defaults`. Typed outside the app (`init --app-path ../shop`), it names the files it wrote from there, as `../shop/.mcp.json`. Run in a folder that holds several apps, it asks once and sets them all up: each app's own `.rails-ai-context.yml` and context files, and one MCP server per app in the folder's configs ([`init`](CLI.md#init-standalone-only)).
136
143
  - `rails ai:context` asks step 1 only when no tool selection is recorded, and step 3 only when no `tool_mode` is recorded. It then writes `.rails-ai-context.yml`, the MCP configs and the `.gitignore` lines before generating. It does not create the initializer or offer the hook. `rails-ai-context context` brings the MCP configs of a recorded selection up to date the same way, and `rails ai:context:<tool>` writes that tool's MCP config along with its files.
137
144
 
138
145
  ---
139
146
 
147
+ ## Uninstalling
148
+
149
+ ```bash
150
+ bundle exec rails-ai-context uninstall # in the Gemfile; then: bundle remove rails-ai-context
151
+ rails-ai-context uninstall # standalone; then, once no app uses it: gem uninstall rails-ai-context
152
+ ```
153
+
154
+ `uninstall` takes out what the gem wrote and nothing you wrote:
155
+
156
+ - Each AI tool's context files. A rules file you wrote stays, and in a root file such as `CLAUDE.md` only the block between the `rails-ai-context` markers goes, so your own lines stay. A file left empty is deleted, and so is a tool's dot-directory (`.cursor/`, `.claude/`) once nothing of yours is in it.
157
+ - The `rails-ai-context` entry in every MCP config, an HTTP one under that name included. Other servers in the file stay; a config left with none is deleted.
158
+ - `.rails-ai-context.yml`, `.ai-context.json` and `config/initializers/rails_ai_context.rb`, edited or not: they configure nothing once the gem is gone.
159
+ - The lines the install added to `.gitignore`, with their comments.
160
+ - The pre-commit hook, when it is the one the install wrote and covers only this app. A hook that covers other apps of the repository loses this one; a hook changed by hand is named and left for you.
161
+
162
+ A `mount RailsAiContext::Engine` line in `config/routes.rb` is your code, so it is named with its line number, not edited. Run in a folder of apps, it does the same for every app below and for the folder's MCP configs. It needs no boot, so it works on an app that cannot start, and the binary of any install can run it: in an app whose bundle pins a version from before `uninstall` existed, `gem install rails-ai-context` and run `rails-ai-context uninstall`.
163
+
164
+ ---
165
+
140
166
  ## Context Modes
141
167
 
142
168
  The gem has two context modes that control how much data goes into the generated files:
@@ -310,7 +336,8 @@ Each `rails ai:context:<tool>` adds its tool to the recorded selection and, in M
310
336
  The gem ships a `rails-ai-context` executable that works **without adding the gem to your Gemfile**. Install globally with `gem install rails-ai-context`, then run from any Rails app directory.
311
337
 
312
338
  ```bash
313
- rails-ai-context init # Interactive setup (creates .rails-ai-context.yml + MCP configs)
339
+ rails-ai-context init # Setup: asks, or takes every answer as a flag (creates .rails-ai-context.yml + MCP configs)
340
+ rails-ai-context init --tools claude --defaults # The same, every answer given as a flag
314
341
  rails-ai-context serve # Start MCP server (stdio)
315
342
  rails-ai-context serve --transport http # Start MCP server (HTTP, port 6029)
316
343
  rails-ai-context serve --transport http --port 8080 # Custom port
@@ -325,6 +352,8 @@ rails-ai-context watch # Watch for changes
325
352
  rails-ai-context inspect # Print introspection JSON
326
353
  rails-ai-context facts # Print schema facts summary
327
354
  rails-ai-context preset architecture # Run a multi-tool preset
355
+ rails-ai-context uninstall # Remove what the gem wrote, keep what you wrote
356
+ rails-ai-context mcp-entry # Print an MCP entry for Claude Desktop, Windsurf, Zed and other clients
328
357
  rails-ai-context version # Print version
329
358
  rails-ai-context help # Show all commands
330
359
  ```
@@ -1142,7 +1171,7 @@ This server is listed on the [official MCP Registry](https://registry.modelconte
1142
1171
  curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=rails-ai-context"
1143
1172
  ```
1144
1173
 
1145
- ### Auto-discovery (recommended)
1174
+ ### Per-tool MCP config files (recommended)
1146
1175
 
1147
1176
  The install generator (or `rails-ai-context init`) creates per-tool MCP config files based on your selected AI tools:
1148
1177
 
@@ -1185,11 +1214,11 @@ GEM_HOME = "/home/user/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0"
1185
1214
 
1186
1215
  > **Why the `[env]` section?** Codex CLI `env_clear()`s the process before spawning MCP servers, stripping Ruby version manager paths. The install generator snapshots your current Ruby environment (PATH, GEM\_HOME, GEM\_PATH, GEM\_ROOT, RUBY\_VERSION, BUNDLE\_PATH) so the MCP server can find gems regardless of version manager (rbenv, rvm, asdf, mise, chruby, or system Ruby).
1187
1216
 
1188
- Each AI tool auto-detects its own config file. No manual config needed - just open your project.
1217
+ Each AI tool finds its own config file when it opens the project, then holds the server back until you approve it once: approve it in Claude Code, turn it on in Cursor, trust the folder in VS Code and Codex CLI, restart OpenCode. The install's summary names the step for each tool you picked ([AI tool setup](SETUP.md#verify-mcp-is-connected)).
1189
1218
 
1190
1219
  ### Claude Code
1191
1220
 
1192
- Auto-discovered via `.mcp.json`. Or add manually:
1221
+ Read from `.mcp.json` once you approve the server. Or add manually:
1193
1222
 
1194
1223
  ```bash
1195
1224
  # In-Gemfile
@@ -1222,7 +1251,7 @@ Or for standalone: replace `"command": "bundle"` / `"args": ["exec", "rails-ai-c
1222
1251
 
1223
1252
  ### Cursor
1224
1253
 
1225
- Auto-discovered via `.cursor/mcp.json`. Or add manually in **Cursor Settings > MCP**:
1254
+ Read from `.cursor/mcp.json` once you turn the server on. Or add manually:
1226
1255
 
1227
1256
  ```json
1228
1257
  {
@@ -1562,17 +1591,17 @@ config.introspectors = %i[schema models routes gems auth api]
1562
1591
 
1563
1592
  ### Claude Code
1564
1593
 
1565
- **Auto-discovery:** Opens `.mcp.json` automatically. No setup needed.
1594
+ **Auto-discovery:** Reads `.mcp.json` when a session starts in the folder, and asks you to approve the `rails-ai-context` server once (`claude mcp reset-project-choices` asks again).
1566
1595
 
1567
1596
  **Context files loaded:**
1568
1597
  - `CLAUDE.md` - read at conversation start
1569
1598
  - `.claude/rules/*.md` - auto-loaded alongside CLAUDE.md (schema, models, and components rules use `paths:` frontmatter for conditional loading)
1570
1599
 
1571
- **MCP tools:** Available immediately via `.mcp.json`.
1600
+ **MCP tools:** Available once the server is approved. `/mcp` lists it.
1572
1601
 
1573
1602
  ### Cursor
1574
1603
 
1575
- **Auto-discovery:** Opens `.cursor/mcp.json` automatically. No setup needed.
1604
+ **Auto-discovery:** Reads `.cursor/mcp.json`. Restart Cursor after the install, and turn `rails-ai-context` on under MCP in Customize if it is off.
1576
1605
 
1577
1606
  **Context files loaded:**
1578
1607
  - `.cursor/rules/*.mdc` - loaded based on `alwaysApply` and `globs` settings