Skip to main content
Run npx @reticlehq/server init in your project root. It installs the SDK, wires your build config, writes the agent rule files, boots the app, and prints a plan you can read. It is idempotent, so running it twice is safe.
This is the PROJECT step. The machine step comes first and is one command in a terminal, curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh, which registers the MCP server with every agent it can reach so the tools are there when you open your agent. init will register the server itself if nobody has, but doing it from inside an agent that has already read its server list means the tools cannot appear until that agent restarts. Terminal first, then open the agent, then init. See the quickstart.
The install is designed for the agent to run rather than you. The agent is about to be the primary user of this tool, so it may as well set up its own workspace.
Always write the package scope: npx @reticlehq/server <command> is the CLI. Dropping the scope and npx-ing the bare, unscoped reticle name fetches a different package published by somebody else, which will not give you Reticle. Once @reticlehq/server is installed, reticle works as a bin name on your PATH, which is the only context where the unscoped name is ours.

What do I paste into my coding agent to install Reticle?

Copy this whole block into Claude Code, Cursor, Copilot, Codex, Windsurf, OpenCode, or any MCP agent. It tells the agent what Reticle is, why it should want it, and what counts as finished. That last part is the one that matters.
Prefer installing the skills instead? npx skills add reticlehq/reticle on most agents, or /plugin marketplace add reticlehq/reticle then /plugin install reticle@reticlehq on Claude Code, which registers the MCP server and all eleven skills in one step. Then type /reticle and the agent runs this same setup from the skill.
The RETICLE_INSTALL_SOURCE=docs_site marker is how we tell which published route an install came through. It is self-declared by this page and never inferred, it carries no information about you or your project, and dropping it changes nothing about the install.
Everything on this page is real output. It was captured by scaffolding a pristine npm create vite React app and running init inside it while writing this.

See the plan before anything is written

--dry-run prints exactly what would happen and touches nothing:
On a fresh Vite + React + TypeScript app, that produced:

Reading the marks

There are five, and they mean different things. This is the part worth understanding, because a run full of green ticks can still leave you with a broken install. Two of the five ask something of you.
A ⚠ is not cosmetic. In the run above, Reticle could not write the Codex CLI’s TOML config, so it printed the exact block to paste. Leave it and Codex simply never sees the tools.
That ℹ line is the one people skim past, so here it is in full:
init wrote the file, but a brand-new Vite template has no testids and no state library, so there was nothing to register. Reticle tells you this instead of counting it as a win. See Instrument your app for what to put in it.

What it actually changes

Four files in your project, none of them mysterious.
The projectId is how Reticle scopes sessions to this project, so two apps running at once don’t get confused for each other.Keeping .reticle/ small. Reticle bounds the directory for you, by count and by total size. Add a retain block to change what it keeps:
Those are the defaults, and every field is optional. sessions is how many session journals survive, visual how many overlay diffs (pixel baselines are never deleted, because the next comparison needs them), feedback how many local copies of reports already sent, and budgetMb the total the whole evidence tier may occupy. 0 means keep none, and "sessions": 0 also stops journals being written in the first place.Saved flows, capsules, baselines, the contract and the intent ledger are not touched by any of this. They are the part meant to be committed, and a bound that deleted them would be deleting the regression checks your team shares.Your app’s own background calls. An analytics or heartbeat endpoint on your app’s own host looks exactly like the app’s work, so Reticle never guesses. If one of them keeps a verdict waiting, or fails and gets blamed on an unrelated action, name it:
Each entry is matched the way urlContains is. A listed request stops holding the wait open and stops contradicting a claim; when a contradiction is still reported, it lists what was set aside. It is never hidden from an assertion that names it: net { urlContains: "/api/heartbeat" } still sees it. Keep entries specific: /api would set aside your whole backend. Third-party calls (another site’s beacon or SDK) need no entry; they are already set aside.
One import, one entry. The plugin stamps source locations onto your elements, which is what turns a DOM node intosrc/components/Login.tsx:81. It also injects connect() so you don’t have to remember to.
This is the file that decides how good your verdicts get. Empty, you still get DOM, network and console. Filled in, your agent can check what the app believes, not just what it rendered.
A rule telling your agent to verify features after building them, and a /reticle command that drives one flow. Skipped entirely with --no-mcp, because rules for tools the agent can’t reach are just noise in the context window.

Flags

Three of these are answers only the caller has. init reads your repository; it cannot read your request, and these live only there.

Already installed? Mostly automatic

The first time reticle mcp starts on a new version it applies the pre-approval rules for the agents it finds, once, and records that it did. You get that by upgrading. There is nothing to type. One case is deliberately left out. Creating Cursor’s permissions.json when you do not already have one supersedes whatever you approved inside Cursor itself, so a version bump doing it silently would make your OTHER MCP servers start prompting again, with nothing to connect that to us. Reticle defers it and waits to be asked:
That writes the files, registers the MCP server with every agent it finds, pre-approves Reticle’s tools so the per-call Accept dialog stops, and stops there: no dev server, no browser, no drive. Every step is idempotent, so a repo that is already wired reports “already” and changes nothing. Two things to know afterwards:
  • A GUI client reads its config at startup. Cursor, Antigravity, Claude Desktop and VS Code need a window reload before the new rules take effect. The CLIs pick them up on their next run.
  • The pre-approval is scoped to reticle alone, never a blanket rule for every MCP server, and never a global auto-run switch. If a client’s approval file did not exist before, init says so in a line, because in Cursor’s case that file supersedes what you had approved inside the app.
Drop --files-only to get the full run: boot the app, drive a flow, return a verdict.

The two restarts you no longer have to think about

Your dev server: init handles it. A dev server that was already running read your build config before init edited it, so it keeps serving the old bundle and nothing connects. init restarts it and waits for the port to answer, rather than telling you to. Your agent: not on the critical path any more. Your agent read its MCP server list at startup, before Reticle existed, and no slash command re-reads it. /mcp manages servers already loaded, so it cannot pick up a new one. That used to mean stopping the install to restart. It does not now: the flow is driven by a child agent process started after registration, which reads the list init just wrote. Your own session picks the tools up whenever you next start it, and nothing is waiting on that. This is a once-per-machine annoyance in any case, because Reticle registers globally.

Confirm it worked

It confirms the app connected, or tells you exactly why it hasn’t. A session in the list is the install actually finished. Not a green tick. A connected app.

Something marked ⚠?

The manual install covers every step init can’t automate, per agent and per framework.
Last modified on September 18, 2026