Tooling

Contro1 CLI

Install and use the contro1 CLI to register AI agents, create approval requests, push AI inventory, retrieve evidence and traces, and test workflows before using the SDK or API.

contro1 puts approvals, Control Map routing checks, quorum, decision waits, AI inventory, traces, and evidence into the terminal workflows where coding agents, scripts, CI jobs, and developers already work.

Key takeaways

  • Connect an AI agent in minutes: register it, attribute requests to it, and test approval flows before writing a full SDK integration.
  • Ask a human before an agent acts: create approval requests from the CLI and wait for decisions inside agent workflows, scripts, or CI.
  • Keep an audit-ready history: retrieve evidence and traces for agent decisions and approved actions.
  • Use a safe token model for agent workflows: scoped, revocable tokens can request approvals and read evidence, but cannot manage users, roles, secrets, or org settings.
  • Automate when needed: every command supports JSON and stable exit codes so agents and developer workflows can act on the result.

Why use the CLI for AI agents

The Contro1 CLI is developer tooling for putting approval control directly in an agent workflow. It gives developers and coding agents a terminal entry point for agent identity, Control Map previews, role-based approval requests, quorum, evidence, traces, and inventory before a full SDK/API integration exists.

Start with the CLI when you want to prove an agent workflow end to end: register the agent, ask a human before it acts, wait for the decision, and pull the audit-ready record afterward.

For coding agents and developer workflows, the CLI can also put approval in front of a local command. That is an important use case, but it is one capability inside the broader agent integration workflow.

  • Register agents so requests and evidence are attributed to the right system.
  • Create approval requests and wait for a human decision from the terminal.
  • Retrieve evidence and traces so agent actions are reviewable later.
  • Send AI inventory updates to the registry without opening the dashboard.
  • Use JSON output and stable exit codes when agents, scripts, or CI need to branch on the result.

Requests API · Webhooks

Install

contro1 is a single, dependency-free binary. Install it with one line - no build step. The same binary works on Windows, macOS and Linux (amd64 and arm64).

The install script is a small convenience wrapper that downloads the official contro1 binary from GitHub Releases. You can inspect it before running it at https://contro1.com/install.sh (PowerShell: https://contro1.com/install.ps1).

Prefer to download manually? Grab the archive for your OS from the GitHub Releases page, extract it, and put the contro1 binary on your PATH.

macOS / Linux
# One-line install (downloads the latest prebuilt binary from GitHub Releases)
curl -fsSL https://contro1.com/install.sh | sh

# Pin a version
curl -fsSL https://contro1.com/install.sh | CONTRO1_VERSION=v0.1.4 sh

contro1 --version
Windows (PowerShell)
# One-line install (downloads the latest prebuilt binary from GitHub Releases)
irm https://contro1.com/install.ps1 | iex

# Restart the terminal, then verify
contro1 --version
From source (Go)
# Requires Go 1.22+
git clone https://github.com/contro1-hq/contro1-cli.git
cd contro1-cli
go build -o contro1 .
# move contro1 onto your PATH, e.g. sudo mv contro1 /usr/local/bin/

Download from GitHub Releases · Source on GitHub

Sign in

Run contro1 auth login. Your browser opens, you approve the sign-in, and you are done. The CLI receives a limited token and stores it in your operating system's secure credential store - Keychain on macOS, Credential Manager on Windows, Secret Service on Linux. The token lasts 90 days, and you can revoke it at any time.

No browser on the machine? Use contro1 auth login --no-browser: the CLI prints a link you open on any device, and you paste back a short one-time code.

  • No setup needed: the CLI defaults to the hosted Contro1 (https://api.contro1.com). For a local or self-hosted instance, run contro1 config set api-url <url> and contro1 config set web-url <url>.
  • If doctor points at localhost unexpectedly, check the active profile with contro1 config get api-url and contro1 config get web-url, or use --profile <name> for a clean hosted profile.
  • CI: set CONTRO1_TOKEN=cco_cli_live_... to skip the keychain. Output also defaults to JSON when CI is set.
  • contro1 auth tokens list and contro1 auth tokens revoke <id> manage your tokens (also in Settings -> APIs & Webhooks).
  • contro1 auth print-access-token --yes prints the raw token for piping into CI (refuses in an interactive terminal without --yes).
macOS / Linux
contro1 auth login                 # opens the browser (hosted Contro1 by default)
contro1 auth login --no-browser    # headless / remote

contro1 whoami                     # who am I, which org, how many scopes
contro1 whoami --scopes            # list the granted scopes
contro1 doctor                     # check connectivity, auth and scopes

# CI / headless token mode
export CONTRO1_TOKEN=cco_cli_live_xxx
Windows (PowerShell)
contro1 auth login                 # opens the browser (hosted Contro1 by default)
contro1 auth login --no-browser    # headless / remote

contro1 whoami
contro1 whoami --scopes
contro1 doctor

# CI / headless token mode
$env:CONTRO1_TOKEN = "cco_cli_live_xxx"

Register an agent

Register the agent once so future requests, traces, and evidence can be attributed to it. This is useful for coding agents, support agents, workflow agents, and custom internal agents.

macOS / Linux
contro1 agents register --name "Claude Code - Laptop" --type coding-agent
contro1 agents list
contro1 agents get <agent_id>

# For scripts or agents, keep stdout machine-readable
AGENT_ID=$(contro1 agents register \
  --name "Claude Code - Laptop" \
  --type coding-agent \
  --quiet \
  --format json | jq -r .agent_id)
Windows (PowerShell)
contro1 agents register --name "Claude Code - Laptop" --type coding-agent
contro1 agents list
contro1 agents get <agent_id>

# For scripts or agents, keep stdout machine-readable
$agent = contro1 agents register `
  --name "Claude Code - Laptop" `
  --type coding-agent `
  --quiet `
  --format json | ConvertFrom-Json
$agent.agent_id

Ask a human before the agent acts

Create an approval request from the terminal and attribute it to an agent. The CLI can then block until the assigned human approves, rejects, or the request times out.

This is the fastest way to test a real Contro1 approval flow before you wire the same behavior through an SDK or direct API call.

Approval request
contro1 requests create --type approval \
  --question "Approve sending this customer email?" \
  --agent "$AGENT_ID" \
  --role support-manager \
  --risk high \
  --reason "Customer-visible action" \
  --wait

contro1 requests list --state queued
contro1 requests get <request_id>
contro1 requests wait <request_id> --timeout 10m
contro1 requests cancel <request_id>

Preview routing with Control Map

Use Control Map before a high-risk request when the agent should know whether the requested role, mapping, shift coverage, fallback reviewers, and quorum can be satisfied right now.

This is especially useful for coding agents and CI workflows: they can fail early with a clear routing reason instead of creating a request that no one can answer.

Control Map preview
contro1 requests control-map \
  --role finance \
  --required-approvals 2 \
  --approval-role finance \
  --must-include-role cfo \
  --risk high \
  --reason "Payment exceeds autonomous limit" \
  --quiet \
  --format json

Create routed and quorum-based requests

The CLI exposes the non-admin routing fields most agents need: required role, SLA, quorum, approval roles, case ids, idempotency ids, trace ids, and policy context.

When --required-approvals is greater than 1 and no approval mode is specified, the CLI uses threshold mode so the quorum is enforced instead of collapsing to a single approval.

  • --role routes the request to the business role that owns the decision.
  • --required-approvals plus --approval-role creates an enforced approval quorum.
  • --correlation-id groups related requests and audit records into one case.
  • --external-request-id is the idempotency key for safe retries.
  • --trace-id and --parent-trace-id connect the request to an agent run or sub-agent run.
Role, quorum and traceability
contro1 requests create \
  --type approval \
  --question "Approve vendor transfer #9831?" \
  --context "Invoice exceeds auto-pay policy; PO and invoice are attached." \
  --agent agt_123 \
  --role finance \
  --required-approvals 2 \
  --approval-role finance \
  --must-include-role cfo \
  --sla-minutes 10 \
  --risk high \
  --reason "Payment exceeds autonomous limit" \
  --correlation-id case-transfer-9831 \
  --external-request-id transfer-9831-approval \
  --trace-id trc_transfer_9831 \
  --wait

Use full API payloads from files

For advanced integrations, pass the same JSON body you would send to POST /requests or POST /requests/control-map. This keeps complex policies, protocol fields, tool calls, sub-agents, retrieved context, and response schemas versioned in your agent repository.

You can also attach individual JSON fragments when the CLI flags cover most of the request but one field is structured.

JSON payloads
contro1 requests control-map --file request.json --format json
contro1 requests create --file request.json --wait

contro1 requests create \
  --question "Approve publishing generated campaign?" \
  --role marketing-manager \
  --tool-calls-file tool-calls.json \
  --retrieved-context-file retrieved-context.json \
  --policy-context-file policy-context.json \
  --response-schema-file response-schema.json \
  --wait

Pull evidence and traces

After a decision, pull the evidence packet and execution trace linked to the request. This is the reviewable record that lets teams understand which agent asked, who decided, and what happened next.

Evidence and traces
contro1 evidence for-request <request_id>
contro1 traces for-request <request_id>
contro1 traces get <trace_id>
contro1 traces for-agent <agent_id>

Keep AI inventory current

Update your AI registry straight from the terminal - no dashboard upload needed. Point the CLI at a JSON file, or pipe JSON in from a scanner. Contro1 updates the registry and recalculates your readiness score.

The file can be your scanner's raw output, or wrapped as { "inventory": { ... } } - both work. Use "-" to read from stdin.

AI registry
# Import an inventory file
contro1 ai-registry import ./inventory.json

# Or pipe JSON from another tool / scanner
cat inventory.json | contro1 ai-registry import -

# See systems, gaps and the readiness score
contro1 ai-registry list
contro1 ai-registry list --quiet --format json

Optional: gate a local command

For coding agents and developer workflows, contro1 run asks for approval, waits for the decision, and runs a local command only if it is approved. It records the command, working directory, git branch and commit, approver, and exit code.

Use it when the agent action is naturally represented as a shell command, such as a deploy, migration, code generation step, or script.

Gated command
# Ask for approval, then deploy only if approved
contro1 run --requires-approval -- npm run deploy

# Attribute to an agent and route to the right approvers
contro1 run \
  --agent agt_123 \
  --role release-manager \
  --required-approvals 2 \
  --risk high \
  --reason "Production DB migration" \
  --requires-approval \
  -- npm run migrate

Read-only admin views

Read non-sensitive organization, API-key, webhook and integration metadata, plus the current approval queue. The CLI never reveals API keys, webhook secrets, or integration tokens.

Read-only views
contro1 org get
contro1 api-keys list
contro1 webhooks status
contro1 webhooks logs
contro1 integrations list
contro1 integrations slack status
contro1 queue list
contro1 queue my-requests

Output formats and exit codes

Every command supports --format table|json|yaml (table for humans, JSON automatically under CI) and --quiet. In JSON/YAML mode, status messages are suppressed so stdout stays parseable. Exit codes are stable so scripts and agents can branch on them.

Exit codeMeaning
0success
1general error
2bad arguments
3auth error (not logged in / token invalid or revoked)
4insufficient scope
5request denied
6timeout
7network error

Can a coding agent learn from the CLI directly?

Yes. The CLI is self-describing, so an agent does not need to read external docs to act safely. It can discover the full command tree, understand its own permissions, and confirm the current state - all in machine-readable JSON.

A good first move for an agent is: run contro1 doctor and contro1 whoami --scopes to learn what it is allowed to do, then contro1 help to discover commands, then add --quiet --format json to any command it runs.

  • contro1 help - top-level commands grouped by topic (Core, Agent workflows, Read-only admin, Operator queue).
  • contro1 <topic> --help and contro1 <topic> <command> --help - flags and examples for each command.
  • contro1 scopes / contro1 whoami --scopes - exactly which actions the current token may perform.
  • contro1 doctor - reachability, authentication, token type and key scopes as a checklist.
  • --quiet --format json on any command - structured output for parsing; stable exit codes for control flow.

Security model (what the CLI cannot do)

The CLI token is scoped on purpose. It can run the developer and agent workflow, but it cannot perform destructive organization administration. Four invariants hold:

  • CLI tokens are denied by default - a global guard allows only an explicit allowlist of CLI surfaces.
  • Within that surface, every action still requires a specific scope.
  • No user/role/department management, secret reveal/rotation, API-key create/delete, integration install, or platform admin from the CLI.
  • Command-run evidence is client-reported, not cryptographically verified execution.

Requests API · Webhooks

Frequently asked questions

Does the CLI have the same power as a dashboard admin?

No. The CLI uses a scoped token (cli_operator_token). It can register agents, create and follow approvals, push the AI inventory, read evidence and traces, and gate local commands when needed, but it cannot manage users, roles, departments, secrets, API keys, integrations or platform settings. Those stay in the dashboard.

Is contro1 run the main purpose of the CLI?

No. The main purpose is giving agents a terminal-native approval workflow: register agents, preview routing, create approval requests, push inventory, and retrieve evidence and traces. contro1 run is an important helper for coding agents and developer workflows when the action is a local command.

How do dangerous agents or workflows request approval?

Call contro1 requests create and contro1 requests wait from the agent workflow. If the action is a local command, you can also wrap it with contro1 run --requires-approval -- <command>. The action only proceeds after a human approves, and the decision is recorded as evidence.

Where is the token stored and how long does it last?

In your OS keychain (Keychain, Credential Manager, or Secret Service), with a 0600 file fallback. Tokens last 90 days and can be revoked anytime with contro1 auth tokens revoke or from Settings -> APIs & Webhooks.

How do I use it in CI?

Set the CONTRO1_TOKEN environment variable to a token value. The CLI uses it directly without touching the keychain, and output defaults to JSON when CI is set.