CLI
Install, authenticate, discover commands, and read the `oxygen` output envelope.
Every command is listed in the CLI reference. MCP tools and the web app call the same /api/cli/* contract, so state created here is visible from all three.
Install and authenticate
npm install -g @oxygen-agent/cli
oxygen login
oxygen status --json
oxygen updateoxygen status compares the local CLI against the deployed API. It stays usable — along with oxygen whoami and oxygen update — when an outdated CLI is refused with cli_update_required.
oxygen login registers the terminal server-side and sends you to Settings → CLI and MCP to approve it; the browser and the terminal show the same confirmation code. No loopback server is involved, so it also works over SSH, WSL, and in containers — open the printed URL in any browser. --no-browser skips the handoff; oxygen login --token <token> stores a token minted on that same page.
For non-interactive environments:
oxygen api-keys create --name "automation key" --json
oxygen auth use-token --token <token> --jsonoxygen talks to https://oxygen-agent.com. oxygen-dev targets the Oxygen dev deployment and is not for customer workspaces.
Profiles and organizations
oxygen profiles list --json
oxygen profiles use <profile> --json
oxygen orgs list --json
oxygen orgs use <organization-slug> --json
oxygen whoami --jsonA profile stores one host plus one token. The active organization scopes tables, context, integrations, runs, and credits.
Discovery
Start from the outcome, then hydrate one exact command:
oxygen capabilities search "waterfall-enrich work emails in this table" --json
oxygen commands search "preview a work-email waterfall" --limit 5 --json
oxygen commands get "enrich-column preview" --jsonThe capability card names the owning primitive, what it is not for, execution and spend posture, related skills, and gateway commands. commands get returns one command's exact arguments, flags, and safety markers. oxygen commands --json still emits the full manifest for diagnostics, but agents should not load it by default.
Skills and provider operations are separate catalogs:
oxygen skills search "host a deterministic signup workflow" --json
oxygen skills get <skill-name> --json
oxygen tools search "public LinkedIn post engagers" --json
oxygen tools get <tool-id> --jsonProvider operations are not CLI commands — they are the units a tool column or oxygen tools run invokes, listed in the provider reference. Public LinkedIn reads prefer native cookieless scraper.* operations; connected linkedin.* is for the workspace account's private data and writes.
Output envelope
--json returns one shape on every state-bearing command:
{
"ok": true,
"data": {
"web_url": "https://oxygen-agent.com/workspaces/<workspace-id>/tables/<table-id>"
},
"meta": {
"command": "tables preview",
"version": "<deployed server version>",
"minimum_cli_version": "<oldest CLI this API accepts>"
}
}A failure keeps meta and replaces data with error.code, error.message, and an optional error.details. The exit code classifies the failure so a shell agent can branch without parsing the body:
| Exit | Meaning |
|---|---|
| 0 | ok |
| 1 | unclassified error |
| 2 | usage or input validation |
| 3 | auth or CLI compatibility (not_authenticated, cli_update_required) |
| 4 | not found |
| 5 | provider or server failure |
| 6 | rate limited — wait error.details.retry_after_seconds, then retry |
| 7 | approval, spend gate, or subscription recovery — follow error.details.next_step |
| 8 | timeout |
data.web_url opens the same state in the web app. Run-oriented commands add run ids, status, item counts, credits, and error summaries.
Safety posture
Previews and dry runs make no provider calls and spend nothing. A paid provider call, AI or tool column run, enrichment run, CRM write, outbound enrollment, or LinkedIn action refuses to execute until you pass --approved, and refuses again without a --max-credits ceiling on anything that carries a price. approval_required and max_credits_required both exit 7 and spend nothing.
oxygen tools run <tool-id> --input-json '{...}' --mode dry-run --json
oxygen tools run <tool-id> --input-json '{...}' --mode live --approved --max-credits 5 --json--max-credits is a ceiling, not a charge: unused reserved credits are released. See Approvals for what each action requires, and check what a run actually cost with:
oxygen billing balance --json
oxygen billing usage --limit 50 --json