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:
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
When neither credential variable is set and the AgentOS enforces authorization, the CLI prompts interactively. In
--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
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 _.
JSON output:
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.
Config locations per client:
Token-bearing config files are written with mode
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.
Result
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
JSON output:
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.
JSON output for
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
<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
Revoking is irreversible; the account’s tokens stop working on their next request. Interactive runs confirm first.
--yes, --json, and non-TTY runs skip the prompt.