Skip to main content
The 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.
The document shapes per command are listed below. Two shared objects appear throughout:
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

Scaffolds a project by shallow-cloning a template repository (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

Connects coding agents to a running AgentOS over MCP. It discovers the AgentOS, mints one service account per client, writes each client’s MCP config, reads the entry back, and verifies it with a real MCP 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:
Result 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

Removes the AgentOS MCP entries from client configs. It works offline by default and needs no running AgentOS or admin credential. Without --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

Run 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

The tokens 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

Lists all service accounts, including revoked ones. Only metadata and the token display prefix are returned, never tokens.

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.

Developer Resources