Reticle

io.github.reticlehqPublished by GitHub account reticlehqv3.9.0Updated Nov 3, 2026

Verify a running web app from the inside over MCP: look, act, observe, assert. No screenshots.

VerifiedSTDIODesktop onlyBrowser AutomationDeveloper Tools

Overview

AI-generated overview

Reticle lets a coding assistant drive and verify a running web app in its own browser tab — look, act, observe, assert — without screenshots.

What you can do
  • Navigate and reload the connected browser tab, and list or yield connected sessions
  • Read the page as a semantic snapshot, resolve locators to refs, and inspect state
  • Act on elements, alone or with a wait for an expected consequence, and chain multi-step actions
  • Observe what the app did: events, network requests and console logs
  • Assert predicates now or within a budget, and replay saved flows affected by code changes
  • Discover and invoke additional unadvertised tools by name on demand
When to use it
Useful when an assistant changes a web app and should prove the change against the real running app instead of guessing from source. It fits front-end and full-stack work where flows need to be driven and verified end to end.
Requirements
Runs locally over stdio via npx; the package starts a bridge on a localhost WebSocket endpoint that the app's browser SDK connects to. The project must be wired with the SDK and build plugin (init changes package.json, the lockfile and build config and starts a dev server). A dev server and a browser session are needed; no API keys or environment variables are declared.
Before you install
Wiring the project modifies files (package.json, lockfile, build config) and starts a dev server, so it should be confirmed with the user first. The assistant can act on and change the live app, and verification results only count as passes when a verdict is explicitly positive. Optional environment variables such as RETICLE_ADVERTISE_ALL_TOOLS change the tool payload.

Installation

In SourceWeft

  1. Open Reticle in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

@reticlehq/server

The Reticle bridge + MCP server. It hosts a localhost WebSocket endpoint your app's @reticlehq/browser SDK connects to, and exposes MCP tools your coding agent uses to look at, act on, observe, and assert against the live app.

bash
npx @reticlehq/server init   # wire the project: SDK + build plugin + MCP registrationnpx @reticlehq/server mcp    # MCP over stdio; auto-starts the bridge on ws://localhost:4400

The package installs a reticle bin, so inside a project reticle mcp and npx @reticlehq/server mcp are the same command. reticle is not a package name on npm.

Point your agent at it. On Claude Code, register it at user scope:

bash
claude mcp add reticle -s user -- npx @reticlehq/server mcp

Default tools (10):

reticle_navigate, reticle_look, reticle_act, reticle_act_and_wait, reticle_observe, reticle_assert, reticle_session, reticle_tools, reticle_run, reticle_verify.

Only reticle_act_and_wait and reticle_assert return a verdict; everything else moves or reads the app.

More tools ship but are not advertised, to keep the per-turn tool payload small: screenshots and visual diff, saved flows, recording, baselines, clock control, viewport, crawl, coverage, network mocking, leases and more. Reach any of them by name with reticle_run, list them with reticle_tools, or advertise the whole surface with RETICLE_ADVERTISE_ALL_TOOLS=1 (this roughly doubles the per-turn tool payload).

See the main README.

License

Apache-2.0.

Source: server/README.md at commit 1c7691b

Tools

10

reticle_navigate

Navigate the connected browser tab to a URL, or reload it in place with { reload: true } (add { hard: true } to bypass the cache). e.g. {"url":"/settings"}

ParametersurlhardreloadsessionIdtimeout_ms

reticle_act_and_wait

Act on a ref, then wait for a predicate to hold — one hop for the act->observe->assert loop. e.g. {"ref":"e42","action":"click","until":{"kind":"signal","name":"todos:loaded"}}

ParametersrefargsuntilactionrequireddetailintenttargetdurablepredicatesessionIdtimeout_msrefuseWhenThrottled

reticle_session

By action: "list" (the default) shows connected tabs; "yield" is MANDATORY before you stop; "tune" hides or moves the HUD; "feedback" reports a problem. e.g. {"action":"yield","mode":"waiting"}

Parametersallhudkindmodeneednotetextclaimlevelmodeltraceaction+9 more

reticle_verify

The Reticle Harness is { action: "explore" }: when the user asks for the Harness, or asks Reticle to drive and verify the app for you, call it and do not drive… e.g. {"action":"change","files":["src/App.tsx"]}

ParametersappsayflowstopwaitapplyfilesnamesrunIdscopesinceactionrequired+14 more

reticle_look

Read the page, by action: "page" is the semantic snapshot of what is rendered, "find" resolves a locator (testid/role/text/component) to refs you can act on, "… e.g. {"action":"find","by":"testid","value":"submit"}

Parametersbyaltidsrefdiffmodenamepathroleselftextattrs+12 more

reticle_observe

What the app DID, by action: "events" is the reaction window since a cursor, "network" the requests it made, "console" what it logged. e.g. {"action":"events"}

ParametersoklevellimitsinceuntilactionassetsbodiesmethodstatusfiltersactionId+4 more

reticle_assert

Prove a consequence, by action: "now" evaluates a predicate against the window that already exists, "wait" waits for one to become true within a budget. e.g. {"action":"now"}

ParameterssinceuntilactiondetailintentpredicatesessionIdtimeout_ms

reticle_act

Act WITHOUT checking the result — if the action is supposed to cause something, use reticle_act_and_wait { until } instead and get the verdict in the same call. e.g. {"ref":"e42","action":"fill","args":{"value":"hello"}}

ParametersrefargsburststepsactiondetailtargetsessionIdtimeout_msonDeviationrefuseWhenThrottled

reticle_tools

Discover Reticle tools on demand. Call with no arguments to list every tool (name + one-line summary); call with names:["reticle_screenshot", …] to load full descriptions and parameters for specific tools. Then invoke them with reticle_run. This avoids paying for every tool definition on every turn. To make a verification REUSABLE (record once, replay free forever), the flow workflow lives here: reticle_record{action:"start"} → act → reticle_record{action:"stop"} → reticle_flow_save → reticle_verify{action:"flows"} (and reticle_verify { action: "heal" } on drift). Load those names when you want to save or re-run a flow.

Parametersnamenamesaction

reticle_run

Invoke any Reticle tool by name (discover names/params first with reticle_tools). On an unknown tool or bad arguments it returns the available names or the tool's params, so you can correct and retry.

ParametersargstoolrequiredsessionId

Version history

4
  1. v3.9.0LatestOct 29, 2026
  2. v3.8.1Oct 26, 2026
  3. v3.8.0Oct 26, 2026
  4. v3.7.0Oct 13, 2026

Score

80% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.