CLI reference
| Flag | Default | Description |
|---|---|---|
-p | Prompt text, or @file to read from file | |
-model | sonnet | Model alias or provider/model-id |
-thinking | medium | off, low, medium, high, xhigh — see Thinking levels |
-max-turns | 0 (unlimited) | Max agent turns per run |
-max-budget | from config | Max USD spend per run (-1 sentinel = use config.json; an explicit 0 means unlimited) |
-yolo | false | Disable sandbox and all permissions |
-permissions | from config | yolo, ask, auto |
-permissions-model | Model for auto mode evaluator | |
-path-scope | derived | workspace or unrestricted |
-allow | Permission pattern (repeatable), e.g. "Bash(go:*)" | |
-allow-path | Allow extra directory outside workspace (repeatable) | |
-output | text | text or json (JSON-lines) |
-login | anthropic, openai, xai (SuperGrok/X OAuth device login), meta (Muse OAuth device login), openai-transcribe | |
-logout | Remove stored credentials for provider |
JSON-lines output
Section titled “JSON-lines output”-output json emits one JSON object per line: lifecycle, message updates, tool
execution, progress and errors.
It also reports what the run cost, so a benchmark or a cost ledger does not have to reconstruct spending from session files:
message_usage— one line per completed assistant message, withrole(mainorsubagent),subagent_idfor a child,provider,model, the token fields (input,output,cache_read,cache_write) andcost_usd.subagent_end— the child’s terminalcost_usd.summary— the run totalcost_usd, the aggregateusage, andby_modelentries split by provider, model and role, each with itsmessagescount, tokens and cost.
{"type":"message_usage","role":"main","provider":"anthropic","model":"claude-sonnet-5","input":1204,"output":318,"cache_read":8192,"cache_write":0,"cost_usd":0.008}{"type":"summary","turns":2,"tools_completed":3,"files_touched":["main.go"],"elapsed_seconds":41,"cost_usd":0.0143,"usage":{"input":1600,"output":420,"cache_read":8192,"cache_write":0},"by_model":[{"provider":"anthropic","model":"claude-sonnet-5","role":"main","messages":2,"input":1600,"output":420,"cache_read":8192,"cache_write":0,"cost_usd":0.0143}]}The main run’s cost comes from the run’s own total and children’s from their terminal cost, so no dollar is counted twice. Costs are rounded to the micro-dollar, well below any provider’s billing granularity.
Version subcommand
Section titled “Version subcommand”moa version # or: moa --version, moa -vPrints the version, commit, and build date.
Update subcommand
Section titled “Update subcommand”moa update # download, verify, and install the latest releasemoa update --check # only report current vs latest, install nothing| Flag | Default | Description |
|---|---|---|
--check | false | Report whether an update is available without installing it |
Downloads the release archive for your platform, verifies its SHA-256 against
the release checksums.txt, and replaces the running binary in place. It never
restarts anything: restart Moa yourself afterwards.
Binaries installed through Homebrew or Nix are refused with a pointer to the
package manager (brew upgrade moa). If the binary’s directory is not writable,
the command fails with a clear message rather than escalating privileges.
Unlike the passive update notice, moa update ignores MOA_NO_UPDATE_CHECK:
it is an explicit request.
Serve subcommand
Section titled “Serve subcommand”moa serve [--host 127.0.0.1] [--port 8080] [--model sonnet] [--token <secret>] [--allowed-hosts <names>]| Flag | Default | Description |
|---|---|---|
--host | 127.0.0.1 | Bind address (use 0.0.0.0 for remote access) |
--port | 8080 | HTTP port |
--model | sonnet | Default model for new sessions |
--token | Shared secret for opt-in auth (or MOA_SERVE_TOKEN). When set, requests need a valid session cookie or ?token=<secret> | |
--automation-token | Shared secret enabling the Automation API (or MOA_AUTOMATION_TOKEN), presented as Authorization: Bearer <secret>. Separate from --token; without it those routes do not exist | |
--allowed-hosts | Comma-separated extra Host names accepted by the anti DNS-rebinding check (localhost/IP literals always allowed; e.g. a Tailscale MagicDNS name) | |
--preview-port | 0 | Initial local port for the Live Preview proxy. Optional: with 0 the port is chosen (and confirmed) the first time you open a preview. The listener is never opened at startup either way — it binds 127.0.0.1 on first use and closes when the preview does |
--preview-public-url | Address through which that listener is reachable from the browser — Moa rewrites the dev server’s origin to it. Required with --preview-port; without either flag the web UI proposes an address and remembers your answer |
See Web UI for details.
Hooks subcommand
Section titled “Hooks subcommand”moa hooks add <source> --project DIR [--when-none inbox|create] [--when-many inbox|latest] [--model M --thinking T --yolo] [--autorun]moa hooks add <source> --session IDmoa hooks add <source> --inboxmoa hooks list [--show-secrets]moa hooks rm <source>| Flag | Default | Description |
|---|---|---|
--project | Target a project directory ({project: DIR}). Mutually exclusive with --session and --inbox | |
--session | Target a live session id. Mutually exclusive with --project and --inbox | |
--inbox | false | Leave events in the inbox. Mutually exclusive with --project and --session |
--when-none | inbox | When the project has no live session: inbox or create |
--when-many | inbox | When the project has several live sessions: inbox or latest |
--model | Model for when-none=create | |
--thinking | Thinking level for when-none=create | |
--yolo | false | Create sessions in yolo permission mode |
--autorun | false | Start a turn on delivery to an idle session. Off by default: the event is recorded without running |
--show-secrets | false | list only: print the full /hooks/<source>/<secret> path |
add generates a 32-byte url-safe secret, writes it to the global config, and
prints the hook path on its own line, preceded by Hook URL path (contains the secret; store it in the provider now):. See Event hooks.
Model aliases
Section titled “Model aliases”| Alias | Resolves to |
|---|---|
sonnet | claude-sonnet-5 |
opus | claude-opus-5 |
haiku | claude-haiku-4-5-20251001 |
fable | claude-fable-5-1 |
codex | gpt-5.3-codex |
codex-spark | gpt-5.3-codex-spark |
codex-5.2 | gpt-5.2-codex |
astra | gpt-6-astra |
gpt-6 | gpt-6-astra |
grok | grok-4.6 (xAI) |
grok-4.6-build | grok-4.6 (the subscription backend’s name for it) |
grok-4.5-build | grok-4.5 (the subscription backend’s name for it) |
muse | muse-spark-1.3 (Meta) |
sol | gpt-5.6-sol |
daybreak | gpt-daybreak-blue-latest (moving alias for the current flagship, with safeguards for defensive cybersecurity work; needs Daybreak provisioning) |
terra | gpt-5.6-terra |
luna | gpt-5.6-luna |
gpt-5.6 | gpt-5.6-sol |
gpt5 | gpt-5.5 |
gpt5.5 | gpt-5.5 |
gpt5-mini | gpt-5.4-mini |
You can also use canonical IDs (claude-sonnet-5) or provider-prefixed IDs (anthropic/claude-sonnet-5). Some known models have no alias and are reachable only by ID: claude-fable-5, claude-opus-4-8, grok-4.5, muse-spark-1.3-contributor (cheaper, but Meta trains on its prompts). Provider-prefixed custom IDs, including xai/<model-id>, are accepted, but context-window management and any unverified pricing metadata are disabled for them.
Thinking levels
Section titled “Thinking levels”off, low, medium, high, xhigh are the canonical levels, but what a
model does with them differs:
- xAI Grok requires reasoning:
off/lowcollapse tolow,xhightohigh. Onlylow,medium,highare distinct there. - Claude Fable 5.1 thinks on every turn.
offis not a real setting for it and is promoted tohigh; the web selector hides the option. xhighonly reaches a higher tier on Anthropic Opus models. Every other Anthropic model caps it athigh. OpenAI models acceptxhighas its own effort level. On GPT-6 Astra, the five UI positions map tolow,medium,high,xhigh, andmaxrespectively, sooffis Astra’s lowest reasoning effort rather than disabled reasoning.
Fast mode
Section titled “Fast mode”Fast mode buys premium speed at a premium price on the same model. It is a
per-session switch in the web UI (GET/PATCH /api/sessions/{id}/fast), not a
CLI flag, and only some models can serve it:
| Provider | Models that support it | What it costs |
|---|---|---|
| Anthropic | Opus models only | 2.5× faster, billed as separate usage credits |
| OpenAI | GPT-6 Astra | Fast mode, 2× the token rate |
| OpenAI | gpt-5.4, gpt-5.5 and gpt-5.6 generations (not the codex or mini variants) | 1.5× faster, burns credits 2.5× |
| xAI | the whole catalogue | priority queue, 2× the token rate |
Turning it on for a model that cannot serve it is not an error: the setting is not stored, and the session stays at standard speed.
The session cost (cost_usd, the budget guardrail) charges a fast request at
the provider’s premium: 2× on Anthropic ($10/$50 per MTok on Opus, cache
multipliers on top), 2× on GPT-6 Astra, 2.5× on earlier supported OpenAI GPT
models, and 2× on xAI. The multiplier applies only
to turns the provider actually served at the premium tier — Anthropic reports
usage.speed, OpenAI and xAI echo service_tier — so a turn that fell back to
standard speed is billed as standard.
Examples
Section titled “Examples”# one-shot promptmoa -p "fix flaky tests"
# explicit provider/modelmoa -model openai/gpt-5.3-codex -p "optimize this query"
# Grok 4.6 with its supported thinking levelsmoa -model grok -thinking high -p "review this change"
# budget-limited runmoa -max-budget 0.50 -p "refactor auth module"
# permissions with allow patternsmoa -permissions ask -allow "Bash(go:*)" -allow "Write(*.go)"
# allow access to extra directorymoa -allow-path /tmp/shared-data
# web UI on the networkmoa serve --host 0.0.0.0 --port 8080