Approvals
Anymo's agents are capable, so capability is gated: anything genuinely risky stops and asks you first, in every mode, with no way to switch that off. Approvals are designed to be rare enough to stay meaningful.
What always asks
Regardless of permission mode, these actions park the run until you decide:
- Shell and code execution, including your own local actions and project test or build commands
- Browser control: every
browser.*action that mutates state - Desktop control: every
computer.*action - MCP and connector tools, always treated as high risk
- Destructive file operations: overwrites and deletes
- Anything a tool itself declares as approval-required
Ordinary reads and in-workspace writes flow without friction in auto mode. That balance is deliberate: a system that asks about everything trains you to click yes without reading, which is no safety at all.
The three permission modes
| Mode | Behavior | Use it for |
|---|---|---|
auto (default) | Low-risk tools proceed; the list above still asks | Day-to-day work |
manual | Every meaningful tool action asks first | Sensitive workspaces, getting to know the agent |
plan | Side effects are denied outright; the agent can only read and propose | Scoping work before letting it act |
Switch modes from the permission pill in the composer, per run. There is no fourth mode and no bypass flag anywhere in the product. Goal turns, skill runs, and scheduled automations all obey the same gates.
Responding
When a run needs you, the request appears inline in the thread and in the Approvals surface: the tool, a one-line summary of the input, and the risk level. Approve and the action executes; deny and it never does, with the run continuing around it. You can attach a reason to either decision.
Unanswered approvals can expire. An expired request fails closed: the action is not executed, and the run is not stuck forever on a prompt you missed.
Everything on the record
Each request and decision is appended to the run's event log as approval.requested, granted, denied, or expired, with the actor and timestamp. When you replay a run a month later, you see exactly what was asked and what you decided. Denials are events too, so "the agent tried and I said no" is part of the audit trail.
Approving from scripts and other machines
Runs hosted on an app-server queue their approvals there. The CLI client lists and answers them:
anymo approvals --websocket 127.0.0.1:9300 --token <token> # what is waiting, with ids
anymo approve --websocket 127.0.0.1:9300 --token <token> \
--approval-id <id> --decision approve --reason "looks safe"
Integrations use the same queue through the approval/respond API method. A manual run with no approver around simply parks; anymo show <run-id> prints any waiting approval ids straight from the local event log.
Programmable decisions
Trusted plugins can register PermissionRequest hooks that allow or deny a request before it reaches you, useful for codifying team rules like "never approve writes outside src/". Hooks can tighten the gate; they cannot loosen what always asks.
Frequently asked questions
Can I turn approvals off for trusted work?
No, and that is the point. auto mode already lets safe work flow; the actions that still ask (shell, browser, desktop, MCP, destructive writes) are the ones that can actually hurt you. There is no "skip permissions" flag in the codebase.
My run says "awaiting approval" and nothing is happening.
That is the system working: something risky is waiting for you. Answer it in the Approvals surface, or deny it to move on. In plan mode, side-effect tools are denied automatically rather than parked.
A swarm run asks a lot. Can that be quieter?
Swarm workers in transaction mode stage their changes instead of writing shared files, so most of their work needs no prompt; you review one consolidated patch set at merge time instead. See Worktrees and isolation.