Documentation — CLI, environment and exit codes
Reference · Runtime

CLI, environment and exit codes

This page lists everything the agentd binary accepts on its command line and from its environment, and every exit code it can end with. It is for operators writing unit files and manifests, and for integrators scripting around the binary. The values here match agentd --help; the per-setting keys live in the Configuration reference.

Synopsis

agentd --config <settings.yaml> [--config <overlay.yaml> …] [--<path> <value> …]
agentd --prompt <TEXT> --intelligence <URL> --model <NAME>
agentd --instruction <TEXT> --intelligence <URL> --model <NAME> [--mcp name=<endpoint> …]
agentd tui|ui [launcher flags] --config <settings.yaml> [--<path> <value> …]
agentd <ask>
  • The first form runs whatever the configuration describes: a one-shot job or a long-lived daemon. See Jobs, daemons and triggers.
  • --prompt delivers one task as a message to the agent's root context, with its full tool surface, and exits when the instance has nothing long-lived armed. The turn's outcome is the exit code, as a run's is: 4 when the model cannot be reached, 7 when a budget refuses or ends the turn, 124 past the deadline.
  • --instruction without a workflow is the one-shot sugar: agentd generates a once → agent → finish workflow named main. With nothing long-lived configured, the process exits when that run ends.
  • tui and ui run the daemon plus a display client. See Subcommands.
  • An ask prints something and exits without starting the runtime. See Asks.

A flag takes its value as the next argument (--drain-timeout 25s). Only -c/--config and --env also accept the = form; --drain-timeout=25s is unknown argument: --drain-timeout, exit 2. In a container args: list, write the flag and its value as two entries.

Subcommands

agentd tui and agentd ui are a launcher. They run the daemon exactly as agentd <args> would, start one display client beside it, sign the client in with a single-use launch code, and tie the two lifetimes together. They add no setting: the live feed needs a2a.events.enabled and the debug panes a2a.introspection.enabled in your own configuration.

FlagSubcommandMeaning
--daemon-log <PATH>tui, uiWhere the daemon's JSON-lines output goes while the client holds the terminal. Default $XDG_RUNTIME_DIR/agentd-<sub>-<pid>.log, else the same name in the temp directory.
--port <N>uiLoopback port the web UI is served on. Default 4173.
--no-openuiPrint the sign-in URL instead of opening a browser.

Every other argument goes to the daemon. The launcher needs a loopback http(s) listener with a fixed port and no a2a.tls.client_ca, and refuses anything else before it spawns a process (exit 2). The client binary is agentd-tui or agentd-ui on PATH, or the path in AGENTD_TUI_BIN / AGENTD_UI_BIN. A build without the a2a feature has no launcher and exits 2. Use the terminal and web UI covers the clients.

Asks

An ask answers a question and exits. None of them binds a socket or calls a model, and only --login dials a server: the token endpoint. Every ask reads the configuration files you name, so a file that does not parse is exit 2 even for --help. Only --validate-config, --capabilities and --effective-config also run validation.

FlagPrintsStreamExit
-h, --helpUsage, the named flags, and the CONFIG PATHS tablestdout0
-V, --versionagentd <version>stdout0
--validate-configOne config.valid line, or one config.invalid line per problem, plus config.warning linesstderr0 valid, 2 invalid
--effective-configThe assembled document, the layer each setting came from, and the instruction's :::!config fragment. On an invalid configuration it still prints, and reports the errors on stderr. Credential-shaped values are "<redacted>".stdout (errors on stderr)0
--config-schemaThe settings JSON Schema (Draft 2020-12)stdout0
--workflow-schemaThe workflow JSON Schema and node registrystdout0
--context-templateThe built-in system-prompt templatestdout0
--capabilitiesThe capabilities manifest: what this binary and configuration servestdout0, or 2 on an invalid configuration
--extensionsEvery A2A extension and binding URI agentd publishes, with its spec and schema locationstdout0
--extension-schema <name>The schema bundle of one extension (command, events, task-annotations)stdout0, or 2 for an unknown name
--login <target>Runs an interactive OAuth device login and caches the token. Targets: intelligence, intelligence:<provider>, mcp:<name>, service:<name>. Needs the oauth feature.stdout0, or 2 on failure
--logout <target>Evicts a cached credentialstdout0, or 2 on failure

Note. --validate-config writes its verdict to stderr. A CI step that captures stdout to check validity sees nothing; branch on the exit code instead.

--validate-config resolves every {{secret:NAME}} reference the document uses. In CI, set each referenced variable to a placeholder value.

--context-template is an ask, so the setting context.template is reached from the command line as --context.template <value>.

Process flags

These flags shape one invocation. They have no configuration path, so no file or environment variable can pin them.

FlagMeaning
-c, --config <PATH>Load a YAML or JSON configuration file. Repeatable; later files override earlier ones key by key, and a list replaces the list under it. Also read from AGENTD_CONFIG (a.yaml:b.yaml), whose files load before any --config.
--env <FILE>Load a dotenv file into this process's environment before anything reads it. Repeatable; later files win, and the real environment always wins over a file. KEY=VALUE, an export prefix, # comments, '…' literals and "…" with escapes. A malformed line is exit 2 naming the file and line.
--freshStart a new durable-store generation instead of resuming. The previous generation stays on the store.
--prompt-missingAsk on /dev/tty, with echo off, for each {{secret:NAME}} the startup check finds missing. Values stay in memory; a restart asks again. Refused without a controlling terminal.

Named flags

The named flags are short spellings for the settings an operator reaches for most. Each sets one configuration path. The Env column is the short environment name; the derived name (AGENTD_<PATH>) works too and wins over the short one when both are set.

FlagPathEnvDefault
--instruction <VALUE>agent.instructionAGENTD_INSTRUCTIONnone
--instruction.text <TEXT>agent.instruction.text
--instruction.file <PATH>agent.instruction.file
--instruction.url <URL>agent.instruction.url
--instruction.oci <REF>agent.instruction.oci
--instruction.mcp <URI>agent.instruction.mcp
--instruction.dir <DIR>agent.instruction.dir
--instruction.glob <GLOBS>agent.instruction.dir.glob
--instruction.order <name|date>agent.instruction.dir.order
--instruction.refresh <auto|off|DUR>agent.instruction.refreshauto
--instruction.unavailable <POLICY>agent.instruction.unavailableauto
--prompt <VALUE>agent.promptAGENTD_PROMPTnone
--prompt.text, .file, .url, .oci, .diragent.prompt.*
--prompt.glob, --prompt.orderagent.prompt.dir.glob, .order
--intelligence <LIST>intelligence.endpointsAGENTD_INTELLIGENCEnone
--intelligence-token <T>intelligence.tokenAGENTD_INTELLIGENCE_TOKENnone
--intelligence-token-file <PATH>intelligence.token_fileAGENTD_INTELLIGENCE_TOKEN_FILEnone
--model <NAME>intelligence.modelAGENTD_MODELnone
--model-swap <POLICY>intelligence.swap_policyAGENTD_MODEL_SWAPfinish-on-old
--budget-tokens-lifetime <N>intelligence.budget.lifetime_tokensAGENTD_BUDGET_TOKENS0 (unbounded)
--mcp name=<endpoint>mcp.servers (adds one)
--mcp-tags name=tag,tagmcp.servers[].tags
--a2a-peer name=<endpoint>a2a.peers (adds one)
--workflow <FILE>workflows (adds one)
--max-steps <N>limits.run.stepsAGENTD_MAX_STEPS500
--max-tokens <N>limits.run.tokensAGENTD_MAX_TOKENS2000000
--deadline <DUR>limits.run.deadlineAGENTD_DEADLINE3600s
--max-depth <N>limits.subagents.depth3
--run-id <ID>lifecycle.run_idAGENTD_RUN_IDa new ULID
--drain-timeout <DUR>lifecycle.drain_timeoutAGENTD_DRAIN_TIMEOUT25s
--watch-configlifecycle.watch_configAGENTD_WATCH_CONFIGfalse
--budget-exit-code <N>lifecycle.exit_code_map (both 3 and 7)none
--listen <TARGET>a2a.listenAGENTD_A2A_LISTENoff
--log-level <LEVEL>observability.log_levelAGENTD_LOG_LEVELinfo
--log-contentobservability.log_contentAGENTD_LOG_CONTENTfalse
--metrics-addr <ADDR>observability.metrics_addrAGENTD_METRICS_ADDRoff
--health-file <PATH>observability.health_fileoff
--events-ring <N>observability.events_ring1024
--traceparent <W3C>observability.traceparentAGENTD_TRACEPARENTderived from the run id
--allow-trifectasecurity.allow_trifectaAGENTD_ALLOW_TRIFECTAfalse
--tls-ca <PATH>security.tls_caAGENTD_TLS_CAbundled roots only
--aauth-provider, --aauth-key-file, --aauth-enroll-token, --aauth-enroll-assertion-file, --aauth-person-serversecurity.aauth.*
--cgroup <auto|PATH>security.cgroup.specoff
--cgroup-memory-max <SIZE>security.cgroup.memory_max
--cgroup-pids-max <N>security.cgroup.pids_max

Notes on a few of them:

  • --model names the turn model: a name declared under intelligence.models, or a literal model string. It is the same setting as intelligence.roles.turn; setting both is refused.
  • A connection that is not the built-in mock: endpoint must name a model. A configuration that leaves it out is refused at load (exit 2).
  • --intelligence takes a comma-separated failover list. An OpenAI-compatible endpoint is written in full, for example https://api.openai.com/v1/chat/completions: a URL with a path is posted to as written.
  • AGENTD_INTELLIGENCE_TOKEN_<N> and AGENTD_INTELLIGENCE_TOKEN_<N>_FILE give endpoint N of the top-level list its own credential (endpoint 1 uses the bare names). They never apply to intelligence.providers.
  • --instruction reads its value as text, a file path, a folder or a URI. An oci:// URI pulls an OCI artifact; any other URI names an MCP resource, including an https:// one. To fetch a document over HTTPS, use --instruction.url. Write and ship instruction documents covers the sources.
  • --budget-exit-code N (0–255) remaps the policy codes 3 and 7 to N, for example 0 so a budget stop is not a pod failure. It touches nothing else.
  • --deadline bounds the whole run, including a model call in flight. A one-shot run takes it as its run deadline.

Every setting as a flag and an environment variable

Every path in the configuration schema is also a flag and an environment variable, derived from the path. agentd --help prints the full table under CONFIG PATHS, and the Configuration reference lists each path with its type and default.

SourceName for the path limits.run.steps
filelimits: { run: { steps: 5 } }
environmentAGENTD_LIMITS_RUN_STEPS
flag--limits.run.steps 5, --limits.run-steps 5 or --limits-run-steps 5

The rules:

  • Values are typed by the schema. Integers, numbers and booleans parse; an enum is checked against its set; a list takes [a, b] or a, b; an object takes a {k: v} or JSON literal. A value that does not type is exit 2 naming its source: invalid AGENTD_LIMITS_RUN_STEPS: expected an integer, got "many".
  • A flag or variable sets its path. For a list or map that means it replaces what the files declared. The repeatable named flags --mcp, --a2a-peer and --workflow add one entry instead.
  • A dotted flag reaches into a free-form map and keeps the key's spelling: --intelligence.headers.x-team ops sets one header.
  • Array elements cannot be addressed: --mcp.servers.0.name is refused. Set the whole list, or use the repeatable flag.
  • An unknown flag is unknown argument: <flag>, exit 2. An AGENTD_ variable that names no path is not read.
  • A boolean flag given alone means true: --a2a.events.enabled.

Precedence

Layers apply key by key, lowest first:

built-in default  <  config files (in order)  <  environment  <  flags

Inside the environment layer, a derived name (AGENTD_INTELLIGENCE_MODEL) wins over a short name (AGENTD_MODEL) for the same path. Flags apply in argument order. ${VAR} and ${VAR:-default} in any string of a file expand from the process environment; an unset variable with no default is exit 2. How configuration works explains the layers, the discovery chain and secret references.

Environment variables

Besides AGENTD_<PATH> and the short names above, agentd reads these variables.

VariableRead for
AGENTD_CONFIGConfiguration files, :-separated, loaded before any --config
AGENTD_INTELLIGENCE_TOKEN_<N>, …_<N>_FILEThe credential for endpoint N of intelligence.endpoints
AGENTD_STATE_DIRThe file store's directory when store.file.path is unset
XDG_STATE_HOMEFallback base: $XDG_STATE_HOME/agentd/state and …/agentd/creds
HOMELast fallback base: $HOME/.local/state/agentd/state and …/creds
AGENTD_CRED_DIRThe OAuth credential cache directory
AGENTD_POD_NAMEThe instance name when agent.name is unset (set it from the downward API)
HOSTNAMEThe instance name when neither agent.name nor AGENTD_POD_NAME is set; the last fallback is agentd
AGENTD_POD_UID, AGENTD_POD_NAMESPACE, AGENTD_NODE_NAMEDescriptive pod identity, never required
OTEL_EXPORTER_OTLP_ENDPOINTThe OTLP collector when observability.otel.endpoint is unset
XDG_RUNTIME_DIRWhere tui/ui put the daemon log by default
AGENTD_TUI_BIN, AGENTD_UI_BINThe display client binary the launcher starts
DOCKER_CONFIGRegistry credentials for oci:// instruction pulls
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILEAWS SigV4 credentials for an endpoint whose auth.source reads them

A {{secret:NAME}} reference in the configuration reads the variable NAME, and {{secret-file:PATH}} reads a file. See Outbound credentials.

Durations

Every duration-typed value, on the command line or in a file, is a number with an optional unit: ms, s, m, h, d or w. A bare number means seconds.

InputMeaning
250ms250 milliseconds
3030 seconds
5m5 minutes
2h2 hours
1d1 day
2w2 weeks

An unknown unit is exit 2: unknown duration unit 'x' in 2x.

Signals

SignalEffect
SIGTERM, SIGINTBegin a graceful drain: stop admitting work, wind down what runs, checkpoint, exit 0. Bounded by lifecycle.drain_timeout.
A second SIGTERM or SIGINTForce the shutdown: the child process groups are killed at once.
SIGHUPReload the configuration files, validate first, apply the reloadable settings. Needs the hot-reload feature; without it SIGHUP keeps its default action and ends the process.

Operate a running daemon covers drain and reload in practice.

Exit codes

The exit code is a stable contract: a scheduler can branch on it without reading a log. A code's meaning never changes; a new outcome gets a new code. The intent column is the retry decision a control plane compiles each code into.

CodeMeaningIntent
0Success. A job finished completed, or a daemon drained cleanly after SIGTERM, SIGINT, admin.drain or a drain policy.complete
1Generic failure. A run failed for a reason with no code of its own, or was cancelled.retriable
2Configuration or usage error. Validation failed, a flag is unknown, a file, url or oci instruction could not be read at load, TLS material is unreadable, a listener could not bind, or the tool registry or workflow set does not build. Retrying reproduces it.terminal
3Partial result. The run stalled, a loop was detected, the result was flagged partial, or the job ended with a run unfinished.policy
4Model unreachable. Every model endpoint failed, or refused its credentials, after retries.retriable
5Refused. The task cannot be done, or was refused.terminal
6A required MCP server is down: something agentd cannot run without failed. The durable store did not open or restore, or the MCP resource the instruction names could not be read at startup. Also the instruction source becoming unreachable under agent.instruction.unavailable: exit.retriable
7A budget was exhausted: the run's steps or tokens, a subagent-tree budget, or the instance's lifetime token budget under lifetime_exhausted: exit.policy
124The run's deadline passed (--deadline, limits.run.deadline). The number echoes timeout(1).policy
137Killed by the OS with SIGKILL (128 + 9), often on out-of-memory.infra
143Killed by the OS with SIGTERM (128 + 15) before a clean drain finished.infra

How to read them:

  • A clean drain is 0, not 143. agentd never exits 137 or 143 itself; the kernel sets them when it kills the process. A rule keyed on 143 to mean "terminated" never fires on a graceful shutdown.
  • Intents. terminal means a retry never helps (FailJob). retriable is usually transient (leave it to backoffLimit). policy is yours to decide. infra is a resource or grace-period fix, never a retry rule.
  • An unrecognised code is retriable. A reader that meets a code it does not know backs off rather than giving up.
  • The remap is narrow. --budget-exit-code and lifecycle.exit_code_map change only 3 and 7. 124 and every other code pass through unchanged. The durable run record keeps the canonical code either way.
  • Only a required MCP server is fatal. A tool server that is down at boot is not: agentd logs mcp.connect.fail, runs without that server's tools, and adds them when the server comes up (mcp.joined). Exit 6 is for the store and the instruction source, which agentd cannot run safely without.
  • A daemon exits 0 on a drain even when individual runs failed; their outcomes are in run.done and in the run records. Only a job's exit code reflects its run.

A one-shot job's code comes from the run the job started. When a job starts several runs, a run that did not succeed decides the code, so a partial success never reads as clean.

Next steps