Skip to content
Theme:

Headless CLI

aether headless runs a single prompt, streams events to stdout, and exits.

Terminal window
aether headless "Explain the settings loader in this project"
Terminal window
aether headless [OPTIONS] [PROMPT]...

If prompt words are provided, Aether joins them with spaces. If no prompt is provided and stdin is not a TTY, Aether reads stdin, trims it, and uses that as the prompt.

Terminal window
git diff --staged | aether headless "Review these changes"

Headless mode has two ways to choose what runs:

OptionBehavior
--agent <name>Resolve a named agent from settings.
--model <provider:model>Create an ad-hoc default agent using that model.

--agent and --model are mutually exclusive. If neither is provided, Aether launches the agent named by the top-level agent setting (when set), otherwise the first user-invocable agent from settings. If there are no configured agents, it falls back to Aether’s built-in default agent spec.

Terminal window
aether headless --agent Researcher "Find the API route definitions"
Terminal window
aether headless --model zai:glm-5.1 \
"Summarize the architecture"

Use --provider for provider-specific request routing and connection overrides. For Microsoft Foundry, configure the resource endpoint and optionally map the catalog model to its deployment name:

Terminal window
aether headless --model azure-foundry:gpt-5.5 \
--provider azure-foundry.url=https://my-resource.openai.azure.com/openai/v1 \
--provider azure-foundry.request-model=production-coding-deployment \
"Summarize the architecture"

For Bedrock inference profiles, keep --model as the Bedrock model ID and pass the ARN separately:

Terminal window
aether headless --model bedrock:anthropic.claude-sonnet-4-5-20250929-v1:0 \
--provider bedrock.inference-profile-arn=arn:aws:bedrock:us-west-2:000000000000:application-inference-profile/000000000000 \
"Summarize the architecture"
FlagTypeDescription
[PROMPT]...positionalPrompt text. Reads stdin if omitted and stdin is not a TTY.
-a, --agentstringNamed agent from settings. Defaults to the top-level agent setting if set, else the first user-invocable agent.
-m, --modelstringAd-hoc model spec. Mutually exclusive with --agent.
-C, --cwdpathWorking directory. Defaults to ..
--settings-jsonstringInline settings JSON.
--settings-filepathSettings JSON file.
--mcp-configpathMCP config file. Repeatable. Replaces the agent’s MCP source list for the run.
--mcp-config-jsonstringInline MCP config JSON. Repeatable. Replaces the agent’s MCP source list for the run.
--system-promptstringAdditional system prompt text.
--outputtext | pretty | jsonOutput format. Defaults to text.
-v, --verboseflagVerbose diagnostic logging to stderr.
--eventscomma-separated listEvent kinds to emit. Omit to emit all.
--providerprovider.field=valueProvider override. Supports PROVIDER.url, PROVIDER.auth, PROVIDER.request-model, and bedrock.inference-profile-arn.

--sandbox-image is a global CLI flag, so it can appear before the subcommand or in the subcommand options shown by help.

Human-readable lines. Final text is printed as plain text; tool calls, tool results, errors, context usage, and other selected events are formatted as simple lines. Background MCP tasks get their own lines as they start and finish (Tool deferred ..., Background task completed ..., Background task failed ..., Background task cancelled ...).

Terminal window
aether headless --output text "What does this project do?"

--output json writes NDJSON to stdout: one aether_core::events::AgentEvent JSON object per line. Parse each line independently:

let event: aether_core::events::AgentEvent = serde_json::from_str(line)?;

Example lines:

{"category":"tool","event":{"type":"call","request":{"id":"tc1","name":"bash","arguments":"{}"}}}
{"category":"message","event":{"type":"text","message_id":"msg1","chunk":"done","is_complete":true}}
{"category":"turn","event":{"type":"ended","outcome":{"status":"completed"}}}

Diagnostics from tracing are written to stderr. Keep stdout and stderr separate when parsing JSON output.

By default, headless mode emits every output event. Use --events to restrict output:

Terminal window
aether headless --output json --events tool_call,tool_result \
"Refactor this module"

Available event kinds:

Event kindDescription
textFinal text chunks.
thoughtFinal reasoning/thought chunks.
tool_callTool invocation.
tool_resultTool return value.
tool_errorTool failure.
auto_continueAgent auto-continuing.
model_switchedModel changed through alloying.
tool_progressTool execution progress.
context_compaction_startedContext compaction beginning.
context_compaction_endedContext compaction finished (completed, failed, or cancelled).
context_compaction_resultContext compaction completed.
context_usageCurrent context-window usage.
session_usagePer-call tokens and estimated cost, plus cumulative totals.
context_clearedContext was cleared.
turn_startedTurn processing began.
turn_endedTurn completed, failed, or was cancelled.
llm_retry_scheduledLLM retry backoff was scheduled.
llm_call_startedLLM call began, including retries.
llm_call_endedLLM call completed, failed, or was cancelled.
tool_execution_startedTool execution began.
tool_definitions_updatedAvailable tool definitions changed.

When --events is set, terminal outcomes are shown only if turn_ended is explicitly listed.

The process exits non-zero when the turn ends with a failed outcome, regardless of event filtering.

Headless mode resolves normal Aether settings from global and project settings unless you provide --settings-file or --settings-json.

MCP configs provided with --mcp-config or --mcp-config-json replace the agent’s MCP source list for that run (they are not merged with the agent’s configured sources).

Terminal window
aether headless \
--agent Researcher \
--mcp-config .aether/readonly-mcp.json \
"Map the auth flow"

Print the fully assembled system prompt for debugging:

Terminal window
aether show-prompt --agent Researcher

show-prompt accepts --cwd, settings overrides, MCP config overrides, --system-prompt, --agent, and --sandbox-image.

Call a model directly with a single prompt and print its response. Unlike headless mode, generate runs no agent loop, no tools, and no MCP servers — it is a raw model call.

Terminal window
aether generate --model anthropic:claude-sonnet-4-5-20250929 --prompt "Explain traits in Rust"

Read the prompt from a file or stdin with --prompt-file -:

Terminal window
cat schema.json | aether generate --model zai:glm-5.1 --prompt-file -
FlagTypeDescription
--modelstringModel spec (provider:model). Required.
--promptstringPrompt text. Mutually exclusive with --prompt-file.
--prompt-filepath or -Read the prompt from a file, or - for stdin. Mutually exclusive with --prompt.
--systemstringOptional system prompt.
--temperaturenumberSampling temperature.
--top-pnumberNucleus sampling probability mass.
--max-tokensnumberUpper bound on generated tokens.
--reasoning-effortminimal | low | medium | high | xhigh | maxReasoning effort for models that support extended thinking.
--outputtext | pretty | jsonOutput format. text prints the raw response; json/pretty wrap it as { "text": "<response>", "model": "<model>" }. Defaults to text.

See Getting Started and Settings for project scaffolding details.