--- summary: "CLI reference for `openclaw agent` (send one agent turn via the Gateway)" read_when: - You want to run one agent turn from scripts (optionally deliver reply) title: "Agent" --- # `openclaw agent` Run one agent turn through the Gateway. Falls back to the embedded agent if the Gateway request fails; pass `--local` to force embedded execution up front. Pass at least one session selector: `--to`, `--session-key`, `--session-id`, or `--agent`. Related: [Agent send tool](/tools/agent-send) ## Options - `-m, --message `: message body - `--message-file `: read the message body from a UTF-8 file - `-t, --to `: recipient used to derive the session key - `--session-key `: explicit session key to use for routing - `--session-id `: explicit session id - `--agent `: agent id; overrides routing bindings - `--model `: model override for this run (`provider/model` or model id) - `--thinking `: agent thinking level (`off`, `minimal`, `low`, `medium`, `high`, plus provider-supported custom levels such as `xhigh`, `adaptive`, or `max`) - `--verbose `: persist verbose level for the session - `--channel `: delivery channel; omit to use the main session channel - `--reply-to `: delivery target override - `--reply-channel `: delivery channel override - `--reply-account `: delivery account override - `--local`: run the embedded agent directly (after plugin registry preload) - `--deliver`: send the reply back to the selected channel/target - `--timeout `: override agent timeout (default 600, or `agents.defaults.timeoutSeconds`); `0` disables the timeout - `--json`: output JSON ## Examples ```bash openclaw agent --to +15555550123 --message "status update" --deliver openclaw agent --agent ops --message "Summarize logs" openclaw agent --agent ops --message-file ./task.md openclaw agent --agent ops --model openai/gpt-5.4 --message "Summarize logs" openclaw agent --session-key agent:ops:incident-42 --message "Summarize status" openclaw agent --agent ops --session-key incident-42 --message "Summarize status" openclaw agent --session-id 1234 --message "Summarize inbox" --thinking medium openclaw agent --to +15555550123 --message "Trace logs" --verbose on --json openclaw agent --agent ops --message "Generate report" --deliver --reply-channel slack --reply-to "#reports" openclaw agent --agent ops --message "Run locally" --local ``` ## Notes - Pass exactly one of `--message` or `--message-file`. `--message-file` strips a leading UTF-8 BOM and preserves multiline content; it rejects files that are not valid UTF-8. - Slash commands (for example `/compact`) cannot run through `--message`. The CLI rejects them and points you at the first-class command instead (`openclaw sessions compact ` for compaction). - `--local` and embedded fallback runs are one-shot: bundled MCP loopback resources and warm Claude stdio sessions opened for the run are retired after the reply, so scripted invocations do not leave local child processes running. Gateway-backed runs keep Gateway-owned MCP loopback resources under the running Gateway process instead. - `--channel`, `--reply-channel`, and `--reply-account` affect reply delivery, not session routing. - `--session-key` selects an explicit session key. Agent-prefixed keys must use `agent::`, and `--agent` must match the key's agent id when both are given. Bare non-sentinel keys scope to `--agent` when supplied, or to the configured default agent otherwise; for example `--agent ops --session-key incident-42` routes to `agent:ops:incident-42`. The literal keys `global` and `unknown` stay unscoped only when no `--agent` is supplied. - `--json` reserves stdout for the JSON response; Gateway, plugin, and embedded-fallback diagnostics go to stderr so scripts can parse stdout directly. - Embedded fallback JSON includes `meta.transport: "embedded"` and `meta.fallbackFrom: "gateway"` so scripts can detect a fallback run. - If the Gateway accepts a run but the CLI times out waiting for the final reply, embedded fallback uses a fresh `gateway-fallback-*` session/run id and reports `meta.fallbackReason: "gateway_timeout"` plus the fallback session fields, instead of racing the Gateway-owned transcript or silently replacing the original session. - `SIGTERM`/`SIGINT` interrupt a waiting Gateway-backed request; if the Gateway already accepted the run, the CLI also sends `chat.abort` for that run id before exiting. `--local` and embedded fallback runs receive the same signal but do not send `chat.abort`. If the internal run-dedup key already has an active run for this session, the response reports `status: "in_flight"` and the non-JSON CLI prints a stderr diagnostic instead of an empty reply. For external cron/systemd wrappers, keep a hard-kill backstop such as `timeout -k 60 600 openclaw agent ...` so the supervisor can reap the process if shutdown cannot drain. - When this command triggers `models.json` regeneration, SecretRef-managed provider credentials are persisted as non-secret markers (for example env var names, `secretref-env:ENV_VAR_NAME`, or `secretref-managed`), never resolved secret plaintext. Marker writes come from the active source config snapshot, not from resolved runtime secret values. ## JSON delivery status With `--json --deliver`, the CLI JSON response includes top-level `deliveryStatus` so scripts can distinguish delivered, suppressed, partial, and failed sends: ```json { "payloads": [{ "text": "Report ready", "mediaUrl": null }], "meta": { "durationMs": 1200 }, "deliveryStatus": { "requested": true, "attempted": true, "status": "sent", "succeeded": true, "resultCount": 1 } } ``` Gateway-backed CLI responses also preserve the raw Gateway result shape at `result.deliveryStatus`. `deliveryStatus.status` is one of: | Status | Meaning | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `sent` | Delivery completed. | | `suppressed` | Delivery was intentionally not sent (for example a message-sending hook cancelled it, or there was no visible result). Terminal, no retry. | | `partial_failed` | At least one payload sent before a later payload failed. | | `failed` | No durable send completed, or delivery preflight failed. | Common fields: - `requested`: always `true` when the object is present. - `attempted`: `true` once the durable send path ran; `false` for preflight failures or no visible payloads. - `succeeded`: `true`, `false`, or `"partial"`; `"partial"` pairs with `status: "partial_failed"`. - `reason`: lowercase snake-case reason from durable delivery or preflight validation. Known values include `cancelled_by_message_sending_hook`, `no_visible_payload`, `no_visible_result`, `channel_resolved_to_internal`, `unknown_channel`, `invalid_delivery_target`, and `no_delivery_target`; failed durable sends may also report the failed stage. Treat unknown values as opaque since the set can expand. - `resultCount`: number of channel send results, when available. - `sentBeforeError`: `true` when a partial failure sent at least one payload before erroring. - `error`: `true` for failed or partial-failed sends. - `errorMessage`: present only when an underlying delivery error message was captured. Preflight failures carry `error`/`reason` but no `errorMessage`. - `payloadOutcomes`: optional per-payload results with `index`, `status`, `reason`, `resultCount`, `error`, `stage`, `sentBeforeError`, or hook metadata when available. ## Related - [CLI reference](/cli) - [Agent runtime](/concepts/agent)