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.What do I give my coding agent?
Not a prompt first: a command. Run the installer in a terminal:irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex.
It registers Reticle with every coding agent it finds and closes with Next steps: restart your agent if it is already open, then paste the prompt it printed. That prompt is the one to give the agent. It has the agent run init, close the coverage gaps reticle doctor lists, and sets what counts as finished: one real flow in your app driven to a verdict, not a config file.
The order matters. An agent reads its MCP server list when it starts, so a prompt pasted into an agent that is already running has no reticle_* tools to call until that agent restarts.
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:
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.
An
ℹ line is the one people skim past. Init prints this one when it finds a state library that it cannot register for you (punctuation changed to fit these docs):
What it actually changes
The files it writes in your project, none of them mysterious..reticle.json (project config)
.reticle.json (project config)
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: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: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.vite.config.ts (the plugin)
vite.config.ts (the plugin)
src/components/Login.tsx:81. It also injects connect() so you don’t have to remember to.src/reticle-dev.ts (your capabilities)
src/reticle-dev.ts (your capabilities)
Trimmed, with the punctuation changed to fit these docs: the real file also has a comment block about where to start and a 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.
declare global block for the DEV type.CLAUDE.md and the /reticle command (agent rules)
CLAUDE.md and the /reticle command (agent rules)
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
init reads your repository; it cannot read your request, and these live only there.
Already installed? Mostly automatic
The first timereticle 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:
- A GUI client reads its config at startup. Cursor, Antigravity and VS Code need a window reload before the new server or rules take effect. The CLIs pick them up on their next run.
- The pre-approval is scoped to
reticlealone, 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,initsays so in a line, because in Cursor’s case that file supersedes what you had approved inside the app.
--files-only for the full run: boot the app and wait for a session to connect. Proving a flow is the first run, a separate call.
The two restarts, and when you need them
Your dev server: restart it once. One that was already running read your build config beforeinit edited it, so it keeps serving a bundle without the SDK. Restart it and hard-reload the tab. init names this case when it finds it.
Your agent: restart it once, if the tools are missing. An agent reads its MCP server list when it starts. If it started before Reticle was registered, the reticle_* tools are not in this session, and no slash command re-reads the list (/mcp manages servers already loaded). Restart the agent once. reticle init --relaunch prints the exact command that resumes this conversation with the tools loaded. Until then, npx @reticlehq/server verify <url> --expect '<predicate JSON>' proves a flow from the shell. Reticle registers globally, so this happens once per machine.
Confirm it worked
Something marked ⚠?
The manual install covers every step
init can’t automate, per agent and per framework.