← Documentation

Astral CLI

Use all of Astral from a terminal: sign in, deploy sites, work with code, and call any platform tool. Built for people and for outside agents like Claude Code and Codex.

Astral CLI

The astral command puts the whole Astral platform in your terminal. Deploy a site, clone a repo, read logs, or call any tool that an Astral agent can call. Use it yourself, or give it to an outside agent such as Claude Code, Codex, or Cursor.

Status. The public API, token sign-in, approvals, and the astral command are live. The package is on npm as @astralos/cli. Items marked (coming soon) show planned behavior.

bash
npm install -g @astralos/cliastral loginastral link --site my-siteastral deploy --prod

Why it is different

  • Every tool is a command. The CLI does not hard-code the platform. It reads the live tool catalog and builds its commands from it. When Astral adds a tool, the CLI has the new command at once, with no CLI update.
  • Made for agents too. Every command has --json output, typed exit codes, and no prompts when there is no terminal. An agent can run it in a loop and branch on the result.
  • Real git. astral code clone uses normal git with short-lived credentials. After the clone, git pull works as usual, and astral code push sends your commits.
  • Safe by default. A token never skips an approval. If a call needs a person to approve it, the CLI prints a link and waits or stops.

Sign in

People: device login

bash
astral login# Open the /device page of your Astral app and enter code: WDJB-MJHTastral whoamiastral logout

The CLI shows a short code. You open /device in your browser, sign in, and approve the code. The CLI then gets a session token. This is the OAuth device flow (RFC 8628), the same flow that the GitHub and Stripe CLIs use.

astral login also takes --with-token (read a token from stdin), --api-url, --scope, and --name.

Agents and CI: access tokens

An access token is a long-lived key with limited rights. You see it one time only. Astral stores only a hash of it.

bash
astral token create --name ci-deploys --scope sites:write --expires-in-days 30astral token listastral token revoke <token_id>export ASTRAL_TOKEN=astral_...

--name is required. Add --agent <agent_id> to make a token for an agent.

Every token has:

  • A principal: a person or an agent.
  • A workspace.
  • Scopes, for example sites:read, sites:write, code:read. A token can never get more rights than the person or agent that made it.
  • An expiry.

You can list and revoke tokens at any time. Every use of a token goes to the workspace event log.

Inside an Astral computer

Eligible agent commands on Astral computers do not need astral login. AIOS supplies ASTRAL_TOKEN, ASTRAL_API_URL, and ASTRAL_WORKSPACE automatically for each command. AIOS does not write the token to disk and deletes it when the command ends.

The token uses the running agent's authority and workspace. Access checks and applicable approvals still apply. Restricted runs, unattended runs with no person, and computers from another workspace do not receive this automatic token.

On your laptop or another external computer, use astral login. The desktop terminal on an Astral computer also needs astral login; automatic sign-in applies to agent commands, not to that terminal.

What you can do

Sites

Link a folder to a site one time. After that, commands in the folder need no --site flag.

bash
astral link --site my-site          # writes .astral/project.jsonastral deploy --prod                 # productionastral deploy --branch feature/pricing   # previewastral deploy --prod --detach        # return when the build startsastral open                          # open the linked siteastral unlinkastral sites listastral sites logs --site <site_id> --follow

A failed or canceled build exits with code 7.

The other site tools come from the catalog. Their flags are the tool's input fields in kebab case, and they take a site id, not a site name:

bash
astral sites rollback --site-id <site_id>astral sites set-env --site-id <site_id> --key API_URL --value https://api.example.comastral sites add-domain --site-id <site_id> --domain example.com

Code

bash
astral code list-reposastral code clone my-app        # real git clone, with astral as the git credential helpercd my-app && git checkout -b fix/header# edit filesgit commit -am "Fix header"astral code push                # a person approves the exact pushastral code get-diff --repo my-app --base main --head fix/header

astral code push waits for the approval by default. --no-wait exits with code 10 and prints the approval link.

Any tool

Each tool in the catalog is also reachable by name:

bash
astral tools listastral tools describe sites.deployastral tools call sites.deploy --input '{"site_id": "..."}'astral tools call sites.deploy --input-file input.json   # or - for stdin

Flags on a generated command map to the tool's input fields. --input '<json>' also works on every generated command. When a hand-written command and a generated command have the same name, the hand-written command wins.

Use Astral inside your own agent

bash
astral mcp            # starts an MCP server over stdio with the same toolsastral agent-setup    # writes an AGENTS.md snippet that teaches your agent the CLI

Add astral mcp to Claude Code, Codex, or Cursor, and that agent can use Astral tools natively. (coming soon)

Built for scripts and agents

Global flags:

  • --json on every command. The JSON is the API response, with a stable shape.
  • -y / --yes skips confirmations. With no terminal, the CLI never prompts.
  • --profile <name> picks a profile.
  • --wait keeps the CLI waiting for an approval. --wait-timeout <seconds> sets the limit (default 900).

Exit codes tell you what happened:

CodeMeaning
0Success
1Unknown failure
2invalid_input
3auth_required or auth_failed
4permission_denied
5not_found
6rate_limited
7upstream_error, or a failed or canceled build
10approval_required

Approvals

Some tools need a person to approve each call, for example a delete, a payment, or a git push. The CLI then exits with code 10 and prints a link. A person opens the link, sees the exact call, and approves or rejects it. Add --wait to keep the CLI waiting until that decision.

Configuration

  • Profiles live in ~/.config/astral/config.toml, one per account or workspace. Tokens live next to it in ~/.config/astral/credentials.json (mode 0600).
  • astral workspace list, astral workspace use <profile>, and astral workspace current manage profiles.
  • A folder can link to a site in .astral/project.json (astral link), so commands in that folder need no --site flag.
  • Environment variables override the config: ASTRAL_TOKEN, ASTRAL_WORKSPACE, ASTRAL_API_URL, ASTRAL_PROFILE. ASTRAL_CONFIG_DIR and ASTRAL_CACHE_DIR move the config and cache folders. The CLI also follows XDG_CONFIG_HOME and XDG_CACHE_HOME.
  • The default API URL is https://www.astralos.ai. Use this exact host in ASTRAL_API_URL. The bare astralos.ai host redirects, and the redirect drops the Authorization header.

The API under the CLI

The CLI is a thin client over a public, versioned HTTP API at https://www.astralos.ai. You can call this API directly.

EndpointWhat it does
POST /api/v1/auth/device/codeStarts a device login. Returns a user_code and a device_code.
POST /api/v1/auth/device/tokenExchanges an approved device_code for a token.
GET /api/v1/whoamiShows the principal, workspace, and scopes of the current token.
GET /api/v1/catalogLists every tool with its input schema.
POST /api/v1/tools/{app}.{tool}Calls one tool. The body is the tool's input JSON.
GET / POST /api/v1/tokens, DELETE /api/v1/tokens/{id}Lists, creates, and revokes tokens.

The git commands use two tools: code.git_read_credentials (clone and pull, no approval) and code.git_write_credentials (push, always needs a person's approval of the exact call, also with a token). The git password is never stored in tool output.

Send the token as Authorization: Bearer astral_.... Every response has the Astral-Api-Version header and one of two shapes:

json
{ "ok": true, "data": { } }{ "ok": false, "error": { "type": "not_found", "message": "...", "details": { } } }

The v1 contract changes only by new, optional fields. A breaking change gets a new version.

Related