gross_revenue. Connect it to the Claros MCP server and it can read those rules
from the approved rule set and check a change against them before it saves.
Check every shell command and edit (hooks)
npx getclaros adds a native hook to each coding agent it finds. The agent then runs getclaros hook <agent>
before each shell command and file edit, whether or not it thought to ask. The hook sends the action to Claros
(POST /v1/check) and answers in the agent’s own protocol:
Every project on this machine by default (the files above);
--project-hooks puts them in this project’s
.claude/settings.json, .codex/hooks.json or .cursor/hooks.json instead (they carry no key and can be committed).
A hook already in place stays where it is. Your own hooks stay; running setup again changes nothing, and puts ours back
if an update removed them; npx getclaros undo takes ours out; npx getclaros status shows which agents are guarded.
Setup proves each hook: it runs the installed hook as the agent would, on a made-up action that breaks one of your rules,
and expects the stop. While every rule is still learning (day 0), it proves the hook with Claros’s built-in test
rule instead, labelled as a test and checked dry (never logged, never counted). The hook also tells Claros once an hour that the agent is running (agent name and version, this
machine’s name, the getclaros version), so it shows on Home → Your agents before it writes anything.
What Claros receives for a shell command:
edit_file / write_file with {file_path, diff | content, project}. No tool mapping is needed:
Claros routes the action to the maps whose rules govern it (Routing) and the judge reads the
command or the diff as free text.
Some actions are answered on the machine, with no round trip (getclaros 0.7.0): a shell command that only reads
(ls, cat, head, tail, grep / rg, find without -delete / -exec, git status / log / diff / show,
pwd, echo …; anything with a redirection, a writer in a pipe or a chain, sudo, command substitution or a program
not on that list goes to Claros), and an action your rules’ instant checks (GET /v1/rules/fast, cached for a minute)
all rule out when every rule that could apply has one. An instant check an editor accepted stops an action on the
machine; Claros still logs it. These are counted in the hourly heartbeat, so coverage counts them.
Only rules that can stop or ask make the agent wait
Since getclaros 0.8.0 the hook asks for the blocking-first answer ("async": true): Claros judges the rules in force
that can stop or ask first, on their own, and answers as soon as they are decided. A stop is answered then (the
check is logged, under the same id, once the other rules are judged); an ask waits for the whole check, since its
question to the owner is opened with it. If none holds it, the action is
allowed then and there; the nudges and the would-have counts of rules still learning are judged after it, and the
check is logged when they are done (the same row, under the check id the hook got). With no rule that can stop or ask
in reach (only nudges and rules still learning), nothing waits on the judge at all. The decision is made on the server
with the rules as they are now, so a rule promoted to stop a second ago already holds the next action.
A nudge judged after its call ran reaches the agent as context: in Claude Code from the PostToolUse hook when the
judge is done by the time the tool is (its outcome is joined to the check once it is logged); otherwise, and in
Codex and Cursor, with the session’s next checked call, marked “About an earlier call (…)”. Each nudge is given once.
If Claros can’t be reached, times out (5 s) or rejects the key, the action runs and the agent shows a warning that it
ran unchecked. init --fail-closed makes the hook block instead.
MCP tool calls are not sent through these hooks: the MCP guard checks those.
Asks wait for the owner
When a rule says ask first, Claros opens a question to the rule’s owner(s) (Asks and approvals) and the hook holds the call: it polls the question’s decision URL with the sha256 of this exact action ({app: null, tool, arguments}) for up to 120 seconds, then
- approved for this action: the call runs, as if nothing had been flagged;
- denied: the call is denied, and the agent reads who said no and why;
- approved for a different action, or no answer in time: denied, “do not run it without their answer”.
init --ask-wait <seconds> changes the wait (it goes into the installed command as hook <agent> --ask-wait N).
Each installed hook entry sets the host’s timeout to the wait plus 30 seconds, so Claude Code, Codex and Cursor
don’t cancel the hook mid-wait (Claude Code and Codex cancel a hook after 600 s when no timeout is set). The agent’s
turn is blocked while it waits; Claude Code shows “Checking with Claros”.
--ask-wait 0 turns waiting off. Then Claude Code and Cursor’s shell hook hand the ask to the person at the keyboard
(the host’s own confirm, naming the owner and the check id). Codex has no ask on PreToolUse and Cursor doesn’t
enforce one on preToolUse yet, so there the call is denied with the rule, who to ask and the check id: the honest
answer when nothing can wait, since letting it run would skip the owner. A later approval doesn’t run a denied call;
the agent has to try again, which opens a new question.
Learn from your corrections (opt-in)
You already teach your agent all day: “no, use our Button, not a div”, “don’t touch the migrations folder”. Withnpx getclaros --learn-corrections (getclaros 0.6.0), Claros learns your rules from those corrections. Off unless you
pass the flag and turn on Learn from my corrections in Claros settings on the web (only you can: an agent’s key
can’t change your preferences). The flag adds the prompt hook; until the setting is on, the hook sends nothing.
- Only corrections leave your machine. A local classifier (no model) keeps imperative fixes right after an agent action (“no, …”, “instead …”, “don’t …”, “always / never …”, “like this”, “use X not Y”) and short instructions right after you rejected or interrupted a call. Every other prompt sends nothing.
- What is sent: the correction and the agent action it corrects (tool, paths, a short diff or summary), redacted on your machine (emails, phones, keys, tokens) and again on the server, plus the images it references (a file path in the prompt, a Cursor attachment, an image you pasted), unless you chose no images. A vision model turns an image into checkable properties for the correction (“spring easing, ~300 ms, no opacity fade”); the image itself is kept only if you chose to keep images.
- What happens: a standing preference (“always”, “never”, “like this”, or the same correction twice) becomes a suggestion in your Inbox: “You told Claude Code: … — keep it as your rule?”. Keep it and it’s your personal rule (a nudge for your agents, with what good looks like); a one-off stays a remembered precedent. The same correction from two people becomes a team suggestion.
- Never in the way: the hook gives up after 1.5 s and always lets the prompt through.
Read the rules over MCP
npx getclaros signs you in and saves the key in ~/.config/getclaros, so no key goes into a project file.
Then add the stdio bridge:
CLAUDE.md / AGENTS.md or rules file:
What a session looks like
From the scripted session ininfra/evals/horizontal.mjs (an invented company’s design-system policy, imported
with maps from policies):
get_workflow {"workflow_id": "wf_design_system"}returns the rules in the policy’s words, each with its response.check_actionon the change the agent is about to write:
var(--color-text-primary) and checks again.
Any rule the judge decides works the same way: the agent sends the file and the diff as they are, and Claros judges
them as free text. Precise rules only fire when the record carries their fields.
Known limits
- Over MCP, the agent decides when to call
check_action. The hooks above check every shell command and edit whether it asks or not; the MCP guard does the same for MCP tools. - Codex runs a new or changed hook only after you trust it in
/hooks, and project hooks only in a trusted project. - An ask holds the agent for up to the wait (120 s by default). Shorten it with
init --ask-wait, or answer from Home on your phone. - Cursor documents no input format for
WriteandDeleteonpreToolUse; the hook readsfile_pathandcontentoredits, the names its other events use. - A rule that only a fact outside the command or diff can decide (which environment a script deploys to) can come back as ask.
- Rules that need a fact the diff doesn’t hold can come back as ask. In our runs a contrast rule (“text meets 4.5:1”) answered “can’t tell” on a diff with token names and no resolved colors, which turns into an ask. Give such a rule a narrower scope on the rules page, or make it a nudge, if that’s too strict for your team.
check_actionis logged like any other check. A wrong stop or nudge can be reported withreport_override(overrides).