# Rust off Rails MCP server

A hosted, read-only Model Context Protocol server: `https://rustoffrails.org/mcp` (Streamable HTTP, stateless, no authentication). Your agent can search the docs of the exact framework version your app uses, read any guide, map Rails and Phoenix concepts, start an app and upgrade one, with nothing to install.

## 1. Connect your agent

There is no sign-in: choose "no authentication" wherever a client asks.

### Claude Code

```sh
claude mcp add --transport http rustoffrails https://rustoffrails.org/mcp
```

Add `--scope user` to have it in every project.

### Claude (Desktop and claude.ai)

Customize → Connectors → Add → Add custom connector. Name it "Rust off Rails", paste the URL, choose no sign-in, then turn it on from the + menu in a chat. Guide: https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp

### Cursor

In `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "rustoffrails": {
      "url": "https://rustoffrails.org/mcp"
    }
  }
}
```

### Codex

```sh
codex mcp add rustoffrails --url https://rustoffrails.org/mcp
```

Or in `~/.codex/config.toml`:

```toml
[mcp_servers.rustoffrails]
url = "https://rustoffrails.org/mcp"
```

### ChatGPT

Turn on developer mode, then create an app (formerly "connector") with the URL and No authentication. OpenAI moves these menus, so see your client's docs for the current path.

## 2. Tools and resources

All read-only. By default they answer from the same docs as https://rustoffrails.org/docs and https://rustoffrails.org/llms.txt; the docs tools take a `version` for any other release.

- `search_docs`: Search the Rust off Rails framework docs (guides, generators, AGENTS.md, stack, workflow…). Returns ranked sections with the doc path, title, a snippet and the URL. Then read a whole doc with read_doc.
- `read_doc`: Read one framework doc as Markdown, by its docs path (e.g. "guides/models.md", "AGENTS.md", "generators/new.md") or slug ("guides/models"). Only docs in the index exist.
- `rails_map`: Look up how a Ruby on Rails or Elixir/Phoenix concept maps to Rust off Rails (RAILS_MAP.md): returns the matching rows with the guide to read.
- `list_skills`: List the Claude Code plugin's skills (/offrails:new, :feature, :scaffold…) with when to use each and an example.
- `starter_prompt`: A ready-to-paste prompt that starts a new Rust off Rails app, for Claude Code (/offrails:new) and for any AGENTS.md agent. Pick a gallery kind, or "custom" with your own name and pitch.
- `stack_versions`: The crate versions the framework was last verified against (stack.md, "Verified against"). Orientation, not a pin: agents still cargo add.
- `framework_info`: The latest framework version and every version whose docs this server has, the install one-liner, the Claude Code plugin commands, the repository and the site's links.
- `upgrade_path`: How to upgrade an app from one framework version to another: the CHANGELOG sections in between, oldest first, with every App migration note, plus which docs were added, removed or changed.
- `diff_doc`: A unified diff of one framework doc between two versions (e.g. guides/models.md from 0.4.0 to 0.6.0).
- `get_release`: A release's tarball URL, its SHA-256 (from the release's checksums.txt) and the exact commands to verify it and vendor it into .offrails/.
- `list_parts`: List the framework's parts (template/parts: mailer, jobs, sign-in, realtime, dev tools…): each one's summary, what it gives you, the parts it requires and the `cargo offrails add <part>` command. Read one with read_part.
- `read_part`: Read one part: its README (what it does, install, adapting it, what not to change), the files it adds and the shared files it wires into.
- `list_snippets`: List the framework's snippets (template/snippets: small tested code to copy, such as an Atom feed, slugs, Markdown, pagination): each one's purpose, what it needs, its files and the `cargo offrails snippet show|add|remove <name>` commands. Read one with read_snippet.
- `read_snippet`: Read one snippet: its README (when to use it, files, wiring, after adding, adapting it, removing it) plus its file list and wires.

Resources: every doc as `offrails://docs/<path>` (for example `offrails://docs/guides/models.md`), as Markdown.

## 3. Prompts

The plugin's skills, as MCP prompts (slash commands in most clients). Every argument is optional. Each prompt tells your agent to read the docs of the version your app vendors (the first line of `.offrails/VERSION`), from `.offrails/` or through the tools with `version`.

- `new` (New app): Create a new Rust off Rails app (rails new): interview, plan, generate.
- `scaffold` (Scaffold a resource): Generate a full CRUD resource (rails g scaffold), e.g. Book title:string rating:integer.
- `generate` (Run a generator): Run a generator other than scaffold: model, migration, job, mailer, channel, authentication, task.
- `feature` (Build a feature): Build or change a feature from a plain request or from what changed in product/: spec, code, green.
- `check` (Definition of Done): Run the Definition of Done (offrails-check, fmt, clippy, tests on SQLite and Postgres, gates) and fix what fails.
- `doctor` (Convention audit): Audit the app against the framework's conventions and report (or fix) violations.
- `deploy` (Deploy): Make the app deployable and ship it (Docker, Fly.io, Kamal, Railway, Render).
- `upgrade` (Upgrade the framework): Upgrade the app's vendored framework (.offrails/) and migrate it to the new conventions (rails app:update).
- `security` (Security review): Deep security review: threat model, the security checklist, scanners, header checks.

## 4. Versions and upgrades

Bundled versions: 0.7.3 (latest), 0.7.2, 0.7.1, 0.7.0, 0.6.2, 0.6.1, 0.6.0, 0.5.0, 0.4.0, 0.3.0. Each one is the release's published tarball, checked against its `checksums.txt` when the site is built.

- `upgrade_path(from, to)`: the release notes in between, oldest first, with every App migration note, and which docs were added, removed or changed.
- `diff_doc(path, from, to)`: what changed in one guide.
- `get_release(version)`: the tarball, its SHA-256 and the exact commands to verify it and vendor it into `.offrails/`.

Upgrading an app is one sentence to your agent:

```text
Upgrade me from 0.4.0 to 0.6.0.
```

It calls `upgrade_path("0.4.0", "0.6.0")`, then `get_release("0.6.0")`, verifies and unpacks the tarball, runs `offrails upgrade --check --fw "$FW"`, and follows that release's `generators/upgrade.md`. The `upgrade` prompt does the same with `from` and `to` as arguments.

## 5. Limits and security

- Read-only and public: no accounts, tokens or cookies; responses are `no-store`.
- Paths and versions resolve against the bundled docs index, never the filesystem.
- Every bundled version is its release tarball, pinned by SHA-256 and checked against the release's `checksums.txt`; `get_release` hands out the same pin.
- 120 requests a minute per IP, 64 KiB request bodies, bounded arguments, 128 KiB results, diffs and prompts.
- CORS allows any origin on `/mcp` only, never with credentials; the `Host` must be rustoffrails.org and the `Origin` a real web origin (the MCP spec's DNS-rebinding guidance).