THE STANDARD · v0.1 · living document
Build CLIs your
agent can actually drive.
Most command-line tools are built for a human at a terminal — they prompt, print prose, and happily mutate state. An agent driving them flies blind. The Agent CLI Guidelinesare an opinionated, versioned standard for tools an agent can discover, drive, and trust.
The gap
The 2025–26 wave of agent CLIs got output right andsafety, self-description, and token discipline wrong. “Read-only by default” — the property everyone talks about — is the one most of them don’t actually ship.
Same job · two outcomes
What following the spec gets you
It refuses to wreck things.
A conformant tool can't change state unless you opt in. A blocked write fails structured — before it ever connects.
$ othercli delete cluster prodDeleting cluster "prod"…✓ 14 nodes terminated. done.$ agentctl delete cluster prod{ "error": "delete is a mutating operation", "code": "WRITE_REFUSED", "remediation": "re-run with --allow-mutations"}exit 11 · nothing touchedIt returns data, not a wall of text.
Stable JSON the agent can parse — projected to the fields it asked for, bounded by default, with the rest one cursor away.
$ othercli list usersUsers (showing all 4,213):• Ada Lovelace — joined 2019, last seen…• Alan Turing — joined 2018, last seen…• … 4,210 more rows flooding context …$ agentctl users list --json --select id,name --limit 2[ { "id": "u_01", "name": "Ada Lovelace" }, { "id": "u_02", "name": "Alan Turing" }]note: 2 of 4213 — pass --limit for moreIts errors tell the agent what to do next.
A machine-readable code and a remediation, not an opaque traceback. The agent self-corrects without a human.
$ othercli get item 42Traceback (most recent call last): File "cli.py", line 211, in mainKeyError: 42$ agentctl get item 42 --json{ "error": "item 42 not found", "code": "NOT_FOUND", "remediation": "list items to find a valid id"}It tells the agent how to use it.
A machine-readable surface — the command tree, exit codes, and live safety state — so an agent learns the tool at runtime.
$ othercli schemaerror: unknown command 'schema'Run othercli --help for usage.$ agentctl schema{ "tool": "agentctl", "read_only": true, "commands": { "…": "the full tree" }, "exit_codes": { "ok": 0, "write_refused": 11 }, "safety": { "allow_mutations": false }}Ten invariants, distilled
A floor an agent can stand on
Read-only by default
Mutations are gated in the binary, not a wrapper. The safe path is the default.
Self-describing
schema + an embedded agent guide. The tool teaches itself at runtime.
Token-bounded
Bounded, projectable, paginated output. Your agent’s context stays its own.
Injection-fenced
Untrusted device/API text is fenced so the agent won’t follow what’s hidden in it.
Agent-completable auth
A real headless path — never a browser-only dead end. Secrets never on argv.
Append-only contract
Commands, flags, and fields don’t shift under the scripts that depend on them.
Built to evolve
A living standard, not a frozen spec.
Every rule is pinned to the assumption about LLM capability behind it — so as context windows grow and models change, you know exactly which rules to revisit. Tools claim a version at a level: Core(the invariants) or Full (the patterns too).