Skip to content
letmoa.run

CLI reference

FlagDefaultDescription
-pPrompt text, or @file to read from file
-modelsonnetModel alias or provider/model-id
-thinkingmediumoff, low, medium, high, xhigh — see Thinking levels
-max-turns0 (unlimited)Max agent turns per run
-max-budgetfrom configMax USD spend per run (-1 sentinel = use config.json; an explicit 0 means unlimited)
-yolofalseDisable sandbox and all permissions
-permissionsfrom configyolo, ask, auto
-permissions-modelModel for auto mode evaluator
-path-scopederivedworkspace or unrestricted
-allowPermission pattern (repeatable), e.g. "Bash(go:*)"
-allow-pathAllow extra directory outside workspace (repeatable)
-outputtexttext or json (JSON-lines)
-loginanthropic, openai, xai (SuperGrok/X OAuth device login), meta (Muse OAuth device login), openai-transcribe
-logoutRemove stored credentials for provider

-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, with role (main or subagent), subagent_id for a child, provider, model, the token fields (input, output, cache_read, cache_write) and cost_usd.
  • subagent_end — the child’s terminal cost_usd.
  • summary — the run total cost_usd, the aggregate usage, and by_model entries split by provider, model and role, each with its messages count, 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.

Terminal window
moa version # or: moa --version, moa -v

Prints the version, commit, and build date.

Terminal window
moa update # download, verify, and install the latest release
moa update --check # only report current vs latest, install nothing
FlagDefaultDescription
--checkfalseReport 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.

Terminal window
moa serve [--host 127.0.0.1] [--port 8080] [--model sonnet] [--token <secret>] [--allowed-hosts <names>]
FlagDefaultDescription
--host127.0.0.1Bind address (use 0.0.0.0 for remote access)
--port8080HTTP port
--modelsonnetDefault model for new sessions
--tokenShared secret for opt-in auth (or MOA_SERVE_TOKEN). When set, requests need a valid session cookie or ?token=<secret>
--automation-tokenShared 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-hostsComma-separated extra Host names accepted by the anti DNS-rebinding check (localhost/IP literals always allowed; e.g. a Tailscale MagicDNS name)
--preview-port0Initial 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-urlAddress 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.

Terminal window
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 ID
moa hooks add <source> --inbox
moa hooks list [--show-secrets]
moa hooks rm <source>
FlagDefaultDescription
--projectTarget a project directory ({project: DIR}). Mutually exclusive with --session and --inbox
--sessionTarget a live session id. Mutually exclusive with --project and --inbox
--inboxfalseLeave events in the inbox. Mutually exclusive with --project and --session
--when-noneinboxWhen the project has no live session: inbox or create
--when-manyinboxWhen the project has several live sessions: inbox or latest
--modelModel for when-none=create
--thinkingThinking level for when-none=create
--yolofalseCreate sessions in yolo permission mode
--autorunfalseStart a turn on delivery to an idle session. Off by default: the event is recorded without running
--show-secretsfalselist 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.

AliasResolves to
sonnetclaude-sonnet-5
opusclaude-opus-5
haikuclaude-haiku-4-5-20251001
fableclaude-fable-5-1
codexgpt-5.3-codex
codex-sparkgpt-5.3-codex-spark
codex-5.2gpt-5.2-codex
astragpt-6-astra
gpt-6gpt-6-astra
grokgrok-4.6 (xAI)
grok-4.6-buildgrok-4.6 (the subscription backend’s name for it)
grok-4.5-buildgrok-4.5 (the subscription backend’s name for it)
musemuse-spark-1.3 (Meta)
solgpt-5.6-sol
daybreakgpt-daybreak-blue-latest (moving alias for the current flagship, with safeguards for defensive cybersecurity work; needs Daybreak provisioning)
terragpt-5.6-terra
lunagpt-5.6-luna
gpt-5.6gpt-5.6-sol
gpt5gpt-5.5
gpt5.5gpt-5.5
gpt5-minigpt-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.

off, low, medium, high, xhigh are the canonical levels, but what a model does with them differs:

  • xAI Grok requires reasoning: off/low collapse to low, xhigh to high. Only low, medium, high are distinct there.
  • Claude Fable 5.1 thinks on every turn. off is not a real setting for it and is promoted to high; the web selector hides the option.
  • xhigh only reaches a higher tier on Anthropic Opus models. Every other Anthropic model caps it at high. OpenAI models accept xhigh as its own effort level. On GPT-6 Astra, the five UI positions map to low, medium, high, xhigh, and max respectively, so off is Astra’s lowest reasoning effort rather than disabled reasoning.

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:

ProviderModels that support itWhat it costs
AnthropicOpus models only2.5× faster, billed as separate usage credits
OpenAIGPT-6 AstraFast mode, 2× the token rate
OpenAIgpt-5.4, gpt-5.5 and gpt-5.6 generations (not the codex or mini variants)1.5× faster, burns credits 2.5×
xAIthe whole cataloguepriority 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.

Terminal window
# one-shot prompt
moa -p "fix flaky tests"
# explicit provider/model
moa -model openai/gpt-5.3-codex -p "optimize this query"
# Grok 4.6 with its supported thinking levels
moa -model grok -thinking high -p "review this change"
# budget-limited run
moa -max-budget 0.50 -p "refactor auth module"
# permissions with allow patterns
moa -permissions ask -allow "Bash(go:*)" -allow "Write(*.go)"
# allow access to extra directory
moa -allow-path /tmp/shared-data
# web UI on the network
moa serve --host 0.0.0.0 --port 8080