Claude Code
Set up Assent for Claude Code in about a minute. Risky tool calls such as git push wait for your answer from your phone or the web.
Claude Code already asks before it runs a tool, but only in the terminal you started it from. The Assent hook sends the risky calls to your Assent inbox instead, so you can answer from your phone, and the call waits until you do. For a call on the ask list, no answer means no call.
The hook is a best-effort tripwire, not a sandbox. It matches the commands Claude Code is about to run against a list of patterns, and a command written to dodge the list (a script file, a renamed binary, an encoded string) can get past it. Keep using Claude Code's own permissions, and a separate account or sandbox for anything you cannot afford to lose.
Set it up
You need the command line and Node.js 20 or later. The steps below are for macOS and Linux. The hook command it installs is written for a POSIX shell and has not been tested with Claude Code on Windows yet; there, use the MCP server for asks.
npm install -g assent-cli
-
In Assent, open Agents, add an agent called
Claude Codeand copy its agent key. -
Save the key in its own config file, readable only by you:
mkdir -p ~/.assent echo '{ "agentKey": "oak_..." }' > ~/.assent/claude-code.json chmod 600 ~/.assent/claude-code.json -
Add the hook to Claude Code:
assent hook claude-code install --config ~/.assent/claude-code.jsonIt shows exactly what it will change in
~/.claude/settings.jsonand writes nothing until you confirm. Pass--yesto skip the question, or--settings .claude/settings.jsonto set it up for one project only. -
Start a new Claude Code session and ask it to push a branch. The ask arrives in Assent; tap Allow or Block.
What it does
The hook runs before every Bash, Edit, Write, MultiEdit, NotebookEdit, WebFetch and MCP tool call.
- Your standing rules come first. A Never rule blocks the call, and an Always rule lets it run when the call is one simple command the rule covers. See Rules.
- Risky calls go to your inbox. A call on the ask list becomes an approve ask, and Claude Code waits for your answer. The ask shows the part that matched, then the whole command with hidden characters made visible, and where it runs. Allow runs it and Block stops it. Each call gets its own ask, so one answer never covers a different command. A call too long to show in full is blocked.
- No answer blocks it. If you have not answered within two minutes, the call is blocked and the ask is withdrawn. If Assent cannot be reached, or the hook has no agent key, risky calls are blocked too.
- Everything else is unchanged. Calls that are not on the ask list and have no rule go to Claude Code's own prompt, as before.
On an ask for one simple command, you can also tap Always or Never, so the next identical call is answered for you. Chained commands, such as cd app && git push, and very long ones always need a fresh answer.
The ask list
By default the hook asks you about these Bash commands, wherever they appear in a command line: after sudo, &&, bash -c or eval, inside quotes or braces, with a path such as /usr/bin/git, or with git options such as git -C app push:
| Pattern | Covers |
|---|---|
git push* | Pushing |
git reset --hard* | Throwing away local work |
rm -r*, rm -fr* | Deleting folders, including rm -R, rm -f -r and rm --recursive |
*deploy* | Anything with deploy in it, such as npm run deploy |
npm publish* | Publishing a package |
terraform apply*, terraform destroy* | Changing infrastructure |
kubectl delete*, docker push* | Removing cluster resources, pushing images |
To use your own list, add hook.ask to the config file. It replaces the default list. tool is the tool name and target is the command, file path or URL, both with * as a wildcard and ignoring case. Leave out target to ask about every call of that tool.
{
"agentKey": "oak_...",
"hook": {
"ask": [
{ "tool": "Bash", "target": "git push*" },
{ "tool": "Bash", "target": "*deploy*" },
{ "tool": "Write", "target": "*.env" },
{ "tool": "mcp__github__*" }
],
"waitSeconds": 300
}
}waitSeconds sets how long a call waits for your answer, from 1 to 3600 seconds (default 120). ASSENT_HOOK_WAIT_SECONDS overrides it. The install records the wait in the hook command (--max-wait) and gives the hook a Claude Code timeout 30 seconds longer, so the hook always answers before Claude Code gives up on it. A longer waitSeconds only takes effect after you run assent hook claude-code install again. A hook added by hand without --max-wait waits at most 45 seconds, inside Claude Code's default timeout.
Remove it
assent hook claude-code uninstallIt shows the change first and removes only the Assent hook, leaving the rest of your settings as they were.