Skip to main content
Your agent is shown ten tools by default: reticle_navigate, reticle_look, reticle_act, reticle_act_and_wait, reticle_observe, reticle_assert, reticle_session, reticle_verify, reticle_tools and reticle_run. Verdicts come from reticle_act_and_wait, reticle_assert, reticle_act { steps } when a step declares expect, and reticle_verify (change/flows). Everything else moves or reads the app and proves nothing. Only verified: "yes" is a pass: unknown means Reticle could not tell, and no-fault means nothing was declared to prove. Most of the rest were not removed. They were merged. reticle_snapshot is reticle_look { action: "page" }; reticle_console is reticle_observe { action: "console" }. One tool, one action argument, same work. Calling a retired name returns the call that replaced it, and reticle_tools prints the whole mapping. That is not a limitation. It is the design. MCP re-sends every advertised tool definition to the model on every single turn, so the tool list is not a menu you pay for once. It’s rent. A wider surface costs tokens on every message. Less obviously, it makes the model wander: give it fifty ways to look at a page and it will try several before doing anything useful. What the verify loop does not advertise are the specialised tools: reticle_screenshot, reticle_visual_diff, reticle_storage, reticle_network_mock, reticle_clock. Each is one reticle_run { tool, args } hop away. A daemon started with RETICLE_ADVERTISE_ALL_TOOLS=1 advertises 30 tools outright, and it switches to the unmerged spelling: reticle_snapshot, reticle_query, reticle_inspect and reticle_state replace reticle_look; reticle_network and reticle_console replace reticle_observe { action }; reticle_wait_for replaces reticle_assert { action: "wait" }; reticle_sessions and reticle_feedback replace reticle_session list and feedback; reticle_act_sequence replaces reticle_act { steps }. Examples in these docs use the default spelling. The counts are asserted by server/src/surface/tools/surface-sizes.test.ts.
Measured with bench/harness/schema-tax.mjs on 2026-10-08: the default surface is 10 tools, about 4,650 schema tokens, against 30 tools, about 35,000 tokens with RETICLE_ADVERTISE_ALL_TOOLS=1, charged on every message. Re-measure before quoting; the surface grows.

The ten, by job

Look

reticle_look { action: "page" | "find" | "element" | "state" }

Act

reticle_act · reticle_act { steps } · reticle_act_and_wait · reticle_navigate

Observe

reticle_observe · { action: "network" } · { action: "console" }

Prove

reticle_act_and_wait · reticle_assert · reticle_verify

Discover

reticle_tools · reticle_run

Session & feedback

reticle_session { action: "list" | "feedback" | "yield" | … }
Verdicts come from reticle_act_and_wait, reticle_assert, reticle_act {steps} when a step declares expect, and reticle_verify (change/flows). Everything else moves or reads the app and proves nothing. Only verified: "yes" is a pass: unknown means Reticle could not tell, and no-fault means nothing was declared to prove. A drive that ends without a verdict has no result, however many tools it used.

Why these and not others

Each one earned its slot, and a couple are there because of measured mistakes. reticle_look { action: "element" } (unmerged name reticle_inspect) maps a DOM node to src/components/Sidebar.tsx:41. Finding a bug is half the job. Knowing which file to open is the half that makes an agent useful. It used to be reachable only through reticle_run, which meant an agent had to already know it existed to use it. reticle_act { steps } (unmerged name reticle_act_sequence) batches a multi-step interaction into one round trip. It was also reachable only through reticle_run, and the consequence is a login form driven one call at a time, over and over. Those repeats were not retries. The calls succeeded and got repeated, because the batching tool was invisible. A tool an agent must already know about is a tool that never gets called.
Trimming further has a floor. An eight-tool cut measurably dropped real-agent accuracy, because the model loses scaffolding and wanders on harder flows. That reading is old enough to be dated evidence rather than proof, and a fresh A/B against a leaner surface is still unrun. Small is good; empty is not.

Reaching every other tool

reticle_run takes a tool name and its arguments. reticle_tools lists what’s available and returns the full argument grammar for any of them, so your agent can discover a tool mid-task without you having pre-loaded its schema. Notable residents of the cold tail: flow recording and replay, visual diffing and screenshots, network mocking, viewport pinning, the clock, storage, and the App Graph map (reticle_map).

Read responses carry their cost

The read tools (reticle_look page and find, reticle_observe network and console) tell you what each answer cost, because a verification tool that quietly eats your context window is not saving you anything:
That is from a real reticle_look { action: "find" } response: seven buttons found, with source pointers, for 236 tokens.

Every response tells you when not to trust it

This is the part we’re proudest of and the part that makes demos slightly less shiny. When the browser tab is backgrounded, every response says so:
When the event buffer has evicted old events, a negative result might be a false negative, and it says that too:
A tool that says “no requests found” when it actually means “I lost the ones you asked about” is worse than useless. It is confidently wrong. Reticle would rather tell you its memory is imperfect.

Reference

These pages are named for the unmerged tools. Each one gives the default spelling (reticle_look { action: "page" } for reticle_snapshot, and so on).

Look

Act

Observe

Prove and discover

The complete reference

Every tool, every argument, including the cold tail.
Last modified on October 25, 2026