agno CLI is published as the agnoctl package and ships as a dependency of agno 2.7+. Installing either package puts the CLI on your PATH:
| Entry point | Package | Notes |
|---|---|---|
agno | agno >= 2.7, agnoctl | Primary command |
agnoctl | agnoctl | Same app. Enables uvx agnoctl <command> without installing the SDK. |
agnoctl requires Python >= 3.9 and depends on typer, rich, and httpx (plus tomli on Python < 3.11). It never imports agno.
Running bare agno prints the command catalog. agno --version prints the CLI version.
Environment Variables
| Variable | Read by | Purpose |
|---|---|---|
AGENTOS_URL | connect, disconnect, status, tokens | AgentOS base URL when --url is not passed. Skips the env-file lookup and localhost probe. |
AGNO_ADMIN_TOKEN | connect, disconnect --revoke, tokens | Admin credential for the service-accounts API. Checked first. |
OS_SECURITY_KEY | connect, disconnect --revoke, tokens | Admin credential fallback when AGNO_ADMIN_TOKEN is unset. |
--json mode or with a non-TTY stdin it exits with an error instead of prompting.
Discovery
Commands that talk to an AgentOS resolve its URL in this order:--url flag, AGENTOS_URL env var, AGENTOS_URL read from .env.production then .env in the current directory, then a probe of http://localhost:7777, :7778, :7779, and :8000. Interactive connect and disconnect runs probe all candidates (including URLs found in existing client configs) and prompt when more than one AgentOS answers; --json and non-TTY runs resolve the single highest-priority target.
Each candidate is checked with GET /health, then GET /info. Servers that report structured discovery fields (mcp: {enabled, path} and auth_mode) are read directly; older servers are probed with a POST /mcp (MCP mounted or not) and an unauthenticated GET /config (auth mode by status code). Detected auth modes: none, security_key, jwt, unknown.
Exit Codes
| Code | Meaning |
|---|---|
0 | Success. For connect: every selected client connected, was already connected, is configured pending a one-time OAuth sign-in, or received manual steps. |
1 | Error. For connect: no client connected. |
2 | Usage error (unknown command, flag, or argument). |
3 | Partial success (connect and disconnect): some clients succeeded, others failed. |
Machine Mode (--json)
Every command accepts --json:
- stdout carries exactly one JSON document and nothing else.
- Interactive prompts are disabled. Runs that would need one fail with an error.
- Errors emit
{"error": "<message>", "hint": "<optional hint>"}and exit non-zero.
url_source is flag, env, env-file, client-config, or default. url_source_file names the env file or client configs the URL came from. mcp.oauth carries {authorization_servers, resource} when /mcp is OAuth-protected. discovered_via is info or probe. Timestamps are Unix epoch seconds.
agno create
git clone --depth 1, 300s timeout) into ./<name> and removing its .git directory. It requires git and fails if the directory already exists. <name> must be a single path segment of letters, digits, -, and _.
| Flag | Default | Description |
|---|---|---|
--template, -t | agentos-docker | Starter template: agentos-aws, agentos-docker, agentos-fly, agentos-gcp, agentos-railway |
--url, -u | none | Clone from a custom template repository URL instead |
--json | off | Emit a single JSON document |
agno connect
initialize + tools/list handshake. The AgentOS must have mcp_server=True. When /mcp is OAuth-protected, entries are written without tokens, nothing is minted, and each app completes a one-time sign-in; --pat opts back into minted tokens.
| Flag | Default | Description |
|---|---|---|
--url | autodiscover | AgentOS base URL |
--clients | detected, plus claude-ai/chatgpt steps when the AgentOS is on a public URL | Comma-separated clients: claude-code, claude-desktop, codex, cursor; claude-ai and chatgpt print manual setup steps. Aliases: claude (Claude Code), claude-app (Claude Desktop), gpt/openai (ChatGPT). |
--name | one account per client | Use one shared service account with this name |
--scopes, -s | server’s run + read scopes | Scope to grant (repeatable) |
--expires | 90d | Token lifetime in days (90d, 30) or never |
--privileged | off | Required when --scopes grants write, delete, admin, or service_accounts scopes |
--pat | off | Mint service-account tokens even when the MCP endpoint is OAuth-protected (for headless clients) |
--server-name | derived from the AgentOS name, fallback agentos | MCP server entry name written to client configs. Letters, digits, -, _ only. |
--project | off | Write project-scoped configs (.mcp.json / .cursor/mcp.json) instead of user-level |
--rotate | off | Rewrite existing entries without asking: revoke and re-mint their accounts, or convert them to OAuth sign-in |
--skip-existing | off | Never touch existing accounts or config entries |
--allow-http | off | Permit sending credentials over plaintext HTTP to a non-loopback host |
--yes, -y | off | Trust a remote AGENTOS_URL from a .env file without prompting |
--json | off | Emit a single JSON document |
| Client | User scope | Project scope (--project) |
|---|---|---|
claude-code | ~/.claude.json | <cwd>/.mcp.json |
claude-desktop | claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\, Linux: ~/.config/Claude/) | n/a |
codex | ~/.codex/config.toml | n/a |
cursor | ~/.cursor/mcp.json | <cwd>/.cursor/mcp.json |
0600. The Claude Desktop entry launches the mcp-remote stdio bridge via npx and passes the token through an AGNO_AUTH_HEADER env entry in the config, keeping it out of argv.
Exit codes: 0 all connected, 1 nothing connected, 2 usage error, 3 partial. JSON output:
status values: connected, already-connected, needs-login (OAuth entry written; carries an instructions array with the client’s sign-in step), skipped, failed, and manual (chat apps; carries url and an instructions array instead of location). Optional result fields: note, rotated (a different token was replaced; restart the client), replaced_url (the entry previously pointed at another AgentOS), replaced_legacy (a stale agno-named entry was renamed), replaced_token_entry (a token-carrying entry was replaced by a tokenless one; the account behind it stays valid), auto (chat-app steps surfaced automatically). warning is set when the AgentOS accepts unauthenticated MCP requests despite enforcing auth elsewhere (a pre-enforcement agno version).
agno disconnect
--server-name, every entry pointing at the target AgentOS is removed (its live address, or every address discovery would have tried when nothing answers). Entries pointing at any other server are never touched.
| Flag | Default | Description |
|---|---|---|
--url | autodiscover | AgentOS base URL |
--clients | detected | Comma-separated clients; claude-ai and chatgpt print manual removal steps |
--server-name | every entry pointing at the target AgentOS | Remove exactly this entry name |
--name | one account per client | With --revoke: the shared service-account name used at connect time |
--revoke | off | Also revoke the matching service accounts (needs the OS and an admin credential) |
--allow-http | off | Permit sending credentials over plaintext HTTP to a non-loopback host |
--yes, -y | off | Trust a remote AGENTOS_URL from a .env file without prompting |
--json | off | Emit a single JSON document |
status values: removed (carries a removed array of entry names), not-found, failed, and manual (chat apps). Exit codes: 0 all removed or nothing to remove, 1 every removal failed, 3 partial (including failed revocations). JSON output:
revocations is populated by --revoke: {"account": "<name>", "status": "revoked" | "not-found" | "failed", "error": null} per account.
agno status
| Flag | Default | Description |
|---|---|---|
--url | autodiscover | AgentOS base URL |
--server-name | derived from the AgentOS name, fallback agentos | MCP server entry name to look for in client configs |
--json | off | Emit a single JSON document |
agno up / down / restart
docker compose against the project’s compose file (600s timeout). Without --file, the first of docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml found in ./ then ./infra is used. up runs docker compose up -d --build; down runs docker compose down; restart runs down, waits 2 seconds, then up.
| Flag | Commands | Description |
|---|---|---|
--file, -f | all | Compose file to use |
--pull, -p | up, restart | Add --pull always to the compose command |
--volumes, -v | down | Add --volumes (removes named volumes, destroys data) |
--dry-run, -dr | all | Print the compose command without running it |
--json | all | Emit a single JSON document |
up and down:
restart nests both phases:
agno tokens
Thetokens subcommands are admin operations against the AgentOS service-accounts API. All three accept --url, --json, --allow-http, and --yes (trust a remote AGENTOS_URL from a .env file without prompting), and resolve the admin credential from AGNO_ADMIN_TOKEN / OS_SECURITY_KEY (or a prompt) when the AgentOS enforces authorization. The CLI refuses to send credentials over plaintext HTTP to a non-loopback host without --allow-http.
agno tokens create
| Flag | Default | Description |
|---|---|---|
--scopes, -s | agents:run, teams:run, workflows:run, sessions:read, config:read | Scope to grant (repeatable) |
--expires | 90d | Days until expiry (90d, 30) or never |
--privileged | off | Required to grant write, delete, admin, or service_accounts scopes |
<name> is a lowercase slug (max 63 chars): a-z, 0-9, -, _, starting with a letter or digit. A name that already exists is a conflict; revoke it or pick another. The plaintext token appears once in the output and is never retrievable again.
JSON output is the service-account object plus a token field:
agno tokens list
agno tokens revoke
| Flag | Default | Description |
|---|---|---|
--yes, -y | off | Skip confirmation prompts (revoking, and trusting a remote .env-file URL) |
--yes, --json, and non-TTY runs skip the prompt.