Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
316
docs/cli/acp.md
Normal file
316
docs/cli/acp.md
Normal file
@@ -0,0 +1,316 @@
|
||||
---
|
||||
summary: "Run the ACP bridge for IDE integrations"
|
||||
read_when:
|
||||
- Setting up ACP-based IDE integrations
|
||||
- Debugging ACP session routing to the Gateway
|
||||
title: "ACP"
|
||||
---
|
||||
|
||||
Run the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) bridge that talks to an OpenClaw Gateway.
|
||||
|
||||
`openclaw acp` speaks ACP over stdio for IDEs and forwards prompts to the Gateway over WebSocket, keeping ACP sessions mapped to Gateway session keys. It is a Gateway-backed ACP bridge, not a full ACP-native editor runtime: it focuses on session routing, prompt delivery, and streaming updates.
|
||||
|
||||
If you want an external MCP client to talk directly to OpenClaw channel conversations instead of hosting an ACP harness session, use [`openclaw mcp serve`](/cli/mcp) instead.
|
||||
|
||||
## What this is not
|
||||
|
||||
`openclaw acp` means OpenClaw acts as an ACP server: an IDE or ACP client connects to OpenClaw, and OpenClaw forwards that work into a Gateway session.
|
||||
|
||||
This is different from [ACP Agents](/tools/acp-agents), where OpenClaw runs an external harness such as Codex or Claude Code through `acpx`.
|
||||
|
||||
Quick rule:
|
||||
|
||||
- editor/client wants to talk ACP to OpenClaw: use `openclaw acp`
|
||||
- OpenClaw should launch Codex/Claude/Gemini as an ACP harness: use `/acp spawn` and [ACP Agents](/tools/acp-agents)
|
||||
|
||||
## Compatibility matrix
|
||||
|
||||
| ACP area | Status | Notes |
|
||||
| --------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `initialize`, `newSession`, `prompt`, `cancel` | Implemented | Core bridge flow over stdio to Gateway chat/send + abort. |
|
||||
| `listSessions`, slash commands | Implemented | Session list works against Gateway session state with bounded cursor pagination and `cwd` filtering where Gateway session rows carry workspace metadata; commands are advertised via `available_commands_update`. |
|
||||
| Session lineage metadata | Implemented | Session listings and session info snapshots include OpenClaw parent and child lineage in `_meta` so ACP clients can render subagent graphs without private Gateway side channels. |
|
||||
| `resumeSession`, `closeSession` | Implemented | Resume rebinds an ACP session to an existing Gateway session without replaying history. Close cancels active bridge work, resolves pending prompts as cancelled, and releases bridge session state. |
|
||||
| `loadSession` | Partial | Rebinds the ACP session to a Gateway session key and replays ACP event-ledger history for bridge-created sessions. Older/no-ledger sessions fall back to stored user/assistant text. |
|
||||
| Prompt content (`text`, embedded `resource`, images) | Partial | Text/resources flatten into chat input; images become Gateway attachments. |
|
||||
| Session modes | Partial | `session/set_mode` is supported; the bridge exposes Gateway-backed session controls for thought level, tool verbosity, reasoning, usage detail, and elevated actions. Broader ACP-native mode/config surfaces are still out of scope. |
|
||||
| Thought streaming | Implemented | Model thinking content streams as `agent_thought_chunk` session updates. ACP-native session plans are not emitted. |
|
||||
| Session info and usage updates | Partial | The bridge emits `session_info_update` and best-effort `usage_update` notifications from cached Gateway session snapshots. Usage is approximate and only sent when Gateway token totals are marked fresh. |
|
||||
| Tool streaming | Partial | `tool_call`/`tool_call_update` events include raw I/O, text content, and best-effort file locations when Gateway tool args/results expose them. Embedded terminals and richer diff-native output are not exposed. |
|
||||
| Exec approvals | Partial | Gateway exec approval prompts during active ACP prompt turns relay to the ACP client with `session/request_permission`. |
|
||||
| Per-session MCP servers (`mcpServers`) | Unsupported | Bridge mode rejects per-session MCP server requests. Configure MCP on the OpenClaw Gateway or agent instead. |
|
||||
| Client filesystem methods (`fs/read_text_file`, `fs/write_text_file`) | Unsupported | The bridge does not call ACP client filesystem methods. |
|
||||
| Client terminal methods (`terminal/*`) | Unsupported | The bridge does not create ACP client terminals or stream terminal ids through tool calls. |
|
||||
|
||||
## Known limitations
|
||||
|
||||
- `loadSession` replays complete ACP event-ledger history only for bridge-created sessions. Older/no-ledger sessions use transcript fallback and do not reconstruct historic tool calls or system notices.
|
||||
- If multiple ACP clients share the same Gateway session key, event and cancel routing are best-effort rather than strictly isolated per client. Prefer the default isolated `acp-bridge:<uuid>` sessions when you need clean editor-local turns.
|
||||
- Gateway stop states translate into ACP stop reasons, but that mapping is less expressive than a fully ACP-native runtime.
|
||||
- Session controls surface a focused subset of Gateway knobs: thought level, tool verbosity, reasoning, usage detail, and elevated actions. Model selection and exec-host controls are not exposed as ACP config options.
|
||||
- `session_info_update` and `usage_update` derive from Gateway session snapshots, not live ACP-native runtime accounting. Usage is approximate, carries no cost data, and is only emitted when the Gateway marks total token data as fresh.
|
||||
- Tool follow-along data is best-effort: the bridge surfaces file paths that appear in known tool args/results, but does not emit ACP terminals or structured file diffs.
|
||||
- Exec approval relay is scoped to the active ACP prompt turn; approvals from other Gateway sessions are ignored.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw acp
|
||||
|
||||
# Remote Gateway
|
||||
openclaw acp --url wss://gateway-host:18789 --token <token>
|
||||
|
||||
# Remote Gateway (token from file)
|
||||
openclaw acp --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token
|
||||
|
||||
# Attach to an existing session key
|
||||
openclaw acp --session agent:main:main
|
||||
|
||||
# Attach by label (must already exist)
|
||||
openclaw acp --session-label "support inbox"
|
||||
|
||||
# Reset the session key before the first prompt
|
||||
openclaw acp --session agent:main:main --reset-session
|
||||
```
|
||||
|
||||
## ACP client (debug)
|
||||
|
||||
Use the built-in ACP client to sanity-check the bridge without an IDE. It spawns the ACP bridge and lets you type prompts interactively.
|
||||
|
||||
```bash
|
||||
openclaw acp client
|
||||
|
||||
# Point the spawned bridge at a remote Gateway
|
||||
openclaw acp client --server-args --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token
|
||||
|
||||
# Override the server command (default: openclaw)
|
||||
openclaw acp client --server "node" --server-args openclaw.mjs acp --url ws://127.0.0.1:19001
|
||||
```
|
||||
|
||||
Permission model (client debug mode):
|
||||
|
||||
- Auto-approval is allowlist-based and applies only to trusted core tool IDs.
|
||||
- `read` auto-approval is scoped to the current working directory (`--cwd` when set).
|
||||
- ACP only auto-approves narrow readonly classes: scoped `read` calls under the active cwd, plus readonly search tools (`search`, `web_search`, `memory_search`). Unknown/non-core tools, out-of-scope reads, exec-capable tools, control-plane tools, mutating tools, and interactive flows always require explicit prompt approval.
|
||||
- Server-provided `toolCall.kind` is treated as untrusted metadata, not an authorization source.
|
||||
- This ACP bridge policy is separate from ACPX harness permissions. If you run OpenClaw through the `acpx` backend, `plugins.entries.acpx.config.permissionMode=approve-all` is the break-glass "yolo" switch for that harness session.
|
||||
|
||||
## Protocol smoke testing
|
||||
|
||||
For protocol-level debugging, start a Gateway with isolated state and drive `openclaw acp` over stdio with an ACP JSON-RPC client. Cover `initialize`, `session/new`, `session/list` with an absolute `cwd`, `session/resume`, `session/close`, duplicate close, and missing resume.
|
||||
|
||||
The proof should include the advertised lifecycle capabilities, a Gateway-backed session row, update notifications, and the Gateway `sessions.list` log:
|
||||
|
||||
```json
|
||||
{
|
||||
"initialize": {
|
||||
"protocolVersion": 1,
|
||||
"agentCapabilities": {
|
||||
"sessionCapabilities": {
|
||||
"list": {},
|
||||
"resume": {},
|
||||
"close": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"listSessions": {
|
||||
"sessions": [
|
||||
{
|
||||
"sessionId": "agent:main:acp-smoke",
|
||||
"cwd": "/path/to/workspace",
|
||||
"_meta": {
|
||||
"sessionKey": "agent:main:acp-smoke",
|
||||
"kind": "direct"
|
||||
}
|
||||
}
|
||||
],
|
||||
"nextCursor": null
|
||||
},
|
||||
"notifications": ["session_info_update", "available_commands_update", "usage_update"],
|
||||
"gatewayLogTail": ["[gateway] ready", "[ws] ⇄ res ✓ sessions.list 305ms"]
|
||||
}
|
||||
```
|
||||
|
||||
Avoid using `openclaw gateway call sessions.list` as the only ACP proof. That CLI path may request a fresh-token operator scope upgrade; ACP bridge correctness is proven by ACP stdio frames plus the Gateway `sessions.list` log.
|
||||
|
||||
## How to use this
|
||||
|
||||
Use ACP when an IDE (or other client) speaks Agent Client Protocol and you want it to drive an OpenClaw Gateway session.
|
||||
|
||||
1. Ensure the Gateway is running (local or remote).
|
||||
2. Configure the Gateway target (config or flags).
|
||||
3. Point your IDE to run `openclaw acp` over stdio.
|
||||
|
||||
Example config (persisted):
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.remote.url wss://gateway-host:18789
|
||||
openclaw config set gateway.remote.token <token>
|
||||
```
|
||||
|
||||
Example direct run (no config write):
|
||||
|
||||
```bash
|
||||
openclaw acp --url wss://gateway-host:18789 --token <token>
|
||||
# preferred for local process safety
|
||||
openclaw acp --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token
|
||||
```
|
||||
|
||||
## Selecting agents
|
||||
|
||||
ACP does not pick agents directly. It routes by the Gateway session key. Use agent-scoped session keys to target a specific agent:
|
||||
|
||||
```bash
|
||||
openclaw acp --session agent:main:main
|
||||
openclaw acp --session agent:design:main
|
||||
openclaw acp --session agent:qa:bug-123
|
||||
```
|
||||
|
||||
Each ACP session maps to a single Gateway session key. One agent can have many sessions; ACP defaults to an isolated `acp-bridge:<uuid>` session unless you override the key or label.
|
||||
|
||||
Per-session `mcpServers` are not supported in bridge mode. If an ACP client sends them during `newSession` or `loadSession`, the bridge returns a clear error instead of silently ignoring them.
|
||||
|
||||
If you want ACPX-backed sessions to see OpenClaw plugin tools or selected built-in tools such as `cron`, enable the gateway-side ACPX MCP bridges instead of trying to pass per-session `mcpServers`. See [ACP Agents](/tools/acp-agents-setup#plugin-tools-mcp-bridge) and [OpenClaw tools MCP bridge](/tools/acp-agents-setup#openclaw-tools-mcp-bridge).
|
||||
|
||||
## Use from `acpx` (Codex, Claude, other ACP clients)
|
||||
|
||||
If you want a coding agent such as Codex or Claude Code to talk to your OpenClaw bot over ACP, use `acpx` with its built-in `openclaw` target.
|
||||
|
||||
Typical flow:
|
||||
|
||||
1. Run the Gateway and make sure the ACP bridge can reach it.
|
||||
2. Point `acpx openclaw` at `openclaw acp`.
|
||||
3. Target the OpenClaw session key you want the coding agent to use.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# One-shot request into your default OpenClaw ACP session
|
||||
acpx openclaw exec "Summarize the active OpenClaw session state."
|
||||
|
||||
# Persistent named session for follow-up turns
|
||||
acpx openclaw sessions ensure --name codex-bridge
|
||||
acpx openclaw -s codex-bridge --cwd /path/to/repo \
|
||||
"Ask my OpenClaw work agent for recent context relevant to this repo."
|
||||
```
|
||||
|
||||
If you want `acpx openclaw` to target a specific Gateway and session key every time, override the `openclaw` agent command in `~/.acpx/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"openclaw": {
|
||||
"command": "env OPENCLAW_HIDE_BANNER=1 OPENCLAW_SUPPRESS_NOTES=1 openclaw acp --url ws://127.0.0.1:18789 --token-file ~/.openclaw/gateway.token --session agent:main:main"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For a repo-local OpenClaw checkout, use the direct CLI entrypoint instead of the dev runner so the ACP stream stays clean:
|
||||
|
||||
```bash
|
||||
env OPENCLAW_HIDE_BANNER=1 OPENCLAW_SUPPRESS_NOTES=1 node openclaw.mjs acp ...
|
||||
```
|
||||
|
||||
This is the easiest way to let Codex, Claude Code, or another ACP-aware client pull contextual information from an OpenClaw agent without scraping a terminal.
|
||||
|
||||
## Zed editor setup
|
||||
|
||||
Add a custom ACP agent in `~/.config/zed/settings.json` (or use Zed's Settings UI):
|
||||
|
||||
```json
|
||||
{
|
||||
"agent_servers": {
|
||||
"OpenClaw ACP": {
|
||||
"type": "custom",
|
||||
"command": "openclaw",
|
||||
"args": ["acp"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To target a specific Gateway or agent:
|
||||
|
||||
```json
|
||||
{
|
||||
"agent_servers": {
|
||||
"OpenClaw ACP": {
|
||||
"type": "custom",
|
||||
"command": "openclaw",
|
||||
"args": [
|
||||
"acp",
|
||||
"--url",
|
||||
"wss://gateway-host:18789",
|
||||
"--token",
|
||||
"<token>",
|
||||
"--session",
|
||||
"agent:design:main"
|
||||
],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In Zed, open the Agent panel and select "OpenClaw ACP" to start a thread.
|
||||
|
||||
## Session mapping
|
||||
|
||||
By default, ACP bridge sessions get an isolated Gateway session key with an `acp-bridge:` prefix. These normal-model bridge sessions are synthetic and disposable: they are subject to stale-entry pruning and are not treated as protected human conversation surfaces. To reuse a known session, pass a session key or label:
|
||||
|
||||
- `--session <key>`: use a specific Gateway session key.
|
||||
- `--session-label <label>`: resolve an existing session by label.
|
||||
- `--reset-session`: mint a fresh session id for that key (same key, new transcript).
|
||||
|
||||
If your ACP client supports metadata, you can override per session:
|
||||
|
||||
```json
|
||||
{
|
||||
"_meta": {
|
||||
"sessionKey": "agent:main:main",
|
||||
"sessionLabel": "support inbox",
|
||||
"resetSession": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about session keys at [/concepts/session](/concepts/session).
|
||||
|
||||
## Options
|
||||
|
||||
- `--url <url>`: Gateway WebSocket URL (defaults to `gateway.remote.url` when configured).
|
||||
- `--token <token>`: Gateway auth token.
|
||||
- `--token-file <path>`: read Gateway auth token from file.
|
||||
- `--password <password>`: Gateway auth password.
|
||||
- `--password-file <path>`: read Gateway auth password from file.
|
||||
- `--session <key>`: default session key.
|
||||
- `--session-label <label>`: default session label to resolve.
|
||||
- `--require-existing`: fail if the session key/label does not exist.
|
||||
- `--reset-session`: reset the session key before first use.
|
||||
- `--no-prefix-cwd`: do not prefix prompts with the working directory.
|
||||
- `--provenance <off|meta|meta+receipt>`: include ACP provenance metadata or receipts.
|
||||
- `--verbose, -v`: verbose logging to stderr.
|
||||
|
||||
Security note:
|
||||
|
||||
- `--token` and `--password` can be visible in local process listings on some systems. Prefer `--token-file`/`--password-file` or environment variables (`OPENCLAW_GATEWAY_TOKEN`, `OPENCLAW_GATEWAY_PASSWORD`).
|
||||
- Gateway auth resolution follows the shared contract used by other Gateway clients:
|
||||
- local mode: env (`OPENCLAW_GATEWAY_*`) then `gateway.auth.*`, falling back to `gateway.remote.*` only when `gateway.auth.*` is unset (a configured-but-unresolved local SecretRef fails closed instead of silently falling back)
|
||||
- remote mode: `gateway.remote.*` with env/config fallback per remote precedence rules
|
||||
- `--url` is override-safe and does not reuse implicit config/env credentials; pass explicit `--token`/`--password` (or file variants)
|
||||
|
||||
### `acp client` options
|
||||
|
||||
- `--cwd <dir>`: working directory for the ACP session.
|
||||
- `--server <command>`: ACP server command (default: `openclaw`).
|
||||
- `--server-args <args...>`: extra arguments passed to the ACP server.
|
||||
- `--server-verbose`: enable verbose logging on the ACP server.
|
||||
- `--verbose, -v`: verbose client logging.
|
||||
- `openclaw acp client` sets `OPENCLAW_SHELL=acp-client` on the spawned bridge process, which can be used for context-specific shell/profile rules.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [ACP agents](/tools/acp-agents)
|
||||
108
docs/cli/agent.md
Normal file
108
docs/cli/agent.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
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 <text>`: message body
|
||||
- `--message-file <path>`: read the message body from a UTF-8 file
|
||||
- `-t, --to <dest>`: recipient used to derive the session key
|
||||
- `--session-key <key>`: explicit session key to use for routing
|
||||
- `--session-id <id>`: explicit session id
|
||||
- `--agent <id>`: agent id; overrides routing bindings
|
||||
- `--model <id>`: model override for this run (`provider/model` or model id)
|
||||
- `--thinking <level>`: agent thinking level (`off`, `minimal`, `low`, `medium`, `high`, plus provider-supported custom levels such as `xhigh`, `adaptive`, or `max`)
|
||||
- `--verbose <on|off>`: persist verbose level for the session
|
||||
- `--channel <channel>`: delivery channel; omit to use the main session channel
|
||||
- `--reply-to <target>`: delivery target override
|
||||
- `--reply-channel <channel>`: delivery channel override
|
||||
- `--reply-account <id>`: delivery account override
|
||||
- `--local`: run the embedded agent directly (after plugin registry preload)
|
||||
- `--deliver`: send the reply back to the selected channel/target
|
||||
- `--timeout <seconds>`: 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 <key>` 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:<agent-id>:<session-key>`, 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)
|
||||
197
docs/cli/agents.md
Normal file
197
docs/cli/agents.md
Normal file
@@ -0,0 +1,197 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw agents` (list/add/delete/bindings/bind/unbind/set identity)"
|
||||
read_when:
|
||||
- You want multiple isolated agents (workspaces + routing + auth)
|
||||
title: "Agents"
|
||||
---
|
||||
|
||||
# `openclaw agents`
|
||||
|
||||
Manage isolated agents (workspaces + auth + routing). Running `openclaw agents` with no subcommand is equivalent to `openclaw agents list`.
|
||||
|
||||
Related:
|
||||
|
||||
- [Multi-agent routing](/concepts/multi-agent)
|
||||
- [Agent workspace](/concepts/agent-workspace)
|
||||
- [Skills config](/tools/skills-config): skill visibility configuration.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw agents list
|
||||
openclaw agents list --bindings
|
||||
openclaw agents add work --workspace ~/.openclaw/workspace-work
|
||||
openclaw agents add work --workspace ~/.openclaw/workspace-work --bind telegram:*
|
||||
openclaw agents add ops --workspace ~/.openclaw/workspace-ops --bind telegram:ops --non-interactive
|
||||
openclaw agents bindings
|
||||
openclaw agents bind --agent work --bind telegram:ops
|
||||
openclaw agents unbind --agent work --bind telegram:ops
|
||||
openclaw agents set-identity --workspace ~/.openclaw/workspace --from-identity
|
||||
openclaw agents set-identity --agent main --avatar avatars/openclaw.png
|
||||
openclaw agents delete work
|
||||
```
|
||||
|
||||
## Command surface
|
||||
|
||||
### `agents list`
|
||||
|
||||
Options: `--json`, `--bindings` (include full routing rules, not only per-agent counts/summaries).
|
||||
|
||||
### `agents add [name]`
|
||||
|
||||
Options: `--workspace <dir>`, `--model <id>`, `--agent-dir <dir>`, `--bind <channel[:accountId]>` (repeatable), `--non-interactive`, `--json`.
|
||||
|
||||
- Passing any explicit add flag switches the command into the non-interactive path.
|
||||
- Non-interactive mode requires both an agent name and `--workspace`.
|
||||
- `main` is reserved and cannot be used as the new agent id.
|
||||
- Interactive mode seeds auth by copying only portable static credentials (`api_key` and static `token` profiles) unless a credential opts out with `copyToAgents: false`; OAuth refresh-token profiles are not copied unless a provider opts in with `copyToAgents: true`. Without a copy, OAuth stays available only through read-through inheritance from the real `main` agent store. If the configured default agent is not `main`, sign in separately for OAuth profiles on the new agent.
|
||||
|
||||
### `agents bindings`
|
||||
|
||||
Options: `--agent <id>`, `--json`.
|
||||
|
||||
### `agents bind`
|
||||
|
||||
Options: `--agent <id>` (defaults to the current default agent), `--bind <channel[:accountId]>` (repeatable), `--json`.
|
||||
|
||||
### `agents unbind`
|
||||
|
||||
Options: `--agent <id>` (defaults to the current default agent), `--bind <channel[:accountId]>` (repeatable), `--all`, `--json`. Accepts either `--all` or one or more `--bind` values, not both.
|
||||
|
||||
### `agents set-identity`
|
||||
|
||||
Options: `--agent <id>`, `--workspace <dir>`, `--identity-file <path>`, `--from-identity`, `--name <name>`, `--theme <theme>`, `--emoji <emoji>`, `--avatar <value>`, `--json`. See [Set identity](#set-identity) below.
|
||||
|
||||
### `agents delete <id>`
|
||||
|
||||
Options: `--force`, `--json`.
|
||||
|
||||
- `main` cannot be deleted.
|
||||
- Without `--force`, interactive confirmation is required (fails in a non-TTY session; re-run with `--force`).
|
||||
- Workspace, agent state, and session transcript directories move to Trash, not hard-deleted.
|
||||
- When the Gateway is reachable, deletion routes through the Gateway so config and session-store cleanup share the same writer as runtime traffic. If the Gateway is unreachable, the CLI falls back to the offline local path.
|
||||
- If another agent's workspace is the same path, inside this workspace, or contains this workspace, the workspace is retained, and `--json` reports `workspaceRetained`, `workspaceRetainedReason`, and `workspaceSharedWith`.
|
||||
|
||||
## Routing bindings
|
||||
|
||||
Use routing bindings to pin inbound channel traffic to a specific agent.
|
||||
|
||||
If you also want different visible skills per agent, configure `agents.defaults.skills` and `agents.list[].skills` in `openclaw.json`. See [Skills config](/tools/skills-config) and [Configuration reference](/gateway/config-agents#agentsdefaultsskills).
|
||||
|
||||
List bindings:
|
||||
|
||||
```bash
|
||||
openclaw agents bindings
|
||||
openclaw agents bindings --agent work
|
||||
openclaw agents bindings --json
|
||||
```
|
||||
|
||||
Add bindings:
|
||||
|
||||
```bash
|
||||
openclaw agents bind --agent work --bind telegram:ops --bind discord:guild-a
|
||||
```
|
||||
|
||||
You can also add bindings when creating an agent:
|
||||
|
||||
```bash
|
||||
openclaw agents add work --workspace ~/.openclaw/workspace-work --bind telegram:* --bind discord:*
|
||||
```
|
||||
|
||||
If you omit `accountId` (`--bind <channel>`), OpenClaw resolves it from plugin setup hooks, forced account binding, or the channel's configured account count.
|
||||
|
||||
If you omit `--agent` for `bind` or `unbind`, OpenClaw targets the current default agent.
|
||||
|
||||
### `--bind` format
|
||||
|
||||
| Format | Meaning |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `--bind <channel>:*` | Match all accounts on the channel. |
|
||||
| `--bind <channel>:<account>` | Match one account. |
|
||||
| `--bind <channel>` | Match the default account only, unless the CLI can safely resolve a plugin-specific account scope. |
|
||||
|
||||
### Binding scope behavior
|
||||
|
||||
- A stored binding without `accountId` matches the channel default account only.
|
||||
- `accountId: "*"` is the channel-wide fallback (all accounts) and is less specific than an explicit account binding.
|
||||
- If the same agent already has a matching channel binding without `accountId`, and you later bind with an explicit or resolved `accountId`, OpenClaw upgrades that existing binding in place instead of adding a duplicate.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# match all accounts on the channel
|
||||
openclaw agents bind --agent work --bind telegram:*
|
||||
|
||||
# match a specific account
|
||||
openclaw agents bind --agent work --bind telegram:ops
|
||||
|
||||
# initial channel-only binding
|
||||
openclaw agents bind --agent work --bind telegram
|
||||
|
||||
# later upgrade to account-scoped binding
|
||||
openclaw agents bind --agent work --bind telegram:alerts
|
||||
```
|
||||
|
||||
After the upgrade, routing for that binding is scoped to `telegram:alerts`. If you also want default-account routing, add it explicitly (for example `--bind telegram:default`).
|
||||
|
||||
Remove bindings:
|
||||
|
||||
```bash
|
||||
openclaw agents unbind --agent work --bind telegram:ops
|
||||
openclaw agents unbind --agent work --all
|
||||
```
|
||||
|
||||
## Identity files
|
||||
|
||||
Each agent workspace can include an `IDENTITY.md` at the workspace root:
|
||||
|
||||
- Example path: `~/.openclaw/workspace/IDENTITY.md`
|
||||
- `set-identity --from-identity` reads from the workspace root (or an explicit `--identity-file`).
|
||||
|
||||
Avatar paths resolve relative to the workspace root and cannot escape it, even through a symlink.
|
||||
|
||||
## Set identity
|
||||
|
||||
`set-identity` writes fields into `agents.list[].identity`: `name`, `theme`, `emoji`, `avatar` (workspace-relative path, http(s) URL, or data URI).
|
||||
|
||||
- `--agent` or `--workspace` selects the target agent. If `--workspace` matches more than one agent, the command fails and asks you to pass `--agent`.
|
||||
- Local workspace-relative avatar image files are limited to 2 MB. HTTP(S) URLs and `data:` URIs are not checked against the local file-size limit.
|
||||
- When no explicit identity fields are provided, the command reads identity data from `IDENTITY.md`.
|
||||
|
||||
Load from `IDENTITY.md`:
|
||||
|
||||
```bash
|
||||
openclaw agents set-identity --workspace ~/.openclaw/workspace --from-identity
|
||||
```
|
||||
|
||||
Override fields explicitly:
|
||||
|
||||
```bash
|
||||
openclaw agents set-identity --agent main --name "OpenClaw" --emoji "🦞" --avatar avatars/openclaw.png
|
||||
```
|
||||
|
||||
Config sample:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "main",
|
||||
identity: {
|
||||
name: "OpenClaw",
|
||||
theme: "space lobster",
|
||||
emoji: "🦞",
|
||||
avatar: "avatars/openclaw.png",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Multi-agent routing](/concepts/multi-agent)
|
||||
- [Agent workspace](/concepts/agent-workspace)
|
||||
138
docs/cli/approvals.md
Normal file
138
docs/cli/approvals.md
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw approvals` and `openclaw exec-policy`"
|
||||
read_when:
|
||||
- You want to edit exec approvals from the CLI
|
||||
- You need to manage allowlists on gateway or node hosts
|
||||
title: "Approvals"
|
||||
---
|
||||
|
||||
# `openclaw approvals`
|
||||
|
||||
Manage exec approvals for the **local host**, **gateway host**, or a **node host**. With no target flag, commands read/write the local approvals file on disk. Use `--gateway` to target the gateway, or `--node <id|name|ip>` to target a specific node.
|
||||
|
||||
Alias: `openclaw exec-approvals`
|
||||
|
||||
Related: [Exec approvals](/tools/exec-approvals), [Nodes](/nodes)
|
||||
|
||||
## `openclaw exec-policy`
|
||||
|
||||
`openclaw exec-policy` is the **local-only** convenience command that keeps requested `tools.exec.*` config and the local host approvals file in sync in one step:
|
||||
|
||||
```bash
|
||||
openclaw exec-policy show
|
||||
openclaw exec-policy show --json
|
||||
|
||||
openclaw exec-policy preset yolo
|
||||
openclaw exec-policy preset cautious --json
|
||||
|
||||
openclaw exec-policy set --host gateway --security full --ask off --ask-fallback full
|
||||
```
|
||||
|
||||
Presets (`yolo`, `cautious`, `deny-all`) apply `host`, `security`, `ask`, and `askFallback` together. `set` applies only the flags you pass; each accepted value is validated (`--host auto|sandbox|gateway|node`, `--security deny|allowlist|full`, `--ask off|on-miss|always`, `--ask-fallback deny|allowlist|full`).
|
||||
|
||||
Scope:
|
||||
|
||||
- Updates the local config file and local approvals file together; does not push policy to the gateway or a node host.
|
||||
- `--host node` is rejected: node exec approvals are fetched from the node at runtime, so local `exec-policy` cannot synchronize them. Use `openclaw approvals set --node <id|name|ip>` instead.
|
||||
- `exec-policy show` marks `host=node` scopes as node-managed at runtime instead of deriving an effective policy from the local approvals file.
|
||||
|
||||
For remote host approvals, use `openclaw approvals set --gateway` or `openclaw approvals set --node <id|name|ip>` directly.
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
openclaw approvals get
|
||||
openclaw approvals get --node <id|name|ip>
|
||||
openclaw approvals get --gateway
|
||||
```
|
||||
|
||||
`get` shows the effective exec policy for the target: the requested `tools.exec` policy, the host approvals-file policy, and the merged effective result.
|
||||
|
||||
Precedence:
|
||||
|
||||
- The host approvals file is the enforceable source of truth.
|
||||
- Requested `tools.exec` policy can narrow or broaden intent, but the effective result is derived from host rules.
|
||||
- `--node` combines the node host approvals file with gateway `tools.exec` policy (both apply at runtime).
|
||||
- If gateway config is unavailable, the CLI falls back to the node approvals snapshot and notes that the final runtime policy could not be computed.
|
||||
|
||||
## Replace approvals from a file
|
||||
|
||||
```bash
|
||||
openclaw approvals set --file ./exec-approvals.json
|
||||
openclaw approvals set --stdin <<'EOF'
|
||||
{ version: 1, defaults: { security: "full", ask: "off", askFallback: "full" } }
|
||||
EOF
|
||||
openclaw approvals set --node <id|name|ip> --file ./exec-approvals.json
|
||||
openclaw approvals set --gateway --file ./exec-approvals.json
|
||||
```
|
||||
|
||||
`set` accepts JSON5, not only strict JSON. Use either `--file` or `--stdin`, not both.
|
||||
|
||||
## "Never prompt" / YOLO example
|
||||
|
||||
Set the host approvals defaults to `full` + `off` for a host that should never stop on exec approvals:
|
||||
|
||||
```bash
|
||||
openclaw approvals set --stdin <<'EOF'
|
||||
{
|
||||
version: 1,
|
||||
defaults: {
|
||||
security: "full",
|
||||
ask: "off",
|
||||
askFallback: "full"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
Node variant: same body with `openclaw approvals set --node <id|name|ip> --stdin`.
|
||||
|
||||
This changes the **host approvals file** only. To keep the requested OpenClaw policy aligned, also set:
|
||||
|
||||
```bash
|
||||
openclaw config set tools.exec.host gateway
|
||||
openclaw config set tools.exec.security full
|
||||
openclaw config set tools.exec.ask off
|
||||
```
|
||||
|
||||
`tools.exec.host=gateway` is explicit here because `host=auto` still means "sandbox when available, otherwise gateway": YOLO is about approvals, not routing. Use `gateway` (or `/exec host=gateway`) when you want host exec even with a sandbox configured.
|
||||
|
||||
Omitted `askFallback` defaults to `deny`. Set `askFallback: "full"` explicitly when upgrading a no-UI host that should keep never-prompt behavior.
|
||||
|
||||
Local shortcut for the same intent, on the local machine only:
|
||||
|
||||
```bash
|
||||
openclaw exec-policy preset yolo
|
||||
```
|
||||
|
||||
## Allowlist helpers
|
||||
|
||||
```bash
|
||||
openclaw approvals allowlist add "~/Projects/**/bin/rg"
|
||||
openclaw approvals allowlist add --agent main --node <id|name|ip> "/usr/bin/uptime"
|
||||
openclaw approvals allowlist add --agent "*" "/usr/bin/uname"
|
||||
|
||||
openclaw approvals allowlist remove "~/Projects/**/bin/rg"
|
||||
```
|
||||
|
||||
## Common options
|
||||
|
||||
`get`, `set`, and `allowlist add|remove` all support:
|
||||
|
||||
- `--node <id|name|ip>` (resolves id, name, IP, or id prefix; same resolver as `openclaw nodes`)
|
||||
- `--gateway`
|
||||
- shared node RPC options: `--url`, `--token`, `--timeout`, `--json`
|
||||
|
||||
No target flag means the local approvals file on disk.
|
||||
|
||||
`allowlist add|remove` also supports `--agent <id>` (defaults to `"*"`, applying to all agents).
|
||||
|
||||
## Notes
|
||||
|
||||
- The node host must advertise `system.execApprovals.get/set` (macOS app or headless node host).
|
||||
- Approvals files are stored per host in the OpenClaw state dir: `$OPENCLAW_STATE_DIR/exec-approvals.json`, or `~/.openclaw/exec-approvals.json` when the variable is unset.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Exec approvals](/tools/exec-approvals)
|
||||
26
docs/cli/attach.md
Normal file
26
docs/cli/attach.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw attach` (launch Claude Code with a scoped Gateway MCP grant)"
|
||||
read_when:
|
||||
- You want Claude Code to use OpenClaw Gateway MCP tools
|
||||
- You need a temporary session-bound MCP grant for an external harness
|
||||
title: "Attach CLI"
|
||||
---
|
||||
|
||||
`openclaw attach` launches Claude Code with a strict temporary MCP config bound to one Gateway session.
|
||||
|
||||
```sh
|
||||
openclaw attach
|
||||
openclaw attach --session agent:main:telegram:123 --ttl 600000
|
||||
openclaw attach --print-config
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--session <key>` binds the grant to a Gateway session. Defaults to the main session.
|
||||
- `--ttl <ms>` requests a positive grant TTL in milliseconds. The Gateway applies its own ceiling.
|
||||
- `--bin <path>` selects the Claude Code binary. Default: `claude`.
|
||||
- `--print-config` writes the temporary `.mcp.json`, prints the launch command and env, and leaves the grant live until TTL expiry (it does not spawn Claude Code or revoke the grant).
|
||||
|
||||
The bearer token is passed through environment variables, not argv. OpenClaw launches Claude Code with `--strict-mcp-config --mcp-config <path>` so ambient Claude MCP servers do not join the attached session. Normal launches (without `--print-config`) revoke the grant when the Claude Code process exits.
|
||||
|
||||
See also: [Gateway CLI](/cli/gateway), [MCP CLI](/cli/mcp), and [ACP CLI](/cli/acp).
|
||||
71
docs/cli/backup.md
Normal file
71
docs/cli/backup.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw backup` (create local backup archives)"
|
||||
read_when:
|
||||
- You want a first-class backup archive for local OpenClaw state
|
||||
- You want to preview which paths would be included before reset or uninstall
|
||||
title: "Backup"
|
||||
---
|
||||
|
||||
# `openclaw backup`
|
||||
|
||||
Create a local backup archive for OpenClaw state, config, auth profiles, channel/provider credentials, sessions, and optionally workspaces.
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
openclaw backup create --output ~/Backups
|
||||
openclaw backup create --dry-run --json
|
||||
openclaw backup create --verify
|
||||
openclaw backup create --no-include-workspace
|
||||
openclaw backup create --only-config
|
||||
openclaw backup verify ./2026-03-09T08-00-00.000+08-00-openclaw-backup.tar.gz
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The archive embeds a `manifest.json` with the resolved source paths and archive layout.
|
||||
- Default output is a timestamped `.tar.gz` archive in the current working directory. Timestamped filenames use your machine's local timezone and include the UTC offset. If the current working directory is inside a backed-up source tree, OpenClaw falls back to your home directory for the default archive location.
|
||||
- Existing archive files are never overwritten. Output paths inside the source state/workspace trees are rejected to avoid self-inclusion.
|
||||
- `openclaw backup verify <archive>` checks that the archive contains exactly one root manifest, rejects traversal-style archive paths, and confirms every manifest-declared payload exists in the tarball. `openclaw backup create --verify` runs that validation immediately after writing the archive.
|
||||
- `openclaw backup create --only-config` backs up just the active JSON config file.
|
||||
|
||||
## What gets backed up
|
||||
|
||||
`openclaw backup create` plans sources from your local OpenClaw install:
|
||||
|
||||
- The state directory (usually `~/.openclaw`)
|
||||
- The active config file path
|
||||
- The resolved `credentials/` directory when it exists outside the state directory
|
||||
- Workspace directories discovered from the current config, unless you pass `--no-include-workspace`
|
||||
|
||||
Auth profiles and other per-agent runtime state live in SQLite under the state directory (`agents/<agentId>/agent/openclaw-agent.sqlite`), so they are covered by the state backup entry automatically.
|
||||
|
||||
`--only-config` skips state, credentials-directory, and workspace discovery and archives only the active config file path.
|
||||
|
||||
OpenClaw canonicalizes paths before building the archive: if config, the credentials directory, or a workspace already live inside the state directory, they are not duplicated as separate top-level backup sources. Missing paths are skipped.
|
||||
|
||||
During archive creation, OpenClaw skips known live-mutation files with no restoration value: active agent session transcripts, cron run logs, rolling logs, delivery queues, socket/pid/temp files under the state directory, and related durable-queue temp files. The JSON result's `skippedVolatileCount` reports how many files were intentionally omitted. SQLite databases under the state directory are snapshotted safely (`VACUUM INTO`) rather than copied live, so open WAL/SHM files do not corrupt the backup.
|
||||
|
||||
Installed plugin source and manifest files under the state directory's `extensions/` tree are included, but their nested `node_modules/` dependency trees are skipped as rebuildable install artifacts. After restoring an archive, use `openclaw plugins update <id>` or reinstall with `openclaw plugins install <spec> --force` if a restored plugin reports missing dependencies.
|
||||
|
||||
## Invalid config behavior
|
||||
|
||||
`openclaw backup` bypasses the normal config preflight so it can still help during recovery. Workspace discovery depends on a valid config, so `openclaw backup create` fails fast when the config file exists but is invalid and workspace backup is still enabled.
|
||||
|
||||
For a partial backup in that situation, rerun with `--no-include-workspace`: it keeps state, config, and the external credentials directory in scope while skipping workspace discovery entirely.
|
||||
|
||||
`--only-config` also works when the config is malformed, since it does not parse the config for workspace discovery.
|
||||
|
||||
## Size and performance
|
||||
|
||||
OpenClaw does not enforce a built-in maximum backup size or per-file size limit. Practical limits come from:
|
||||
|
||||
- Available space for the temporary archive write plus the final archive
|
||||
- Time to walk large workspace trees and compress them into a `.tar.gz`
|
||||
- Time to rescan the archive with `--verify` or `openclaw backup verify`
|
||||
- Destination filesystem behavior: OpenClaw prefers a no-overwrite hard-link publish step and falls back to exclusive copy when hard links are unsupported
|
||||
|
||||
Large workspaces are usually the main driver of archive size. Use `--no-include-workspace` for a smaller/faster backup, or `--only-config` for the smallest archive.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
262
docs/cli/browser.md
Normal file
262
docs/cli/browser.md
Normal file
@@ -0,0 +1,262 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw browser` (lifecycle, profiles, tabs, actions, state, and debugging)"
|
||||
read_when:
|
||||
- You use `openclaw browser` and want examples for common tasks
|
||||
- You want to control a browser running on another machine via a node host
|
||||
- You want to attach to your local signed-in Chrome via Chrome MCP
|
||||
title: "Browser"
|
||||
---
|
||||
|
||||
# `openclaw browser`
|
||||
|
||||
Manage OpenClaw's browser control surface and run browser actions: lifecycle, profiles, tabs, snapshots, screenshots, navigation, input, state emulation, and debugging.
|
||||
|
||||
Related: [Browser tool](/tools/browser)
|
||||
|
||||
## Common flags
|
||||
|
||||
- `--url <gatewayWsUrl>`: Gateway WebSocket URL (defaults to config).
|
||||
- `--token <token>`: Gateway token (if required).
|
||||
- `--timeout <ms>`: request timeout in ms (default: `30000`).
|
||||
- `--expect-final`: wait for a final Gateway response.
|
||||
- `--browser-profile <name>`: choose a browser profile (default: `openclaw`, or `browser.defaultProfile`).
|
||||
- `--json`: machine-readable output (where supported).
|
||||
|
||||
## Quick start (local)
|
||||
|
||||
```bash
|
||||
openclaw browser profiles
|
||||
openclaw browser --browser-profile openclaw start
|
||||
openclaw browser --browser-profile openclaw open https://example.com
|
||||
openclaw browser --browser-profile openclaw snapshot
|
||||
```
|
||||
|
||||
Agents can run the same readiness check with `browser({ action: "doctor" })`.
|
||||
|
||||
## Quick troubleshooting
|
||||
|
||||
If `start` fails with `not reachable after start`, troubleshoot CDP readiness first. If `start` and `tabs` succeed but `open` or `navigate` fails, the browser control plane is healthy and the failure is usually a navigation SSRF policy block.
|
||||
|
||||
Minimal sequence:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile openclaw doctor
|
||||
openclaw browser --browser-profile openclaw start
|
||||
openclaw browser --browser-profile openclaw tabs
|
||||
openclaw browser --browser-profile openclaw open https://example.com
|
||||
```
|
||||
|
||||
Detailed guidance: [Browser troubleshooting](/tools/browser#cdp-startup-failure-vs-navigation-ssrf-block)
|
||||
|
||||
## Lifecycle
|
||||
|
||||
```bash
|
||||
openclaw browser status
|
||||
openclaw browser doctor
|
||||
openclaw browser doctor --deep
|
||||
openclaw browser start
|
||||
openclaw browser start --headless
|
||||
openclaw browser stop
|
||||
openclaw browser --browser-profile openclaw reset-profile
|
||||
```
|
||||
|
||||
- `doctor --deep` adds a live snapshot probe: useful when basic CDP readiness is green but you want proof the current tab can be inspected.
|
||||
- `stop` closes the active control session and clears temporary emulation overrides even for `attachOnly` and remote CDP profiles where OpenClaw did not launch the browser process itself. For local managed profiles, `stop` also stops the spawned browser process.
|
||||
- `start --headless` applies only to that start request, and only when OpenClaw launches a local managed browser. It does not rewrite `browser.headless` or profile config, and is a no-op for an already-running browser.
|
||||
- On Linux hosts without `DISPLAY` or `WAYLAND_DISPLAY`, local managed profiles run headless automatically unless `OPENCLAW_BROWSER_HEADLESS=0`, `browser.headless=false`, or `browser.profiles.<name>.headless=false` explicitly requests a visible browser.
|
||||
|
||||
## If the command is missing
|
||||
|
||||
If `openclaw browser` is an unknown command, check `plugins.allow` in `~/.openclaw/openclaw.json`. When `plugins.allow` is present, list the bundled browser plugin explicitly unless the config already has a root `browser` block:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
allow: ["telegram", "browser"],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
An explicit root `browser` block (for example `browser.enabled=true` or `browser.profiles.<name>`) also activates the bundled browser plugin under a restrictive plugin allowlist.
|
||||
|
||||
Related: [Browser tool](/tools/browser#missing-browser-command-or-tool)
|
||||
|
||||
## Profiles
|
||||
|
||||
Profiles are named browser routing configs:
|
||||
|
||||
- `openclaw` (default): launches or attaches to a dedicated OpenClaw-managed Chrome instance (isolated user data dir).
|
||||
- `user`: controls your existing signed-in Chrome session via Chrome DevTools MCP.
|
||||
- custom CDP profiles: point at a local or remote CDP endpoint.
|
||||
|
||||
```bash
|
||||
openclaw browser profiles
|
||||
openclaw browser create-profile --name work --color "#FF5A36"
|
||||
openclaw browser create-profile --name chrome-live --driver existing-session
|
||||
openclaw browser create-profile --name remote --cdp-url https://browser-host.example.com
|
||||
openclaw browser delete-profile --name work
|
||||
```
|
||||
|
||||
Use a specific profile with `--browser-profile <name>` on any subcommand, for example `openclaw browser --browser-profile work tabs`.
|
||||
|
||||
## Tabs
|
||||
|
||||
```bash
|
||||
openclaw browser tabs
|
||||
openclaw browser tab new --label docs
|
||||
openclaw browser tab label t1 docs
|
||||
openclaw browser tab select 2
|
||||
openclaw browser tab close 2
|
||||
openclaw browser open https://docs.openclaw.ai --label docs
|
||||
openclaw browser focus docs
|
||||
openclaw browser close t1
|
||||
```
|
||||
|
||||
`tabs` returns `suggestedTargetId` first, then the stable `tabId` (such as `t1`), the optional label, and the raw `targetId`. Pass `suggestedTargetId` back into `focus`, `close`, snapshots, and actions. Assign a label with `open --label`, `tab new --label`, or `tab label`; labels, tab ids, raw target ids, and unique target-id prefixes are all accepted. The request field is still named `targetId` for compatibility, but it accepts any of these tab references.
|
||||
|
||||
Raw target ids are volatile diagnostic handles, not durable agent memory: when Chromium replaces the underlying raw target during a navigation or form submit, OpenClaw keeps the stable `tabId`/label attached to the replacement tab when it can prove the match. Prefer `suggestedTargetId`.
|
||||
|
||||
## Snapshot / screenshot / actions
|
||||
|
||||
Snapshot:
|
||||
|
||||
```bash
|
||||
openclaw browser snapshot
|
||||
openclaw browser snapshot --urls
|
||||
```
|
||||
|
||||
Screenshot:
|
||||
|
||||
```bash
|
||||
openclaw browser screenshot
|
||||
openclaw browser screenshot --full-page
|
||||
openclaw browser screenshot --ref e12
|
||||
openclaw browser screenshot --labels
|
||||
```
|
||||
|
||||
- `--full-page` is for page captures only; it cannot be combined with `--ref` or `--element`.
|
||||
- `existing-session` / `user` profiles support page screenshots and `--ref` screenshots from snapshot output, but not CSS `--element` screenshots.
|
||||
- `--labels` overlays current snapshot refs on the screenshot. On Playwright-backed profiles it works with `--full-page` (full-page overlay), `--ref` (element-clip overlay by ARIA ref), and `--element` (element-clip overlay by CSS selector); in element-clip modes labels are projected relative to the element. The response also includes an `annotations` array (omitted when empty) with each ref's bounding box: `ref`, `number`, `role`, optional `name`, and `box: {x, y, width, height}` in the captured image's coordinate space (viewport / fullpage / element-relative).
|
||||
`existing-session` profiles render a chrome-mcp overlay on page screenshots but do not use the Playwright projection helper and do not include `annotations`; CSS `--element` screenshots are unsupported there. Without Playwright or chrome-mcp, labeled screenshots are not available.
|
||||
- `snapshot --urls` appends discovered link destinations to AI snapshots so agents can choose direct navigation targets instead of guessing from link text alone.
|
||||
|
||||
Navigate/click/type (ref-based UI automation):
|
||||
|
||||
```bash
|
||||
openclaw browser navigate https://example.com
|
||||
openclaw browser click <ref>
|
||||
openclaw browser click-coords 120 340
|
||||
openclaw browser type <ref> "hello"
|
||||
openclaw browser press Enter
|
||||
openclaw browser hover <ref>
|
||||
openclaw browser scrollintoview <ref>
|
||||
openclaw browser drag <startRef> <endRef>
|
||||
openclaw browser select <ref> OptionA OptionB
|
||||
openclaw browser fill --fields '[{"ref":"1","value":"Ada"}]'
|
||||
openclaw browser wait --text "Done"
|
||||
openclaw browser evaluate --fn '(el) => el.textContent' --ref <ref>
|
||||
openclaw browser evaluate --fn 'const title = document.title; return title;'
|
||||
openclaw browser evaluate --timeout-ms 30000 --fn 'async () => { await window.ready; return true; }'
|
||||
```
|
||||
|
||||
`evaluate --fn` accepts a function source, an expression, or a statement body. Statement bodies are wrapped as async functions, so use `return` for the value you want back. Use `--timeout-ms` when the page-side function may need longer than the default evaluate timeout. `browser.evaluateEnabled=false` (default: `true`) disables both `evaluate` and `wait --fn`.
|
||||
|
||||
Action responses return the current raw `targetId` after action-triggered page replacement when OpenClaw can prove the replacement tab. Scripts should still store and pass `suggestedTargetId`/labels for long-lived workflows.
|
||||
|
||||
File + dialog helpers:
|
||||
|
||||
```bash
|
||||
openclaw browser upload /tmp/openclaw/uploads/file.pdf --ref <ref>
|
||||
openclaw browser upload media://inbound/file.pdf --ref <ref>
|
||||
openclaw browser waitfordownload
|
||||
openclaw browser download <ref> report.pdf
|
||||
openclaw browser dialog --accept
|
||||
openclaw browser dialog --dismiss --dialog-id d1
|
||||
```
|
||||
|
||||
Managed Chrome profiles save ordinary click-triggered downloads into the OpenClaw downloads directory (`/tmp/openclaw/downloads` by default, or the configured temp root). Use `waitfordownload` or `download` when the agent needs to wait for a specific file and return its path; those explicit waiters own the next download. Uploads accept files from the OpenClaw temp uploads root and OpenClaw-managed inbound media, including `media://inbound/<id>` and sandbox-relative `media/inbound/<id>` references. Nested media refs, traversal, and arbitrary local paths are rejected.
|
||||
|
||||
When an action opens a modal dialog, the action response returns `blockedByDialog` with `browserState.dialogs.pending`; pass `--dialog-id` to answer it directly. Dialogs handled outside OpenClaw appear under `browserState.dialogs.recent`.
|
||||
|
||||
## State and storage
|
||||
|
||||
Viewport + emulation:
|
||||
|
||||
```bash
|
||||
openclaw browser resize 1280 720
|
||||
openclaw browser set viewport 1280 720
|
||||
openclaw browser set offline on
|
||||
openclaw browser set media dark
|
||||
openclaw browser set timezone Europe/London
|
||||
openclaw browser set locale en-GB
|
||||
openclaw browser set geo 51.5074 -0.1278 --accuracy 25
|
||||
openclaw browser set device "iPhone 14"
|
||||
openclaw browser set headers '{"x-test":"1"}'
|
||||
openclaw browser set credentials myuser mypass
|
||||
```
|
||||
|
||||
Cookies + storage:
|
||||
|
||||
```bash
|
||||
openclaw browser cookies
|
||||
openclaw browser cookies set session abc123 --url https://example.com
|
||||
openclaw browser cookies clear
|
||||
openclaw browser storage local get
|
||||
openclaw browser storage local set token abc123
|
||||
openclaw browser storage session clear
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
```bash
|
||||
openclaw browser console --level error
|
||||
openclaw browser pdf
|
||||
openclaw browser responsebody "**/api"
|
||||
openclaw browser highlight <ref>
|
||||
openclaw browser errors --clear
|
||||
openclaw browser requests --filter api
|
||||
openclaw browser trace start
|
||||
openclaw browser trace stop --out trace.zip
|
||||
```
|
||||
|
||||
## Existing Chrome via MCP
|
||||
|
||||
Use the built-in `user` profile, or create your own `existing-session` profile:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile user tabs
|
||||
openclaw browser create-profile --name chrome-live --driver existing-session
|
||||
openclaw browser create-profile --name brave-live --driver existing-session --user-data-dir "~/Library/Application Support/BraveSoftware/Brave-Browser"
|
||||
openclaw browser create-profile --name chrome-port --driver existing-session --cdp-url http://127.0.0.1:9222
|
||||
openclaw browser --browser-profile chrome-live tabs
|
||||
```
|
||||
|
||||
The default existing-session path is host-only Chrome MCP auto-connect. If the browser is already running with a DevTools endpoint, pass `--cdp-url` so Chrome MCP attaches to that endpoint instead. For Docker, Browserless, or other remote setups where Chrome MCP semantics are not needed, use a CDP profile instead.
|
||||
|
||||
Current existing-session limits:
|
||||
|
||||
- Snapshot-driven actions use refs, not CSS selectors.
|
||||
- `browser.actionTimeoutMs` defaults supported `act` requests to 60000 ms when callers omit `timeoutMs`; per-call `timeoutMs` still wins.
|
||||
- `click` is left-click only.
|
||||
- `type` does not support `slowly=true`.
|
||||
- `press` does not support `delayMs`.
|
||||
- `hover`, `scrollintoview`, `drag`, `select`, `fill`, and `evaluate` reject per-call timeout overrides.
|
||||
- `select` supports one value only.
|
||||
- `wait --load networkidle` is not supported (works on managed and raw/remote CDP profiles).
|
||||
- File uploads require `--ref` / `--input-ref`, do not support CSS `--element`, and support one file at a time.
|
||||
- Dialog hooks do not support `--timeout`.
|
||||
- Screenshots support page captures and `--ref`, but not CSS `--element`.
|
||||
- `responsebody`, download interception, PDF export, and batch actions still require a managed browser or raw CDP profile.
|
||||
|
||||
## Remote browser control (node host proxy)
|
||||
|
||||
If the Gateway runs on a different machine than the browser, run a **node host** on the machine that has Chrome/Brave/Edge/Chromium. The Gateway proxies browser actions to that node; no separate browser control server is required.
|
||||
|
||||
Use `gateway.nodes.browser.mode` to control auto-routing and `gateway.nodes.browser.node` to pin a specific node if multiple are connected.
|
||||
|
||||
Security + remote setup: [Browser tool](/tools/browser), [Remote access](/gateway/remote), [Tailscale](/gateway/tailscale), [Security](/gateway/security)
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Browser](/tools/browser)
|
||||
155
docs/cli/channels.md
Normal file
155
docs/cli/channels.md
Normal file
@@ -0,0 +1,155 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw channels` (accounts, status, capabilities, resolve, logs, login/logout)"
|
||||
read_when:
|
||||
- You want to add or remove channel accounts (Discord, Google Chat, iMessage, Matrix, Signal, Slack, Telegram, WhatsApp, and more)
|
||||
- You want to check channel status or tail channel logs
|
||||
title: "Channels"
|
||||
---
|
||||
|
||||
# `openclaw channels`
|
||||
|
||||
Manage chat channel accounts and their runtime status on the Gateway.
|
||||
|
||||
Related docs:
|
||||
|
||||
- Channel guides: [Channels](/channels)
|
||||
- Gateway configuration: [Configuration](/gateway/configuration)
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
openclaw channels list
|
||||
openclaw channels list --all
|
||||
openclaw channels status
|
||||
openclaw channels capabilities
|
||||
openclaw channels capabilities --channel discord --target channel:123
|
||||
openclaw channels resolve --channel slack "#general" "@jane"
|
||||
openclaw channels logs --channel all
|
||||
```
|
||||
|
||||
`channels list` shows chat channels only: configured accounts by default, with `installed`, `configured`, and `enabled` status tags per account (`--json` for machine output). Pass `--all` to also surface bundled channels that have no configured account yet and installable catalog channels that are not yet on disk. Provider auth and model usage live elsewhere: `openclaw models auth list` for provider auth profiles, `openclaw status` or `openclaw models list` for usage/quota.
|
||||
|
||||
## Status / capabilities / resolve / logs
|
||||
|
||||
- `channels status`: `--channel <name>`, `--probe`, `--timeout <ms>` (default `10000`), `--json`
|
||||
- `channels capabilities`: `--channel <name>`, `--account <id>` (requires `--channel`), `--target <dest>` (requires `--channel`), `--timeout <ms>` (default `10000`, capped at `30000`), `--json`
|
||||
- `channels resolve <entries...>`: `--channel <name>`, `--account <id>`, `--kind <auto|user|group>` (default `auto`), `--json`
|
||||
- `channels logs`: `--channel <name|all>` (default `all`), `--lines <n>` (default `200`), `--json`
|
||||
|
||||
`channels status --probe` is the live path: on a reachable gateway it runs per-account
|
||||
`probeAccount` and optional `auditAccount` checks, so output can include transport
|
||||
state plus probe results such as `works`, `probe failed`, `audit ok`, or `audit failed`.
|
||||
If the gateway is unreachable, `channels status` falls back to config-only summaries
|
||||
instead of live probe output.
|
||||
|
||||
Do not use `openclaw sessions`, Gateway `sessions.list`, or the agent
|
||||
`sessions_list` tool as a channel socket-health signal. Those surfaces report
|
||||
stored conversation rows, not provider runtime state. After a Discord provider
|
||||
restart, a connected but quiet account may be healthy while no Discord session
|
||||
row appears until the next inbound or outbound conversation event.
|
||||
|
||||
## Add / remove accounts
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel telegram --token <bot-token>
|
||||
openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY"
|
||||
openclaw channels remove --channel telegram --delete
|
||||
```
|
||||
|
||||
<Tip>
|
||||
`openclaw channels add --help` shows per-channel flags (token, private key, app token, signal-cli paths, etc).
|
||||
</Tip>
|
||||
|
||||
`channels remove` only operates on installed/configured channel plugins. Use `channels add` first for installable catalog channels. Without `--delete` it asks to disable the account and keeps its config; `--delete` removes the config entries without prompting.
|
||||
For runtime-backed channel plugins, `channels remove` also asks the running Gateway to stop the selected account before it updates config, so disabling or deleting an account does not leave the old listener active until restart.
|
||||
|
||||
Non-interactive add flags shared across channels: `--account <id>`, `--name <name>`, `--token`, `--token-file`, `--bot-token`, `--app-token`, `--secret`, `--secret-file`, `--password`, `--cli-path`, `--url`, `--base-url`, `--http-url`, `--auth-dir`, and `--use-env` (env-backed auth, default account only, where supported). Channel-specific flags include:
|
||||
|
||||
| Channel | Flags |
|
||||
| ----------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| Google Chat | `--webhook-path`, `--webhook-url`, `--audience-type`, `--audience` |
|
||||
| iMessage | `--cli-path`, `--db-path`, `--service`, `--region` |
|
||||
| Matrix | `--homeserver`, `--user-id`, `--access-token`, `--password`, `--device-name`, `--initial-sync-limit` |
|
||||
| Nostr | `--private-key`, `--relay-urls` |
|
||||
| Signal | `--signal-number`, `--cli-path`, `--http-url`, `--http-host`, `--http-port` |
|
||||
| Tlon | `--ship`, `--url`, `--code`, `--group-channels`, `--dm-allowlist`, `--auto-discover-channels` |
|
||||
| WhatsApp | `--auth-dir` |
|
||||
|
||||
If a channel plugin needs to be installed during a flag-driven add command, OpenClaw uses the channel's default install source without opening the interactive plugin install prompt.
|
||||
|
||||
When you run `openclaw channels add` without flags, the interactive wizard can prompt:
|
||||
|
||||
- account ids per selected channel
|
||||
- optional display names for those accounts
|
||||
- `Route these channel accounts to agents now?`
|
||||
|
||||
If you confirm bind now, the wizard asks which agent should own each configured channel account and writes account-scoped routing bindings.
|
||||
|
||||
You can also manage the same routing rules later with `openclaw agents bindings`, `openclaw agents bind`, and `openclaw agents unbind` (see [agents](/cli/agents)).
|
||||
|
||||
When you add a non-default account to a channel that is still using single-account top-level settings, OpenClaw promotes those top-level values into the channel's account map before writing the new account. Promotion reuses an existing named account when the channel has exactly one, or when `defaultAccount` points at one; otherwise the values land in `channels.<channel>.accounts.default`.
|
||||
|
||||
Routing behavior stays consistent:
|
||||
|
||||
- Existing channel-only bindings (no `accountId`) continue to match the default account.
|
||||
- `channels add` does not auto-create or rewrite bindings in non-interactive mode.
|
||||
- Interactive setup can optionally add account-scoped bindings.
|
||||
|
||||
If your config was already in a mixed state (named accounts present and top-level single-account values still set), run `openclaw doctor --fix` to move account-scoped values into the promoted account chosen for that channel.
|
||||
|
||||
## Login and logout (interactive)
|
||||
|
||||
```bash
|
||||
openclaw channels login --channel whatsapp
|
||||
openclaw channels logout --channel whatsapp
|
||||
```
|
||||
|
||||
- `channels login` supports `--account <id>` and `--verbose`; `channels logout` supports `--account <id>`.
|
||||
- `channels login` and `logout` can infer the channel when only one configured channel supports that action; with several, pass `--channel`.
|
||||
- `channels logout` prefers the live Gateway path when reachable, so logout stops any active listener before clearing channel auth state. If a local Gateway is not reachable, it falls back to local auth cleanup; with `gateway.mode: "remote"` the gateway error fails the command instead.
|
||||
- After a successful login, the CLI asks a reachable local Gateway to start the account; in remote mode it saves auth locally and notes that the remote runtime was not restarted.
|
||||
- Run `channels login` from a terminal on the gateway host. Agent `exec` blocks this interactive login flow; channel-native agent login tools, such as `whatsapp_login`, should be used from chat when available.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Run `openclaw status --deep` for a broad probe.
|
||||
- Use `openclaw doctor` for guided fixes.
|
||||
- `openclaw channels status` falls back to config-only summaries when the gateway is unreachable. If a supported channel credential is configured via SecretRef but unavailable in the current command path, it reports that account as configured with degraded notes instead of showing it as not configured.
|
||||
|
||||
## Capabilities probe
|
||||
|
||||
Fetch provider capability hints (intents/scopes where available) plus static feature support:
|
||||
|
||||
```bash
|
||||
openclaw channels capabilities
|
||||
openclaw channels capabilities --channel discord --target channel:123
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `--channel` is optional; omit it to list every channel (including plugin-provided channels).
|
||||
- `--account` is only valid with `--channel`.
|
||||
- `--target` accepts `channel:<id>` or a raw numeric channel id and only applies to Discord. For Discord voice channels, the permission check flags missing `ViewChannel`, `Connect`, `Speak`, `SendMessages`, and `ReadMessageHistory`.
|
||||
- Probes are provider-specific: Discord bot identity + intents plus optional channel permissions; Slack bot + user scopes; Telegram bot flags + webhook; Signal daemon version; Microsoft Teams app token + Graph roles/scopes (annotated where known). Channels without probes report `Probe: unavailable`.
|
||||
|
||||
## Resolve names to IDs
|
||||
|
||||
Resolve channel/user names to IDs using the provider directory:
|
||||
|
||||
```bash
|
||||
openclaw channels resolve --channel slack "#general" "@jane"
|
||||
openclaw channels resolve --channel discord "My Server/#support" "@someone"
|
||||
openclaw channels resolve --channel matrix "Project Room"
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Use `--kind user|group|auto` to force the target type.
|
||||
- Resolution prefers active matches when multiple entries share the same name.
|
||||
- `channels resolve` is read-only. If a selected account is configured via SecretRef but that credential is unavailable in the current command path, the command returns degraded unresolved results with notes instead of aborting the entire run.
|
||||
- `channels resolve` does not install channel plugins. Use `channels add --channel <name>` before resolving names for an installable catalog channel.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Channels overview](/channels)
|
||||
21
docs/cli/clawbot.md
Normal file
21
docs/cli/clawbot.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw clawbot` (legacy alias namespace)"
|
||||
read_when:
|
||||
- You maintain older scripts using `openclaw clawbot ...`
|
||||
- You need migration guidance to current commands
|
||||
title: "Clawbot"
|
||||
---
|
||||
|
||||
# `openclaw clawbot`
|
||||
|
||||
Legacy alias namespace kept for backward compatibility. It registers the same QR command as the top-level CLI, so `openclaw clawbot qr` accepts every [`openclaw qr`](/cli/qr) flag.
|
||||
|
||||
## Migration
|
||||
|
||||
Prefer the modern top-level command:
|
||||
|
||||
- `openclaw clawbot qr` -> `openclaw qr`
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
95
docs/cli/commitments.md
Normal file
95
docs/cli/commitments.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw commitments` (inspect and dismiss inferred follow-ups)"
|
||||
read_when:
|
||||
- You want to inspect inferred follow-up commitments
|
||||
- You want to dismiss pending check-ins
|
||||
- You are auditing what heartbeat may deliver
|
||||
title: "`openclaw commitments`"
|
||||
---
|
||||
|
||||
List and manage inferred follow-up commitments.
|
||||
|
||||
Commitments are opt-in (`commitments.enabled`), short-lived follow-up memories
|
||||
created from conversation context and delivered by heartbeat. See
|
||||
[Inferred commitments](/concepts/commitments) for the conceptual guide and config.
|
||||
|
||||
With no subcommand, `openclaw commitments` lists pending commitments.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw commitments [--all] [--agent <id>] [--status <status>] [--json]
|
||||
openclaw commitments list [--all] [--agent <id>] [--status <status>] [--json]
|
||||
openclaw commitments dismiss <id...> [--json]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `--all`: show all statuses instead of only pending commitments.
|
||||
- `--agent <id>`: filter to one agent id.
|
||||
- `--status <status>`: filter by status. Values: `pending`, `sent`,
|
||||
`dismissed`, `snoozed`, or `expired`. Unknown values exit with an error.
|
||||
- `--json`: output machine-readable JSON.
|
||||
|
||||
`dismiss` marks the given commitment ids as `dismissed` so heartbeat will not
|
||||
deliver them.
|
||||
|
||||
## Examples
|
||||
|
||||
List pending commitments:
|
||||
|
||||
```bash
|
||||
openclaw commitments
|
||||
```
|
||||
|
||||
List every stored commitment:
|
||||
|
||||
```bash
|
||||
openclaw commitments --all
|
||||
```
|
||||
|
||||
Filter to one agent:
|
||||
|
||||
```bash
|
||||
openclaw commitments --agent main
|
||||
```
|
||||
|
||||
Find snoozed commitments:
|
||||
|
||||
```bash
|
||||
openclaw commitments --status snoozed
|
||||
```
|
||||
|
||||
Dismiss one or more commitments:
|
||||
|
||||
```bash
|
||||
openclaw commitments dismiss cm_abc123 cm_def456
|
||||
```
|
||||
|
||||
Export as JSON:
|
||||
|
||||
```bash
|
||||
openclaw commitments --all --json
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Text output prints the commitment count, the store path, any active filters,
|
||||
and one row per commitment:
|
||||
|
||||
- commitment id
|
||||
- status
|
||||
- kind (`event_check_in`, `deadline_check`, `care_check_in`, or `open_loop`)
|
||||
- earliest due time
|
||||
- scope (agent/channel/target)
|
||||
- suggested check-in text
|
||||
|
||||
JSON output includes the count, the active status and agent filters, the
|
||||
commitment store path, and the full stored records.
|
||||
|
||||
## Related
|
||||
|
||||
- [Inferred commitments](/concepts/commitments)
|
||||
- [Memory overview](/concepts/memory)
|
||||
- [Heartbeat](/gateway/heartbeat)
|
||||
- [Scheduled tasks](/automation/cron-jobs)
|
||||
51
docs/cli/completion.md
Normal file
51
docs/cli/completion.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw completion` (generate/install shell completion scripts)"
|
||||
read_when:
|
||||
- You want shell completions for zsh/bash/fish/PowerShell
|
||||
- You need to cache completion scripts under OpenClaw state
|
||||
title: "Completion"
|
||||
---
|
||||
|
||||
# `openclaw completion`
|
||||
|
||||
Generate shell completion scripts, cache them under OpenClaw state, and optionally install them into your shell profile.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw completion # print zsh script to stdout
|
||||
openclaw completion --shell fish # print fish script
|
||||
openclaw completion --write-state # cache scripts for all shells
|
||||
openclaw completion --write-state --install # cache, then install in one step
|
||||
openclaw completion --shell bash --write-state
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `-s, --shell <shell>`: shell target (`zsh`, `bash`, `powershell`, `fish`; default: `zsh`)
|
||||
- `-i, --install`: install completion by adding a source line for the cached script to your shell profile
|
||||
- `--write-state`: write completion script(s) to `$OPENCLAW_STATE_DIR/completions` (default `~/.openclaw/completions`) without printing to stdout; with `--shell` writes only that shell, otherwise all four
|
||||
- `-y, --yes`: skip install confirmation prompts (non-interactive)
|
||||
|
||||
## Install flow
|
||||
|
||||
`--install` points your profile at the cached script, so the cache must exist first: if it is missing, the command fails and tells you to run `openclaw completion --write-state`. Combine `--write-state --install` to do both in one step. Without `--shell`, `--install` detects the shell from `$SHELL` (falling back to zsh).
|
||||
|
||||
The install writes a small `# OpenClaw Completion` block into your shell profile and replaces any older slow `source <(openclaw completion ...)` lines with the cached source line:
|
||||
|
||||
| Shell | Profile |
|
||||
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| bash | `~/.bashrc` (falls back to `~/.bash_profile` when `~/.bashrc` is missing) |
|
||||
| fish | `~/.config/fish/config.fish` |
|
||||
| powershell | `~/.config/powershell/Microsoft.PowerShell_profile.ps1` (on Windows: `Documents/PowerShell/Microsoft.PowerShell_profile.ps1`, or `Documents/WindowsPowerShell/...` for Windows PowerShell) |
|
||||
| zsh | `~/.zshrc` |
|
||||
|
||||
## Notes
|
||||
|
||||
- Without `--install` or `--write-state`, the command prints the script to stdout.
|
||||
- Completion generation eagerly loads the full command tree, including plugin CLI commands, so nested subcommands are included.
|
||||
- `openclaw update` refreshes the completion cache automatically after a successful update; `openclaw doctor` can repair missing or stale completion setups.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
500
docs/cli/config.md
Normal file
500
docs/cli/config.md
Normal file
@@ -0,0 +1,500 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw config` (get/set/patch/unset/file/schema/validate)"
|
||||
read_when:
|
||||
- You want to read or edit config non-interactively
|
||||
title: "Config"
|
||||
sidebarTitle: "Config"
|
||||
---
|
||||
|
||||
Non-interactive helpers for `openclaw.json`: get/set/patch/unset a value by path, print the schema, validate, or print the active file path. Run `openclaw config` with no subcommand to open the same guided wizard as `openclaw configure`.
|
||||
|
||||
<Note>
|
||||
When `OPENCLAW_NIX_MODE=1`, OpenClaw treats `openclaw.json` as immutable. Read-only commands (`config get`, `config file`, `config schema`, `config validate`) still work; config writers refuse. Edit the Nix source for the install instead; for the first-party nix-openclaw distribution, use the [nix-openclaw Quick Start](https://github.com/openclaw/nix-openclaw#quick-start) and set values under `programs.openclaw.config` or `instances.<name>.config`.
|
||||
</Note>
|
||||
|
||||
## Root options
|
||||
|
||||
<ParamField path="--section <section>" type="string">
|
||||
Repeatable guided-setup section filter when you run `openclaw config` without a subcommand.
|
||||
</ParamField>
|
||||
|
||||
Guided sections: `workspace`, `model`, `web`, `gateway`, `daemon`, `channels`, `plugins`, `skills`, `health`.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw config file
|
||||
openclaw config --section model
|
||||
openclaw config --section gateway --section daemon
|
||||
openclaw config schema
|
||||
openclaw config get browser.executablePath
|
||||
openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
openclaw config set browser.profiles.work.executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
openclaw config set agents.defaults.heartbeat.every "2h"
|
||||
openclaw config set 'agents.list[0].tools.exec.node' "node-id-or-name"
|
||||
openclaw config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json --merge
|
||||
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
|
||||
openclaw config set secrets.providers.vaultfile --provider-source file --provider-path /etc/openclaw/secrets.json --provider-mode json
|
||||
openclaw config patch --file ./openclaw.patch.json5 --dry-run
|
||||
openclaw config unset plugins.entries.brave.config.webSearch.apiKey
|
||||
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN --dry-run
|
||||
openclaw config validate
|
||||
openclaw config validate --json
|
||||
```
|
||||
|
||||
### Paths
|
||||
|
||||
Dot or bracket notation. Quote bracket paths in shell examples so zsh does not glob-expand `[0]`:
|
||||
|
||||
```bash
|
||||
openclaw config get agents.defaults.workspace
|
||||
openclaw config get 'agents.list[0].id'
|
||||
openclaw config get agents.list
|
||||
openclaw config set 'agents.list[1].tools.exec.node' "node-id-or-name"
|
||||
```
|
||||
|
||||
### `config get`
|
||||
|
||||
Reads a value from the redacted config snapshot (secrets never print). `--json` prints the raw value as JSON; otherwise strings/numbers/booleans print bare and objects/arrays print as formatted JSON.
|
||||
|
||||
```bash
|
||||
openclaw config get browser.executablePath
|
||||
openclaw config get agents.defaults.model --json
|
||||
```
|
||||
|
||||
### `config file`
|
||||
|
||||
Prints the active config file path, resolved from `OPENCLAW_CONFIG_PATH` or the default location. The path names a regular file, not a symlink; see [Write safety](#write-safety).
|
||||
|
||||
### `config schema`
|
||||
|
||||
Prints the generated JSON schema for `openclaw.json` to stdout.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="What it includes">
|
||||
- The current root config schema, plus a root `$schema` string field for editor tooling.
|
||||
- Field `title` / `description` docs metadata used by the Control UI.
|
||||
- Nested object, wildcard (`*`), and array-item (`[]`) nodes inherit the same `title` / `description` metadata when matching field docs exist.
|
||||
- `anyOf` / `oneOf` / `allOf` branches inherit the same docs metadata too.
|
||||
- Best-effort live plugin + channel schema metadata when runtime manifests can be loaded.
|
||||
- A clean fallback schema even when the current config is invalid.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Related runtime RPC">
|
||||
`config.schema.lookup` returns one normalized config path with a shallow schema node (`title`, `description`, `type`, `enum`, `const`, common bounds), matched UI hint metadata, and immediate child summaries. Use it for path-scoped drill-down in Control UI or custom clients.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
```bash
|
||||
openclaw config schema
|
||||
openclaw config schema > openclaw.schema.json
|
||||
```
|
||||
|
||||
### `config validate`
|
||||
|
||||
Validates the current config against the active schema without starting the gateway.
|
||||
|
||||
```bash
|
||||
openclaw config validate
|
||||
openclaw config validate --json
|
||||
```
|
||||
|
||||
<Note>
|
||||
If validation is already failing, start with `openclaw configure` or `openclaw doctor --fix`. `openclaw chat` does not bypass the invalid-config guard.
|
||||
</Note>
|
||||
|
||||
## Values
|
||||
|
||||
Values parse as JSON5 when possible; otherwise they are treated as raw strings. Use `--strict-json` to require standard JSON with no string fallback (JSON5-only syntax such as comments, trailing commas, or unquoted keys is then rejected). `--json` is a legacy alias for `--strict-json` on `config set`.
|
||||
|
||||
```bash
|
||||
openclaw config set agents.defaults.heartbeat.every "0m"
|
||||
openclaw config set gateway.port 19001 --strict-json
|
||||
openclaw config set channels.whatsapp.groups '["*"]' --strict-json
|
||||
```
|
||||
|
||||
`config get <path> --json` prints the raw value as JSON instead of terminal-formatted text.
|
||||
|
||||
<Note>
|
||||
Object assignment replaces the target path by default. Protected paths that commonly hold user-added entries refuse replacements that would remove existing entries unless you pass `--replace`: `agents.defaults.models`, `agents.list`, `models.providers`, `models.providers.<id>`, `models.providers.<id>.models`, `plugins.entries`, and `auth.profiles`.
|
||||
</Note>
|
||||
|
||||
Use `--merge` when adding entries to those maps:
|
||||
|
||||
```bash
|
||||
openclaw config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json --merge
|
||||
openclaw config set models.providers.ollama.models '[{"id":"llama3.2","name":"Llama 3.2"}]' --strict-json --merge
|
||||
```
|
||||
|
||||
Use `--replace` only when the provided value should intentionally become the complete target value.
|
||||
|
||||
## `config set` modes
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Value mode">
|
||||
```bash
|
||||
openclaw config set <path> <value>
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="SecretRef builder mode">
|
||||
```bash
|
||||
openclaw config set channels.discord.token \
|
||||
--ref-provider default \
|
||||
--ref-source env \
|
||||
--ref-id DISCORD_BOT_TOKEN
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Provider builder mode">
|
||||
Targets `secrets.providers.<alias>` paths only:
|
||||
|
||||
```bash
|
||||
openclaw config set secrets.providers.vault \
|
||||
--provider-source exec \
|
||||
--provider-command /usr/local/bin/openclaw-vault \
|
||||
--provider-arg read \
|
||||
--provider-arg openai/api-key \
|
||||
--provider-timeout-ms 5000
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Batch mode">
|
||||
```bash
|
||||
openclaw config set --batch-json '[
|
||||
{
|
||||
"path": "secrets.providers.default",
|
||||
"provider": { "source": "env" }
|
||||
},
|
||||
{
|
||||
"path": "channels.discord.token",
|
||||
"ref": { "source": "env", "provider": "default", "id": "DISCORD_BOT_TOKEN" }
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw config set --batch-file ./config-set.batch.json --dry-run
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Warning>
|
||||
SecretRef assignments are rejected on unsupported runtime-mutable surfaces (for example `hooks.token`, `commands.ownerDisplaySecret`, Discord thread-binding webhook tokens, and WhatsApp creds JSON). See [SecretRef Credential Surface](/reference/secretref-credential-surface).
|
||||
</Warning>
|
||||
|
||||
Batch parsing always uses the batch payload (`--batch-json`/`--batch-file`) as the source of truth; `--strict-json` / `--json` do not change batch parsing behavior.
|
||||
|
||||
JSON path/value mode also works for SecretRefs and providers directly:
|
||||
|
||||
```bash
|
||||
openclaw config set channels.discord.token \
|
||||
'{"source":"env","provider":"default","id":"DISCORD_BOT_TOKEN"}' \
|
||||
--strict-json
|
||||
|
||||
openclaw config set secrets.providers.vaultfile \
|
||||
'{"source":"file","path":"/etc/openclaw/secrets.json","mode":"json"}' \
|
||||
--strict-json
|
||||
```
|
||||
|
||||
### Provider builder flags
|
||||
|
||||
Provider builder targets must use `secrets.providers.<alias>` as the path.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Common flags">
|
||||
- `--provider-source <env|file|exec>`
|
||||
- `--provider-timeout-ms <ms>` (`file`, `exec`)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Env provider (--provider-source env)">
|
||||
- `--provider-allowlist <ENV_VAR>` (repeatable)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="File provider (--provider-source file)">
|
||||
- `--provider-path <path>` (required)
|
||||
- `--provider-mode <singleValue|json>`
|
||||
- `--provider-max-bytes <bytes>`
|
||||
- `--provider-allow-insecure-path`
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Exec provider (--provider-source exec)">
|
||||
- `--provider-command <path>` (required)
|
||||
- `--provider-arg <arg>` (repeatable)
|
||||
- `--provider-no-output-timeout-ms <ms>`
|
||||
- `--provider-max-output-bytes <bytes>`
|
||||
- `--provider-json-only`
|
||||
- `--provider-env <KEY=VALUE>` (repeatable)
|
||||
- `--provider-pass-env <ENV_VAR>` (repeatable)
|
||||
- `--provider-trusted-dir <path>` (repeatable)
|
||||
- `--provider-allow-insecure-path`
|
||||
- `--provider-allow-symlink-command`
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Hardened exec provider example:
|
||||
|
||||
```bash
|
||||
openclaw config set secrets.providers.vault \
|
||||
--provider-source exec \
|
||||
--provider-command /usr/local/bin/openclaw-vault \
|
||||
--provider-arg read \
|
||||
--provider-arg openai/api-key \
|
||||
--provider-json-only \
|
||||
--provider-pass-env VAULT_TOKEN \
|
||||
--provider-trusted-dir /usr/local/bin \
|
||||
--provider-timeout-ms 5000
|
||||
```
|
||||
|
||||
## `config patch`
|
||||
|
||||
Paste or pipe a config-shaped JSON5 patch instead of running many path-based `config set` commands. Objects merge recursively; arrays and scalar values replace the target; `null` deletes the target path.
|
||||
|
||||
```bash
|
||||
openclaw config patch --file ./openclaw.patch.json5 --dry-run
|
||||
openclaw config patch --file ./openclaw.patch.json5
|
||||
```
|
||||
|
||||
Pipe a patch over stdin for remote setup scripts:
|
||||
|
||||
```bash
|
||||
ssh user@gateway-host 'openclaw config patch --stdin --dry-run' < ./openclaw.patch.json5
|
||||
ssh user@gateway-host 'openclaw config patch --stdin' < ./openclaw.patch.json5
|
||||
```
|
||||
|
||||
Example patch:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
slack: {
|
||||
enabled: true,
|
||||
mode: "socket",
|
||||
botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
|
||||
appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
|
||||
groupPolicy: "open",
|
||||
requireMention: false,
|
||||
},
|
||||
discord: {
|
||||
enabled: true,
|
||||
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
|
||||
dmPolicy: "disabled",
|
||||
dm: { enabled: false },
|
||||
groupPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openai/gpt-5.5" },
|
||||
models: {
|
||||
"openai/gpt-5.5": { params: { fastMode: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Use `--replace-path <path>` when one object or array must become exactly the provided value instead of being recursively patched:
|
||||
|
||||
```bash
|
||||
openclaw config patch --file ./discord.patch.json5 --replace-path 'channels.discord.guilds["123"].channels'
|
||||
```
|
||||
|
||||
`--dry-run` runs schema and SecretRef resolvability checks without writing. Exec-backed SecretRefs are skipped by default during dry-run; add `--allow-exec` when you intentionally want dry-run to execute provider commands.
|
||||
|
||||
## Dry run
|
||||
|
||||
`--dry-run` validates changes without writing `openclaw.json`. Available on `config set`, `config patch`, and `config unset`.
|
||||
|
||||
```bash
|
||||
openclaw config set channels.discord.token \
|
||||
--ref-provider default \
|
||||
--ref-source env \
|
||||
--ref-id DISCORD_BOT_TOKEN \
|
||||
--dry-run \
|
||||
--json
|
||||
|
||||
openclaw config set channels.discord.token \
|
||||
--ref-provider vault \
|
||||
--ref-source exec \
|
||||
--ref-id discord/token \
|
||||
--dry-run \
|
||||
--allow-exec
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Dry-run behavior">
|
||||
- Builder mode: runs SecretRef resolvability checks for changed refs/providers.
|
||||
- JSON mode (`--strict-json`, `--json`, or batch mode): runs schema validation plus SecretRef resolvability checks.
|
||||
- Policy validation runs against the full post-change config, so parent-object writes (for example setting `hooks` as an object) cannot bypass unsupported-surface validation.
|
||||
- Exec SecretRef checks are skipped by default to avoid command side effects; pass `--allow-exec` to opt in (this may execute provider commands). `--allow-exec` is dry-run only and errors without `--dry-run`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--dry-run --json fields">
|
||||
- `ok`: whether dry-run passed
|
||||
- `operations`: number of assignments evaluated
|
||||
- `checks`: whether schema/resolvability checks ran
|
||||
- `checks.resolvabilityComplete`: whether resolvability checks ran to completion (false when exec refs are skipped)
|
||||
- `refsChecked`: number of refs actually resolved during dry-run
|
||||
- `skippedExecRefs`: number of exec refs skipped because `--allow-exec` was not set
|
||||
- `errors`: structured missing-path, schema, or resolvability failures when `ok=false`
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### JSON output shape
|
||||
|
||||
```json5
|
||||
{
|
||||
ok: boolean,
|
||||
operations: number,
|
||||
configPath: string,
|
||||
inputModes: ["value" | "json" | "builder" | "unset", ...],
|
||||
checks: {
|
||||
schema: boolean,
|
||||
resolvability: boolean,
|
||||
resolvabilityComplete: boolean,
|
||||
},
|
||||
refsChecked: number,
|
||||
skippedExecRefs: number,
|
||||
errors?: [
|
||||
{
|
||||
kind: "missing-path" | "schema" | "resolvability",
|
||||
message: string,
|
||||
ref?: string, // present for resolvability errors
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Success example">
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"operations": 1,
|
||||
"configPath": "~/.openclaw/openclaw.json",
|
||||
"inputModes": ["builder"],
|
||||
"checks": {
|
||||
"schema": false,
|
||||
"resolvability": true,
|
||||
"resolvabilityComplete": true
|
||||
},
|
||||
"refsChecked": 1,
|
||||
"skippedExecRefs": 0
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Failure example">
|
||||
```json
|
||||
{
|
||||
"ok": false,
|
||||
"operations": 1,
|
||||
"configPath": "~/.openclaw/openclaw.json",
|
||||
"inputModes": ["builder"],
|
||||
"checks": {
|
||||
"schema": false,
|
||||
"resolvability": true,
|
||||
"resolvabilityComplete": true
|
||||
},
|
||||
"refsChecked": 1,
|
||||
"skippedExecRefs": 0,
|
||||
"errors": [
|
||||
{
|
||||
"kind": "resolvability",
|
||||
"message": "Error: Environment variable \"MISSING_TEST_SECRET\" is not set.",
|
||||
"ref": "env:default:MISSING_TEST_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="If dry-run fails">
|
||||
- `config schema validation failed`: your post-change config shape is invalid; fix the path/value or provider/ref object shape.
|
||||
- `Config policy validation failed: unsupported SecretRef usage`: move that credential back to plaintext/string input; keep SecretRefs on supported surfaces only.
|
||||
- `SecretRef assignment(s) could not be resolved`: the referenced provider/ref cannot currently resolve (missing env var, invalid file pointer, exec provider failure, or provider/source mismatch).
|
||||
- `Dry run note: skipped <n> exec SecretRef resolvability check(s)`: rerun with `--allow-exec` if you need exec resolvability validation.
|
||||
- For batch mode, fix failing entries and rerun `--dry-run` before writing.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Applying changes
|
||||
|
||||
After every successful `config set` / `config patch` / `config unset`, the CLI prints one of three hints so you know whether the gateway needs a restart:
|
||||
|
||||
| Hint | Meaning |
|
||||
| --------------------------------------------------- | -------------------------------------- |
|
||||
| `Restart the gateway to apply.` | The changed path needs a full restart. |
|
||||
| `Change will apply without restarting the gateway.` | Hot reload picks it up automatically. |
|
||||
| `No gateway restart needed.` | Nothing runtime-relevant changed. |
|
||||
|
||||
Writes to `plugins.entries` (or any subpath) always require a restart, since the CLI cannot prove every plugin's reload metadata is loaded.
|
||||
|
||||
## Write safety
|
||||
|
||||
`openclaw config set` and other OpenClaw-owned config writers validate the full post-change config before committing it to disk. If the new payload fails schema validation or looks like a destructive clobber, the active config is left alone and the rejected payload is saved beside it as `openclaw.json.rejected.*`.
|
||||
|
||||
<Warning>
|
||||
The active config path must be a regular file. Symlinked `openclaw.json` layouts are unsupported for writes; use `OPENCLAW_CONFIG_PATH` to point directly at the real file instead.
|
||||
</Warning>
|
||||
|
||||
Prefer CLI writes for small edits:
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.reload.mode hybrid --dry-run
|
||||
openclaw config set gateway.reload.mode hybrid
|
||||
openclaw config validate
|
||||
```
|
||||
|
||||
If a write is rejected, inspect the saved payload and fix the full config shape:
|
||||
|
||||
```bash
|
||||
CONFIG="$(openclaw config file)"
|
||||
ls -lt "$CONFIG".rejected.* 2>/dev/null | head
|
||||
openclaw config validate
|
||||
```
|
||||
|
||||
Direct editor writes are still allowed, but the running Gateway treats them as untrusted until they validate. Invalid direct edits fail startup or are skipped by hot reload; Gateway does not rewrite `openclaw.json`. Run `openclaw doctor --fix` to repair prefixed/clobbered config or restore the last-known-good copy. See [Gateway troubleshooting](/gateway/troubleshooting#gateway-rejected-invalid-config).
|
||||
|
||||
Whole-file recovery is reserved for doctor repair. Plugin schema changes or `minHostVersion` skew stay loud instead of rolling back unrelated user settings such as models, providers, auth profiles, channels, gateway exposure, tools, memory, browser, or cron config.
|
||||
|
||||
## Repair loop
|
||||
|
||||
After `openclaw config validate` passes, use the local TUI to have an embedded agent compare the active config against the docs while you validate each change from the same terminal:
|
||||
|
||||
```bash
|
||||
openclaw chat
|
||||
```
|
||||
|
||||
Inside the TUI, a leading `!` runs a literal local shell command (after a one-time per-session confirmation prompt):
|
||||
|
||||
```text
|
||||
!openclaw config file
|
||||
!openclaw docs gateway auth token secretref
|
||||
!openclaw config validate
|
||||
!openclaw doctor
|
||||
```
|
||||
|
||||
<Steps>
|
||||
<Step title="Compare with docs">
|
||||
Ask the agent to compare your current config with the relevant docs page and suggest the smallest fix.
|
||||
</Step>
|
||||
<Step title="Apply targeted edits">
|
||||
Apply targeted edits with `openclaw config set` or `openclaw configure`.
|
||||
</Step>
|
||||
<Step title="Re-validate">
|
||||
Rerun `openclaw config validate` after each change.
|
||||
</Step>
|
||||
<Step title="Doctor for runtime issues">
|
||||
If validation passes but the runtime is still unhealthy, run `openclaw doctor` or `openclaw doctor --fix` for migration and repair help.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Configuration](/gateway/configuration)
|
||||
65
docs/cli/configure.md
Normal file
65
docs/cli/configure.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw configure` (interactive configuration prompts)"
|
||||
read_when:
|
||||
- You want to tweak credentials, devices, or agent defaults interactively
|
||||
title: "Configure"
|
||||
---
|
||||
|
||||
# `openclaw configure`
|
||||
|
||||
Interactive prompts for targeted changes to an existing setup: credentials, devices, agent defaults, gateway, channels, plugins, skills, and health checks.
|
||||
|
||||
Use `openclaw onboard` or `openclaw setup` for the full guided first-run journey, `openclaw setup --baseline` for the baseline config/workspace only, and `openclaw channels add` when you only need channel account setup.
|
||||
|
||||
<Tip>
|
||||
`openclaw config` with no subcommand opens the same wizard. Use `openclaw config get|set|unset` for non-interactive edits.
|
||||
</Tip>
|
||||
|
||||
## Options
|
||||
|
||||
`--section <section>`: repeatable section filter. Available sections:
|
||||
|
||||
`workspace`, `model`, `web`, `gateway`, `daemon`, `channels`, `plugins`, `skills`, `health`
|
||||
|
||||
```bash
|
||||
openclaw configure
|
||||
openclaw configure --section web
|
||||
openclaw configure --section model --section channels
|
||||
openclaw configure --section gateway --section daemon
|
||||
```
|
||||
|
||||
Selecting `gateway`, `daemon`, or `health` (or running the full wizard with no `--section`) prompts where the Gateway runs and updates `gateway.mode`. Section filters that skip all three go straight to the requested setup with no gateway-mode prompt. Picking remote gateway mode writes the remote config and exits immediately; it does not run local-only steps like plugin installs.
|
||||
|
||||
<Note>
|
||||
`openclaw configure` requires an interactive terminal (both stdin and stdout must be TTYs). Without one it prints the equivalent non-interactive `openclaw config get|set|patch|validate` commands and exits with an error instead of partially running.
|
||||
</Note>
|
||||
|
||||
## Model section
|
||||
|
||||
<Note>
|
||||
**Model** includes a multi-select for the `agents.defaults.models` allowlist (what shows up in `/model` and the model picker). Provider-scoped setup choices merge their selected models into the existing allowlist instead of replacing unrelated providers already in the config.
|
||||
|
||||
Re-running provider auth from configure preserves an existing `agents.defaults.model.primary`, even when the provider's auth step returns a config patch with its own recommended default model. Adding or reauthing a provider makes its models available without taking over your current primary model. Use `openclaw models auth login --provider <id> --set-default` or `openclaw models set <model>` to intentionally change the default model.
|
||||
</Note>
|
||||
|
||||
When configure starts from a provider auth choice, the default-model and allowlist pickers prefer that provider automatically. For paired providers such as Volcengine and BytePlus, the same preference also matches their coding-plan variants (`volcengine-plan/*`, `byteplus-plan/*`). If the preferred-provider filter would produce an empty list, configure falls back to the unfiltered catalog instead of showing a blank picker.
|
||||
|
||||
## Web section
|
||||
|
||||
`openclaw configure --section web` picks a web-search provider and configures its credentials. Some providers show provider-specific follow-ups:
|
||||
|
||||
- **Grok** can offer optional `x_search` setup with the same xAI OAuth profile or API key, and let you pick an `x_search` model.
|
||||
- **Kimi** can ask for the Moonshot API region (`api.moonshot.ai` vs `api.moonshot.cn`) and the default Kimi web-search model.
|
||||
|
||||
## Other notes
|
||||
|
||||
- After local config writes, configure installs selected downloadable plugins when the chosen setup path requires them. Remote gateway config does not install local plugin packages.
|
||||
- Channel-oriented services (Slack/Discord/Matrix/Microsoft Teams) prompt for channel/room allowlists during setup. You can enter names or IDs; the wizard resolves names to IDs when possible.
|
||||
- If you run the daemon install step, token auth requires a token. If `gateway.auth.token` is SecretRef-managed, configure validates the SecretRef but does not persist resolved plaintext token values into supervisor service environment metadata; if the SecretRef is unresolved, configure blocks daemon install with actionable remediation guidance.
|
||||
- If both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, configure blocks daemon install until you set the mode explicitly.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Configuration](/gateway/configuration)
|
||||
- Config CLI: [Config](/cli/config)
|
||||
268
docs/cli/crestodian.md
Normal file
268
docs/cli/crestodian.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
summary: "CLI reference and security model for Crestodian, the configless-safe setup and repair helper"
|
||||
read_when:
|
||||
- You run openclaw with no command after setup and want to understand Crestodian
|
||||
- You need a configless-safe way to inspect or repair OpenClaw
|
||||
- You are designing or enabling message-channel rescue mode
|
||||
title: "Crestodian"
|
||||
---
|
||||
|
||||
# `openclaw crestodian`
|
||||
|
||||
Crestodian is OpenClaw's local setup, repair, and configuration helper. It stays reachable when the normal agent path is broken: it can run when `openclaw.json` is missing or invalid, the Gateway is down, plugin command registration is unavailable, or no agent is configured yet.
|
||||
|
||||
## When it starts
|
||||
|
||||
Running `openclaw` with no subcommand routes based on config state:
|
||||
|
||||
- Config missing, or exists with no authored settings (empty, or only `$schema`/`meta` keys): starts classic onboarding.
|
||||
- Config exists but fails validation: starts Crestodian.
|
||||
- Config exists and is valid: opens the normal agent TUI (against a reachable configured Gateway, or locally if none is reachable). Use `/crestodian` inside the TUI, or run `openclaw crestodian` directly, to reach Crestodian.
|
||||
|
||||
Running `openclaw crestodian` always starts Crestodian explicitly, regardless of config state. `openclaw --help` and `openclaw --version` keep their normal fast paths.
|
||||
|
||||
Noninteractive bare `openclaw` (no TTY) exits with a short message instead of printing root help: it points to non-interactive onboarding on a fresh install, to `openclaw crestodian --message "status"` when config is invalid, or to `openclaw agent --local ...` when config is valid.
|
||||
|
||||
`openclaw onboard --modern` starts Crestodian as the modern onboarding preview. Plain `openclaw onboard` keeps classic onboarding.
|
||||
|
||||
## What Crestodian shows
|
||||
|
||||
Interactive Crestodian opens the same TUI shell as `openclaw tui`, with a Crestodian chat backend. The startup greeting covers:
|
||||
|
||||
- config validity and the default agent
|
||||
- the model or deterministic planner path Crestodian is using
|
||||
- Gateway reachability from the first startup probe
|
||||
- the next recommended debug action
|
||||
|
||||
It does not dump secrets or load plugin CLI commands just to start.
|
||||
|
||||
Use `status` for the detailed inventory: config path, docs/source paths, local CLI probes, API-key presence, agents, model, and Gateway details.
|
||||
|
||||
Crestodian uses the same reference discovery as regular agents: in a Git checkout it points at local `docs/` and the source tree; in an npm install it uses bundled docs and links to [https://github.com/openclaw/openclaw](https://github.com/openclaw/openclaw), with guidance to check source when docs are not enough.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw
|
||||
openclaw crestodian
|
||||
openclaw crestodian --json
|
||||
openclaw crestodian --message "models"
|
||||
openclaw crestodian --message "validate config"
|
||||
openclaw crestodian --message "setup workspace ~/Projects/work model openai/gpt-5.5" --yes
|
||||
openclaw crestodian --message "set default model openai/gpt-5.5" --yes
|
||||
openclaw onboard --modern
|
||||
```
|
||||
|
||||
Inside the Crestodian TUI:
|
||||
|
||||
```text
|
||||
status
|
||||
health
|
||||
doctor
|
||||
doctor fix
|
||||
validate config
|
||||
setup
|
||||
setup workspace ~/Projects/work model openai/gpt-5.5
|
||||
config set gateway.port 19001
|
||||
config set-ref gateway.auth.token env OPENCLAW_GATEWAY_TOKEN
|
||||
gateway status
|
||||
restart gateway
|
||||
agents
|
||||
create agent work workspace ~/Projects/work
|
||||
models
|
||||
set default model openai/gpt-5.5
|
||||
plugins list
|
||||
plugins search slack
|
||||
plugin install clawhub:openclaw-codex-app-server
|
||||
plugin uninstall openclaw-codex-app-server
|
||||
talk to work agent
|
||||
talk to agent for ~/Projects/work
|
||||
audit
|
||||
quit
|
||||
```
|
||||
|
||||
## Operations and approval
|
||||
|
||||
Crestodian uses typed operations instead of editing config ad hoc.
|
||||
|
||||
Read-only, run immediately: show overview, list agents, list installed plugins, search ClawHub plugins, show model/backend status, run status/health checks, check Gateway reachability, run doctor without interactive fixes, validate config, show the audit-log path.
|
||||
|
||||
Persistent, require conversational approval (or `--yes` for a direct command): write config, `config set`, `config set-ref`, setup/onboarding bootstrap, change the default model, start/stop/restart the Gateway, create agents, install or uninstall plugins, run doctor repairs that rewrite config or state.
|
||||
|
||||
Applied writes are recorded in `~/.openclaw/audit/crestodian.jsonl`. Discovery is not audited; only applied operations and writes are.
|
||||
|
||||
Channel setup can run as a hosted conversation when the host supports masked
|
||||
input. The local Crestodian TUI does not accept sensitive wizard answers;
|
||||
instead it directs you to `openclaw channels add --channel <channel>`, whose
|
||||
interactive prompts mask credentials.
|
||||
|
||||
## Setup bootstrap
|
||||
|
||||
`setup` is the chat-first onboarding bootstrap. It writes only through typed config operations and asks for approval first.
|
||||
|
||||
```text
|
||||
setup
|
||||
setup workspace ~/Projects/work
|
||||
setup workspace ~/Projects/work model openai/gpt-5.5
|
||||
```
|
||||
|
||||
When no model is configured, setup picks the first usable backend in this order and tells you what it chose:
|
||||
|
||||
1. Existing explicit model, if already configured.
|
||||
2. `OPENAI_API_KEY` -> `openai/gpt-5.5`
|
||||
3. `ANTHROPIC_API_KEY` -> `anthropic/claude-opus-4-8`
|
||||
4. Claude Code CLI -> `claude-cli/claude-opus-4-8`
|
||||
5. Codex -> `openai/gpt-5.5` through the Codex app-server harness
|
||||
|
||||
If none are available, setup still writes the default workspace and leaves the model unset. Install or log into Codex/Claude Code, or expose `OPENAI_API_KEY`/`ANTHROPIC_API_KEY`, then run setup again.
|
||||
|
||||
## Model-assisted planner
|
||||
|
||||
Interactive Crestodian is AI-first. Exact typed commands run instantly and deterministically. Every other message runs through the same embedded agent loop as regular OpenClaw agents, restricted to one ring-zero `crestodian` tool that wraps the typed operations: read actions run freely, mutations require your conversational yes for that exact operation, and every applied write is audited and re-validated. The agent session persists, so the custodian has real multi-turn memory. It first uses the configured OpenClaw model; with no usable model it falls back to a local runtime already present on the machine:
|
||||
|
||||
- Claude Code CLI: `claude-cli/claude-opus-4-8` (agent loop; the ring-zero tool is served over MCP, see the trust model below)
|
||||
- Codex app-server harness: `openai/gpt-5.5` (agent loop with an enforced single-tool allow-list)
|
||||
|
||||
When the agent loop is unavailable, Crestodian degrades to a bounded single-turn planner, and without any model to deterministic typed commands. The planner cannot mutate config directly; it must translate the request into one of Crestodian's typed commands, and normal approval/audit rules apply. Crestodian prints the model it used and the interpreted command before running anything. Fallback planner turns are temporary, tool-disabled where the runtime supports it, and use a temporary workspace/session.
|
||||
|
||||
Message-channel rescue mode never uses the model-assisted planner. Remote rescue stays deterministic so a broken or compromised normal agent path cannot be used as a config editor.
|
||||
|
||||
### CLI harness trust model
|
||||
|
||||
Embedded runtimes and the Codex app-server harness enforce the ring-zero
|
||||
restriction directly: the run carries a tool allow-list with only the
|
||||
`crestodian` tool. CLI harnesses (Claude Code, Gemini CLI) cannot enforce an
|
||||
OpenClaw tool allow-list — the CLI owns its native tools and its own permission
|
||||
policy, so OpenClaw fails closed if asked to restrict one. For CLI-harness
|
||||
models Crestodian instead:
|
||||
|
||||
- injects a dedicated MCP server that serves only the `crestodian` tool and
|
||||
replaces OpenClaw's normal MCP tool surface for the run (for Claude Code the
|
||||
generated config is applied with `--strict-mcp-config`, so no other MCP
|
||||
servers are loaded),
|
||||
- keeps every config mutation inside the tool's approval and audit contract —
|
||||
reads run freely, writes require your conversational yes, and every applied
|
||||
write is audited and re-validated,
|
||||
- leaves native tools (file reads, shell) to the harness. They follow the same
|
||||
permission posture as normal OpenClaw agent runs on this machine: with
|
||||
OpenClaw's default exec settings Claude Code runs with permissions bypassed,
|
||||
and a restricted `tools.exec` config falls back to the CLI's own permission
|
||||
policy.
|
||||
|
||||
Only Crestodian sessions get the crestodian MCP server; normal agent runs
|
||||
never see this tool. Treat a Crestodian session on a CLI-harness model like a
|
||||
normal local agent run on the same host: the ring-zero tool adds an audited,
|
||||
approval-gated path for config repair, but it does not prevent the harness's
|
||||
native tools from touching files directly. The Codex app-server fallback and
|
||||
API-key models enforce the strict single-tool loop; prefer those when you want
|
||||
the hard restriction.
|
||||
|
||||
## Switching to an agent
|
||||
|
||||
Use a natural-language selector to leave Crestodian and open the normal TUI:
|
||||
|
||||
```text
|
||||
talk to agent
|
||||
talk to work agent
|
||||
switch to main agent
|
||||
```
|
||||
|
||||
`openclaw tui`, `openclaw chat`, and `openclaw terminal` open the normal agent TUI directly; they do not start Crestodian. After switching into the normal TUI, `/crestodian` returns to Crestodian, optionally with a follow-up request:
|
||||
|
||||
```text
|
||||
/crestodian
|
||||
/crestodian restart gateway
|
||||
```
|
||||
|
||||
## Message rescue mode
|
||||
|
||||
Message rescue mode is the message-channel entrypoint for Crestodian: use it when your normal agent is dead but a trusted channel (for example WhatsApp) still receives commands.
|
||||
|
||||
Supported command: `/crestodian <request>`.
|
||||
|
||||
```text
|
||||
You, in a trusted owner DM: /crestodian status
|
||||
OpenClaw: Crestodian rescue mode. Gateway reachable: no. Config valid: no.
|
||||
You: /crestodian restart gateway
|
||||
OpenClaw: Plan: restart the Gateway. Reply /crestodian yes to apply.
|
||||
You: /crestodian yes
|
||||
OpenClaw: Applied. Audit entry written.
|
||||
```
|
||||
|
||||
Agent creation can also be queued locally or via rescue:
|
||||
|
||||
```text
|
||||
create agent work workspace ~/Projects/work model openai/gpt-5.5
|
||||
/crestodian create agent work workspace ~/Projects/work
|
||||
```
|
||||
|
||||
Remote rescue is an admin surface and must be treated like remote config repair, not normal chat.
|
||||
|
||||
Security contract for remote rescue:
|
||||
|
||||
- Disabled when sandboxing is active for the agent/session; Crestodian refuses remote rescue and points to local CLI repair.
|
||||
- Default effective state is `auto`: allow remote rescue only in trusted YOLO operation, where the runtime already has unsandboxed local authority (`tools.exec.security` resolves to `full` and `tools.exec.ask` resolves to `off`, with sandbox mode `off`).
|
||||
- Requires an explicit owner identity; no wildcard sender rules, open group policy, unauthenticated webhooks, or anonymous channels.
|
||||
- Owner DMs only by default; group/channel rescue needs explicit opt-in.
|
||||
- Plugin search and list are read-only. Plugin install is always local-only (blocked in rescue, even when otherwise enabled) because it downloads executable code. Plugin uninstall can be approved as a persistent rescue operation.
|
||||
- Remote rescue cannot open the local TUI or switch into an interactive agent session; use local `openclaw` for agent handoff.
|
||||
- Persistent writes still require approval, even in rescue mode.
|
||||
- Every applied rescue operation is audited. Message-channel rescue records channel, account, sender, and source-address metadata; config-mutating operations also record config hashes before and after.
|
||||
- Secrets are never echoed. SecretRef inspection reports availability, not values.
|
||||
- If the Gateway is alive, rescue prefers Gateway typed operations; if it is dead, rescue uses only the minimal local repair surface that does not depend on the normal agent loop.
|
||||
|
||||
Config shape:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"crestodian": {
|
||||
"rescue": {
|
||||
"enabled": "auto",
|
||||
"ownerDmOnly": true,
|
||||
"pendingTtlMinutes": 15,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`: `"auto"` (default) allows rescue only when the effective runtime is YOLO and sandboxing is off; `false` never allows message-channel rescue; `true` explicitly allows rescue when owner/channel checks pass (still subject to the sandboxing denial).
|
||||
- `ownerDmOnly`: restrict rescue to owner direct messages. Default `true`.
|
||||
- `pendingTtlMinutes`: how long a pending rescue write stays open for `/crestodian yes` approval before expiring. Default `15`.
|
||||
|
||||
Remote rescue is covered by the Docker lane:
|
||||
|
||||
```bash
|
||||
pnpm test:docker:crestodian-rescue
|
||||
```
|
||||
|
||||
Configless local planner fallback is covered by:
|
||||
|
||||
```bash
|
||||
pnpm test:docker:crestodian-planner
|
||||
```
|
||||
|
||||
An opt-in live channel command-surface smoke checks `/crestodian status` plus a persistent approval roundtrip through the rescue handler:
|
||||
|
||||
```bash
|
||||
pnpm test:live:crestodian-rescue-channel
|
||||
```
|
||||
|
||||
Configless setup through explicit Crestodian commands is covered by:
|
||||
|
||||
```bash
|
||||
pnpm test:docker:crestodian-first-run
|
||||
```
|
||||
|
||||
That lane starts with an empty state dir, verifies the modern onboard Crestodian entrypoint, sets the default model, creates an additional agent, configures Discord through a plugin enablement plus token SecretRef, validates config, and checks the audit log. QA Lab has a repo-backed scenario for the same Ring 0 flow:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa suite --scenario crestodian-ring-zero-setup
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Doctor](/cli/doctor)
|
||||
- [TUI](/cli/tui)
|
||||
- [Sandbox](/cli/sandbox)
|
||||
- [Security](/cli/security)
|
||||
333
docs/cli/cron.md
Normal file
333
docs/cli/cron.md
Normal file
@@ -0,0 +1,333 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw cron` (schedule and run background jobs)"
|
||||
read_when:
|
||||
- You want scheduled jobs and wakeups
|
||||
- You are debugging cron execution and logs
|
||||
title: "Cron"
|
||||
---
|
||||
|
||||
# `openclaw cron`
|
||||
|
||||
Manage cron jobs for the Gateway scheduler.
|
||||
|
||||
<Tip>
|
||||
Run `openclaw cron --help` for the full command surface. See [Cron jobs](/automation/cron-jobs) for the conceptual guide.
|
||||
</Tip>
|
||||
|
||||
<Note>
|
||||
All cron mutations (`add`/`create`, `update`/`edit`, `remove`, `run`) require `operator.admin`. Command-payload runs execute directly in the Gateway process, not as an agent `tools.exec` tool call; `tools.exec.*` and exec approvals still govern model-visible exec tools.
|
||||
</Note>
|
||||
|
||||
## Create jobs quickly
|
||||
|
||||
`openclaw cron create` is an alias for `openclaw cron add`. For new jobs, put the schedule first and the prompt second:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 7 * * *" \
|
||||
"Summarize overnight updates." \
|
||||
--name "Morning brief" \
|
||||
--agent ops
|
||||
```
|
||||
|
||||
Use `--webhook <url>` when the job should POST the finished payload instead of delivering to a chat target:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 18 * * 1-5" \
|
||||
"Summarize today's deploys as JSON." \
|
||||
--name "Deploy digest" \
|
||||
--webhook "https://example.invalid/openclaw/cron"
|
||||
```
|
||||
|
||||
Use `--command` for deterministic shell-style jobs that run inside OpenClaw cron without starting an isolated agent/model run:
|
||||
|
||||
```bash
|
||||
openclaw cron create "*/15 * * * *" \
|
||||
--name "Queue depth probe" \
|
||||
--command "scripts/check-queue.sh" \
|
||||
--command-cwd "/srv/app" \
|
||||
--announce \
|
||||
--channel telegram \
|
||||
--to "-1001234567890"
|
||||
```
|
||||
|
||||
`--command <shell>` stores `argv: ["sh", "-lc", <shell>]`. Use `--command-argv '["node","scripts/report.mjs"]'` for exact argv execution. Command jobs capture stdout/stderr, record normal cron history, and route output through the same `announce`, `webhook`, or `none` delivery modes as isolated jobs. A command that prints only `NO_REPLY` is suppressed.
|
||||
|
||||
## Sessions
|
||||
|
||||
`--session` accepts `main`, `isolated`, `current`, or `session:<id>`.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Session keys">
|
||||
- `main` binds to the agent's main session.
|
||||
- `isolated` creates a fresh transcript and session id for each run.
|
||||
- `current` binds to the active session at creation time.
|
||||
- `session:<id>` pins to an explicit persistent session key.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Isolated session semantics">
|
||||
Isolated runs reset ambient conversation context. Channel and group routing, send/queue policy, elevation, origin, and ACP runtime binding are reset for the new run. Safe preferences and explicit user-selected model or auth overrides can carry across runs.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Delivery
|
||||
|
||||
`openclaw cron list` and `openclaw cron show <job-id>` preview the resolved delivery route. For `channel: "last"`, the preview shows whether the route resolved from the main or current session, or will fail closed.
|
||||
|
||||
Provider-prefixed targets can disambiguate unresolved announce channels. For example, `to: "telegram:123"` selects Telegram when `delivery.channel` is omitted or `last`. Only prefixes advertised by the loaded plugin are provider selectors. If `delivery.channel` is explicit, the prefix must match that channel; `channel: "whatsapp"` with `to: "telegram:123"` is rejected. Service prefixes such as `imessage:` and `sms:` remain channel-owned target syntax.
|
||||
|
||||
<Note>
|
||||
Isolated `cron add` jobs default to `--announce` delivery. Use `--no-deliver` to keep output internal. `--deliver` remains as a deprecated alias for `--announce`.
|
||||
</Note>
|
||||
|
||||
### Delivery ownership
|
||||
|
||||
Isolated cron chat delivery is shared between the agent and the runner:
|
||||
|
||||
- The agent can send directly using the `message` tool when a chat route is available.
|
||||
- `announce` fallback-delivers the final reply only when the agent did not send directly to the resolved target.
|
||||
- `webhook` posts the finished payload to a URL.
|
||||
- `none` disables runner fallback delivery.
|
||||
|
||||
Use `cron add|create --webhook <url>` or `cron edit <job-id> --webhook <url>` to set webhook delivery. Do not combine `--webhook` with chat delivery flags such as `--announce`, `--no-deliver`, `--channel`, `--to`, `--thread-id`, or `--account`.
|
||||
|
||||
`cron edit <job-id>` can unset individual delivery routing fields with `--clear-channel`, `--clear-to`, `--clear-thread-id`, and `--clear-account` (each is rejected when combined with its matching set flag). Unlike `--no-deliver`, which only disables runner fallback delivery, these remove the stored field so the job resolves that part of its route from defaults again.
|
||||
|
||||
`--announce` is runner fallback delivery for the final reply. `--no-deliver` disables that fallback but does not remove the agent's `message` tool when a chat route is available.
|
||||
|
||||
Reminders created from an active chat preserve the live chat delivery target for fallback announce delivery. Internal session keys may be lowercase; do not use them as a source of truth for case-sensitive provider IDs such as Matrix room IDs.
|
||||
|
||||
### Failure delivery
|
||||
|
||||
Failure notifications resolve in this order:
|
||||
|
||||
1. `delivery.failureDestination` on the job.
|
||||
2. Global `cron.failureDestination`.
|
||||
3. The job's primary announce target (when neither of the above resolves to a concrete destination).
|
||||
|
||||
<Note>
|
||||
Main-session jobs may only use `delivery.failureDestination` when primary delivery mode is `webhook`. Isolated jobs accept it in all modes.
|
||||
</Note>
|
||||
|
||||
Isolated cron runs treat run-level agent failures as job errors even when no reply payload is produced, so model/provider failures still increment error counters and trigger failure notifications.
|
||||
|
||||
Command cron jobs do not start an isolated agent turn. A zero exit code records `ok`; non-zero exit, signal, timeout, or no-output timeout records `error` and can trigger the same failure notification path.
|
||||
|
||||
If an isolated run times out before the first model request, `openclaw cron show` and `openclaw cron runs` include a phase-specific error such as `setup timed out before runner start` or a stall message naming the last-known startup phase (for example `context-engine`). For CLI-backed providers, the pre-model watchdog stays active until the external CLI turn starts, so session lookup, hook, auth, prompt, and CLI setup stalls are reported as pre-model cron failures.
|
||||
|
||||
## Scheduling
|
||||
|
||||
### One-shot jobs
|
||||
|
||||
`--at <datetime>` schedules a one-shot run. Offset-less datetimes are treated as UTC unless you also pass `--tz <iana>`, which interprets the wall-clock time in the given timezone.
|
||||
|
||||
<Note>
|
||||
One-shot jobs delete after success by default. Use `--keep-after-run` to preserve them.
|
||||
</Note>
|
||||
|
||||
### Recurring jobs
|
||||
|
||||
Recurring jobs use exponential retry backoff after consecutive errors: 30s, 1m, 5m, 15m, 60m. The schedule returns to normal after the next successful run.
|
||||
|
||||
Skipped runs are tracked separately from execution errors. They do not affect retry backoff, but `openclaw cron edit <job-id> --failure-alert-include-skipped` can opt failure alerts into repeated skipped-run notifications.
|
||||
|
||||
For isolated jobs that target a local configured model provider (base URL on loopback, a private network, or `.local`), cron runs a lightweight provider preflight before starting the agent turn: `api: "ollama"` providers are probed at `/api/tags`; other local OpenAI-compatible providers (`api: "openai-completions"`, e.g. vLLM, SGLang, LM Studio) are probed at `/models`. If the endpoint is unreachable, the run is recorded as `skipped` and retried on a later schedule; the reachability result is cached per endpoint for 5 minutes so many jobs against the same local server do not hammer it with repeated probes.
|
||||
|
||||
Cron jobs, pending runtime state, and run history live in the shared SQLite state database. Legacy `jobs.json`, `<name>-state.json`, and `runs/*.jsonl` files are imported once and renamed with a `.migrated` suffix. After import, edit schedules with `openclaw cron add|edit|remove` instead of editing JSON files.
|
||||
|
||||
### Manual runs
|
||||
|
||||
`openclaw cron run <job-id>` force-runs by default and returns as soon as the manual run is queued. Successful responses include `{ ok: true, enqueued: true, runId }`. Use the returned `runId` to inspect the later result:
|
||||
|
||||
```bash
|
||||
openclaw cron run <job-id>
|
||||
openclaw cron runs --id <job-id> --run-id <run-id>
|
||||
```
|
||||
|
||||
Add `--wait` when a script should block until that exact queued run records a terminal status:
|
||||
|
||||
```bash
|
||||
openclaw cron run <job-id> --wait --wait-timeout 10m --poll-interval 2s
|
||||
```
|
||||
|
||||
With `--wait`, the CLI still calls `cron.run` first, then polls `cron.runs` for the returned `runId`. The command exits `0` only when the run finishes with status `ok`. It exits non-zero when the run finishes with `error` or `skipped`, when the Gateway response does not include a `runId`, or when `--wait-timeout` expires (default `10m`, polled every `2s` by default). `--poll-interval` must be greater than zero.
|
||||
|
||||
<Note>
|
||||
Use `--due` when you want the manual command to run only if the job is currently due. If `--due --wait` does not enqueue a run, the command returns the normal non-run response instead of polling.
|
||||
</Note>
|
||||
|
||||
## Models
|
||||
|
||||
`cron add|edit --model <ref>` selects an allowed model for the job. `cron add|edit --fallbacks <list>` sets per-job fallback models, for example `--fallbacks openrouter/gpt-4.1-mini,openai/gpt-5`; pass `--fallbacks ""` for a strict run with no fallbacks. `cron edit <job-id> --clear-fallbacks` removes the per-job fallback override. `cron edit <job-id> --clear-model` removes the per-job model override so the job follows normal cron model-selection precedence (a stored cron-session override if present, otherwise the agent/default model); it cannot be combined with `--model`. `cron add|edit --thinking <level>` sets a per-job thinking override; `cron edit <job-id> --clear-thinking` removes it so the job follows normal cron thinking precedence, and it cannot be combined with `--thinking`.
|
||||
|
||||
<Warning>
|
||||
If the model is not allowed or cannot be resolved, cron fails the run with an explicit validation error instead of falling back to the job's agent or default model selection.
|
||||
</Warning>
|
||||
|
||||
Cron `--model` is a **job primary**, not a chat-session `/model` override. That means:
|
||||
|
||||
- Configured model fallbacks still apply when the selected job model fails.
|
||||
- Per-job payload `fallbacks` replaces the configured fallback list when present.
|
||||
- An empty per-job fallback list (`--fallbacks ""` or `fallbacks: []` in the job payload/API) makes the cron run strict.
|
||||
- When a job has `--model` but no fallback list is configured, OpenClaw passes an explicit empty fallback override so the agent primary is not appended as a hidden retry target.
|
||||
- Local-provider preflight checks walk configured fallbacks before marking a cron run `skipped`.
|
||||
|
||||
`openclaw doctor` reports jobs that already have `payload.model` set, including provider namespace counts and mismatches against `agents.defaults.model`. Use that check when auth, provider, or billing behavior looks different between live chat and scheduled jobs.
|
||||
|
||||
### Isolated cron model precedence
|
||||
|
||||
Isolated cron resolves the active model in this order:
|
||||
|
||||
1. Gmail-hook override.
|
||||
2. Per-job `--model`.
|
||||
3. Stored cron-session model override (when the user selected one).
|
||||
4. Agent or default model selection.
|
||||
|
||||
### Fast mode
|
||||
|
||||
Isolated cron fast mode follows the resolved live model selection. Model config `params.fastMode` applies by default, but a stored session `fastMode` override still wins over config. When the resolved mode is `auto`, the cutoff uses the selected model's `params.fastAutoOnSeconds` value, defaulting to 60 seconds.
|
||||
|
||||
### Live model switch retries
|
||||
|
||||
If an isolated run throws `LiveSessionModelSwitchError`, cron persists the switched provider and model (and switched auth profile override when present) for the active run before retrying. The outer retry loop is bounded to two switch retries after the initial attempt, then aborts instead of looping forever.
|
||||
|
||||
## Run output and denials
|
||||
|
||||
### Stale acknowledgement suppression
|
||||
|
||||
Isolated cron turns suppress stale acknowledgement-only replies. If the first result is just an interim status update and no descendant subagent run is responsible for the eventual answer, cron re-prompts once for the real result before delivery.
|
||||
|
||||
### Silent token suppression
|
||||
|
||||
If an isolated cron run returns only the silent token (`NO_REPLY` or `no_reply`), cron suppresses both direct outbound delivery and the fallback queued summary path, so nothing is posted back to chat.
|
||||
|
||||
### Structured denials
|
||||
|
||||
Isolated cron runs use structured execution-denial metadata from the embedded run (fatal exec-tool errors coded `SYSTEM_RUN_DENIED` or `INVALID_REQUEST`) as the authoritative denial signal. They also honor node-host `UNAVAILABLE` wrappers around a nested structured error carrying one of those codes.
|
||||
|
||||
Cron does not classify final-output prose or approval-looking refusal phrases as denials unless the embedded run also provides structured denial metadata, so ordinary assistant text is not treated as a blocked command.
|
||||
|
||||
`cron list` and run history surface the denial reason instead of reporting a blocked command as `ok`.
|
||||
|
||||
## Retention
|
||||
|
||||
Retention and pruning are controlled in config:
|
||||
|
||||
- `cron.sessionRetention` (default `24h`, or `false` to disable) prunes completed isolated run sessions.
|
||||
- `cron.runLog.keepLines` (default `2000`) prunes retained SQLite run-history rows per job. `cron.runLog.maxBytes` (default `2000000`) remains accepted for compatibility with older file-backed run logs; SQLite pruning is row-count based.
|
||||
|
||||
## Migrating older jobs
|
||||
|
||||
<Note>
|
||||
If you have cron jobs from before the current delivery and store format, run `openclaw doctor --fix`. Doctor normalizes legacy cron fields (`jobId`, `schedule.cron`, top-level delivery fields including legacy `threadId`, payload `provider` delivery aliases) and migrates `notify: true` webhook fallback jobs from `cron.webhook` to explicit webhook delivery. Jobs that already announce to a chat keep that delivery and get a completion webhook destination. When `cron.webhook` is unset, the inert top-level `notify` marker is removed for jobs with no migration target (the existing delivery is preserved unchanged), so `doctor --fix` no longer keeps re-warning about them.
|
||||
</Note>
|
||||
|
||||
## Common edits
|
||||
|
||||
Update delivery settings without changing the message:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel telegram --to "123456789"
|
||||
```
|
||||
|
||||
Disable delivery for an isolated job:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --no-deliver
|
||||
```
|
||||
|
||||
Enable lightweight bootstrap context for an isolated job:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --light-context
|
||||
```
|
||||
|
||||
Announce to a specific channel:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel slack --to "channel:C1234567890"
|
||||
```
|
||||
|
||||
Announce to a Telegram forum topic:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel telegram --to "-1001234567890" --thread-id 42
|
||||
```
|
||||
|
||||
Create an isolated job with lightweight bootstrap context:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 7 * * *" \
|
||||
"Summarize overnight updates." \
|
||||
--name "Lightweight morning brief" \
|
||||
--session isolated \
|
||||
--light-context \
|
||||
--no-deliver
|
||||
```
|
||||
|
||||
`--light-context` applies to isolated agent-turn jobs only. For cron runs, lightweight mode keeps bootstrap context empty instead of injecting the full workspace bootstrap set.
|
||||
|
||||
Create a command job with exact argv, cwd, env, stdin, and output limits:
|
||||
|
||||
```bash
|
||||
openclaw cron create "*/30 * * * *" \
|
||||
--name "Position export" \
|
||||
--command-argv '["node","scripts/export-position.mjs"]' \
|
||||
--command-cwd "/srv/app" \
|
||||
--command-env "NODE_ENV=production" \
|
||||
--command-input '{"mode":"summary"}' \
|
||||
--timeout-seconds 120 \
|
||||
--no-output-timeout-seconds 30 \
|
||||
--output-max-bytes 65536 \
|
||||
--webhook "https://example.invalid/openclaw/cron"
|
||||
```
|
||||
|
||||
## Common admin commands
|
||||
|
||||
Manual run and inspection:
|
||||
|
||||
```bash
|
||||
openclaw cron list
|
||||
openclaw cron list --agent ops
|
||||
openclaw cron get <job-id>
|
||||
openclaw cron show <job-id>
|
||||
openclaw cron run <job-id>
|
||||
openclaw cron run <job-id> --due
|
||||
openclaw cron run <job-id> --wait --wait-timeout 10m
|
||||
openclaw cron run <job-id> --wait --wait-timeout 10m --poll-interval 2s
|
||||
openclaw cron runs --id <job-id> --limit 50
|
||||
openclaw cron runs --id <job-id> --run-id <run-id>
|
||||
```
|
||||
|
||||
`openclaw cron list` shows all matching jobs by default. Pass `--agent <id>` to show only jobs whose effective normalized agent id matches; jobs without a stored agent id count as the configured default agent.
|
||||
|
||||
`openclaw cron get <job-id>` returns the stored job JSON directly. Use `cron show <job-id>` when you want the human-readable view with delivery-route preview.
|
||||
|
||||
`cron list --json` and `cron show <job-id> --json` include a top-level `status` field on each job, computed from `enabled`, `state.runningAtMs`, and `state.lastRunStatus`. Values: `disabled`, `running`, `ok`, `error`, `skipped`, or `idle`. This mirrors the human-readable status column so external tooling can read job state without re-deriving it.
|
||||
|
||||
`cron runs` entries include delivery diagnostics with the intended cron target, the resolved target, message-tool sends, fallback use, and delivered state.
|
||||
|
||||
Agent and session retargeting:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --agent ops
|
||||
openclaw cron edit <job-id> --clear-agent
|
||||
openclaw cron edit <job-id> --session current
|
||||
openclaw cron edit <job-id> --session "session:daily-brief"
|
||||
```
|
||||
|
||||
`openclaw cron add` warns when `--agent` is omitted on agent-turn jobs and falls back to the default agent (`main`). Pass `--agent <id>` at create time to pin a specific agent.
|
||||
|
||||
Delivery tweaks:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel slack --to "channel:C1234567890"
|
||||
openclaw cron edit <job-id> --webhook "https://example.invalid/openclaw/cron"
|
||||
openclaw cron edit <job-id> --best-effort-deliver
|
||||
openclaw cron edit <job-id> --no-best-effort-deliver
|
||||
openclaw cron edit <job-id> --no-deliver
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Scheduled tasks](/automation/cron-jobs)
|
||||
54
docs/cli/daemon.md
Normal file
54
docs/cli/daemon.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw daemon` (legacy alias for gateway service management)"
|
||||
read_when:
|
||||
- You still use `openclaw daemon ...` in scripts
|
||||
- You need service lifecycle commands (install/start/stop/restart/status)
|
||||
title: "Daemon"
|
||||
---
|
||||
|
||||
# `openclaw daemon`
|
||||
|
||||
Legacy alias for Gateway service management. `openclaw daemon ...` maps to the same service-control commands as `openclaw gateway ...`. Prefer [`openclaw gateway`](/cli/gateway) for current docs and examples.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw daemon status
|
||||
openclaw daemon install
|
||||
openclaw daemon start
|
||||
openclaw daemon stop
|
||||
openclaw daemon restart
|
||||
openclaw daemon uninstall
|
||||
```
|
||||
|
||||
## Subcommands and options
|
||||
|
||||
| Subcommand | Options |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `status` | `--url`, `--token`, `--password`, `--timeout`, `--no-probe`, `--require-rpc`, `--deep`, `--json` |
|
||||
| `install` | `--port`, `--runtime <node\|bun>`, `--token`, `--wrapper <path>`, `--force`, `--json` |
|
||||
| `uninstall` | `--json` |
|
||||
| `start` | `--json` |
|
||||
| `stop` | `--json`, `--disable` (launchd only: persistently suppress KeepAlive/RunAtLoad until next start) |
|
||||
| `restart` | `--force`, `--safe`, `--skip-deferral`, `--wait <duration>`, `--json` |
|
||||
|
||||
- `status`: shows service install state (launchd/systemd/schtasks) and probes Gateway health.
|
||||
- `install`: installs the service; `--force` reinstalls/overwrites an existing install.
|
||||
- `restart --safe`: asks the running Gateway to preflight active work and schedule one coalesced restart after work drains, bounded by `gateway.reload.deferralTimeoutMs` (default 300000ms/5 minutes; set to `0` to wait indefinitely). When that budget expires, the restart is forced anyway. Plain `restart` uses the service manager directly; `--force` is the immediate override.
|
||||
- `restart --safe --skip-deferral`: bypasses the active-work deferral gate so the Gateway restarts immediately even when blockers are reported. Requires `--safe`.
|
||||
|
||||
## Notes
|
||||
|
||||
- `status` resolves configured auth SecretRefs for probe auth when possible. If a required SecretRef is unresolved, `status --json` reports `rpc.authWarning`; pass `--token`/`--password` explicitly or resolve the secret source first. Unresolved-auth warnings are suppressed once the probe otherwise succeeds.
|
||||
- `status --deep` adds a best-effort system-level scan for other gateway-like services (prints cleanup hints; one Gateway per machine is still the recommendation) and runs config validation in plugin-aware mode, surfacing plugin manifest warnings that the fast default path skips.
|
||||
- On Linux systemd installs, token-drift checks inspect both `Environment=` and `EnvironmentFile=` unit sources.
|
||||
- Token-drift checks resolve `gateway.auth.token` SecretRefs using merged runtime env (service command env first, then process env). If token auth is not effectively active (`gateway.auth.mode` of `password`/`none`/`trusted-proxy`, or unset with password able to win), config token resolution is skipped.
|
||||
- `install` validates a SecretRef-managed `gateway.auth.token` is resolvable but never persists the resolved value into service environment metadata; if it can't resolve, install fails closed.
|
||||
- If both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, `install` blocks until you set the mode explicitly.
|
||||
- On macOS, `install` keeps LaunchAgent plists and the generated env file/wrapper owner-only (mode `0600`/`0700`) instead of embedding secrets in `EnvironmentVariables`.
|
||||
- Running multiple Gateways on one host: isolate ports, config/state, and workspaces. See [Multiple gateways](/gateway#multiple-gateways-same-host).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway runbook](/gateway)
|
||||
33
docs/cli/dashboard.md
Normal file
33
docs/cli/dashboard.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw dashboard` (open the Control UI)"
|
||||
read_when:
|
||||
- You want to open the Control UI with your current token
|
||||
- You want to print the URL without launching a browser
|
||||
title: "Dashboard"
|
||||
---
|
||||
|
||||
# `openclaw dashboard`
|
||||
|
||||
Open the Control UI using your current auth.
|
||||
|
||||
```bash
|
||||
openclaw dashboard
|
||||
openclaw dashboard --no-open
|
||||
openclaw dashboard --yes
|
||||
```
|
||||
|
||||
- `--no-open`: print the URL but do not launch a browser.
|
||||
- `--yes`: start/install the Gateway without prompting when needed.
|
||||
|
||||
Notes:
|
||||
|
||||
- Resolves configured `gateway.auth.token` SecretRefs when possible.
|
||||
- Follows `gateway.tls.enabled`: TLS-enabled gateways print/open `https://` Control UI URLs and connect over `wss://`.
|
||||
- For SecretRef-managed tokens (resolved or unresolved), the printed/copied/opened URL never includes the token, so external secrets do not leak into terminal output, clipboard history, or browser-launch arguments.
|
||||
- If `gateway.auth.token` is SecretRef-managed but unresolved, the command prints a non-tokenized URL and remediation guidance instead of an invalid token placeholder.
|
||||
- If clipboard/browser delivery fails for a token-authenticated URL, the command logs a safe manual-auth hint naming `OPENCLAW_GATEWAY_TOKEN`, `gateway.auth.token`, and the URL fragment key `token`, without printing the token value.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Dashboard](/web/dashboard)
|
||||
193
docs/cli/devices.md
Normal file
193
docs/cli/devices.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw devices` (device pairing + token rotation/revocation)"
|
||||
read_when:
|
||||
- You are approving device pairing requests
|
||||
- You need to rotate or revoke device tokens
|
||||
title: "Devices"
|
||||
---
|
||||
|
||||
# `openclaw devices`
|
||||
|
||||
Manage device pairing requests and device-scoped tokens.
|
||||
|
||||
## Common options
|
||||
|
||||
- `--url <url>`: Gateway WebSocket URL (defaults to `gateway.remote.url` when configured)
|
||||
- `--token <token>`: Gateway token (if required)
|
||||
- `--password <password>`: Gateway password (password auth)
|
||||
- `--timeout <ms>`: RPC timeout
|
||||
- `--json`: JSON output (recommended for scripting)
|
||||
|
||||
<Warning>
|
||||
When you set `--url`, the CLI does not fall back to config or environment credentials. Pass `--token` or `--password` explicitly, or the command errors.
|
||||
</Warning>
|
||||
|
||||
## Commands
|
||||
|
||||
### `openclaw devices list`
|
||||
|
||||
List pending pairing requests and paired devices.
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
openclaw devices list --json
|
||||
```
|
||||
|
||||
For a pending request on an already-paired device, the output shows requested access next to the device's current approved access, so scope/role upgrades are visible instead of looking like a lost pairing.
|
||||
|
||||
### `openclaw devices approve [requestId] [--latest]`
|
||||
|
||||
Approve a pending pairing request by exact `requestId`. Omitting `requestId`, or passing `--latest`, only previews the newest pending request and exits (code 1); rerun with the exact request ID to approve.
|
||||
|
||||
```bash
|
||||
openclaw devices approve
|
||||
openclaw devices approve <requestId>
|
||||
openclaw devices approve --latest
|
||||
```
|
||||
|
||||
<Note>
|
||||
If a device retries pairing with changed auth details (role, scopes, or public key), OpenClaw supersedes the previous pending entry with a new `requestId`. Run `openclaw devices list` right before approval to get the current id.
|
||||
</Note>
|
||||
|
||||
Approval behavior:
|
||||
|
||||
- If the device is already paired and requests broader scopes or role, OpenClaw keeps the existing approval and creates a new pending upgrade request. Compare `Requested` vs `Approved` in `openclaw devices list`, or preview with `--latest`, before approving.
|
||||
- Approving a `node` role or other non-operator role requires `operator.admin`. `operator.pairing` is enough for operator-device approvals, but only when the requested operator scopes stay within the caller's own scopes. See [Operator scopes](/gateway/operator-scopes).
|
||||
- If `gateway.nodes.pairing.autoApproveCidrs` is configured, first-time `role: node` requests from matching client IPs can be auto-approved before they appear in this list. Disabled by default; never applies to operator/browser clients or upgrade requests.
|
||||
|
||||
### `openclaw devices reject <requestId>`
|
||||
|
||||
Reject a pending device pairing request.
|
||||
|
||||
```bash
|
||||
openclaw devices reject <requestId>
|
||||
```
|
||||
|
||||
### `openclaw devices remove <deviceId>`
|
||||
|
||||
Remove one paired device entry.
|
||||
|
||||
```bash
|
||||
openclaw devices remove <deviceId>
|
||||
openclaw devices remove <deviceId> --json
|
||||
```
|
||||
|
||||
A caller authenticated with a paired device token can remove only its **own** device entry. Removing another device requires `operator.admin`.
|
||||
|
||||
### `openclaw devices clear --yes [--pending]`
|
||||
|
||||
Clear paired devices in bulk. Gated by `--yes`.
|
||||
|
||||
```bash
|
||||
openclaw devices clear --yes
|
||||
openclaw devices clear --yes --pending
|
||||
openclaw devices clear --yes --pending --json
|
||||
```
|
||||
|
||||
`--pending` also rejects all pending pairing requests.
|
||||
|
||||
### `openclaw devices rotate --device <id> --role <role> [--scope <scope...>]`
|
||||
|
||||
Rotate a device token for a role, optionally updating its scopes.
|
||||
|
||||
```bash
|
||||
openclaw devices rotate --device <deviceId> --role operator --scope operator.read --scope operator.write
|
||||
```
|
||||
|
||||
- The target role must already exist in that device's approved pairing contract; rotation cannot mint a new unapproved role.
|
||||
- Omitting `--scope` reuses the stored token's cached approved scopes on later reconnects. Passing explicit `--scope` values replaces the stored scope set for future cached-token reconnects.
|
||||
- A non-admin paired-device caller can rotate only its **own** device token, and the target scope set must stay within the caller's own operator scopes; rotation cannot mint or preserve a broader token than the caller already has.
|
||||
|
||||
Returns rotation metadata as JSON. If the caller rotates its own token while authenticated with that device token, the response includes the replacement token so the client can persist it before reconnecting. Shared/admin rotations never echo the bearer token.
|
||||
|
||||
### `openclaw devices revoke --device <id> --role <role>`
|
||||
|
||||
Revoke a device token for a role.
|
||||
|
||||
```bash
|
||||
openclaw devices revoke --device <deviceId> --role node
|
||||
```
|
||||
|
||||
A non-admin paired-device caller can revoke only its **own** device token. Revoking another device's token requires `operator.admin`. The target scope set must also fit within the caller's own operator scopes; pairing-only callers cannot revoke admin/write operator tokens.
|
||||
|
||||
## Notes
|
||||
|
||||
- These commands require `operator.pairing` (or `operator.admin`) scope. Non-operator device roles always require `operator.admin`; see [Operator scopes](/gateway/operator-scopes).
|
||||
- Token rotation and revocation stay inside the device's approved pairing role set and scope baseline. A stray cached token entry does not grant a token-management target.
|
||||
- For paired-device token sessions, cross-device management (`remove`, `rotate`, `revoke`) is self-only unless the caller has `operator.admin`.
|
||||
- Token rotation returns a new token (sensitive) — treat it like a secret.
|
||||
- If pairing scope is unavailable on local loopback and no explicit `--url` is passed, `list`/`approve` can fall back to local pairing state.
|
||||
|
||||
## Token drift recovery checklist
|
||||
|
||||
Use this when Control UI or other clients keep failing with `AUTH_TOKEN_MISMATCH`, `AUTH_DEVICE_TOKEN_MISMATCH`, or `AUTH_SCOPE_MISMATCH`.
|
||||
|
||||
1. Confirm current gateway token source:
|
||||
|
||||
```bash
|
||||
openclaw config get gateway.auth.token
|
||||
```
|
||||
|
||||
2. List paired devices and identify the affected device id:
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
```
|
||||
|
||||
3. Rotate the operator token for the affected device:
|
||||
|
||||
```bash
|
||||
openclaw devices rotate --device <deviceId> --role operator
|
||||
```
|
||||
|
||||
4. If rotation is not enough, remove the stale pairing and approve again:
|
||||
|
||||
```bash
|
||||
openclaw devices remove <deviceId>
|
||||
openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
5. Retry the client connection with the current shared token/password.
|
||||
|
||||
Notes:
|
||||
|
||||
- Normal reconnect auth precedence: explicit shared token/password first, then explicit `deviceToken`, then stored device token, then bootstrap token.
|
||||
- Trusted `AUTH_TOKEN_MISMATCH` recovery can temporarily send both the shared token and the stored device token together for one bounded retry.
|
||||
- `AUTH_SCOPE_MISMATCH` means the device token was recognized but does not carry the requested scope set; fix the pairing/scope approval contract before changing shared gateway auth.
|
||||
|
||||
Related:
|
||||
|
||||
- [Dashboard auth troubleshooting](/web/dashboard#if-you-see-unauthorized-1008)
|
||||
- [Gateway troubleshooting](/gateway/troubleshooting#dashboard-control-ui-connectivity)
|
||||
|
||||
## Paperclip / `openclaw_gateway` first-run approval
|
||||
|
||||
Paperclip agents connecting through the `openclaw_gateway` adapter go through the same first-run device pairing approval as any other new client. If Paperclip reports `openclaw_gateway_pairing_required`, approve the pending device and retry.
|
||||
|
||||
```bash
|
||||
openclaw devices approve --latest
|
||||
```
|
||||
|
||||
The preview prints the exact `openclaw devices approve <requestId>` command; verify the details, then rerun that command with the request ID to approve it. For a remote gateway or explicit credentials, pass the same options while previewing and approving:
|
||||
|
||||
```bash
|
||||
openclaw devices approve --latest --url <gateway-ws-url> --token <gateway-token>
|
||||
```
|
||||
|
||||
To avoid re-approving after every restart, configure a persistent `adapterConfig.devicePrivateKeyPem` in Paperclip instead of letting it generate a new ephemeral device identity each run:
|
||||
|
||||
```json
|
||||
{
|
||||
"adapterConfig": {
|
||||
"devicePrivateKeyPem": "<ed25519-private-key-pkcs8-pem>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If approval keeps failing, run `openclaw devices list` first to confirm a pending request exists.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Nodes](/nodes)
|
||||
73
docs/cli/directory.md
Normal file
73
docs/cli/directory.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw directory` (self, peers, groups)"
|
||||
read_when:
|
||||
- You want to look up contacts/groups/self ids for a channel
|
||||
- You are developing a channel directory adapter
|
||||
title: "Directory"
|
||||
---
|
||||
|
||||
# `openclaw directory`
|
||||
|
||||
Directory lookups for channels that support them: contacts/peers, groups, and "me" (self).
|
||||
|
||||
Results are meant to be pasted into other commands, especially `openclaw message send --target ...`.
|
||||
|
||||
## Common flags
|
||||
|
||||
- `--channel <name>`: channel id/alias (required when multiple channels are configured; auto-selected when only one is configured)
|
||||
- `--account <id>`: account id (default: channel default)
|
||||
- `--json`: output JSON
|
||||
|
||||
Default (non-JSON) output is `id` (and sometimes `name`) separated by a tab.
|
||||
|
||||
## Notes
|
||||
|
||||
- For many channels, results are config-backed (allowlists / configured groups) rather than a live provider directory.
|
||||
- An already-installed channel plugin can lack directory support. In that case the command reports the unsupported operation; it does not try to reinstall or upgrade the plugin to add support.
|
||||
|
||||
## Using results with `message send`
|
||||
|
||||
```bash
|
||||
openclaw directory peers list --channel slack --query "U0"
|
||||
openclaw message send --channel slack --target user:U012ABCDEF --message "hello"
|
||||
```
|
||||
|
||||
## ID formats by channel
|
||||
|
||||
| Channel | Target id format |
|
||||
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| WhatsApp | `+15551234567` (DM), `1234567890-1234567890@g.us` (group), `120363123456789@newsletter` (Channel/Newsletter, outbound only) |
|
||||
| Signal | Configured aliases resolve to E.164/UUID DM targets or `group:<id>` group targets |
|
||||
| Telegram | `@username` or numeric chat id; groups use numeric ids |
|
||||
| Slack | `user:U…` and `channel:C…` |
|
||||
| Discord | `user:<id>` and `channel:<id>` |
|
||||
| Matrix (plugin) | `user:@user:server`, `room:!roomId:server`, or `#alias:server` |
|
||||
| Microsoft Teams (plugin) | `user:<id>` and `conversation:<id>` |
|
||||
| Zalo (plugin) | User id (Bot API) |
|
||||
| Zalo Personal / `zalouser` (plugin) | Thread id (DM/group), from `zca` (`me`, `friend list`, `group list`) |
|
||||
|
||||
## Self ("me")
|
||||
|
||||
```bash
|
||||
openclaw directory self --channel zalouser
|
||||
```
|
||||
|
||||
## Peers (contacts/users)
|
||||
|
||||
```bash
|
||||
openclaw directory peers list --channel zalouser
|
||||
openclaw directory peers list --channel zalouser --query "name"
|
||||
openclaw directory peers list --channel zalouser --limit 50
|
||||
```
|
||||
|
||||
## Groups
|
||||
|
||||
```bash
|
||||
openclaw directory groups list --channel zalouser
|
||||
openclaw directory groups list --channel zalouser --query "work"
|
||||
openclaw directory groups members --channel zalouser --group-id <id>
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
51
docs/cli/dns.md
Normal file
51
docs/cli/dns.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw dns` (wide-area discovery helpers)"
|
||||
read_when:
|
||||
- You want wide-area discovery (DNS-SD) via Tailscale + CoreDNS
|
||||
- You're setting up split DNS for a custom discovery domain (example: openclaw.internal)
|
||||
title: "DNS"
|
||||
---
|
||||
|
||||
# `openclaw dns`
|
||||
|
||||
DNS helpers for wide-area discovery (Tailscale + CoreDNS). Currently macOS + Homebrew CoreDNS only.
|
||||
|
||||
Related:
|
||||
|
||||
- Gateway discovery: [Discovery](/gateway/discovery)
|
||||
- Wide-area discovery config: [Configuration](/gateway/configuration)
|
||||
|
||||
## `dns setup`
|
||||
|
||||
Plan or apply CoreDNS setup for unicast DNS-SD discovery.
|
||||
|
||||
```bash
|
||||
openclaw dns setup
|
||||
openclaw dns setup --domain openclaw.internal
|
||||
openclaw dns setup --apply
|
||||
```
|
||||
|
||||
| Option | Effect |
|
||||
| ------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `--domain <domain>` | Wide-area discovery domain (for example `openclaw.internal`). |
|
||||
| `--apply` | Install/update CoreDNS config and (re)start the service. Requires sudo, macOS only. |
|
||||
|
||||
Without `--domain`, OpenClaw uses `discovery.wideArea.domain` from config.
|
||||
|
||||
Without `--apply`, the command only prints:
|
||||
|
||||
- Resolved discovery domain and zone file path
|
||||
- Current tailnet IPs
|
||||
- Recommended `openclaw.json` discovery config
|
||||
- Tailscale Split DNS nameserver/domain values to set in the Tailscale admin console
|
||||
|
||||
With `--apply` (macOS only, requires Homebrew CoreDNS):
|
||||
|
||||
- Bootstraps the zone file if missing
|
||||
- Adds the CoreDNS import stanza if missing
|
||||
- Restarts the `coredns` brew service
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Discovery](/gateway/discovery)
|
||||
61
docs/cli/docs.md
Normal file
61
docs/cli/docs.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw docs` (search the live docs index)"
|
||||
read_when:
|
||||
- You want to search the live OpenClaw docs from the terminal
|
||||
- You need to know which hosted search API the docs CLI calls
|
||||
title: "Docs"
|
||||
---
|
||||
|
||||
# `openclaw docs`
|
||||
|
||||
Search the live OpenClaw docs index from the terminal.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw docs # print docs entrypoint and example search
|
||||
openclaw docs <query...> # search the live docs index
|
||||
```
|
||||
|
||||
| Argument | Description |
|
||||
| ------------ | ---------------------------------------------------------------------------------- |
|
||||
| `[query...]` | Free-form search query. Multi-word queries are joined with spaces and sent as one. |
|
||||
|
||||
With no query, `openclaw docs` prints the docs entrypoint URL and a sample search command instead of running a search.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw docs browser existing-session
|
||||
openclaw docs sandbox allowHostControl
|
||||
openclaw docs gateway token secretref
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
`openclaw docs` calls `https://docs.openclaw.ai/api/search` and renders the JSON results. The search request uses a fixed 30 second timeout.
|
||||
|
||||
## Output
|
||||
|
||||
In a rich (TTY) terminal, results render as a heading followed by a bullet list: page title, linked docs URL, and a short snippet on the next line. Empty results print "No results.".
|
||||
|
||||
In non-rich output (piped, `--no-color`, scripts), the same data renders as Markdown:
|
||||
|
||||
```markdown
|
||||
# Docs search: <query>
|
||||
|
||||
- [Title](https://docs.openclaw.ai/...) - snippet
|
||||
- [Title](https://docs.openclaw.ai/...) - snippet
|
||||
```
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
| ---- | ------------------------------------------------------------------------ |
|
||||
| `0` | Search succeeded, including zero-result responses. |
|
||||
| `1` | The hosted docs search API call failed; stderr prints the error message. |
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Live docs](https://docs.openclaw.ai)
|
||||
219
docs/cli/doctor.md
Normal file
219
docs/cli/doctor.md
Normal file
@@ -0,0 +1,219 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw doctor` (health checks + guided repairs)"
|
||||
read_when:
|
||||
- You have connectivity/auth issues and want guided fixes
|
||||
- You updated and want a sanity check
|
||||
title: "Doctor"
|
||||
---
|
||||
|
||||
# `openclaw doctor`
|
||||
|
||||
Health checks and quick fixes for the gateway, channels, plugins, skills, model routing, local state, and config migrations. Use it whenever something is not behaving as expected and you want one command to explain what is wrong.
|
||||
|
||||
Related:
|
||||
|
||||
- Troubleshooting: [Troubleshooting](/gateway/troubleshooting)
|
||||
- Security audit: [Security](/gateway/security)
|
||||
|
||||
## Postures
|
||||
|
||||
| Posture | Command | Behavior |
|
||||
| ------- | ------------------------ | --------------------------------------------------------------------------- |
|
||||
| Inspect | `openclaw doctor` | Human-oriented checks and guided prompts. |
|
||||
| Repair | `openclaw doctor --fix` | Applies supported repairs, prompting unless non-interactive repair is safe. |
|
||||
| Lint | `openclaw doctor --lint` | Read-only structured findings for CI, preflight, and review gates. |
|
||||
|
||||
Prefer `--lint` when automation needs a stable result. Prefer `--fix` when a human operator wants doctor to edit config or state.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
openclaw doctor --lint
|
||||
openclaw doctor --lint --json
|
||||
openclaw doctor --lint --severity-min warning
|
||||
openclaw doctor --lint --all
|
||||
openclaw doctor --lint --allow-exec
|
||||
openclaw doctor --deep
|
||||
openclaw doctor --fix
|
||||
openclaw doctor --fix --non-interactive
|
||||
openclaw doctor --generate-gateway-token
|
||||
openclaw doctor --post-upgrade
|
||||
openclaw doctor --post-upgrade --json
|
||||
```
|
||||
|
||||
For channel-specific permissions, use the channel probes instead of `doctor`:
|
||||
|
||||
```bash
|
||||
openclaw channels capabilities --channel discord --target channel:<channel-id>
|
||||
openclaw channels status --probe
|
||||
```
|
||||
|
||||
`channels capabilities` reports the bot's effective permissions for a specific channel target. `channels status --probe` audits all configured channels and voice auto-join targets.
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Effect |
|
||||
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--no-workspace-suggestions` | Disable workspace memory/search suggestions. |
|
||||
| `--yes` | Accept defaults without prompting. |
|
||||
| `--repair` / `--fix` | Apply recommended non-service repairs without prompting (`--fix` is an alias). Gateway service installs/rewrites still require interactive confirmation or explicit `gateway` commands. |
|
||||
| `--force` | Apply aggressive repairs, including overwriting custom service config. |
|
||||
| `--non-interactive` | Run without prompts; safe migrations and non-service repairs only. |
|
||||
| `--generate-gateway-token` | Generate and configure a gateway token. |
|
||||
| `--allow-exec` | Allow doctor to execute configured `exec` SecretRefs while verifying secrets. |
|
||||
| `--deep` | Scan system services for extra gateway installs; report recent Gateway supervisor restart handoffs. |
|
||||
| `--lint` | Run modernized health checks in read-only mode and emit diagnostic findings. |
|
||||
| `--post-upgrade` | Run post-upgrade plugin compatibility probes; findings go to stdout; exit code 1 if any error-level finding is present. |
|
||||
| `--json` | With `--lint`: JSON findings. With `--post-upgrade`: machine-readable envelope `{ probesRun, findings }`. |
|
||||
| `--severity-min <level>` | With `--lint`: drop findings below `info`, `warning`, or `error`. |
|
||||
| `--all` | With `--lint`: run all registered checks, including opt-in checks excluded from the default set. |
|
||||
| `--skip <id>` | With `--lint`: skip a check id. Repeatable. |
|
||||
| `--only <id>` | With `--lint`: run only the given check id(s). Repeatable. |
|
||||
|
||||
`--json`, `--severity-min`, `--all`, `--only`, and `--skip` are only accepted together with `--lint`.
|
||||
|
||||
## Lint mode
|
||||
|
||||
`openclaw doctor --lint` is read-only: no prompts, no repair, no config/state rewrites.
|
||||
|
||||
```bash
|
||||
openclaw doctor --lint
|
||||
openclaw doctor --lint --severity-min warning
|
||||
openclaw doctor --lint --json
|
||||
openclaw doctor --lint --all
|
||||
openclaw doctor --lint --allow-exec
|
||||
openclaw doctor --lint --only core/doctor/gateway-config --json
|
||||
```
|
||||
|
||||
Human output is compact:
|
||||
|
||||
```text
|
||||
doctor --lint: ran 6 check(s), 1 finding(s)
|
||||
[warning] core/doctor/gateway-config gateway.mode - gateway.mode is unset; gateway start will be blocked.
|
||||
fix: Run `openclaw configure` and set Gateway mode (local/remote), or `openclaw config set gateway.mode local`.
|
||||
```
|
||||
|
||||
JSON output is the scripting surface:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": false,
|
||||
"checksRun": 5,
|
||||
"checksSkipped": 0,
|
||||
"findings": [
|
||||
{
|
||||
"checkId": "core/doctor/gateway-config",
|
||||
"severity": "warning",
|
||||
"message": "gateway.mode is unset; gateway start will be blocked.",
|
||||
"path": "gateway.mode",
|
||||
"fixHint": "Run `openclaw configure` and set Gateway mode (local/remote), or `openclaw config set gateway.mode local`."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Exit codes:
|
||||
|
||||
| Code | Meaning |
|
||||
| ---- | ------------------------------------------------------------- |
|
||||
| `0` | No findings at or above the selected severity threshold. |
|
||||
| `1` | At least one finding meets the selected threshold. |
|
||||
| `2` | Command/runtime failure before lint findings can be produced. |
|
||||
|
||||
`--severity-min` controls both which findings print and the exit threshold: `openclaw doctor --lint --severity-min error` can print nothing and exit `0` even when lower-severity `info`/`warning` findings exist.
|
||||
|
||||
`--all` controls which checks are selected before severity filtering. The default lint run excludes checks that are deep, historical, or more likely to surface repairable legacy residue; use `--all` for the complete inventory. `--only <id>` is the most precise selector and can run any registered check by id.
|
||||
|
||||
## Structured health checks
|
||||
|
||||
Modern doctor checks use a small split contract:
|
||||
|
||||
```ts
|
||||
detect(ctx, scope?) -> HealthFinding[]
|
||||
repair?(ctx, findings) -> HealthRepairResult
|
||||
```
|
||||
|
||||
`detect()` powers `doctor --lint`. `repair()` is optional and only runs under `doctor --fix` / `doctor --repair`. Checks that have not migrated to this shape still use the legacy doctor contribution flow.
|
||||
|
||||
Repair contexts can carry `dryRun`/`diff` requests; repair results can return structured `diffs` (config/file edits) and `effects` (service, process, package, state, or other side effects), so converted checks can grow toward `doctor --fix --dry-run` without moving mutation planning into `detect()`.
|
||||
|
||||
`repair()` reports `status: "repaired" | "skipped" | "failed"` (omitted status means `repaired`). When repair returns `skipped` or `failed`, doctor reports the reason and skips validation for that check. After a successful repair, doctor re-runs `detect()` scoped to the repaired findings; if the finding is still present, doctor reports a repair warning instead of treating the change as complete.
|
||||
|
||||
A finding includes:
|
||||
|
||||
| Field | Purpose |
|
||||
| ----------------- | ------------------------------------------------------ |
|
||||
| `checkId` | Stable id for skip/only filters and CI allowlists. |
|
||||
| `severity` | `info`, `warning`, or `error`. |
|
||||
| `message` | Human-readable problem statement. |
|
||||
| `path` | Config, file, or logical path when available. |
|
||||
| `line` / `column` | Source location when available. |
|
||||
| `ocPath` | Precise `oc://` address when a check can point to one. |
|
||||
| `fixHint` | Suggested operator action or repair summary. |
|
||||
|
||||
Modernized core doctor checks stay attached to the ordered doctor contribution that owns their human `doctor` / `doctor --fix` behavior. The shared structured health registry is the extension point: bundled and plugin-backed checks run after core doctor checks once their owning package registers them in the active command path. `openclaw/plugin-sdk/health` exposes the same contract for plugin authors.
|
||||
|
||||
## Check selection
|
||||
|
||||
```bash
|
||||
openclaw doctor --lint --only core/doctor/gateway-config --json
|
||||
openclaw doctor --lint --skip core/doctor/skills-readiness
|
||||
openclaw doctor --lint --all --skip core/doctor/session-locks
|
||||
```
|
||||
|
||||
`--only` and `--skip` accept full check ids and may be repeated. If an `--only` id is not registered, no check runs for that id; use `checksRun`/`checksSkipped` in the output to confirm a focused gate selects the checks you expect.
|
||||
|
||||
## Post-upgrade mode
|
||||
|
||||
`openclaw doctor --post-upgrade` runs plugin compatibility probes for chaining after a build or upgrade. Findings go to stdout; exit code is 1 if any finding has `level: "error"`. Add `--json` for a machine-readable envelope (`{ probesRun, findings }`), suitable for CI, the community `fork-upgrade` skill, and other post-upgrade smoke tooling. If the installed plugin index is missing or malformed, JSON mode still emits the envelope with a `plugin.index_unavailable` error finding.
|
||||
|
||||
## Notes
|
||||
|
||||
- In Nix mode (`OPENCLAW_NIX_MODE=1`), read-only doctor checks still work, but `doctor --fix`, `doctor --repair`, `doctor --yes`, and `doctor --generate-gateway-token` are disabled because `openclaw.json` is immutable. Edit the Nix source for this install instead; for nix-openclaw, use the agent-first [Quick Start](https://github.com/openclaw/nix-openclaw#quick-start).
|
||||
- Interactive prompts (keychain/OAuth fixes, etc.) only run when stdin is a TTY and `--non-interactive` is **not** set. Headless runs (cron, Telegram, no terminal) skip prompts.
|
||||
- Non-interactive `doctor` runs skip eager plugin loading so headless health checks stay fast. Interactive sessions still load the plugin surfaces needed by the legacy health/repair flow.
|
||||
- `--lint` is stricter than `--non-interactive`: always read-only, never prompts, never applies safe migrations. Use `doctor --fix` or `doctor --repair` when you want doctor to make changes.
|
||||
- Doctor does not execute `exec` SecretRefs while checking secrets by default. Use `--allow-exec` (with or without `--lint`) only when you intentionally want doctor to run those configured secret resolvers.
|
||||
- Any config write (including a `--fix` repair) rotates a backup to `~/.openclaw/openclaw.json.bak` (with a numbered `.bak.1`..`.bak.4` ring). `--fix` also drops unknown config keys reported by schema validation, listing each removal; it skips this while an update is in progress so partially written upgrade state is not stripped before its migration finishes.
|
||||
- Set `OPENCLAW_SERVICE_REPAIR_POLICY=external` when another supervisor owns the gateway lifecycle. Doctor still reports gateway/service health and applies non-service repairs, but skips service install/start/restart/bootstrap and legacy service cleanup.
|
||||
- On Linux, doctor ignores inactive extra gateway-like systemd units and does not rewrite command/entrypoint metadata for a running systemd gateway service during repair. Stop the service first, or use `openclaw gateway install --force` to replace the active launcher.
|
||||
- `doctor --fix --non-interactive` reports missing or stale gateway service definitions but does not install or rewrite them outside update repair mode. Run `openclaw gateway install` for a missing service, or `openclaw gateway install --force` to replace the launcher.
|
||||
- State integrity checks detect orphan transcript files in the sessions directory. Archiving them as `.deleted.<timestamp>` requires interactive confirmation; `--fix`, `--yes`, and headless runs leave them in place.
|
||||
- Doctor scans `~/.openclaw/cron/jobs.json` (or `cron.store`) for legacy cron job shapes and rewrites them before importing canonical rows into SQLite.
|
||||
- Doctor reports cron jobs with an explicit `payload.model` override, including provider-namespace counts and mismatches against `agents.defaults.model`, so scheduled jobs that do not inherit the default model are visible during auth or billing investigations.
|
||||
- On Linux, doctor warns when the user's crontab still runs the unmaintained legacy `~/.openclaw/bin/ensure-whatsapp.sh`, which can misreport `Gateway inactive` when cron lacks the systemd user-bus environment.
|
||||
- When WhatsApp is enabled, doctor checks for a degraded Gateway event loop with local `openclaw-tui` clients still running. `doctor --fix` stops only verified local TUI clients so WhatsApp replies are not queued behind stale TUI refresh loops.
|
||||
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, image/video generation models, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` also migrates legacy `openai-codex:*` auth profiles and `auth.order.openai-codex` entries to `openai:*`, moves Codex intent onto provider/model-scoped `agentRuntime.id: "codex"` entries, removes stale whole-agent/session runtime pins, and keeps repaired OpenAI agent refs on Codex auth routing instead of direct OpenAI API-key auth.
|
||||
- Doctor cleans legacy plugin dependency staging state from older OpenClaw versions and relinks the host `openclaw` package for managed npm plugins that declare it as a peer dependency. It also repairs missing downloadable plugins referenced by config (`plugins.entries`, configured channels, configured provider/search settings, configured agent runtimes). During package updates, doctor skips package-manager plugin repair until the package swap completes; rerun `openclaw doctor --fix` afterward if a configured plugin still needs recovery. If a download fails, doctor reports the install error and preserves the configured plugin entry for the next repair attempt.
|
||||
- Doctor repairs stale plugin config by removing missing plugin ids from `plugins.allow`/`plugins.deny`/`plugins.entries`, plus matching dangling channel config, heartbeat targets, and channel model overrides, when plugin discovery is healthy.
|
||||
- Doctor quarantines invalid plugin config by disabling the affected `plugins.entries.<id>` entry and removing its invalid `config` payload. Gateway startup already skips only that bad plugin so other plugins and channels keep running.
|
||||
- Doctor removes the retired `plugins.entries.codex.config.codexDynamicToolsProfile`; the Codex app-server always keeps Codex-native workspace tools native.
|
||||
- Doctor auto-migrates legacy flat Talk config (`talk.voiceId`, `talk.modelId`, and friends) into `talk.provider` + `talk.providers.<provider>`. Repeat `doctor --fix` runs no longer report/apply Talk normalization when the only difference is object key order.
|
||||
- Doctor includes a memory-search readiness check and can recommend `openclaw configure --section model` when embedding credentials are missing.
|
||||
- Doctor warns when no command owner is configured. The command owner is the human operator account allowed to run owner-only commands and approve dangerous actions. DM pairing only lets someone talk to the bot; if you approved a sender before first-owner bootstrap existed, set `commands.ownerAllowFrom` explicitly.
|
||||
- Doctor reports an info note when Codex-mode agents are configured and personal Codex CLI assets exist in the operator's Codex home. Local Codex app-server launches use isolated per-agent homes; install the Codex plugin first if needed, then use `openclaw migrate plan codex` to inventory assets that should be promoted deliberately.
|
||||
- Doctor warns when skills allowed for the default agent are unavailable in the current runtime environment (missing bins, env vars, config, or OS requirements). `doctor --fix` can disable those unavailable skills with `skills.entries.<skill>.enabled=false`; install/configure the missing requirement instead if you want to keep the skill active.
|
||||
- If sandbox mode is enabled but Docker is unavailable, doctor reports a high-signal warning with remediation (`install Docker` or `openclaw config set agents.defaults.sandbox.mode off`).
|
||||
- If legacy sandbox registry files or shard directories are present (`~/.openclaw/sandbox/containers.json`, `~/.openclaw/sandbox/browsers.json`, `~/.openclaw/sandbox/containers/`, or `~/.openclaw/sandbox/browsers/`), doctor reports them; `--fix` migrates valid entries into SQLite and quarantines invalid legacy files.
|
||||
- If `gateway.auth.token`/`gateway.auth.password` are SecretRef-managed and unavailable in the current command path, doctor reports a read-only warning and does not write plaintext fallback credentials. For exec-backed SecretRefs, doctor skips execution unless `--allow-exec` is present.
|
||||
- If channel SecretRef inspection fails in a fix path, doctor continues and reports a warning instead of exiting early.
|
||||
- After state-directory migrations, doctor warns when enabled default Telegram or Discord accounts depend on env fallback and `TELEGRAM_BOT_TOKEN` or `DISCORD_BOT_TOKEN` is unavailable to the doctor process.
|
||||
- Telegram `allowFrom` username auto-resolution (`doctor --fix`) requires a resolvable Telegram token in the current command path. If token inspection is unavailable, doctor reports a warning and skips auto-resolution for that pass.
|
||||
|
||||
## macOS: `launchctl` env overrides
|
||||
|
||||
If you previously ran `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...` (or `...PASSWORD`), that value overrides your config file and can cause persistent "unauthorized" errors.
|
||||
|
||||
```bash
|
||||
launchctl getenv OPENCLAW_GATEWAY_TOKEN
|
||||
launchctl getenv OPENCLAW_GATEWAY_PASSWORD
|
||||
|
||||
launchctl unsetenv OPENCLAW_GATEWAY_TOKEN
|
||||
launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway doctor](/gateway/doctor)
|
||||
50
docs/cli/flows.md
Normal file
50
docs/cli/flows.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
summary: "Redirect: flow commands live under `openclaw tasks flow`"
|
||||
read_when:
|
||||
- You encounter `openclaw flows` in older docs or release notes
|
||||
- You want a quick TaskFlow inspection reference
|
||||
title: "Flows (redirect)"
|
||||
---
|
||||
|
||||
# `openclaw tasks flow`
|
||||
|
||||
There is no top-level `openclaw flows` command. Durable TaskFlow inspection lives under `openclaw tasks flow`.
|
||||
|
||||
## Subcommands
|
||||
|
||||
```bash
|
||||
openclaw tasks flow list [--json] [--status <name>]
|
||||
openclaw tasks flow show <lookup> [--json]
|
||||
openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
| Subcommand | Description | Arguments / options |
|
||||
| ---------- | -------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `list` | List tracked TaskFlows. | `--json` machine-readable output; `--status <name>` filter (see status values below). |
|
||||
| `show` | Show one TaskFlow. | `<lookup>` flow id or owner key; `--json` machine-readable output. |
|
||||
| `cancel` | Cancel a running TaskFlow. | `<lookup>` flow id or owner key. |
|
||||
|
||||
`<lookup>` accepts either a flow id (returned by `list` / `show`) or the flow's owner key (the stable identifier the owning subsystem uses to track the flow).
|
||||
|
||||
### Status filter values
|
||||
|
||||
`--status` on `list` accepts one of: `queued`, `running`, `waiting`, `blocked`, `succeeded`, `failed`, `cancelled`, `lost`.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw tasks flow list
|
||||
openclaw tasks flow list --status running
|
||||
openclaw tasks flow list --json
|
||||
openclaw tasks flow show flow_abc123
|
||||
openclaw tasks flow show flow_abc123 --json
|
||||
openclaw tasks flow cancel flow_abc123
|
||||
```
|
||||
|
||||
For TaskFlow concepts and authoring, see [TaskFlow](/automation/taskflow). For the parent `tasks` command, see [tasks CLI reference](/cli/tasks).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Automation](/automation)
|
||||
- [TaskFlow](/automation/taskflow)
|
||||
553
docs/cli/gateway.md
Normal file
553
docs/cli/gateway.md
Normal file
@@ -0,0 +1,553 @@
|
||||
---
|
||||
summary: "OpenClaw Gateway CLI (`openclaw gateway`) — run, query, and discover gateways"
|
||||
read_when:
|
||||
- Running the Gateway from the CLI (dev or servers)
|
||||
- Debugging Gateway auth, bind modes, and connectivity
|
||||
- Discovering gateways via Bonjour (local + wide-area DNS-SD)
|
||||
title: "Gateway"
|
||||
sidebarTitle: "Gateway"
|
||||
---
|
||||
|
||||
The Gateway is OpenClaw's WebSocket server (channels, nodes, sessions, hooks). All subcommands below live under `openclaw gateway ...`.
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Bonjour discovery" href="/gateway/bonjour">
|
||||
Local mDNS + wide-area DNS-SD setup.
|
||||
</Card>
|
||||
<Card title="Discovery overview" href="/gateway/discovery">
|
||||
How OpenClaw advertises and finds gateways.
|
||||
</Card>
|
||||
<Card title="Configuration" href="/gateway/configuration">
|
||||
Top-level gateway config keys.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Run the Gateway
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
openclaw gateway run # equivalent, explicit form
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Startup behavior">
|
||||
- Refuses to start unless `gateway.mode=local` is set in `~/.openclaw/openclaw.json`. Use `--allow-unconfigured` for ad-hoc/dev runs; it bypasses the guard without writing or repairing config.
|
||||
- `openclaw onboard --mode local` and `openclaw setup` write `gateway.mode=local`. If the config file exists but `gateway.mode` is missing, that is treated as damaged/clobbered config and the Gateway refuses to guess `local` for you — re-run onboarding, set the key manually, or pass `--allow-unconfigured`.
|
||||
- Binding beyond loopback without auth is blocked.
|
||||
- `--bind` values `lan`, `tailnet`, and `custom` resolve over IPv4-only paths today; IPv6-only bring-your-own-host setups need an IPv4 sidecar or proxy in front of the Gateway.
|
||||
- `SIGUSR1` triggers an in-process restart when authorized. `commands.restart` (default: enabled) gates externally-sent `SIGUSR1`; set it to `false` to block manual OS-signal restarts while still allowing restart via the `gateway restart` command, the gateway tool, and config-apply/update.
|
||||
- `SIGINT`/`SIGTERM` stop the process but do not restore custom terminal state — if you wrap the CLI in a TUI or raw-mode input, restore the terminal yourself before exit.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Options
|
||||
|
||||
<ParamField path="--port <port>" type="number">
|
||||
WebSocket port (default from config/env; usually `18789`).
|
||||
</ParamField>
|
||||
<ParamField path="--bind <mode>" type="string">
|
||||
Bind mode: `loopback` (default), `lan`, `tailnet`, `auto`, `custom`.
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
Shared token for `connect.params.auth.token`. Defaults to `OPENCLAW_GATEWAY_TOKEN` when set.
|
||||
</ParamField>
|
||||
<ParamField path="--auth <mode>" type="string">
|
||||
Auth mode: `none`, `token`, `password`, `trusted-proxy`.
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
Password for `--auth password`.
|
||||
</ParamField>
|
||||
<ParamField path="--password-file <path>" type="string">
|
||||
Read the Gateway password from a file.
|
||||
</ParamField>
|
||||
<ParamField path="--tailscale <mode>" type="string">
|
||||
Tailscale exposure: `off`, `serve`, `funnel`.
|
||||
</ParamField>
|
||||
<ParamField path="--tailscale-reset-on-exit" type="boolean">
|
||||
Reset Tailscale serve/funnel config on shutdown.
|
||||
</ParamField>
|
||||
<ParamField path="--allow-unconfigured" type="boolean">
|
||||
Start without enforcing `gateway.mode=local`. Ad-hoc/dev bootstrap only; does not persist or repair config.
|
||||
</ParamField>
|
||||
<ParamField path="--dev" type="boolean">
|
||||
Create a dev config + workspace if missing (skips `BOOTSTRAP.md`).
|
||||
</ParamField>
|
||||
<ParamField path="--reset" type="boolean">
|
||||
Reset dev config, credentials, sessions, and workspace. Requires `--dev`.
|
||||
</ParamField>
|
||||
<ParamField path="--force" type="boolean">
|
||||
Kill any existing listener on the target port before starting.
|
||||
</ParamField>
|
||||
<ParamField path="--verbose" type="boolean">
|
||||
Verbose logging to stdout/stderr.
|
||||
</ParamField>
|
||||
<ParamField path="--cli-backend-logs" type="boolean">
|
||||
Only show CLI backend logs in the console (also enables stdout/stderr).
|
||||
</ParamField>
|
||||
<ParamField path="--ws-log <style>" type="string" default="auto">
|
||||
WebSocket log style: `auto`, `full`, `compact`.
|
||||
</ParamField>
|
||||
<ParamField path="--compact" type="boolean">
|
||||
Alias for `--ws-log compact`.
|
||||
</ParamField>
|
||||
<ParamField path="--raw-stream" type="boolean">
|
||||
Log raw model stream events to JSONL.
|
||||
</ParamField>
|
||||
<ParamField path="--raw-stream-path <path>" type="string">
|
||||
Raw stream JSONL path.
|
||||
</ParamField>
|
||||
|
||||
`--claude-cli-logs` is a deprecated alias for `--cli-backend-logs`.
|
||||
|
||||
For `--bind custom`, set `gateway.customBindHost` to an IPv4 address; the Gateway falls back to `0.0.0.0` if that address is unavailable. IPv6-only bring-your-own-host setups need an IPv4 sidecar or proxy in front of the Gateway.
|
||||
|
||||
## Restart the Gateway
|
||||
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
openclaw gateway restart --safe
|
||||
openclaw gateway restart --safe --skip-deferral
|
||||
openclaw gateway restart --force
|
||||
openclaw gateway restart --wait 30s
|
||||
```
|
||||
|
||||
`--safe` asks the running Gateway to preflight active work and schedule one coalesced restart after that work drains. The wait is bounded by `gateway.reload.deferralTimeoutMs` (default: 5 minutes / `300000`); when the budget expires the restart is forced. Set `deferralTimeoutMs: 0` to wait indefinitely (with periodic still-pending warnings) instead of forcing. `--safe` cannot combine with `--force` or `--wait`.
|
||||
|
||||
`--skip-deferral` bypasses the active-work deferral gate on a safe restart, so the Gateway restarts immediately even with reported blockers. It requires `--safe` — use it when a deferral is stuck on a runaway task.
|
||||
|
||||
`--wait <duration>` overrides the drain budget for a plain (non-safe) restart. Accepts bare milliseconds or unit suffixes `ms`, `s`, `m`, `h`, `d` (e.g. `30s`, `5m`, `1h30m`); `--wait 0` waits indefinitely. Not compatible with `--force` or `--safe`.
|
||||
|
||||
`--force` skips the active-work drain and restarts immediately. Plain `restart` (no flags) keeps the existing service-manager restart behavior.
|
||||
|
||||
<Warning>
|
||||
Inline `--password` can be exposed in local process listings. Prefer `--password-file`, env, or a SecretRef-backed `gateway.auth.password`.
|
||||
</Warning>
|
||||
|
||||
### Gateway profiling
|
||||
|
||||
- `OPENCLAW_GATEWAY_STARTUP_TRACE=1` logs phase timings during startup, including per-phase `eventLoopMax` delay and plugin lookup-table timings (installed-index, manifest registry, startup planning, owner-map work).
|
||||
- `OPENCLAW_GATEWAY_RESTART_TRACE=1` logs restart-scoped `restart trace:` lines: signal handling, active-work drain, shutdown phases, next start, ready timing, and memory metrics.
|
||||
- `OPENCLAW_DIAGNOSTICS=timeline` with `OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=<path>` writes a best-effort JSONL startup diagnostics timeline for external QA harnesses (equivalent to config `diagnostics.flags: ["timeline"]`; the path is still env-only). Add `OPENCLAW_DIAGNOSTICS_EVENT_LOOP=1` to include event-loop samples.
|
||||
- `pnpm build` then `pnpm test:startup:gateway -- --runs 5 --warmup 1` benchmarks Gateway startup against the built CLI entry: first process output, `/healthz`, `/readyz`, startup trace timings, event-loop delay, and plugin lookup-table timing.
|
||||
- `pnpm build` then `pnpm test:restart:gateway -- --case skipChannels --runs 1 --restarts 5` benchmarks in-process restart on macOS or Linux (not supported on Windows; restart requires `SIGUSR1`). Uses `SIGUSR1`, enables both traces in the child process, and records next `/healthz`, next `/readyz`, downtime, ready timing, CPU, RSS, and restart trace metrics.
|
||||
- `/healthz` is liveness; `/readyz` is usable readiness. Treat trace lines and benchmark output as owner-attribution signal, not a complete performance conclusion from one span or sample.
|
||||
|
||||
## Query a running Gateway
|
||||
|
||||
All query commands use WebSocket RPC.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Output modes">
|
||||
- Default: human-readable (colored in TTY).
|
||||
- `--json`: machine-readable JSON (no styling/spinner).
|
||||
- `--no-color` (or `NO_COLOR=1`): disable ANSI while keeping human layout.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Shared options">
|
||||
- `--url <url>`: Gateway WebSocket URL.
|
||||
- `--token <token>`: Gateway token.
|
||||
- `--password <password>`: Gateway password.
|
||||
- `--timeout <ms>`: timeout/budget (default varies per command; see each command below).
|
||||
- `--expect-final`: wait for a "final" response (agent calls).
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
When you set `--url`, the CLI does not fall back to config or environment credentials. Pass `--token` or `--password` explicitly. Missing explicit credentials is an error.
|
||||
</Note>
|
||||
|
||||
### `gateway health`
|
||||
|
||||
```bash
|
||||
openclaw gateway health --url ws://127.0.0.1:18789
|
||||
openclaw gateway health --port 18789
|
||||
```
|
||||
|
||||
`/healthz` is a liveness probe: it returns as soon as the server can answer HTTP. `/readyz` is stricter and stays red while startup plugin sidecars, channels, or configured hooks are still settling. Local or authenticated detailed `/readyz` responses include an `eventLoop` diagnostic block (delay, utilization, CPU-core ratio, `degraded` flag).
|
||||
|
||||
<ParamField path="--port <port>" type="number">
|
||||
Target a local loopback Gateway on this port. Overrides `OPENCLAW_GATEWAY_URL` and `OPENCLAW_GATEWAY_PORT` for this call.
|
||||
</ParamField>
|
||||
|
||||
### `gateway usage-cost`
|
||||
|
||||
Fetch usage-cost summaries from session logs.
|
||||
|
||||
```bash
|
||||
openclaw gateway usage-cost
|
||||
openclaw gateway usage-cost --days 7
|
||||
openclaw gateway usage-cost --agent work --json
|
||||
openclaw gateway usage-cost --all-agents
|
||||
openclaw gateway usage-cost --json
|
||||
```
|
||||
|
||||
<ParamField path="--days <days>" type="number" default="30">
|
||||
Number of days to include.
|
||||
</ParamField>
|
||||
<ParamField path="--agent <id>" type="string">
|
||||
Scope the summary to one configured agent id.
|
||||
</ParamField>
|
||||
<ParamField path="--all-agents" type="boolean">
|
||||
Aggregate across all configured agents. Cannot combine with `--agent`.
|
||||
</ParamField>
|
||||
|
||||
### `gateway stability`
|
||||
|
||||
Fetch the recent diagnostic stability recorder from a running Gateway.
|
||||
|
||||
```bash
|
||||
openclaw gateway stability
|
||||
openclaw gateway stability --type payload.large
|
||||
openclaw gateway stability --bundle latest
|
||||
openclaw gateway stability --bundle latest --export
|
||||
openclaw gateway stability --json
|
||||
```
|
||||
|
||||
<ParamField path="--limit <limit>" type="number" default="25">
|
||||
Maximum recent events to include (max `1000`).
|
||||
</ParamField>
|
||||
<ParamField path="--type <type>" type="string">
|
||||
Filter by diagnostic event type, e.g. `payload.large` or `diagnostic.memory.pressure`.
|
||||
</ParamField>
|
||||
<ParamField path="--since-seq <seq>" type="number">
|
||||
Include only events after a diagnostic sequence number.
|
||||
</ParamField>
|
||||
<ParamField path="--bundle [path]" type="string">
|
||||
Read a persisted stability bundle instead of calling the running Gateway. `--bundle latest` (or bare `--bundle`) picks the newest bundle under the state directory; you can also pass a bundle JSON path directly.
|
||||
</ParamField>
|
||||
<ParamField path="--export" type="boolean">
|
||||
Write a shareable support diagnostics zip instead of printing stability details.
|
||||
</ParamField>
|
||||
<ParamField path="--output <path>" type="string">
|
||||
Output path for `--export`.
|
||||
</ParamField>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Privacy and bundle behavior">
|
||||
- Records keep operational metadata: event names, counts, byte sizes, memory readings, queue/session state, approval ids, channel/plugin names, and redacted session summaries. They exclude chat text, webhook bodies, tool outputs, raw request/response bodies, tokens, cookies, secret values, hostnames, and raw session ids. Set `diagnostics.enabled: false` to disable the recorder entirely.
|
||||
- Fatal Gateway exits, shutdown timeouts, and restart startup failures write the same diagnostic snapshot to `~/.openclaw/logs/stability/openclaw-stability-*.json` when the recorder has events. Inspect the newest bundle with `openclaw gateway stability --bundle latest`; `--limit`, `--type`, and `--since-seq` apply to bundle output too.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### `gateway diagnostics export`
|
||||
|
||||
Write a local diagnostics zip designed for bug reports. For the privacy model and bundle contents, see [Diagnostics Export](/gateway/diagnostics).
|
||||
|
||||
```bash
|
||||
openclaw gateway diagnostics export
|
||||
openclaw gateway diagnostics export --output openclaw-diagnostics.zip
|
||||
openclaw gateway diagnostics export --json
|
||||
```
|
||||
|
||||
<ParamField path="--output <path>" type="string">
|
||||
Output zip path. Defaults to a support export under the state directory.
|
||||
</ParamField>
|
||||
<ParamField path="--log-lines <count>" type="number" default="5000">
|
||||
Maximum sanitized log lines to include.
|
||||
</ParamField>
|
||||
<ParamField path="--log-bytes <bytes>" type="number" default="1000000">
|
||||
Maximum log bytes to inspect.
|
||||
</ParamField>
|
||||
<ParamField path="--url <url>" type="string">
|
||||
Gateway WebSocket URL for the health snapshot.
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
Gateway token for the health snapshot.
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
Gateway password for the health snapshot.
|
||||
</ParamField>
|
||||
<ParamField path="--timeout <ms>" type="number" default="3000">
|
||||
Status/health snapshot timeout.
|
||||
</ParamField>
|
||||
<ParamField path="--no-stability-bundle" type="boolean">
|
||||
Skip persisted stability bundle lookup.
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
Print the written path, size, and manifest as JSON.
|
||||
</ParamField>
|
||||
|
||||
The export bundles: `manifest.json` (file inventory), `summary.md` (Markdown summary), `diagnostics.json` (top-level config/logs/discovery/stability/status/health summary), `config/sanitized.json`, `status/gateway-status.json`, `health/gateway-health.json`, `logs/openclaw-sanitized.jsonl`, and `stability/latest.json` when a bundle exists.
|
||||
|
||||
It is designed to be shared. It keeps operational details useful for debugging — safe log fields, subsystem names, status codes, durations, configured modes, ports, plugin/provider ids, non-secret feature settings, and redacted operational log messages — and omits or redacts chat text, webhook bodies, tool outputs, credentials, cookies, account/message identifiers, prompt/instruction text, hostnames, and secret values. When a log message looks like user/chat/tool payload text (e.g. "user said", "chat text", "tool output", "webhook body"), the export keeps only the fact that a message was omitted plus its byte count.
|
||||
|
||||
### `gateway status`
|
||||
|
||||
Shows the Gateway service (launchd/systemd/schtasks) plus an optional connectivity/auth probe.
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
openclaw gateway status --json
|
||||
openclaw gateway status --require-rpc
|
||||
```
|
||||
|
||||
<ParamField path="--url <url>" type="string">
|
||||
Add an explicit probe target. Configured remote + localhost are still probed.
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
Token auth for the probe.
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
Password auth for the probe.
|
||||
</ParamField>
|
||||
<ParamField path="--timeout <ms>" type="number" default="10000">
|
||||
Probe timeout.
|
||||
</ParamField>
|
||||
<ParamField path="--no-probe" type="boolean">
|
||||
Skip the connectivity probe (service-only view).
|
||||
</ParamField>
|
||||
<ParamField path="--deep" type="boolean">
|
||||
Scan system-level services too.
|
||||
</ParamField>
|
||||
<ParamField path="--require-rpc" type="boolean">
|
||||
Upgrade the connectivity probe to a read probe and exit non-zero if it fails. Cannot combine with `--no-probe`.
|
||||
</ParamField>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Status semantics">
|
||||
- Stays available for diagnostics even when the local CLI config is missing or invalid.
|
||||
- Default output proves service state, WebSocket connect, and the auth capability visible at handshake time — not read/write/admin operations.
|
||||
- Probes are non-mutating for first-time device auth: they reuse an existing cached device token when one exists, but never create a new CLI device identity or read-only pairing record just to check status.
|
||||
- Resolves configured auth SecretRefs for probe auth when possible. If a required SecretRef is unresolved, `--json` reports `rpc.authWarning` when probe connectivity/auth fails; pass `--token`/`--password` explicitly or fix the secret source. Unresolved-auth warnings are suppressed once the probe succeeds.
|
||||
- JSON output includes `gateway.version` when the running Gateway reports it; `--require-rpc` can fall back to the `status.runtimeVersion` RPC payload if the handshake probe cannot supply version metadata.
|
||||
- Use `--require-rpc` in scripts/automation when a listening service is not enough and you need read-scope RPC to be healthy too.
|
||||
- `--deep` scans for extra launchd/systemd/schtasks installs; when multiple gateway-like services are found, human output prints cleanup hints (usually run one gateway per machine) and reports a recent supervisor restart handoff when relevant.
|
||||
- `--deep` also runs config validation in plugin-aware mode (`pluginValidation: "full"`) and surfaces plugin manifest warnings (e.g. missing channel config metadata). Default `gateway status` keeps the fast read-only path that skips plugin validation.
|
||||
- Human output includes the resolved file log path plus CLI-vs-service config paths/validity to help diagnose profile or state-dir drift.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Linux systemd auth-drift checks">
|
||||
- Service auth drift checks read both `Environment=` and `EnvironmentFile=` from the unit (including `%h`, quoted paths, multiple files, and optional `-` files).
|
||||
- Resolves `gateway.auth.token` SecretRefs using merged runtime env (service command env first, then process env fallback).
|
||||
- Token-drift checks skip config token resolution when token auth is not effectively active (`gateway.auth.mode` explicitly `password`/`none`/`trusted-proxy`, or mode unset where password can win and no token candidate can win).
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### `gateway probe`
|
||||
|
||||
The "debug everything" command. It always probes:
|
||||
|
||||
- your configured remote gateway (if set), and
|
||||
- localhost (loopback), **even if remote is configured**.
|
||||
|
||||
Passing `--url` adds that explicit target ahead of both. Human output labels targets `URL (explicit)`, `Remote (configured)` / `Remote (configured, inactive)`, and `Local loopback`.
|
||||
|
||||
<Note>
|
||||
If multiple probe targets are reachable, all are printed. An SSH tunnel, TLS/proxy URL, and configured remote URL can point at the same gateway even with different transport ports; `multiple_gateways` is reserved for distinct or identity-ambiguous reachable gateways. Running multiple gateways is supported for isolated profiles (e.g. a rescue bot), but most installs run a single gateway.
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
openclaw gateway probe
|
||||
openclaw gateway probe --json
|
||||
openclaw gateway probe --port 18789
|
||||
```
|
||||
|
||||
<ParamField path="--port <port>" type="number">
|
||||
Use this port for the local loopback probe target and SSH tunnel remote port. Without `--url`, this selects only the local loopback target instead of configured gateway environment URL, environment port, or remote targets.
|
||||
</ParamField>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Interpretation">
|
||||
- `Reachable: yes` means at least one target accepted a WebSocket connect.
|
||||
- `Capability: read-only|write-capable|admin-capable|pairing-pending|connect-only` reports what the probe could prove about auth, separate from reachability.
|
||||
- `Read probe: ok` means read-scope detail RPC calls (`health`/`status`/`system-presence`/`config.get`) also succeeded.
|
||||
- `Read probe: limited - missing scope: operator.read` means connect succeeded but read-scope RPC is limited. Reported as **degraded** reachability, not full failure.
|
||||
- `Read probe: failed` after `Connect: ok` means the WebSocket connected but follow-up read diagnostics timed out or failed — also **degraded**, not unreachable.
|
||||
- Like `gateway status`, probe reuses existing cached device auth but does not create first-time device identity or pairing state.
|
||||
- Exit code is non-zero only when no probed target is reachable.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="JSON output">
|
||||
Top level:
|
||||
|
||||
- `ok`: at least one target is reachable.
|
||||
- `degraded`: at least one target accepted a connection but did not complete full detail RPC diagnostics.
|
||||
- `capability`: best capability seen across reachable targets (`read_only`, `write_capable`, `admin_capable`, `pairing_pending`, `connected_no_operator_scope`, or `unknown`).
|
||||
- `primaryTargetId`: best target to treat as the active winner, in order: explicit URL, SSH tunnel, configured remote, local loopback.
|
||||
- `warnings[]`: best-effort warning records with `code`, `message`, optional `targetIds`.
|
||||
- `network`: local loopback/tailnet URL hints derived from current config and host networking.
|
||||
- `discovery.timeoutMs` / `discovery.count`: the actual discovery budget/result count used for this probe pass.
|
||||
|
||||
Per target (`targets[].connect`): `ok` (reachability + degraded classification), `rpcOk` (full detail RPC success), `scopeLimited` (detail RPC failed on missing operator scope).
|
||||
|
||||
Per target (`targets[].auth`): `role` and `scopes` reported in `hello-ok` when available, plus the surfaced `capability` classification.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Common warning codes">
|
||||
- `ssh_tunnel_failed`: SSH tunnel setup failed; the command fell back to direct probes.
|
||||
- `multiple_gateways`: distinct gateway identities were reachable, or OpenClaw could not prove reachable targets are the same gateway. An SSH tunnel, proxy URL, or configured remote URL to the same gateway does not trigger this.
|
||||
- `auth_secretref_unresolved`: a configured auth SecretRef could not be resolved for a failed target.
|
||||
- `probe_scope_limited`: WebSocket connect succeeded, but the read probe was limited by missing `operator.read`.
|
||||
- `local_tls_runtime_unavailable`: local Gateway TLS is enabled but OpenClaw could not load the local certificate fingerprint.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
#### Remote over SSH (Mac app parity)
|
||||
|
||||
The macOS app "Remote over SSH" mode uses a local port-forward so a loopback-only remote gateway becomes reachable at `ws://127.0.0.1:<port>`.
|
||||
|
||||
CLI equivalent:
|
||||
|
||||
```bash
|
||||
openclaw gateway probe --ssh user@gateway-host
|
||||
```
|
||||
|
||||
<ParamField path="--ssh <target>" type="string">
|
||||
`user@host` or `user@host:port` (port defaults to `22`).
|
||||
</ParamField>
|
||||
<ParamField path="--ssh-identity <path>" type="string">
|
||||
Identity file.
|
||||
</ParamField>
|
||||
<ParamField path="--ssh-auto" type="boolean">
|
||||
Pick the first discovered gateway host as SSH target from the resolved discovery endpoint (`local.` plus the configured wide-area domain, if any). TXT-only hints are ignored.
|
||||
</ParamField>
|
||||
|
||||
Config defaults (optional): `gateway.remote.sshTarget`, `gateway.remote.sshIdentity`.
|
||||
|
||||
### `gateway call <method>`
|
||||
|
||||
Low-level RPC helper.
|
||||
|
||||
```bash
|
||||
openclaw gateway call status
|
||||
openclaw gateway call logs.tail --params '{"limit": 200}'
|
||||
```
|
||||
|
||||
<ParamField path="--params <json>" type="string" default="{}">
|
||||
JSON object string for params.
|
||||
</ParamField>
|
||||
<ParamField path="--url <url>" type="string">
|
||||
Gateway WebSocket URL.
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
Gateway token.
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
Gateway password.
|
||||
</ParamField>
|
||||
<ParamField path="--timeout <ms>" type="number" default="10000">
|
||||
Timeout budget.
|
||||
</ParamField>
|
||||
<ParamField path="--expect-final" type="boolean">
|
||||
Mainly for agent-style RPCs that stream intermediate events before a final payload.
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
Machine-readable JSON output.
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
`--params` must be valid JSON, and each method validates its own param shape (extra/misnamed fields are rejected).
|
||||
</Note>
|
||||
|
||||
## Manage the Gateway service
|
||||
|
||||
```bash
|
||||
openclaw gateway install
|
||||
openclaw gateway start
|
||||
openclaw gateway stop
|
||||
openclaw gateway restart
|
||||
openclaw gateway uninstall
|
||||
```
|
||||
|
||||
### Install with a wrapper
|
||||
|
||||
Use `--wrapper` when the managed service must start through another executable, for example a secrets manager shim or a run-as helper. The wrapper receives the normal Gateway args and is responsible for eventually exec'ing `openclaw` or Node with those args.
|
||||
|
||||
```bash
|
||||
cat > ~/.local/bin/openclaw-doppler <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
exec doppler run --project my-project --config production -- openclaw "$@"
|
||||
EOF
|
||||
chmod +x ~/.local/bin/openclaw-doppler
|
||||
|
||||
openclaw gateway install --wrapper ~/.local/bin/openclaw-doppler --force
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
You can also set the wrapper through the environment. `gateway install` validates that the path is an executable file, writes the wrapper into the service `ProgramArguments`, and persists `OPENCLAW_WRAPPER` in the service environment for later forced reinstalls, updates, and doctor repairs.
|
||||
|
||||
```bash
|
||||
OPENCLAW_WRAPPER="$HOME/.local/bin/openclaw-doppler" openclaw gateway install --force
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
To remove a persisted wrapper, clear `OPENCLAW_WRAPPER` while reinstalling:
|
||||
|
||||
```bash
|
||||
OPENCLAW_WRAPPER= openclaw gateway install --force
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Command options">
|
||||
- `gateway status`: `--url`, `--token`, `--password`, `--timeout`, `--no-probe`, `--require-rpc`, `--deep`, `--json`
|
||||
- `gateway install`: `--port`, `--runtime <node|bun>` (default: `node`), `--token`, `--wrapper <path>`, `--force`, `--json`
|
||||
- `gateway restart`: `--safe`, `--skip-deferral`, `--force`, `--wait <duration>`, `--json`
|
||||
- `gateway uninstall|start`: `--json`
|
||||
- `gateway stop`: `--disable`, `--json`
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Lifecycle behavior">
|
||||
- Use `gateway restart` to restart a managed service. Do not chain `gateway stop` and `gateway start` as a restart substitute.
|
||||
- On macOS, `gateway stop` uses `launchctl bootout` by default, which removes the LaunchAgent from the current boot session without persisting a disable — KeepAlive auto-recovery stays active for future crashes and `gateway start` re-enables cleanly without a manual `launchctl enable`. Pass `--disable` to persistently suppress KeepAlive and RunAtLoad so the gateway does not respawn until the next explicit `gateway start`; use this when a manual stop should survive reboots.
|
||||
- Lifecycle commands accept `--json` for scripting.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Auth and SecretRefs at install time">
|
||||
- When token auth requires a token and `gateway.auth.token` is SecretRef-managed, `gateway install` validates that the SecretRef is resolvable but does not persist the resolved token into service environment metadata.
|
||||
- If token auth requires a token and the configured token SecretRef is unresolved, install fails closed instead of persisting fallback plaintext.
|
||||
- For password auth on `gateway run`, prefer `OPENCLAW_GATEWAY_PASSWORD`, `--password-file`, or a SecretRef-backed `gateway.auth.password` over inline `--password`.
|
||||
- In inferred auth mode, shell-only `OPENCLAW_GATEWAY_PASSWORD` does not relax install token requirements; use durable config (`gateway.auth.password` or config `env`) when installing a managed service.
|
||||
- If both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, install is blocked until mode is set explicitly.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Discover gateways (Bonjour)
|
||||
|
||||
`gateway discover` scans for Gateway beacons (`_openclaw-gw._tcp`).
|
||||
|
||||
- Multicast DNS-SD: `local.`
|
||||
- Unicast DNS-SD (wide-area Bonjour): choose a domain (example: `openclaw.internal.`) and set up split DNS + a DNS server; see [Bonjour](/gateway/bonjour).
|
||||
|
||||
Only gateways with Bonjour discovery enabled (default) advertise the beacon.
|
||||
|
||||
TXT hints on every beacon: `role` (gateway role hint), `transport` (transport hint, e.g. `gateway`), `gatewayPort` (WebSocket port, usually `18789`), `tailnetDns` (MagicDNS hostname, when available), `gatewayTls` / `gatewayTlsSha256` (TLS enabled + cert fingerprint). `sshPort` and `cliPath` are published only in full discovery mode (`discovery.mdns.mode: "full"`; default is `"minimal"`, which omits them — clients then default SSH targets to port `22`).
|
||||
|
||||
### `gateway discover`
|
||||
|
||||
```bash
|
||||
openclaw gateway discover
|
||||
```
|
||||
|
||||
<ParamField path="--timeout <ms>" type="number" default="2000">
|
||||
Per-command timeout (browse/resolve).
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
Machine-readable output (also disables styling/spinner).
|
||||
</ParamField>
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw gateway discover --timeout 4000
|
||||
openclaw gateway discover --json | jq '.beacons[].wsUrl'
|
||||
```
|
||||
|
||||
<Note>
|
||||
- Scans `local.` plus the configured wide-area domain when one is enabled.
|
||||
- `wsUrl` in JSON output is derived from the resolved service endpoint, not from TXT-only hints such as `lanHost` or `tailnetDns`.
|
||||
- `discovery.mdns.mode` controls `sshPort`/`cliPath` publication on both `local.` mDNS and wide-area DNS-SD (see above).
|
||||
|
||||
</Note>
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway runbook](/gateway)
|
||||
41
docs/cli/health.md
Normal file
41
docs/cli/health.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw health` (gateway health snapshot via RPC)"
|
||||
read_when:
|
||||
- You want to quickly check the running Gateway's health
|
||||
title: "Health"
|
||||
---
|
||||
|
||||
# `openclaw health`
|
||||
|
||||
Fetch a health snapshot from the running Gateway over WebSocket RPC (no direct channel sockets from the CLI).
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ---------------- | ------- | --------------------------------------------------------------------------------- |
|
||||
| `--json` | `false` | Print machine-readable JSON instead of text. |
|
||||
| `--timeout <ms>` | `10000` | Connection timeout in milliseconds. |
|
||||
| `--verbose` | `false` | Forces a live probe and expands output across all configured accounts and agents. |
|
||||
| `--debug` | `false` | Alias for `--verbose`. |
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw health
|
||||
openclaw health --json
|
||||
openclaw health --timeout 2500
|
||||
openclaw health --verbose
|
||||
openclaw health --debug
|
||||
```
|
||||
|
||||
## Behavior
|
||||
|
||||
- Without `--verbose`, the Gateway can return a cached snapshot (fresh for up to 60 seconds and unchanged from live channel runtime state) and refresh it in the background for the next caller.
|
||||
- `--verbose` forces a live probe (per-channel account probes), prints Gateway connection details, and expands human-readable output across all configured accounts and agents instead of just the default agent.
|
||||
- `--json` always returns the full snapshot: channels, per-account probes, plugin load state, context-engine quarantine state, model-pricing cache state, event-loop health, and per-agent session stores.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [`openclaw status`](/cli/status) — local diagnosis and channel probes without a full health snapshot
|
||||
- [Gateway health](/gateway/health)
|
||||
124
docs/cli/hooks.md
Normal file
124
docs/cli/hooks.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw hooks` (agent hooks)"
|
||||
read_when:
|
||||
- You want to manage agent hooks
|
||||
- You want to inspect hook availability or enable workspace hooks
|
||||
title: "Hooks"
|
||||
---
|
||||
|
||||
# `openclaw hooks`
|
||||
|
||||
Manage agent hooks (event-driven automations for commands like `/new`, `/reset`, and gateway startup). Bare `openclaw hooks` is equivalent to `openclaw hooks list`.
|
||||
|
||||
Related: [Hooks](/automation/hooks) - [Plugin hooks](/plugins/hooks)
|
||||
|
||||
## List hooks
|
||||
|
||||
```bash
|
||||
openclaw hooks list [--eligible] [--json] [-v|--verbose]
|
||||
```
|
||||
|
||||
Lists hooks discovered from workspace, managed, extra, and bundled directories.
|
||||
|
||||
- `--eligible`: only hooks whose requirements are met.
|
||||
- `--json`: structured output.
|
||||
- `-v, --verbose`: include a Missing column with unmet requirements.
|
||||
|
||||
```
|
||||
Hooks (4/5 ready)
|
||||
|
||||
Ready:
|
||||
🚀 boot-md ✓ - Run BOOT.md on gateway startup
|
||||
📎 bootstrap-extra-files ✓ - Inject additional workspace bootstrap files during agent bootstrap
|
||||
📝 command-logger ✓ - Log all command events to a centralized audit file
|
||||
💾 session-memory ✓ - Save session context to memory when /new or /reset command is issued
|
||||
```
|
||||
|
||||
## Get hook info
|
||||
|
||||
```bash
|
||||
openclaw hooks info <name> [--json]
|
||||
```
|
||||
|
||||
`<name>` is the hook name or hook key (for example `session-memory`). Shows source, file/handler paths, homepage, events, and per-requirement status (binaries, env, config, OS).
|
||||
|
||||
## Check eligibility
|
||||
|
||||
```bash
|
||||
openclaw hooks check [--json]
|
||||
```
|
||||
|
||||
Prints a ready/not-ready count summary; with hooks not ready, lists each with its blocking reason.
|
||||
|
||||
## Enable a hook
|
||||
|
||||
```bash
|
||||
openclaw hooks enable <name>
|
||||
```
|
||||
|
||||
Adds/updates `hooks.internal.entries.<name>.enabled = true` in config and also flips the `hooks.internal.enabled` master switch on (the gateway does not load any internal hook handler until at least one is configured). Fails if the hook does not exist, is plugin-managed, or is not eligible (missing requirements).
|
||||
|
||||
Plugin-managed hooks show `plugin:<id>` in `hooks list` and cannot be enabled/disabled here; enable or disable the owning plugin instead.
|
||||
|
||||
Restart the gateway after enabling (macOS menu bar app restart, or restart your gateway process in dev) so it reloads hooks.
|
||||
|
||||
## Disable a hook
|
||||
|
||||
```bash
|
||||
openclaw hooks disable <name>
|
||||
```
|
||||
|
||||
Sets `hooks.internal.entries.<name>.enabled = false`. Restart the gateway afterward.
|
||||
|
||||
## Install and update hook packs
|
||||
|
||||
```bash
|
||||
openclaw plugins install <package> # npm by default
|
||||
openclaw plugins install npm:<package> # npm only
|
||||
openclaw plugins install <package> --pin # pin resolved version
|
||||
openclaw plugins install <path> # local directory or archive
|
||||
openclaw plugins install -l <path> # link a local directory instead of copying
|
||||
|
||||
openclaw plugins update <id>
|
||||
openclaw plugins update --all
|
||||
openclaw plugins update --dry-run
|
||||
```
|
||||
|
||||
Hook packs install through the unified plugins installer/updater; `openclaw hooks install` / `openclaw hooks update` still work as deprecated aliases that print a warning and forward to the `plugins` commands.
|
||||
|
||||
- Npm specs are registry-only: package name plus an optional exact version or dist-tag. Git/URL/file specs and semver ranges are rejected. Dependency installs run project-local with `--ignore-scripts`.
|
||||
- Bare specs and `@latest` stay on the stable track; if npm resolves to a prerelease, OpenClaw stops and asks you to opt in explicitly (`@beta`, `@rc`, or an exact prerelease version).
|
||||
- Supported archives: `.zip`, `.tgz`, `.tar.gz`, `.tar`.
|
||||
- `-l, --link` links a local directory instead of copying it (adds it to `hooks.internal.load.extraDirs`); linked hook packs are managed hooks from an operator-configured directory, not workspace hooks.
|
||||
- `--pin` records npm installs as an exact resolved `name@version` in `hooks.internal.installs`.
|
||||
- Install copies the pack into `~/.openclaw/hooks/<id>`, enables its hooks under `hooks.internal.entries.*`, and records the install under `hooks.internal.installs`.
|
||||
- If a stored integrity hash no longer matches the fetched artifact, OpenClaw warns and prompts before continuing; pass global `--yes` to bypass the prompt (for example in CI).
|
||||
|
||||
## Bundled hooks
|
||||
|
||||
| Hook | Events | What it does |
|
||||
| --------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| boot-md | `gateway:startup` | Runs `BOOT.md` at gateway startup for each configured agent scope |
|
||||
| bootstrap-extra-files | `agent:bootstrap` | Injects extra bootstrap files (for example monorepo `AGENTS.md`/`TOOLS.md`) during agent bootstrap |
|
||||
| command-logger | `command` | Logs command events to `~/.openclaw/logs/commands.log` |
|
||||
| compaction-notifier | `session:compact:before`, `session:compact:after` | Sends visible chat notices when session compaction starts and finishes |
|
||||
| session-memory | `command:new`, `command:reset` | Saves session context to memory on `/new` or `/reset` |
|
||||
|
||||
Enable any bundled hook with `openclaw hooks enable <hook-name>`. Full details, config keys, and defaults: [Bundled hooks](/automation/hooks#bundled-hooks).
|
||||
|
||||
### command-logger log file
|
||||
|
||||
```bash
|
||||
tail -n 20 ~/.openclaw/logs/commands.log # recent commands
|
||||
cat ~/.openclaw/logs/commands.log | jq . # pretty-print
|
||||
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq . # filter by action
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `hooks list --json`, `info --json`, and `check --json` write structured JSON directly to stdout.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Automation hooks](/automation/hooks)
|
||||
442
docs/cli/index.md
Normal file
442
docs/cli/index.md
Normal file
@@ -0,0 +1,442 @@
|
||||
---
|
||||
summary: "OpenClaw CLI index: command list, global flags, and links to per-command pages"
|
||||
read_when:
|
||||
- Finding the right `openclaw` subcommand
|
||||
- Looking up global flags or output styling rules
|
||||
title: "CLI reference"
|
||||
---
|
||||
|
||||
`openclaw` is the main CLI entry point. Each core command has a dedicated
|
||||
reference page or is documented with the command it aliases; this index lists
|
||||
the commands, global flags, and output styling rules that apply across the CLI.
|
||||
|
||||
Setup commands by intent:
|
||||
|
||||
- `openclaw setup` and `openclaw onboard` run the full guided first-run path for gateway, model auth, workspace, channels, skills, and health.
|
||||
- `openclaw setup --baseline` creates the baseline config and workspace without walking the guided onboarding flow.
|
||||
- `openclaw configure` changes targeted parts of an existing setup: model auth, gateway, channels, plugins, or skills.
|
||||
- `openclaw channels add` configures channel accounts after the baseline exists; run without flags for guided setup, or with channel-specific flags for scripts.
|
||||
|
||||
## Command pages
|
||||
|
||||
| Area | Commands |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Setup and onboarding | [`crestodian`](/cli/crestodian) · [`setup`](/cli/setup) · [`onboard`](/cli/onboard) · [`configure`](/cli/configure) · [`config`](/cli/config) · [`completion`](/cli/completion) · [`doctor`](/cli/doctor) · [`dashboard`](/cli/dashboard) |
|
||||
| Reset, backup, and migration | [`backup`](/cli/backup) · [`migrate`](/cli/migrate) · [`reset`](/cli/reset) · [`uninstall`](/cli/uninstall) · [`update`](/cli/update) |
|
||||
| Messaging and agents | [`message`](/cli/message) · [`agent`](/cli/agent) · [`agents`](/cli/agents) · [`attach`](/cli/attach) · [`acp`](/cli/acp) · [`mcp`](/cli/mcp) |
|
||||
| Health and sessions | [`status`](/cli/status) · [`health`](/cli/health) · [`sessions`](/cli/sessions) |
|
||||
| Gateway and logs | [`gateway`](/cli/gateway) · [`logs`](/cli/logs) · [`system`](/cli/system) |
|
||||
| Models and inference | [`models`](/cli/models) · [`infer`](/cli/infer) · `capability` (alias for [`infer`](/cli/infer)) · [`memory`](/cli/memory) · [`commitments`](/cli/commitments) · [`wiki`](/cli/wiki) |
|
||||
| Network and nodes | [`directory`](/cli/directory) · [`nodes`](/cli/nodes) · [`devices`](/cli/devices) · [`node`](/cli/node) |
|
||||
| Runtime and sandbox | [`approvals`](/cli/approvals) · `exec-policy` (see [`approvals`](/cli/approvals)) · [`sandbox`](/cli/sandbox) · [`tui`](/cli/tui) · `chat`/`terminal` (aliases for [`tui --local`](/cli/tui)) · [`browser`](/cli/browser) |
|
||||
| Automation | [`cron`](/cli/cron) · [`tasks`](/cli/tasks) · [`hooks`](/cli/hooks) · [`webhooks`](/cli/webhooks) · [`transcripts`](/cli/transcripts) |
|
||||
| Discovery and docs | [`dns`](/cli/dns) · [`docs`](/cli/docs) |
|
||||
| Pairing and channels | [`pairing`](/cli/pairing) · [`qr`](/cli/qr) · [`channels`](/cli/channels) |
|
||||
| Security and plugins | [`security`](/cli/security) · [`secrets`](/cli/secrets) · [`skills`](/cli/skills) · [`plugins`](/cli/plugins) · [`proxy`](/cli/proxy) |
|
||||
| Legacy aliases | [`daemon`](/cli/daemon) (gateway service) · [`clawbot`](/cli/clawbot) (namespace) |
|
||||
| Plugins (optional) | [`path`](/cli/path) · [`policy`](/cli/policy) · [`voicecall`](/cli/voicecall) · [`workboard`](/cli/workboard) (if installed) |
|
||||
|
||||
## Global flags
|
||||
|
||||
| Flag | Purpose |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `--dev` | Isolate state under `~/.openclaw-dev`, default gateway port 19001, and shift derived ports |
|
||||
| `--profile <name>` | Isolate state under `~/.openclaw-<name>` (`OPENCLAW_STATE_DIR`/`OPENCLAW_CONFIG_PATH`) |
|
||||
| `--container <name>` | Run the CLI inside a running Podman/Docker container named `<name>` (default: env `OPENCLAW_CONTAINER`) |
|
||||
| `--log-level <level>` | Override the global log level for file + console output |
|
||||
| `--no-color` | Disable ANSI colors (`NO_COLOR=1` is also respected) |
|
||||
| `--update` | Shorthand for [`openclaw update`](/cli/update); works for both source checkouts and package installs |
|
||||
| `-V`, `--version`, `-v` | Print version and exit |
|
||||
|
||||
## Output modes
|
||||
|
||||
- ANSI colors and progress indicators render only in TTY sessions.
|
||||
- OSC-8 hyperlinks render as clickable links where supported; otherwise the
|
||||
CLI falls back to plain URLs.
|
||||
- `--json` (and `--plain` where supported) disables styling for clean output.
|
||||
- Long-running commands show a progress indicator (OSC 9;4 when supported).
|
||||
|
||||
## Color palette
|
||||
|
||||
OpenClaw uses a lobster palette for CLI output:
|
||||
|
||||
| Token | Hex | Used for |
|
||||
| -------------- | --------- | ------------------------------------ |
|
||||
| `accent` | `#FF5A2D` | Headings, labels, primary highlights |
|
||||
| `accentBright` | `#FF7A3D` | Command names, emphasis |
|
||||
| `accentDim` | `#D14A22` | Secondary highlight text |
|
||||
| `info` | `#FF8A5B` | Informational values |
|
||||
| `success` | `#2FBF71` | Success states |
|
||||
| `warn` | `#FFB020` | Warnings, option flags, fallbacks |
|
||||
| `error` | `#E23D2D` | Errors, failures |
|
||||
| `muted` | `#8B7F77` | De-emphasis, metadata |
|
||||
|
||||
Palette source of truth: `packages/terminal-core/src/palette.ts`.
|
||||
|
||||
## Command tree
|
||||
|
||||
<Accordion title="Full command tree">
|
||||
|
||||
This map covers core commands and their primary subcommands. Plugin-added
|
||||
subcommands (for example under `skills`, `plugins`, and `wiki`) evolve
|
||||
independently; run `<command> --help` for the authoritative, current list.
|
||||
|
||||
```
|
||||
openclaw [--dev] [--profile <name>] <command>
|
||||
crestodian
|
||||
setup
|
||||
onboard
|
||||
configure
|
||||
config
|
||||
get
|
||||
set
|
||||
unset
|
||||
file
|
||||
schema
|
||||
validate
|
||||
completion
|
||||
doctor
|
||||
dashboard
|
||||
backup
|
||||
create
|
||||
verify
|
||||
migrate
|
||||
list
|
||||
plan <provider>
|
||||
apply <provider>
|
||||
security
|
||||
audit
|
||||
secrets
|
||||
reload
|
||||
audit
|
||||
configure
|
||||
apply
|
||||
reset
|
||||
uninstall
|
||||
update
|
||||
wizard
|
||||
status
|
||||
repair
|
||||
channels
|
||||
list
|
||||
status
|
||||
capabilities
|
||||
resolve
|
||||
logs
|
||||
add
|
||||
remove
|
||||
login
|
||||
logout
|
||||
directory
|
||||
self
|
||||
peers list
|
||||
groups list|members
|
||||
skills
|
||||
search
|
||||
install
|
||||
update
|
||||
verify
|
||||
workshop list|inspect|propose-create|propose-update|revise|apply|reject|quarantine
|
||||
list
|
||||
info
|
||||
check
|
||||
plugins
|
||||
list
|
||||
search
|
||||
inspect
|
||||
install
|
||||
uninstall
|
||||
update
|
||||
enable
|
||||
disable
|
||||
doctor
|
||||
build
|
||||
validate
|
||||
init
|
||||
registry
|
||||
marketplace list|entries|refresh
|
||||
workboard
|
||||
list
|
||||
create
|
||||
show
|
||||
dispatch
|
||||
memory
|
||||
status
|
||||
index
|
||||
search
|
||||
transcripts
|
||||
list
|
||||
show
|
||||
path
|
||||
path
|
||||
resolve
|
||||
find
|
||||
set
|
||||
validate
|
||||
emit
|
||||
commitments
|
||||
list
|
||||
dismiss
|
||||
wiki
|
||||
status
|
||||
doctor
|
||||
init
|
||||
compile
|
||||
lint
|
||||
ingest
|
||||
okf import
|
||||
search
|
||||
get
|
||||
apply synthesis|metadata
|
||||
bridge import
|
||||
unsafe-local import
|
||||
chatgpt import|rollback
|
||||
obsidian status|search|open|command|daily
|
||||
message
|
||||
send
|
||||
broadcast
|
||||
poll
|
||||
react
|
||||
reactions
|
||||
read
|
||||
edit
|
||||
delete
|
||||
pin
|
||||
unpin
|
||||
pins
|
||||
permissions
|
||||
search
|
||||
thread create|list|reply
|
||||
emoji list|upload
|
||||
sticker send|upload
|
||||
role info|add|remove
|
||||
channel info|list
|
||||
member info
|
||||
voice status
|
||||
event list|create
|
||||
timeout
|
||||
kick
|
||||
ban
|
||||
agent
|
||||
agents
|
||||
list
|
||||
add
|
||||
delete
|
||||
bindings
|
||||
bind
|
||||
unbind
|
||||
set-identity
|
||||
attach
|
||||
acp
|
||||
mcp
|
||||
serve
|
||||
list
|
||||
show
|
||||
set
|
||||
unset
|
||||
status
|
||||
health
|
||||
sessions
|
||||
cleanup
|
||||
tasks
|
||||
list
|
||||
audit
|
||||
maintenance
|
||||
show
|
||||
notify
|
||||
cancel
|
||||
flow list|show|cancel
|
||||
gateway
|
||||
call
|
||||
usage-cost
|
||||
health
|
||||
stability
|
||||
diagnostics export
|
||||
status
|
||||
probe
|
||||
discover
|
||||
install
|
||||
uninstall
|
||||
start
|
||||
stop
|
||||
restart
|
||||
run
|
||||
daemon
|
||||
status
|
||||
install
|
||||
uninstall
|
||||
start
|
||||
stop
|
||||
restart
|
||||
logs
|
||||
system
|
||||
event
|
||||
heartbeat last|enable|disable
|
||||
presence
|
||||
models
|
||||
list
|
||||
status
|
||||
set
|
||||
set-image
|
||||
aliases list|add|remove
|
||||
fallbacks list|add|remove|clear
|
||||
image-fallbacks list|add|remove|clear
|
||||
scan
|
||||
auth list|add|login|setup-token|paste-token|paste-api-key|login-github-copilot
|
||||
auth order get|set|clear
|
||||
infer (alias: capability)
|
||||
list
|
||||
inspect
|
||||
model run|list|inspect|providers|auth login|logout|status
|
||||
image generate|edit|describe|describe-many|providers
|
||||
audio transcribe|providers
|
||||
tts convert|voices|personas|providers|status|enable|disable|set-provider|set-persona
|
||||
video generate|describe|providers
|
||||
web search|fetch|providers
|
||||
embedding create|providers
|
||||
sandbox
|
||||
list
|
||||
recreate
|
||||
explain
|
||||
cron
|
||||
status
|
||||
list
|
||||
get
|
||||
add
|
||||
edit
|
||||
rm
|
||||
enable
|
||||
disable
|
||||
runs
|
||||
run
|
||||
nodes
|
||||
status
|
||||
describe
|
||||
list
|
||||
pending
|
||||
approve
|
||||
reject
|
||||
rename
|
||||
invoke
|
||||
notify
|
||||
push
|
||||
canvas snapshot|present|hide|navigate|eval
|
||||
canvas a2ui push|reset
|
||||
camera list|snap|clip
|
||||
screen record
|
||||
location get
|
||||
devices
|
||||
list
|
||||
remove
|
||||
clear
|
||||
approve
|
||||
reject
|
||||
rotate
|
||||
revoke
|
||||
node
|
||||
run
|
||||
status
|
||||
install
|
||||
uninstall
|
||||
stop
|
||||
restart
|
||||
approvals
|
||||
get
|
||||
set
|
||||
allowlist add|remove
|
||||
exec-policy
|
||||
show
|
||||
preset
|
||||
set
|
||||
browser
|
||||
status
|
||||
start
|
||||
stop
|
||||
reset-profile
|
||||
tabs
|
||||
open
|
||||
focus
|
||||
close
|
||||
profiles
|
||||
create-profile
|
||||
delete-profile
|
||||
screenshot
|
||||
snapshot
|
||||
navigate
|
||||
resize
|
||||
click
|
||||
type
|
||||
press
|
||||
hover
|
||||
drag
|
||||
select
|
||||
upload
|
||||
fill
|
||||
dialog
|
||||
wait
|
||||
evaluate
|
||||
console
|
||||
pdf
|
||||
hooks
|
||||
list
|
||||
info
|
||||
check
|
||||
enable
|
||||
disable
|
||||
install
|
||||
update
|
||||
webhooks
|
||||
gmail setup|run
|
||||
proxy
|
||||
start
|
||||
run
|
||||
coverage
|
||||
sessions
|
||||
query
|
||||
blob
|
||||
purge
|
||||
pairing
|
||||
list
|
||||
approve
|
||||
qr
|
||||
clawbot
|
||||
qr
|
||||
docs
|
||||
dns
|
||||
setup
|
||||
tui
|
||||
chat (alias: tui --local)
|
||||
terminal (alias: tui --local)
|
||||
```
|
||||
|
||||
Plugins can add additional top-level commands, such as
|
||||
[`openclaw workboard`](/cli/workboard) or `openclaw voicecall`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Chat slash commands
|
||||
|
||||
Chat messages support `/...` commands. See [slash commands](/tools/slash-commands).
|
||||
|
||||
Highlights:
|
||||
|
||||
- `/status` - quick diagnostics.
|
||||
- `/trace` - session-scoped plugin trace/debug lines.
|
||||
- `/config` - persisted config changes.
|
||||
- `/debug` - runtime-only config overrides (memory, not disk; requires `commands.debug: true`).
|
||||
|
||||
## Usage tracking
|
||||
|
||||
`openclaw status --usage` and the Control UI surface provider usage/quota when
|
||||
OAuth/API credentials are available. Data comes directly from provider usage
|
||||
endpoints and is normalized to `X% left`. Providers with current usage
|
||||
windows: Anthropic, Gemini CLI, GitHub Copilot, MiniMax, OpenAI Codex,
|
||||
Xiaomi, and z.ai.
|
||||
|
||||
See [Usage tracking](/concepts/usage-tracking) for details.
|
||||
|
||||
## Related
|
||||
|
||||
- [Slash commands](/tools/slash-commands)
|
||||
- [Configuration](/gateway/configuration)
|
||||
- [Environment](/help/environment)
|
||||
318
docs/cli/infer.md
Normal file
318
docs/cli/infer.md
Normal file
@@ -0,0 +1,318 @@
|
||||
---
|
||||
summary: "Infer-first CLI for provider-backed model, image, audio, TTS, video, web, and embedding workflows"
|
||||
read_when:
|
||||
- Adding or modifying `openclaw infer` commands
|
||||
- Designing stable headless capability automation
|
||||
title: "Inference CLI"
|
||||
---
|
||||
|
||||
`openclaw infer` is the canonical headless surface for provider-backed inference. It exposes capability families (`model`, `image`, `audio`, `tts`, `video`, `web`, `embedding`), not raw gateway RPC names or agent tool ids. `openclaw capability ...` is an alias for the same command tree.
|
||||
|
||||
Reasons to prefer it over a one-off provider wrapper:
|
||||
|
||||
- Reuses providers and models already configured in OpenClaw.
|
||||
- Stable `--json` envelope for scripts and agent-driven automation (see [JSON output](#json-output)).
|
||||
- Runs the normal local path without the gateway for most subcommands.
|
||||
- For end-to-end provider checks, it exercises the shipped CLI, config loading, default-agent resolution, bundled plugin activation, and the shared capability runtime before the provider request goes out.
|
||||
|
||||
## Turn infer into a skill
|
||||
|
||||
Copy and paste this to an agent:
|
||||
|
||||
```text
|
||||
Read https://docs.openclaw.ai/cli/infer, then create a skill that routes my common workflows to `openclaw infer`.
|
||||
Focus on model runs, image generation, video generation, audio transcription, TTS, web search, and embeddings.
|
||||
```
|
||||
|
||||
A good infer-based skill maps common user intents to the right subcommand, includes a few canonical examples per workflow, prefers `openclaw infer ...` over lower-level alternatives, and does not re-document the entire infer surface in the skill body.
|
||||
|
||||
## Command tree
|
||||
|
||||
```text
|
||||
openclaw infer
|
||||
list
|
||||
inspect
|
||||
|
||||
model
|
||||
run
|
||||
list
|
||||
inspect
|
||||
providers
|
||||
auth login
|
||||
auth logout
|
||||
auth status
|
||||
|
||||
image
|
||||
generate
|
||||
edit
|
||||
describe
|
||||
describe-many
|
||||
providers
|
||||
|
||||
audio
|
||||
transcribe
|
||||
providers
|
||||
|
||||
tts
|
||||
convert
|
||||
voices
|
||||
providers
|
||||
personas
|
||||
status
|
||||
enable
|
||||
disable
|
||||
set-provider
|
||||
set-persona
|
||||
|
||||
video
|
||||
generate
|
||||
describe
|
||||
providers
|
||||
|
||||
web
|
||||
search
|
||||
fetch
|
||||
providers
|
||||
|
||||
embedding
|
||||
create
|
||||
providers
|
||||
```
|
||||
|
||||
`infer list` / `infer inspect --name <capability>` show this tree as data (capability id, transports, description).
|
||||
|
||||
## Common tasks
|
||||
|
||||
| Task | Command | Notes |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| Run a text/model prompt | `openclaw infer model run --prompt "..." --json` | Local by default |
|
||||
| Run a model prompt on images | `openclaw infer model run --prompt "Describe this" --file ./image.png --model provider/model` | Repeat `--file` for multiple images |
|
||||
| Generate an image | `openclaw infer image generate --prompt "..." --json` | Use `image edit` when starting from an existing file |
|
||||
| Describe an image file or URL | `openclaw infer image describe --file ./image.png --prompt "..." --json` | `--model` must be an image-capable `<provider/model>` |
|
||||
| Transcribe audio | `openclaw infer audio transcribe --file ./memo.m4a --json` | `--model` must be `<provider/model>` |
|
||||
| Synthesize speech | `openclaw infer tts convert --text "..." --output ./speech.mp3 --json` | `tts status` only runs through the gateway |
|
||||
| Generate a video | `openclaw infer video generate --prompt "..." --json` | Supports provider hints such as `--resolution` |
|
||||
| Describe a video file | `openclaw infer video describe --file ./clip.mp4 --json` | `--model` must be `<provider/model>` |
|
||||
| Search the web | `openclaw infer web search --query "..." --json` | |
|
||||
| Fetch a web page | `openclaw infer web fetch --url https://example.com --json` | |
|
||||
| Create embeddings | `openclaw infer embedding create --text "..." --json` | |
|
||||
|
||||
## Behavior
|
||||
|
||||
- Use `--json` when the output feeds another command or script; text output otherwise.
|
||||
- Use `--provider` or `--model provider/model` to pin a specific backend.
|
||||
- Use `model run --thinking <level>` for a one-shot thinking/reasoning override: `off`, `minimal`, `low`, `medium`, `high`, `adaptive`, `xhigh`, or `max`.
|
||||
- For `image describe`, `audio transcribe`, and `video describe`, `--model` must use the form `<provider/model>`.
|
||||
- For `image describe`, `--file` accepts local paths and HTTP(S) URLs; remote URLs go through the normal media-fetch SSRF policy.
|
||||
- Stateless execution commands (`model run`, `image *`, `audio *`, `video *`, `web *`, `embedding *`) default to local. Gateway-managed state commands (`tts status`) default to gateway.
|
||||
- The local path never requires the gateway to be running.
|
||||
- Local `model run` is a lean one-shot provider completion: it resolves the configured agent model and auth but does not start a chat-agent turn, load tools, or open bundled MCP servers.
|
||||
- `model run --file` attaches image files (auto-detected MIME type) to the prompt; repeat `--file` for multiple images. Non-image files are rejected — use `infer audio transcribe` or `infer video describe` instead.
|
||||
- `model run --gateway` exercises Gateway routing, saved auth, provider selection, and the embedded runtime, but stays a raw model probe: no prior session transcript, bootstrap/AGENTS context, tools, or bundled MCP servers.
|
||||
- `model run --gateway --model <provider/model>` requires a trusted-operator gateway credential, because it asks the Gateway to run a one-off provider/model override.
|
||||
|
||||
## Model
|
||||
|
||||
Text inference and model/provider inspection.
|
||||
|
||||
```bash
|
||||
openclaw infer model run --prompt "Reply with exactly: smoke-ok" --json
|
||||
openclaw infer model run --prompt "Summarize this changelog entry" --model openai/gpt-5.4 --json
|
||||
openclaw infer model run --prompt "Describe this image in one sentence" --file ./photo.jpg --model google/gemini-2.5-flash --json
|
||||
openclaw infer model run --prompt "Use more reasoning here" --thinking high --json
|
||||
openclaw infer model providers --json
|
||||
openclaw infer model inspect --model gpt-5.5 --json
|
||||
```
|
||||
|
||||
Use full `<provider/model>` refs with `--local` to smoke-test one provider without starting the Gateway or loading the agent tool surface:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local --model anthropic/claude-sonnet-4-6 --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model cerebras/zai-glm-4.7 --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model google/gemini-2.5-flash --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model groq/llama-3.1-8b-instant --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model mistral/mistral-medium-3-5 --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model mistral/mistral-small-latest --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model openai/gpt-5.5 --prompt "Reply with exactly: pong" --json
|
||||
openclaw infer model run --local --model ollama/qwen2.5vl:7b --prompt "Describe this image." --file ./photo.jpg --json
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Local `model run` is the narrowest CLI smoke for provider/model/auth health: for non-ChatGPT-Codex providers it sends only the supplied prompt.
|
||||
- Local `model run --model <provider/model>` can resolve exact bundled static-catalog rows (the same rows `openclaw models list --all` shows) before that provider is written to config. Provider auth is still required; missing credentials fail as auth errors, not `Unknown model`.
|
||||
- For Mistral Medium 3.5 reasoning probes, leave temperature unset/default. Mistral rejects `reasoning_effort="high"` with `temperature: 0`; use default temperature or a non-zero value such as `0.7`.
|
||||
- OpenAI ChatGPT/Codex OAuth (`openai-chatgpt-responses` API) local probes add a minimal system instruction so the transport can populate its required `instructions` field — no full agent context, tools, memory, or session transcript.
|
||||
- `model run --file` attaches image content directly to the single user message. Common formats (PNG, JPEG, WebP) work when MIME type is detected as `image/*`; unsupported or unrecognized files fail before the provider is called. Use `infer image describe` instead when you want OpenClaw's image-model routing and fallbacks rather than a direct multimodal-model probe.
|
||||
- The selected model must support image input; text-only models may reject the request at the provider layer.
|
||||
- `model run --prompt` must contain non-whitespace text; empty prompts are rejected before any provider or Gateway call.
|
||||
- Local `model run` exits non-zero when the provider returns no text output, so unreachable providers and empty completions do not look like successful probes.
|
||||
- Use `model run --gateway` to test Gateway routing or agent-runtime setup while keeping the model input raw. Use `openclaw agent` or a chat surface for full agent context, tools, memory, and session transcript.
|
||||
- `--thinking adaptive` maps to the completion-runtime level `medium`; `--thinking max` maps to `max` for OpenAI models that support the native max effort, otherwise `xhigh`.
|
||||
- `model auth login`, `model auth logout`, and `model auth status` manage saved provider auth state.
|
||||
|
||||
## Image
|
||||
|
||||
Generation, edit, and description.
|
||||
|
||||
```bash
|
||||
openclaw infer image generate --prompt "friendly lobster illustration" --json
|
||||
openclaw infer image generate --prompt "cinematic product photo of headphones" --json
|
||||
openclaw infer image generate --model openai/gpt-image-1.5 --output-format png --background transparent --prompt "simple red circle sticker on a transparent background" --json
|
||||
openclaw infer image generate --model openai/gpt-image-2 --quality low --openai-moderation low --prompt "low-cost draft poster" --json
|
||||
openclaw infer image generate --prompt "slow image backend" --timeout-ms 180000 --json
|
||||
openclaw infer image edit --file ./logo.png --model openai/gpt-image-1.5 --output-format png --background transparent --prompt "keep the logo, remove the background" --json
|
||||
openclaw infer image edit --file ./poster.png --prompt "make this a vertical story ad" --size 2160x3840 --aspect-ratio 9:16 --resolution 4K --json
|
||||
openclaw infer image describe --file ./photo.jpg --json
|
||||
openclaw infer image describe --file https://example.com/photo.png --json
|
||||
openclaw infer image describe --file ./receipt.jpg --prompt "Extract the merchant, date, and total" --json
|
||||
openclaw infer image describe-many --file ./before.png --file ./after.png --prompt "Compare the screenshots and list visible UI changes" --json
|
||||
openclaw infer image describe --file ./ui-screenshot.png --model openai/gpt-5.4-mini --json
|
||||
openclaw infer image describe --file ./photo.jpg --model ollama/qwen2.5vl:7b --prompt "Describe the image in one sentence" --timeout-ms 300000 --json
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Use `image edit` when starting from existing input files; `--size`, `--aspect-ratio`, or `--resolution` add geometry hints on providers/models that support them.
|
||||
- `--output-format png --background transparent` with `--model openai/gpt-image-1.5` gives transparent-background OpenAI PNG output; `--openai-background` is an OpenAI-specific alias for the same hint. Providers that do not declare background support report it as an ignored override (see `ignoredOverrides` in the [JSON envelope](#json-output)).
|
||||
- `--quality low|medium|high|auto` works for providers that support image-quality hints, including OpenAI. OpenAI also accepts `--openai-moderation low|auto`.
|
||||
- `image providers --json` lists which bundled image providers are discoverable, configured, selected, and which generation/edit capabilities each exposes.
|
||||
- `image generate --model <provider/model> --json` is the narrowest live smoke for image-generation changes:
|
||||
|
||||
```bash
|
||||
openclaw infer image providers --json
|
||||
openclaw infer image generate \
|
||||
--model google/gemini-3.1-flash-image-preview \
|
||||
--prompt "Minimal flat test image: one blue square on a white background, no text." \
|
||||
--output ./openclaw-infer-image-smoke.png \
|
||||
--json
|
||||
```
|
||||
|
||||
The response reports `ok`, `provider`, `model`, `attempts`, and written output paths. When `--output` is set, the final extension may follow the provider's returned MIME type.
|
||||
|
||||
- For `image describe` and `image describe-many`, use `--prompt` for a task-specific instruction (OCR, comparison, UI inspection, concise captioning).
|
||||
- Use `--timeout-ms` for slow local vision models or cold Ollama starts.
|
||||
- For `image describe`, an explicit `--model` (must be an image-capable `<provider/model>`) runs first, then tries configured `agents.defaults.imageModel.fallbacks` if that call fails. Input-preparation errors (missing file, unsupported URL) fail before any fallback attempt, and the model must be image-capable in the model catalog or provider config.
|
||||
- For local Ollama vision models, pull the model first and set `OLLAMA_API_KEY` to any placeholder value, for example `ollama-local`. See [Ollama](/providers/ollama#vision-and-image-description).
|
||||
|
||||
## Audio
|
||||
|
||||
File transcription (not realtime session management).
|
||||
|
||||
```bash
|
||||
openclaw infer audio transcribe --file ./memo.m4a --json
|
||||
openclaw infer audio transcribe --file ./team-sync.m4a --language en --prompt "Focus on names and action items" --json
|
||||
openclaw infer audio transcribe --file ./memo.m4a --model openai/whisper-1 --json
|
||||
```
|
||||
|
||||
`--model` must be `<provider/model>`.
|
||||
|
||||
## TTS
|
||||
|
||||
Speech synthesis and TTS provider/persona state.
|
||||
|
||||
```bash
|
||||
openclaw infer tts convert --text "hello from openclaw" --output ./hello.mp3 --json
|
||||
openclaw infer tts convert --text "Your build is complete" --output ./build-complete.mp3 --json
|
||||
openclaw infer tts providers --json
|
||||
openclaw infer tts personas --json
|
||||
openclaw infer tts status --json
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `tts status` only supports `--gateway` (it reflects gateway-managed TTS state).
|
||||
- Use `tts providers`, `tts voices`, `tts personas`, `tts set-provider`, and `tts set-persona` to inspect and configure TTS behavior.
|
||||
|
||||
## Video
|
||||
|
||||
Generation and description.
|
||||
|
||||
```bash
|
||||
openclaw infer video generate --prompt "cinematic sunset over the ocean" --json
|
||||
openclaw infer video generate --prompt "slow drone shot over a forest lake" --resolution 768P --duration 6 --json
|
||||
openclaw infer video describe --file ./clip.mp4 --json
|
||||
openclaw infer video describe --file ./clip.mp4 --model openai/gpt-5.4-mini --json
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `video generate` accepts `--size`, `--aspect-ratio`, `--resolution`, `--duration`, `--audio`, `--watermark`, and `--timeout-ms`, forwarded to the video-generation runtime.
|
||||
- `--model` must be `<provider/model>` for `video describe`.
|
||||
|
||||
## Web
|
||||
|
||||
Search and fetch.
|
||||
|
||||
```bash
|
||||
openclaw infer web search --query "OpenClaw docs" --json
|
||||
openclaw infer web search --query "OpenClaw infer web providers" --json
|
||||
openclaw infer web fetch --url https://docs.openclaw.ai/cli/infer --json
|
||||
openclaw infer web providers --json
|
||||
```
|
||||
|
||||
`web providers` lists available, configured, and selected providers for search and fetch.
|
||||
|
||||
## Embedding
|
||||
|
||||
Vector creation and embedding-provider inspection.
|
||||
|
||||
```bash
|
||||
openclaw infer embedding create --text "friendly lobster" --json
|
||||
openclaw infer embedding create --text "customer support ticket: delayed shipment" --model openai/text-embedding-3-large --json
|
||||
openclaw infer embedding providers --json
|
||||
```
|
||||
|
||||
## JSON output
|
||||
|
||||
Infer commands normalize JSON output under a shared envelope:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"capability": "image.generate",
|
||||
"transport": "local",
|
||||
"provider": "openai",
|
||||
"model": "gpt-image-2",
|
||||
"attempts": [],
|
||||
"outputs": []
|
||||
}
|
||||
```
|
||||
|
||||
Stable top-level fields:
|
||||
|
||||
- `ok`
|
||||
- `capability`
|
||||
- `transport`
|
||||
- `provider`
|
||||
- `model`
|
||||
- `attempts`
|
||||
- `inputs` (image attachments sent with the request, when applicable)
|
||||
- `outputs`
|
||||
- `ignoredOverrides` (hint keys a provider does not support, when applicable)
|
||||
- `error`
|
||||
|
||||
For generated media commands, `outputs` contains files written by OpenClaw. Use the `path`, `mimeType`, `size`, and any media-specific dimensions in that array for automation instead of parsing human-readable stdout.
|
||||
|
||||
## Common pitfalls
|
||||
|
||||
```bash
|
||||
# Bad
|
||||
openclaw infer media image generate --prompt "friendly lobster"
|
||||
|
||||
# Good
|
||||
openclaw infer image generate --prompt "friendly lobster"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bad
|
||||
openclaw infer audio transcribe --file ./memo.m4a --model whisper-1 --json
|
||||
|
||||
# Good
|
||||
openclaw infer audio transcribe --file ./memo.m4a --model openai/whisper-1 --json
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Models](/concepts/models)
|
||||
61
docs/cli/logs.md
Normal file
61
docs/cli/logs.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw logs` (tail gateway logs via RPC)"
|
||||
read_when:
|
||||
- You need to tail Gateway logs remotely (without SSH)
|
||||
- You want JSON log lines for tooling
|
||||
title: "Logs"
|
||||
---
|
||||
|
||||
# `openclaw logs`
|
||||
|
||||
Tail Gateway file logs over RPC. Works in remote mode.
|
||||
|
||||
## Options
|
||||
|
||||
- `--limit <n>`: max log lines to return (default `200`)
|
||||
- `--max-bytes <n>`: max bytes to read from the log file (default `250000`)
|
||||
- `--follow`: follow the log stream
|
||||
- `--interval <ms>`: polling interval while following (default `1000`)
|
||||
- `--json`: emit line-delimited JSON events
|
||||
- `--plain`: plain text output without styled formatting
|
||||
- `--no-color`: disable ANSI colors
|
||||
- `--local-time`: render timestamps in your local timezone (default)
|
||||
- `--utc`: render timestamps in UTC
|
||||
|
||||
## Shared Gateway RPC options
|
||||
|
||||
- `--url <url>`: Gateway WebSocket URL
|
||||
- `--token <token>`: Gateway token
|
||||
- `--timeout <ms>`: timeout in ms (default `30000`)
|
||||
- `--expect-final`: wait for a final response when the Gateway call is agent-backed
|
||||
|
||||
Passing `--url` skips auto-applied config credentials; include `--token` explicitly if the target Gateway requires auth.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw logs
|
||||
openclaw logs --follow
|
||||
openclaw logs --follow --interval 2000
|
||||
openclaw logs --limit 500 --max-bytes 500000
|
||||
openclaw logs --json
|
||||
openclaw logs --plain
|
||||
openclaw logs --no-color
|
||||
openclaw logs --utc
|
||||
openclaw logs --follow --local-time
|
||||
openclaw logs --url ws://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
```
|
||||
|
||||
## Fallback and recovery behavior
|
||||
|
||||
- If the implicit local loopback Gateway asks for pairing, closes during connect, or times out before `logs.tail` answers, `openclaw logs` falls back to the configured Gateway file log automatically. Explicit `--url` targets never use this fallback.
|
||||
- `--follow` does not fall back to that configured file after an implicit local Gateway RPC failure — a stale side-by-side file could mislead a live tail. On Linux it instead uses the active user-systemd Gateway journal by PID when available (prints the selected source); otherwise it keeps retrying the live Gateway.
|
||||
- During `--follow`, transient disconnects (WebSocket close, timeout, connection drop) trigger automatic reconnection with exponential backoff: up to 8 retries, capped at 30s between attempts. A warning prints to stderr on each retry, and a `[logs] gateway reconnected` notice prints once a poll succeeds. In `--json` mode both are emitted as `{"type":"notice"}` records on stderr. Non-recoverable errors (auth failure, bad configuration) still exit immediately.
|
||||
- In `--follow --json` mode, log-source transitions are emitted as `{"type":"meta"}` records. Track cursors per `sourceKind`: a stream can move from Gateway file output (`sourceKind: "file"`) to local journal fallback (`sourceKind: "journal"`, `localFallback: true`, with `service.pid`/`service.unit`) and back to Gateway file output after recovery. Do not assume one stable source or cursor for the whole session, and tolerate overlapping lines when recovery replays the Gateway file cursor.
|
||||
|
||||
## Related
|
||||
|
||||
- [Logging overview](/logging)
|
||||
- [Gateway CLI](/cli/gateway)
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway logging](/gateway/logging)
|
||||
831
docs/cli/mcp.md
Normal file
831
docs/cli/mcp.md
Normal file
@@ -0,0 +1,831 @@
|
||||
---
|
||||
summary: "Expose OpenClaw channel conversations over MCP and manage saved MCP server definitions"
|
||||
read_when:
|
||||
- Connecting Codex, Claude Code, or another MCP client to OpenClaw-backed channels
|
||||
- Running `openclaw mcp serve`
|
||||
- Managing OpenClaw-saved MCP server definitions
|
||||
title: "MCP"
|
||||
sidebarTitle: "MCP"
|
||||
---
|
||||
|
||||
`openclaw mcp` has two jobs:
|
||||
|
||||
- run OpenClaw as an MCP server with `openclaw mcp serve`
|
||||
- manage OpenClaw-managed outbound MCP server definitions with `list`, `show`, `status`, `doctor`, `probe`, `add`, `set`, `configure`, `tools`, `login`, `logout`, `reload`, and `unset`
|
||||
|
||||
`serve` is OpenClaw acting as an MCP server. The other subcommands are OpenClaw acting as an MCP client-side registry for servers its own runtimes may consume later.
|
||||
|
||||
<Note>
|
||||
`list`, `show`, `set`, and `unset` only read and write OpenClaw-managed `mcp.servers` entries in OpenClaw config. They do not include mcporter servers from `config/mcporter.json`; use `mcporter list` for that registry.
|
||||
</Note>
|
||||
|
||||
Use [`openclaw acp`](/cli/acp) when OpenClaw should host a coding harness session itself and route that runtime through ACP.
|
||||
|
||||
## Choose the right MCP path
|
||||
|
||||
| Goal | Use | Why |
|
||||
| ------------------------------------------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| Let an external MCP client read/send OpenClaw channel conversations | `openclaw mcp serve` | OpenClaw is the MCP server and exposes Gateway-backed conversations over stdio. |
|
||||
| Save third-party MCP servers for OpenClaw-managed agent runs | `openclaw mcp add`, `set`, `configure`, `tools`, `login` | OpenClaw is the MCP client-side registry and later projects those servers into eligible runtimes. |
|
||||
| Check a saved server without running an agent turn | `openclaw mcp status`, `doctor`, `probe` | `status` and `doctor` inspect config; `probe` opens a live MCP connection and lists capabilities. |
|
||||
| Edit MCP config from a browser | Control UI `/mcp` | The page shows inventory, enablement, OAuth/filter summaries, command hints, and a scoped `mcp` editor. |
|
||||
| Give Codex app-server a scoped native MCP server | `mcp.servers.<name>.codex` | The `codex` block only affects Codex app-server thread projection and is stripped before native config handoff. |
|
||||
| Run ACP-hosted harness sessions | [`openclaw acp`](/cli/acp) and [ACP Agents](/tools/acp-agents-setup) | ACP bridge mode does not accept per-session MCP server injection; configure gateway/plugin bridges instead. |
|
||||
|
||||
<Tip>
|
||||
If you are not sure which path you need, start with `openclaw mcp status --verbose`. It shows what OpenClaw has saved without starting any MCP servers.
|
||||
</Tip>
|
||||
|
||||
## OpenClaw as an MCP server
|
||||
|
||||
This is the `openclaw mcp serve` path.
|
||||
|
||||
### When to use serve
|
||||
|
||||
Use `openclaw mcp serve` when:
|
||||
|
||||
- Codex, Claude Code, or another MCP client should talk directly to OpenClaw-backed channel conversations
|
||||
- you already have a local or remote OpenClaw Gateway with routed sessions
|
||||
- you want one MCP server that works across OpenClaw's channel backends instead of running separate per-channel bridges
|
||||
|
||||
Use [`openclaw acp`](/cli/acp) instead when OpenClaw should host the coding runtime itself and keep the agent session inside OpenClaw.
|
||||
|
||||
### How it works
|
||||
|
||||
`openclaw mcp serve` starts a stdio MCP server. The MCP client owns that process. While the client keeps the stdio session open, the bridge connects to a local or remote OpenClaw Gateway over WebSocket and exposes routed channel conversations over MCP.
|
||||
|
||||
<Steps>
|
||||
<Step title="Client spawns the bridge">
|
||||
The MCP client spawns `openclaw mcp serve`.
|
||||
</Step>
|
||||
<Step title="Bridge connects to Gateway">
|
||||
The bridge connects to the OpenClaw Gateway over WebSocket.
|
||||
</Step>
|
||||
<Step title="Sessions become MCP conversations">
|
||||
Routed sessions become MCP conversations and transcript/history tools.
|
||||
</Step>
|
||||
<Step title="Live events queue">
|
||||
Live events are queued in memory while the bridge is connected.
|
||||
</Step>
|
||||
<Step title="Optional Claude push">
|
||||
If Claude channel mode is enabled, the same session can also receive Claude-specific push notifications.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Important behavior">
|
||||
- live queue state starts when the bridge connects
|
||||
- older transcript history is read with `messages_read`
|
||||
- Claude push notifications only exist while the MCP session is alive
|
||||
- when the client disconnects, the bridge exits and the live queue is gone
|
||||
- one-shot agent entry points such as `openclaw agent` and `openclaw infer model run` retire any bundled MCP runtimes they open when the reply completes, so repeated scripted runs do not accumulate stdio MCP child processes
|
||||
- stdio MCP servers launched by OpenClaw (bundled or user-configured) are torn down as a process tree on shutdown, so child subprocesses started by the server do not survive after the parent stdio client exits
|
||||
- deleting or resetting a session disposes that session's MCP clients through the shared runtime cleanup path, so there are no lingering stdio connections tied to a removed session
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Choose a client mode
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Generic MCP clients">
|
||||
Standard MCP tools only. Use `conversations_list`, `messages_read`, `events_poll`, `events_wait`, `messages_send`, and the approval tools.
|
||||
</Tab>
|
||||
<Tab title="Claude Code">
|
||||
Standard MCP tools plus the Claude-specific channel adapter. Enable `--claude-channel-mode on` or leave the default `auto`.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
Today, `auto` behaves the same as `on`. There is no client capability detection yet.
|
||||
</Note>
|
||||
|
||||
### What serve exposes
|
||||
|
||||
The bridge uses existing Gateway session route metadata to expose channel-backed conversations. A conversation appears when OpenClaw already has session state with a known route such as:
|
||||
|
||||
- `channel`
|
||||
- recipient or destination metadata
|
||||
- optional `accountId`
|
||||
- optional `threadId`
|
||||
|
||||
This gives MCP clients one place to:
|
||||
|
||||
- list recent routed conversations
|
||||
- read recent transcript history
|
||||
- wait for new inbound events
|
||||
- send a reply back through the same route
|
||||
- see approval requests that arrive while the bridge is connected
|
||||
|
||||
### Usage
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Local Gateway">
|
||||
```bash
|
||||
openclaw mcp serve
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Remote Gateway (token)">
|
||||
```bash
|
||||
openclaw mcp serve --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Remote Gateway (password)">
|
||||
```bash
|
||||
openclaw mcp serve --url wss://gateway-host:18789 --password-file ~/.openclaw/gateway.password
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Verbose / Claude off">
|
||||
```bash
|
||||
openclaw mcp serve --verbose
|
||||
openclaw mcp serve --claude-channel-mode off
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Bridge tools
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="conversations_list">
|
||||
Lists recent session-backed conversations that already have route metadata in Gateway session state.
|
||||
|
||||
Filters: `limit` (max 500), `search`, `channel`, `includeDerivedTitles`, `includeLastMessage`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="conversation_get">
|
||||
Returns one conversation by `session_key` using a direct Gateway session lookup.
|
||||
</Accordion>
|
||||
<Accordion title="messages_read">
|
||||
Reads recent transcript messages for one session-backed conversation. `limit` defaults to 20, max 200.
|
||||
</Accordion>
|
||||
<Accordion title="attachments_fetch">
|
||||
Extracts non-text message content blocks from one transcript message. This is a metadata view over transcript content, not a standalone durable attachment blob store.
|
||||
</Accordion>
|
||||
<Accordion title="events_poll">
|
||||
Reads queued live events since a numeric cursor. `limit` max 200.
|
||||
</Accordion>
|
||||
<Accordion title="events_wait">
|
||||
Long-polls until the next matching queued event arrives or a timeout expires (default 30s, max 300s).
|
||||
|
||||
Use this when a generic MCP client needs near-real-time delivery without a Claude-specific push protocol.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="messages_send">
|
||||
Sends text back through the same route already recorded on the session.
|
||||
|
||||
Current behavior:
|
||||
|
||||
- requires an existing conversation route
|
||||
- uses the session's channel, recipient, account id, and thread id
|
||||
- sends text only
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="permissions_list_open">
|
||||
Lists pending exec/plugin approval requests the bridge has observed since it connected to the Gateway.
|
||||
</Accordion>
|
||||
<Accordion title="permissions_respond">
|
||||
Resolves one pending exec/plugin approval request with:
|
||||
|
||||
- `allow-once`
|
||||
- `allow-always`
|
||||
- `deny`
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Event model
|
||||
|
||||
The bridge keeps an in-memory event queue while it is connected.
|
||||
|
||||
Current event types:
|
||||
|
||||
- `message`
|
||||
- `exec_approval_requested`
|
||||
- `exec_approval_resolved`
|
||||
- `plugin_approval_requested`
|
||||
- `plugin_approval_resolved`
|
||||
- `claude_permission_request`
|
||||
|
||||
<Warning>
|
||||
- the queue is live-only; it starts when the MCP bridge starts
|
||||
- `events_poll` and `events_wait` do not replay older Gateway history by themselves
|
||||
- durable backlog should be read with `messages_read`
|
||||
|
||||
</Warning>
|
||||
|
||||
### Claude channel notifications
|
||||
|
||||
The bridge can also expose Claude-specific channel notifications. This is the OpenClaw equivalent of a Claude Code channel adapter: standard MCP tools remain available, but live inbound messages can also arrive as Claude-specific MCP notifications.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="off">
|
||||
`--claude-channel-mode off`: standard MCP tools only.
|
||||
</Tab>
|
||||
<Tab title="on">
|
||||
`--claude-channel-mode on`: enable Claude channel notifications.
|
||||
</Tab>
|
||||
<Tab title="auto (default)">
|
||||
`--claude-channel-mode auto`: current default; same bridge behavior as `on`.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
When Claude channel mode is enabled, the server advertises Claude experimental capabilities and can emit:
|
||||
|
||||
- `notifications/claude/channel`
|
||||
- `notifications/claude/channel/permission`
|
||||
|
||||
Current bridge behavior:
|
||||
|
||||
- inbound `user` transcript messages are forwarded as `notifications/claude/channel`
|
||||
- Claude permission requests received over MCP are tracked in-memory
|
||||
- if the command owner in the linked conversation later sends `yes <id>` or `no <id>` (`<id>` is the 5-letter request id, excluding `l`), the bridge converts that to `notifications/claude/channel/permission`
|
||||
- these notifications are live-session only; if the MCP client disconnects, there is no push target
|
||||
|
||||
This is intentionally client-specific. Generic MCP clients should rely on the standard polling tools.
|
||||
|
||||
### MCP client config
|
||||
|
||||
Example stdio client config:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"openclaw": {
|
||||
"command": "openclaw",
|
||||
"args": [
|
||||
"mcp",
|
||||
"serve",
|
||||
"--url",
|
||||
"wss://gateway-host:18789",
|
||||
"--token-file",
|
||||
"/path/to/gateway.token"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For most generic MCP clients, start with the standard tool surface and ignore Claude mode. Turn Claude mode on only for clients that actually understand the Claude-specific notification methods.
|
||||
|
||||
### Options
|
||||
|
||||
`openclaw mcp serve` supports:
|
||||
|
||||
<ParamField path="--url" type="string">
|
||||
Gateway WebSocket URL. Defaults to `gateway.remote.url` when configured.
|
||||
</ParamField>
|
||||
<ParamField path="--token" type="string">
|
||||
Gateway token.
|
||||
</ParamField>
|
||||
<ParamField path="--token-file" type="string">
|
||||
Read token from file.
|
||||
</ParamField>
|
||||
<ParamField path="--password" type="string">
|
||||
Gateway password.
|
||||
</ParamField>
|
||||
<ParamField path="--password-file" type="string">
|
||||
Read password from file.
|
||||
</ParamField>
|
||||
<ParamField path="--claude-channel-mode" type='"auto" | "on" | "off"'>
|
||||
Claude notification mode. Default `auto`.
|
||||
</ParamField>
|
||||
<ParamField path="-v, --verbose" type="boolean">
|
||||
Verbose logs on stderr.
|
||||
</ParamField>
|
||||
|
||||
<Tip>
|
||||
Prefer `--token-file` or `--password-file` over inline secrets when possible.
|
||||
</Tip>
|
||||
|
||||
### Security and trust boundary
|
||||
|
||||
The bridge does not invent routing. It only exposes conversations that Gateway already knows how to route.
|
||||
|
||||
That means:
|
||||
|
||||
- sender allowlists, pairing, and channel-level trust still belong to the underlying OpenClaw channel configuration
|
||||
- `messages_send` can only reply through an existing stored route
|
||||
- approval state is live/in-memory only for the current bridge session
|
||||
- bridge auth should use the same Gateway token or password controls you would trust for any other remote Gateway client
|
||||
|
||||
If a conversation is missing from `conversations_list`, the usual cause is not MCP configuration. It is missing or incomplete route metadata in the underlying Gateway session.
|
||||
|
||||
### Testing
|
||||
|
||||
OpenClaw ships a deterministic Docker smoke for this bridge:
|
||||
|
||||
```bash
|
||||
pnpm test:docker:mcp-channels
|
||||
```
|
||||
|
||||
That smoke runs a single container: it seeds conversation state, starts the Gateway, then spawns `openclaw mcp serve` as a stdio child process and drives it as an MCP client. It verifies conversation discovery, transcript reads, attachment metadata reads, live event queue behavior, and Claude-style channel and permission notifications over the real stdio MCP bridge. Outbound send routing (`messages_send` reusing the stored conversation route) is covered separately by unit tests in `src/mcp/channel-server.test.ts`.
|
||||
|
||||
This is the fastest way to prove the bridge works without wiring a real Telegram, Discord, or iMessage account into the test run.
|
||||
|
||||
For broader testing context, see [Testing](/help/testing).
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="No conversations returned">
|
||||
Usually means the Gateway session is not already routable. Confirm that the underlying session has stored channel/provider, recipient, and optional account/thread route metadata.
|
||||
</Accordion>
|
||||
<Accordion title="events_poll or events_wait misses older messages">
|
||||
Expected. The live queue starts when the bridge connects. Read older transcript history with `messages_read`.
|
||||
</Accordion>
|
||||
<Accordion title="Claude notifications do not show up">
|
||||
Check all of these:
|
||||
|
||||
- the client kept the stdio MCP session open
|
||||
- `--claude-channel-mode` is `on` or `auto`
|
||||
- the client actually understands the Claude-specific notification methods
|
||||
- the inbound message happened after the bridge connected
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Approvals are missing">
|
||||
`permissions_list_open` only shows approval requests observed while the bridge was connected. It is not a durable approval history API.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## OpenClaw as an MCP client registry
|
||||
|
||||
This is the `openclaw mcp list`, `show`, `status`, `doctor`, `probe`, `add`, `set`,
|
||||
`configure`, `tools`, `login`, `logout`, `reload`, and `unset` path.
|
||||
|
||||
These commands do not expose OpenClaw over MCP. They manage OpenClaw-managed MCP server definitions under `mcp.servers` in OpenClaw config. They do not read mcporter servers from `config/mcporter.json`.
|
||||
|
||||
Those saved definitions are for runtimes that OpenClaw launches or configures later, such as embedded OpenClaw and other runtime adapters. OpenClaw stores the definitions centrally so those runtimes do not need to keep their own duplicate MCP server lists.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Important behavior">
|
||||
- these commands only read or write OpenClaw config
|
||||
- `status`, `list`, `show`, `doctor` without `--probe`, `set`, `configure`, `tools`, `logout`, `reload`, and `unset` do not connect to the target MCP server
|
||||
- `login` performs the MCP OAuth network flow for the configured HTTP server and saves the resulting local credentials
|
||||
- `status --verbose` prints resolved transport, auth, timeout, filter, and parallel-tool-call hints without connecting
|
||||
- `doctor` checks saved definitions for local setup problems such as missing stdio commands, invalid working directories, missing TLS files, disabled servers, literal sensitive header/env values, and incomplete OAuth authorization
|
||||
- `doctor --probe` adds the same live connection proof as `probe` after static checks pass
|
||||
- `probe` connects to the selected server or all configured servers, lists tools, and reports capabilities/diagnostics
|
||||
- `add` builds a definition from flags and probes before saving unless `--no-probe` is set or OAuth authorization is needed first
|
||||
- runtime adapters decide which transport shapes they actually support at execution time
|
||||
- `enabled: false` keeps a server saved but excludes it from embedded runtime discovery
|
||||
- `timeout` and `connectTimeout` set per-server request and connection timeouts in seconds
|
||||
- `supportsParallelToolCalls: true` marks servers that adapters can call concurrently
|
||||
- HTTP servers can use static headers, OAuth login, TLS verification control, and mTLS certificate/key paths
|
||||
- embedded OpenClaw exposes configured MCP tools in normal `coding` and `messaging` tool profiles; `minimal` still hides them, and `tools.deny: ["bundle-mcp"]` disables them explicitly
|
||||
- per-server `toolFilter.include` and `toolFilter.exclude` filter discovered MCP tools before they become OpenClaw tools
|
||||
- servers that advertise resources or prompts also expose utility tools for listing/reading resources and listing/fetching prompts; those generated utility names (`resources_list`, `resources_read`, `prompts_list`, `prompts_get`) use the same include/exclude filter
|
||||
- dynamic MCP tool-list changes invalidate the cached catalog for that session; the next discovery/use refreshes from the server
|
||||
- repeated MCP tool request/protocol failures pause that server briefly so one broken server does not consume the whole turn
|
||||
- session-scoped bundled MCP runtimes are reaped after `mcp.sessionIdleTtlMs` milliseconds of idle time (default 10 minutes; set `0` to disable) and one-shot embedded runs clean them up at run end
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Runtime adapters may normalize this shared registry into the shape their downstream client expects. For example, embedded OpenClaw consumes OpenClaw `transport` values directly, while Claude Code and Gemini receive CLI-native `type` values such as `http`, `sse`, or `stdio`.
|
||||
|
||||
Codex app-server also honors an optional `codex` block on each server. This is
|
||||
OpenClaw projection metadata for Codex app-server threads only; it does not
|
||||
change ACP sessions, generic Codex harness config, or other runtime adapters.
|
||||
Use non-empty `codex.agents` to project a server only into specific OpenClaw
|
||||
agent ids. Empty, blank, or invalid agent lists are rejected by config
|
||||
validation and omitted by the runtime projection path instead of becoming
|
||||
global. Use `codex.defaultToolsApprovalMode` (`auto`, `prompt`, or `approve`)
|
||||
to emit Codex's native `default_tools_approval_mode` for a trusted server.
|
||||
OpenClaw strips the `codex` metadata before handing the native `mcp_servers`
|
||||
config to Codex.
|
||||
|
||||
### Saved MCP server definitions
|
||||
|
||||
Commands:
|
||||
|
||||
- `openclaw mcp list`
|
||||
- `openclaw mcp show [name]`
|
||||
- `openclaw mcp status [--verbose]`
|
||||
- `openclaw mcp doctor [name] [--probe]`
|
||||
- `openclaw mcp probe [name]`
|
||||
- `openclaw mcp add <name> [flags]`
|
||||
- `openclaw mcp set <name> <json>`
|
||||
- `openclaw mcp configure <name> [flags]`
|
||||
- `openclaw mcp tools <name> [--include csv] [--exclude csv] [--clear]`
|
||||
- `openclaw mcp login <name> [--code code]`
|
||||
- `openclaw mcp logout <name>`
|
||||
- `openclaw mcp reload`
|
||||
- `openclaw mcp unset <name>`
|
||||
|
||||
Notes:
|
||||
|
||||
- `list` sorts server names.
|
||||
- `show` without a name prints the full configured MCP server object.
|
||||
- `status` classifies configured transports without connecting. `--verbose` includes resolved launch, timeout, OAuth, filter, and parallel-call details.
|
||||
- `doctor` performs static checks without connecting. Add `--probe` when the command should also verify that enabled servers connect.
|
||||
- `probe` connects and reports tool counts, resources/prompts support, list-change support, and diagnostics.
|
||||
- `add` accepts stdio flags such as `--command`, `--arg`, `--env`, and `--cwd`, or HTTP flags such as `--url`, `--transport`, `--header`, `--auth oauth`, TLS, timeout, and tool-selection flags.
|
||||
- `set` expects one JSON object value on the command line.
|
||||
- `configure` updates enablement, tool filters, timeouts, OAuth, TLS, and parallel-tool-call hints without replacing the whole server definition. Add `--probe` to verify the updated server before saving.
|
||||
- `tools` updates per-server tool filters. Include/exclude entries are MCP tool names and simple `*` globs.
|
||||
- `login` runs the OAuth flow for HTTP servers configured with `auth: "oauth"`. The first run prints an authorization URL; rerun with `--code` after approval.
|
||||
- `logout` clears stored OAuth credentials for the named server without removing the saved server definition.
|
||||
- `reload` disposes cached in-process MCP runtimes for the current CLI process only. Gateway or agent processes in another process still need their own reload or restart path.
|
||||
- Use `transport: "streamable-http"` for Streamable HTTP MCP servers. `openclaw mcp set` also normalizes CLI-native `type: "http"` to the same canonical config shape for compatibility.
|
||||
- `unset` fails if the named server does not exist.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw mcp list
|
||||
openclaw mcp show context7 --json
|
||||
openclaw mcp status --verbose
|
||||
openclaw mcp doctor --probe
|
||||
openclaw mcp probe context7 --json
|
||||
openclaw mcp add memory --command npx --arg -y --arg @modelcontextprotocol/server-memory
|
||||
openclaw mcp set context7 '{"command":"uvx","args":["context7-mcp"]}'
|
||||
openclaw mcp tools context7 --include 'resolve-library-id,get-library-docs'
|
||||
openclaw mcp set docs '{"url":"https://mcp.example.com","transport":"streamable-http"}'
|
||||
openclaw mcp configure docs --timeout 20 --connect-timeout 5 --include 'search,read_*'
|
||||
openclaw mcp configure docs --auth oauth --oauth-scope 'docs.read'
|
||||
openclaw mcp login docs
|
||||
openclaw mcp logout docs
|
||||
openclaw mcp unset context7
|
||||
```
|
||||
|
||||
### Common server recipes
|
||||
|
||||
These examples save server definitions only. Run `openclaw mcp doctor --probe` afterward to prove that the server starts and exposes tools.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Filesystem">
|
||||
```bash
|
||||
openclaw mcp add files \
|
||||
--command npx \
|
||||
--arg -y \
|
||||
--arg @modelcontextprotocol/server-filesystem \
|
||||
--arg "$HOME/Documents" \
|
||||
--include 'read_file,list_directory,search_files'
|
||||
openclaw mcp doctor files --probe
|
||||
```
|
||||
|
||||
Scope filesystem servers to the smallest directory tree that the agent should read or edit.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Memory">
|
||||
```bash
|
||||
openclaw mcp add memory \
|
||||
--command npx \
|
||||
--arg -y \
|
||||
--arg @modelcontextprotocol/server-memory
|
||||
openclaw mcp probe memory --json
|
||||
```
|
||||
|
||||
Use a tool filter if the server exposes write tools that should not be available to normal agents.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Local script">
|
||||
```bash
|
||||
openclaw mcp add local-tools \
|
||||
--command node \
|
||||
--arg ./dist/mcp-server.js \
|
||||
--cwd /srv/openclaw-tools \
|
||||
--env API_BASE=https://internal.example
|
||||
openclaw mcp status --verbose
|
||||
```
|
||||
|
||||
`doctor` checks that `cwd` exists and that the command resolves from the configured environment.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Remote HTTP">
|
||||
```bash
|
||||
openclaw mcp add docs \
|
||||
--url https://mcp.example.com/mcp \
|
||||
--transport streamable-http \
|
||||
--auth oauth \
|
||||
--oauth-scope docs.read \
|
||||
--timeout 20 \
|
||||
--connect-timeout 5 \
|
||||
--include 'search,read_*'
|
||||
openclaw mcp doctor docs --probe
|
||||
```
|
||||
|
||||
Use OAuth when the remote server supports it. If the server requires static headers, avoid committing literal bearer tokens.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Desktop/CUA">
|
||||
```bash
|
||||
openclaw mcp set cua-driver '{"command":"cua-driver","args":["mcp"]}'
|
||||
openclaw mcp tools cua-driver --include 'list_apps,observe,click,type'
|
||||
openclaw mcp doctor cua-driver --probe
|
||||
```
|
||||
|
||||
Direct desktop-control servers inherit the permissions of the process they launch. Use narrow tool filters and OS-level permission prompts.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### JSON output shapes
|
||||
|
||||
Use `--json` for scripts and dashboards. Field sets can grow over time, so consumers should ignore unknown keys.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="status --json">
|
||||
```json
|
||||
{
|
||||
"path": "/home/user/.openclaw/openclaw.json",
|
||||
"servers": [
|
||||
{
|
||||
"name": "docs",
|
||||
"configured": true,
|
||||
"enabled": true,
|
||||
"ok": true,
|
||||
"transport": "streamable-http",
|
||||
"launch": "streamable-http https://mcp.example.com/mcp",
|
||||
"auth": "oauth",
|
||||
"authStatus": {
|
||||
"hasTokens": true,
|
||||
"hasClientInformation": true,
|
||||
"hasCodeVerifier": false,
|
||||
"hasDiscoveryState": true,
|
||||
"hasLastAuthorizationUrl": false
|
||||
},
|
||||
"requestTimeoutMs": 20000,
|
||||
"connectionTimeoutMs": 5000,
|
||||
"toolFilter": {
|
||||
"include": ["search", "read_*"],
|
||||
"exclude": []
|
||||
},
|
||||
"supportsParallelToolCalls": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
<Accordion title="doctor --json">
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"path": "/home/user/.openclaw/openclaw.json",
|
||||
"servers": [
|
||||
{
|
||||
"name": "docs",
|
||||
"ok": true,
|
||||
"issues": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "OAuth credentials are not authorized; run openclaw mcp login docs"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`doctor --json` exits nonzero when any enabled checked server has an `error`-level issue. `warning` and `info` issues are reported but do not make the command fail by themselves.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="probe --json">
|
||||
```json
|
||||
{
|
||||
"generatedAt": "2026-05-31T09:00:00.000Z",
|
||||
"servers": {
|
||||
"docs": {
|
||||
"launch": "streamable-http https://mcp.example.com/mcp",
|
||||
"tools": 2,
|
||||
"resources": true,
|
||||
"listChanged": {
|
||||
"tools": true,
|
||||
"resources": false,
|
||||
"prompts": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": ["docs__read_page", "docs__search"],
|
||||
"diagnostics": []
|
||||
}
|
||||
```
|
||||
|
||||
`probe --json` opens a live MCP client session and prints its result directly; unlike `status`/`doctor`, the output has no top-level `path` field. `resources` and `prompts` keys are present only when the server actually advertises that capability (a server without prompts omits the `prompts` key rather than reporting `false`). Use `probe` for reachability and capability proof, not for static config audits.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Example config shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"context7": {
|
||||
"command": "uvx",
|
||||
"args": ["context7-mcp"]
|
||||
},
|
||||
"docs": {
|
||||
"url": "https://mcp.example.com",
|
||||
"transport": "streamable-http",
|
||||
"timeout": 20,
|
||||
"connectTimeout": 5,
|
||||
"supportsParallelToolCalls": true,
|
||||
"auth": "oauth",
|
||||
"oauth": {
|
||||
"scope": "docs.read"
|
||||
},
|
||||
"sslVerify": true,
|
||||
"clientCert": "/path/to/client.crt",
|
||||
"clientKey": "/path/to/client.key",
|
||||
"toolFilter": {
|
||||
"include": ["search_*"],
|
||||
"exclude": ["admin_*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Stdio transport
|
||||
|
||||
Launches a local child process and communicates over stdin/stdout.
|
||||
|
||||
| Field | Description |
|
||||
| -------------------------- | --------------------------------- |
|
||||
| `command` | Executable to spawn (required) |
|
||||
| `args` | Array of command-line arguments |
|
||||
| `env` | Extra environment variables |
|
||||
| `cwd` / `workingDirectory` | Working directory for the process |
|
||||
|
||||
<Warning>
|
||||
**Stdio env safety filter**
|
||||
|
||||
OpenClaw rejects interpreter-startup, loader-hijack, and shell-init env keys before spawning a stdio MCP server, even if they appear in a server's `env` block. This uses the same host environment security policy as other OpenClaw-spawned processes: it blocks known interpreter startup hooks (for example `NODE_OPTIONS`, `PYTHONSTARTUP`, `PERL5OPT`, `RUBYOPT`, `BASHOPTS`, `KSH_ENV`), shared-library and function-injection prefixes (`DYLD_*`, `LD_*`, `BASH_FUNC_*`), and similar runtime-control variables. Startup drops these silently and logs a warning so they cannot inject an implicit prelude, swap the interpreter, enable a debugger, or hijack the dynamic linker against the stdio process. An explicit allowlist keeps ordinary MCP credential env vars usable (`GITHUB_TOKEN`, `GH_TOKEN`, `GITLAB_TOKEN`, `NPM_TOKEN`, `NODE_AUTH_TOKEN`, `DATABASE_URL`, `MONGODB_URI`, `REDIS_URL`, `AMQP_URL`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`), along with ordinary proxy and server-specific env vars (`HTTP_PROXY`, custom `*_API_KEY`, etc.). Other `AWS_*` keys such as `AWS_CONFIG_FILE` and `AWS_SHARED_CREDENTIALS_FILE` remain blocked because they point at credential files rather than carry a credential value directly.
|
||||
|
||||
If your MCP server genuinely needs one of the blocked variables, set it on the gateway host process instead of under the stdio server's `env`.
|
||||
</Warning>
|
||||
|
||||
### SSE / HTTP transport
|
||||
|
||||
Connects to a remote MCP server over HTTP Server-Sent Events.
|
||||
|
||||
| Field | Description |
|
||||
| ------------------------------ | ---------------------------------------------------------------- |
|
||||
| `url` | HTTP or HTTPS URL of the remote server (required) |
|
||||
| `headers` | Optional key-value map of HTTP headers (for example auth tokens) |
|
||||
| `connectionTimeoutMs` | Per-server connection timeout in ms (optional) |
|
||||
| `connectTimeout` | Per-server connection timeout in seconds (optional) |
|
||||
| `timeout` / `requestTimeoutMs` | Per-server MCP request timeout in seconds or ms |
|
||||
| `auth: "oauth"` | Use MCP OAuth token storage and `openclaw mcp login` |
|
||||
| `sslVerify` | Set false only for explicitly trusted private HTTPS endpoints |
|
||||
| `clientCert` / `clientKey` | mTLS client certificate and key paths |
|
||||
| `supportsParallelToolCalls` | Hint that concurrent calls are safe for this server |
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"remote-tools": {
|
||||
"url": "https://mcp.example.com",
|
||||
"auth": "oauth",
|
||||
"timeout": 20,
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Sensitive values in `url` (userinfo) and `headers` are redacted in logs and status output. `openclaw mcp doctor` warns when sensitive-looking `headers` or `env` entries contain literal values, so operators can move those values out of committed config.
|
||||
|
||||
### OAuth workflow
|
||||
|
||||
OAuth is for HTTP MCP servers that advertise the MCP OAuth flow. Static `Authorization` headers are ignored for a server while `auth: "oauth"` is enabled.
|
||||
|
||||
<Steps>
|
||||
<Step title="Save the server">
|
||||
Add or update the server with `auth: "oauth"` and any optional OAuth metadata.
|
||||
|
||||
```bash
|
||||
openclaw mcp set docs '{"url":"https://mcp.example.com/mcp","transport":"streamable-http","auth":"oauth","oauth":{"scope":"docs.read"}}'
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Start login">
|
||||
Run login to create the authorization request.
|
||||
|
||||
```bash
|
||||
openclaw mcp login docs
|
||||
```
|
||||
|
||||
OpenClaw prints the authorization URL and stores temporary OAuth verifier state under the OpenClaw state directory.
|
||||
|
||||
</Step>
|
||||
<Step title="Finish with the code">
|
||||
After approving in the browser, pass the returned code back to OpenClaw.
|
||||
|
||||
```bash
|
||||
openclaw mcp login docs --code abc123
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Check authorization">
|
||||
Use status or doctor to confirm that tokens are present.
|
||||
|
||||
```bash
|
||||
openclaw mcp status --verbose
|
||||
openclaw mcp doctor docs --probe
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Clear credentials">
|
||||
Logout removes stored OAuth credentials but keeps the saved server definition.
|
||||
|
||||
```bash
|
||||
openclaw mcp logout docs
|
||||
```
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
If the provider rotates tokens or the authorization state gets stuck, run `openclaw mcp logout <name>`, then repeat `login`. `logout` can clear credentials for a saved HTTP server even after `auth: "oauth"` has been removed from config, as long as the server name and URL still identify the credential store entry.
|
||||
|
||||
### Streamable HTTP transport
|
||||
|
||||
`streamable-http` is an additional transport option alongside `sse` and `stdio`. It uses HTTP streaming for bidirectional communication with remote MCP servers.
|
||||
|
||||
| Field | Description |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------- |
|
||||
| `url` | HTTP or HTTPS URL of the remote server (required) |
|
||||
| `transport` | Set to `"streamable-http"` to select this transport; when omitted, OpenClaw uses `sse` |
|
||||
| `headers` | Optional key-value map of HTTP headers (for example auth tokens) |
|
||||
| `connectionTimeoutMs` | Per-server connection timeout in ms (optional) |
|
||||
| `connectTimeout` | Per-server connection timeout in seconds (optional) |
|
||||
| `timeout` / `requestTimeoutMs` | Per-server MCP request timeout in seconds or ms |
|
||||
| `auth: "oauth"` | Use MCP OAuth token storage and `openclaw mcp login` |
|
||||
| `sslVerify` | Set false only for explicitly trusted private HTTPS endpoints |
|
||||
| `clientCert` / `clientKey` | mTLS client certificate and key paths |
|
||||
| `supportsParallelToolCalls` | Hint that concurrent calls are safe for this server |
|
||||
|
||||
OpenClaw config uses `transport: "streamable-http"` as the canonical spelling. CLI-native MCP `type: "http"` values are accepted when saved through `openclaw mcp set` and repaired by `openclaw doctor --fix` in existing config, but `transport` is what embedded OpenClaw consumes directly.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"streaming-tools": {
|
||||
"url": "https://mcp.example.com/stream",
|
||||
"transport": "streamable-http",
|
||||
"connectTimeout": 10,
|
||||
"timeout": 30,
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Registry commands do not start the channel bridge. Only `probe` and `doctor --probe` open a live MCP client session to prove the target server is reachable.
|
||||
</Note>
|
||||
|
||||
## Control UI
|
||||
|
||||
The browser Control UI includes a dedicated MCP settings page at `/mcp`. It shows configured server counts, enabled/OAuth/filter summaries, per-server transport rows, enable/disable controls, common CLI commands, and a scoped editor for the `mcp` config section.
|
||||
|
||||
Use the page for operator edits and quick inventory. Use `openclaw mcp doctor --probe` or `openclaw mcp probe` when you need live server proof.
|
||||
|
||||
Operator workflow:
|
||||
|
||||
1. Open the Control UI and choose **MCP**.
|
||||
2. Review the summary cards for total, enabled, OAuth, and filtered servers.
|
||||
3. Use each server row for transport, auth, filter, timeout, and command hints.
|
||||
4. Toggle enablement when you want to keep a definition but exclude it from runtime discovery.
|
||||
5. Edit the scoped `mcp` config section for structural changes such as new servers, headers, TLS, OAuth metadata, or tool filters.
|
||||
6. Choose **Save** to persist config only, or **Save & Publish** to apply through the Gateway config path.
|
||||
7. Run `openclaw mcp doctor --probe` when you need live proof that the edited server starts and lists tools.
|
||||
|
||||
Notes:
|
||||
|
||||
- command snippets quote server names so unusual names remain copyable in a shell
|
||||
- displayed URL-like values are redacted before rendering when they contain embedded credentials
|
||||
- the page does not start MCP transports by itself
|
||||
- active runtimes may need `openclaw mcp reload`, Gateway config publish, or process restart depending on which process owns the MCP clients
|
||||
|
||||
## Current limits
|
||||
|
||||
This page documents the bridge as shipped today.
|
||||
|
||||
Current limits:
|
||||
|
||||
- conversation discovery depends on existing Gateway session route metadata
|
||||
- no generic push protocol beyond the Claude-specific adapter
|
||||
- no message edit or react tools yet
|
||||
- HTTP/SSE/streamable-http transport connects to a single remote server; no multiplexed upstream yet
|
||||
- `permissions_list_open` only includes approvals observed while the bridge is connected
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Plugins](/cli/plugins)
|
||||
207
docs/cli/memory.md
Normal file
207
docs/cli/memory.md
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw memory` (status/index/search/promote/promote-explain/rem-harness/rem-backfill)"
|
||||
read_when:
|
||||
- You want to index or search semantic memory
|
||||
- You're debugging memory availability or indexing
|
||||
- You want to promote recalled short-term memory into `MEMORY.md`
|
||||
title: "Memory"
|
||||
---
|
||||
|
||||
# `openclaw memory`
|
||||
|
||||
Manage semantic memory indexing, search, and promotion into `MEMORY.md`.
|
||||
Provided by the bundled `memory-core` plugin, available when
|
||||
`plugins.slots.memory` selects `memory-core` (the default). Other memory
|
||||
plugins expose their own CLI namespaces.
|
||||
|
||||
Related: [Memory](/concepts/memory) concept, [Dreaming](/concepts/dreaming),
|
||||
[Memory config reference](/reference/memory-config), [Memory Wiki](/plugins/memory-wiki),
|
||||
[wiki](/cli/wiki), [Plugins](/tools/plugin).
|
||||
|
||||
## `memory status`
|
||||
|
||||
```bash
|
||||
openclaw memory status [--agent <id>] [--deep] [--index] [--fix] [--json] [--verbose]
|
||||
```
|
||||
|
||||
Without `--agent`, runs for every agent in `agents.list`; if no agent list is
|
||||
configured, falls back to the default agent.
|
||||
|
||||
| Flag | Effect |
|
||||
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--deep` | Probe vector-store, embedding-provider, and semantic-search readiness (implies extra provider calls). Plain `memory status` stays fast and skips this; unknown vector/semantic state means it was not probed. QMD lexical `searchMode: "search"` always skips semantic vector probes, even with `--deep`. |
|
||||
| `--index` | Reindex if the store is dirty. Implies `--deep`. |
|
||||
| `--fix` | Repair stale recall locks and normalize promotion metadata. |
|
||||
| `--json` | Print JSON. |
|
||||
| `--verbose` | Emit detailed per-phase logs. |
|
||||
|
||||
If the `Dreaming` line stays `off` even with `dreaming.enabled: true`, or
|
||||
scheduled sweeps never seem to run, the managed dreaming cron depends on the
|
||||
default agent's heartbeat firing to trigger reconciliation. See
|
||||
[Dreaming](/concepts/dreaming) for scheduling details.
|
||||
|
||||
Status also lists any extra search paths from `agents.defaults.memorySearch.extraPaths`.
|
||||
|
||||
## `memory index`
|
||||
|
||||
```bash
|
||||
openclaw memory index [--agent <id>] [--force] [--verbose]
|
||||
```
|
||||
|
||||
Same per-agent scoping as `status`. `--force` runs a full reindex instead of
|
||||
an incremental one. `--verbose` prints per-agent provider, model, sources, and
|
||||
extra-path details before showing indexing progress.
|
||||
|
||||
## `memory search`
|
||||
|
||||
```bash
|
||||
openclaw memory search [query] [--query <text>] [--agent <id>] [--max-results <n>] [--min-score <n>] [--json]
|
||||
```
|
||||
|
||||
- Query: positional `[query]` or `--query <text>`. If both are set, `--query`
|
||||
wins. If neither is set, the command errors.
|
||||
- `--agent <id>`: defaults to the default agent (not the full agent list).
|
||||
- `--max-results <n>`: cap result count (positive integer).
|
||||
- `--min-score <n>`: filter out matches below this score.
|
||||
|
||||
## `memory promote`
|
||||
|
||||
Rank short-term candidates from `memory/YYYY-MM-DD.md` and optionally append
|
||||
top entries to `MEMORY.md`.
|
||||
|
||||
```bash
|
||||
openclaw memory promote [--agent <id>] [--limit <n>] [--min-score <n>] \
|
||||
[--min-recall-count <n>] [--min-unique-queries <n>] [--apply] [--include-promoted] [--json]
|
||||
```
|
||||
|
||||
| Flag | Default | Effect |
|
||||
| -------------------------- | ------------ | ----------------------------------------------------------------- |
|
||||
| `--limit <n>` | | Max candidates to return/apply. |
|
||||
| `--min-score <n>` | `0.75` | Minimum weighted promotion score. |
|
||||
| `--min-recall-count <n>` | `3` | Minimum recall count required. |
|
||||
| `--min-unique-queries <n>` | `2` | Minimum distinct query count required. |
|
||||
| `--apply` | preview only | Append selected candidates to `MEMORY.md` and mark them promoted. |
|
||||
| `--include-promoted` | | Include candidates already promoted in previous cycles. |
|
||||
| `--json` | | Print JSON. |
|
||||
|
||||
These CLI defaults differ from the scheduled dreaming sweep's deep-phase
|
||||
thresholds (see [Dreaming](#dreaming) below); pass explicit flags to match
|
||||
sweep behavior for a one-off manual run.
|
||||
|
||||
Ranking signals: recall frequency, retrieval relevance, query diversity,
|
||||
temporal recency, cross-day consolidation, and derived concept richness, drawn
|
||||
from both memory recalls and daily-ingestion passes, plus a light/REM phase
|
||||
reinforcement boost for repeated dreaming revisits. Before writing, promotion
|
||||
re-reads the live daily note, so edits or deletions to short-term snippets
|
||||
since ranking are respected instead of promoting from a stale snapshot.
|
||||
|
||||
## `memory promote-explain`
|
||||
|
||||
Explain one promotion candidate's score breakdown.
|
||||
|
||||
```bash
|
||||
openclaw memory promote-explain <selector> [--agent <id>] [--include-promoted] [--json]
|
||||
```
|
||||
|
||||
`<selector>` matches a candidate's key (exact or substring), path, or snippet
|
||||
text.
|
||||
|
||||
## `memory rem-harness`
|
||||
|
||||
Preview REM reflections, candidate truths, and deep-phase promotion output
|
||||
without writing anything.
|
||||
|
||||
```bash
|
||||
openclaw memory rem-harness [--agent <id>] [--path <file-or-dir>] [--grounded] [--include-promoted] [--json]
|
||||
```
|
||||
|
||||
- `--path <file-or-dir>`: seed the harness from historical `YYYY-MM-DD.md`
|
||||
daily files instead of the live workspace.
|
||||
- `--grounded`: also render a grounded `What Happened` / `Reflections` /
|
||||
`Possible Lasting Updates` preview from the historical notes.
|
||||
|
||||
## `memory rem-backfill`
|
||||
|
||||
Write grounded historical REM summaries into `DREAMS.md` for UI review.
|
||||
Reversible.
|
||||
|
||||
```bash
|
||||
openclaw memory rem-backfill --path <file-or-dir> [--agent <id>] [--stage-short-term] [--json]
|
||||
openclaw memory rem-backfill --rollback [--rollback-short-term] [--json]
|
||||
```
|
||||
|
||||
- `--path <file-or-dir>`: required unless `--rollback`/`--rollback-short-term`
|
||||
is set. Historical daily memory file(s) or directory to backfill from.
|
||||
- `--stage-short-term`: also seed grounded durable candidates into the live
|
||||
short-term promotion store so the normal deep phase can rank them.
|
||||
- `--rollback`: remove previously written grounded diary entries from
|
||||
`DREAMS.md`.
|
||||
- `--rollback-short-term`: remove previously staged grounded short-term
|
||||
candidates.
|
||||
|
||||
## Dreaming
|
||||
|
||||
Dreaming is the background memory consolidation system with three cooperative
|
||||
phases, run in order on one schedule: **light** (sort/stage short-term
|
||||
material), **REM** (reflect and surface themes), **deep** (promote durable
|
||||
facts into `MEMORY.md`). Only deep writes to `MEMORY.md`.
|
||||
|
||||
- Enable with `plugins.entries.memory-core.config.dreaming.enabled: true`
|
||||
(default `false`); `memory-core` auto-manages the sweep cron job, no manual
|
||||
`openclaw cron add` required.
|
||||
- Toggle from chat with `/dreaming on|off`; inspect with `/dreaming status`
|
||||
(or `/dreaming`/`/dreaming help`). `on`/`off` requires channel owner status
|
||||
or gateway `operator.admin`; `status` and help stay available to anyone who
|
||||
can invoke the command.
|
||||
- Human-readable phase output goes to `DREAMS.md` (or an existing `dreams.md`).
|
||||
By default (`dreaming.storage.mode: "separate"`) each phase also writes a
|
||||
standalone report to `memory/dreaming/<phase>/YYYY-MM-DD.md`; set `mode:
|
||||
"inline"` to fold reports into the daily memory file instead, or `"both"`
|
||||
for both.
|
||||
- Scheduled and manual `memory promote` runs share the same deep-phase
|
||||
ranking signals; only the default thresholds differ (see table above vs.
|
||||
scheduled defaults below).
|
||||
- Scheduled runs fan out across every configured agent's memory workspace.
|
||||
|
||||
Scheduled defaults (`plugins.entries.memory-core.config.dreaming`):
|
||||
|
||||
| Key | Default |
|
||||
| -------------------------------------- | ----------- |
|
||||
| `frequency` | `0 3 * * *` |
|
||||
| `phases.deep.minScore` | `0.8` |
|
||||
| `phases.deep.minRecallCount` | `3` |
|
||||
| `phases.deep.minUniqueQueries` | `3` |
|
||||
| `phases.deep.recencyHalfLifeDays` | `14` |
|
||||
| `phases.deep.maxAgeDays` | `30` |
|
||||
| `phases.deep.maxPromotedSnippetTokens` | `160` |
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"memory-core": {
|
||||
"config": {
|
||||
"dreaming": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Full key list and phase details: [Dreaming](/concepts/dreaming),
|
||||
[Memory config reference](/reference/memory-config#dreaming).
|
||||
|
||||
## SecretRef gateway dependency
|
||||
|
||||
If active memory remote API key fields are configured as SecretRefs, `memory`
|
||||
commands resolve them from the active gateway snapshot; if the gateway is
|
||||
unavailable, the command fails fast. This requires a gateway supporting the
|
||||
`secrets.resolve` method; older gateways return an unknown-method error.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Memory overview](/concepts/memory)
|
||||
221
docs/cli/message.md
Normal file
221
docs/cli/message.md
Normal file
@@ -0,0 +1,221 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw message` (send + channel actions)"
|
||||
read_when:
|
||||
- Adding or modifying message CLI actions
|
||||
- Changing outbound channel behavior
|
||||
title: "Message"
|
||||
---
|
||||
|
||||
# `openclaw message`
|
||||
|
||||
Single outbound command for sending messages and channel actions across
|
||||
Discord, Google Chat, iMessage, Matrix, Mattermost (plugin), Microsoft Teams,
|
||||
Signal, Slack, Telegram, and WhatsApp.
|
||||
|
||||
```bash
|
||||
openclaw message <subcommand> [flags]
|
||||
```
|
||||
|
||||
## Channel selection
|
||||
|
||||
- `--channel <name>` is required if more than one channel is configured; with
|
||||
exactly one channel configured, that channel is the default.
|
||||
- Values: `discord|googlechat|imessage|matrix|mattermost|msteams|signal|slack|telegram|whatsapp`
|
||||
(Mattermost requires the plugin).
|
||||
- Channel-prefixed targets (for example `discord:channel:123`) resolve the
|
||||
owning plugin without an explicit `--channel`.
|
||||
|
||||
## Target formats (`-t, --target`)
|
||||
|
||||
| Channel | Format |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| Discord | `channel:<id>`, `user:<id>`, `<@id>` mention, or a bare numeric id (treated as a channel id) |
|
||||
| Google Chat | `spaces/<spaceId>` or `users/<userId>` |
|
||||
| iMessage | handle, `chat_id:<id>`, `chat_guid:<guid>`, or `chat_identifier:<id>` |
|
||||
| Mattermost (plugin) | `channel:<id>`, `user:<id>`, `@username`, or a bare id (treated as a channel) |
|
||||
| Matrix | `@user:server`, `!room:server`, or `#alias:server` |
|
||||
| Microsoft Teams | `conversation:<id>` (`19:...@thread.tacv2`), a bare conversation id, or `user:<aad-object-id>` |
|
||||
| Signal | `+E.164`, `group:<id>`, `uuid:<id>`, `username:<name>`/`u:<name>`, or any of these prefixed with `signal:` |
|
||||
| Slack | `channel:<id>` or `user:<id>` (a bare id is treated as a channel) |
|
||||
| Telegram | chat id, `@username`, or a forum topic target: `<chatId>:topic:<topicId>` (or `--thread-id <topicId>`) |
|
||||
| WhatsApp | E.164, group JID (`...@g.us`), or Channel/Newsletter JID (`...@newsletter`) |
|
||||
|
||||
Channel name lookup: for providers with a directory (Discord/Slack/etc), names
|
||||
like `Help` or `#help` resolve via the directory cache, falling back to a live
|
||||
directory lookup on a cache miss where the provider supports it.
|
||||
|
||||
## Common flags
|
||||
|
||||
Every action accepts: `--channel <name>`, `--account <id>`, `--json`,
|
||||
`--dry-run`, `--verbose`. Actions that take a destination also accept
|
||||
`-t, --target <dest>`.
|
||||
|
||||
## SecretRef resolution
|
||||
|
||||
`openclaw message` resolves channel SecretRefs before running the action,
|
||||
scoped as narrowly as possible:
|
||||
|
||||
- channel-scoped when `--channel` is set (or inferred from a prefixed target)
|
||||
- account-scoped when `--account` is also set
|
||||
- all configured channels when neither is set
|
||||
|
||||
Unresolved SecretRefs on unrelated channels never block a targeted action; an
|
||||
unresolved SecretRef on the selected channel/account fails the action closed.
|
||||
|
||||
## Actions
|
||||
|
||||
### Core
|
||||
|
||||
| Action | Channels | Required | Notes |
|
||||
| --------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `send` | Discord, Google Chat, iMessage, Matrix, Mattermost (plugin), Microsoft Teams, Signal, Slack, Telegram, WhatsApp | `--target`, plus one of `--message`/`--media`/`--presentation` | See [Send](#send) below. |
|
||||
| `poll` | Discord, Matrix, Microsoft Teams, Telegram, WhatsApp | `--target`, `--poll-question`, `--poll-option` (repeat) | See [Poll](#poll) below. |
|
||||
| `react` | Discord, Google Chat, Matrix, Nextcloud Talk, Signal, Slack, Telegram, WhatsApp | `--message-id`, `--target` | `--emoji`, `--remove` (needs `--emoji`; omit it to clear own reactions where supported, see [Reactions](/tools/reactions)). WhatsApp: `--participant`, `--from-me`. Signal group reactions require `--target-author` or `--target-author-uuid`. Nextcloud Talk only adds reactions; `--remove` errors. |
|
||||
| `reactions` | Discord, Google Chat, Matrix, Microsoft Teams, Slack | `--message-id`, `--target` | `--limit`. |
|
||||
| `read` | Discord, Matrix, Microsoft Teams, Slack | `--target` | `--limit`, `--message-id`, `--before`, `--after`. Discord: `--around`, `--include-thread`. Slack: `--message-id` reads a specific timestamp, combine with `--thread-id` for an exact thread reply. |
|
||||
| `edit` | Discord, Matrix, Microsoft Teams, Slack, Telegram | `--message-id`, `--message`, `--target` | Telegram forum threads use `--thread-id`. |
|
||||
| `delete` | Discord, Matrix, Microsoft Teams, Slack, Telegram | `--message-id`, `--target` | |
|
||||
| `pin` / `unpin` | Discord, Matrix, Microsoft Teams, Slack | `--message-id`, `--target` | `unpin` also accepts `--pinned-message-id` (Microsoft Teams: the pin/list-pins resource id, not the chat message id). |
|
||||
| `pins` (list) | Discord, Matrix, Microsoft Teams, Slack | `--target` | `--limit`. |
|
||||
| `permissions` | Discord, Matrix | `--target` | Matrix: available only when encryption is enabled and verification actions are allowed. |
|
||||
| `search` | Discord | `--guild-id`, `--query` | `--channel-id`, `--channel-ids` (repeat), `--author-id`, `--author-ids` (repeat), `--limit`. |
|
||||
| `member info` | Discord, Matrix, Microsoft Teams, Slack | `--user-id` | `--guild-id` (Discord). |
|
||||
|
||||
### Send
|
||||
|
||||
```bash
|
||||
openclaw message send --channel discord \
|
||||
--target channel:123 --message "hi" --reply-to 456
|
||||
```
|
||||
|
||||
- `--media <path-or-url>`: attach image/audio/video/document (local path or
|
||||
URL).
|
||||
- `--presentation <json>`: shared payload with `text`, `context`, `divider`,
|
||||
`buttons`, `select` blocks, rendered per channel capability. See
|
||||
[Message Presentation](/plugins/message-presentation).
|
||||
- `--delivery <json>`: generic delivery preferences, for example `{"pin":
|
||||
true}`. `--pin` is shorthand for pinned delivery when the channel supports
|
||||
it.
|
||||
- `--reply-to <id>`, `--thread-id <id>` (Telegram forum topic; Slack thread
|
||||
timestamp, same field as `--reply-to`).
|
||||
- `--force-document` (Telegram, WhatsApp): send images/GIFs/videos as
|
||||
documents to avoid channel compression.
|
||||
- `--silent` (Telegram, Discord): send without a notification.
|
||||
- `--gif-playback` (WhatsApp only): treat video media as GIF playback.
|
||||
|
||||
```bash
|
||||
openclaw message send --channel discord \
|
||||
--target channel:123 --message "Choose:" \
|
||||
--presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Approve","value":"approve","style":"success"},{"label":"Decline","value":"decline","style":"danger"}]}]}'
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw message send --channel telegram --target @mychat --message "Choose:" \
|
||||
--presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Yes","value":"cmd:yes"},{"label":"No","value":"cmd:no"}]}]}'
|
||||
```
|
||||
|
||||
Telegram Mini App buttons use `webApp` (`web_app` still parses for legacy
|
||||
JSON) and only render in private chats between a user and the bot:
|
||||
|
||||
```bash
|
||||
openclaw message send --channel telegram --target 123456789 --message "Open app:" \
|
||||
--presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Launch","webApp":{"url":"https://example.com/app"}}]}]}'
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw message send --channel telegram --target @mychat \
|
||||
--media ./diagram.png --force-document
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw message send --channel msteams \
|
||||
--target conversation:19:abc@thread.tacv2 \
|
||||
--presentation '{"title":"Status update","blocks":[{"type":"text","text":"Build completed"}]}'
|
||||
```
|
||||
|
||||
### Poll
|
||||
|
||||
```bash
|
||||
openclaw message poll --channel discord \
|
||||
--target channel:123 \
|
||||
--poll-question "Snack?" \
|
||||
--poll-option Pizza --poll-option Sushi \
|
||||
--poll-multi --poll-duration-hours 48
|
||||
```
|
||||
|
||||
- `--poll-option <choice>`: repeat 2-12 times.
|
||||
- `--poll-multi`: allow multiple selections.
|
||||
- Discord: `--poll-duration-hours`, `--silent`, `--message`.
|
||||
- Telegram: `--poll-duration-seconds <n>` (5-600), `--silent`,
|
||||
`--poll-anonymous` / `--poll-public`, `--thread-id`.
|
||||
|
||||
```bash
|
||||
openclaw message poll --channel telegram \
|
||||
--target @mychat \
|
||||
--poll-question "Lunch?" \
|
||||
--poll-option Pizza --poll-option Sushi \
|
||||
--poll-duration-seconds 120 --silent
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw message poll --channel msteams \
|
||||
--target conversation:19:abc@thread.tacv2 \
|
||||
--poll-question "Lunch?" \
|
||||
--poll-option Pizza --poll-option Sushi
|
||||
```
|
||||
|
||||
### Threads
|
||||
|
||||
- `thread create`: channels Discord. Required: `--thread-name`, `--target`
|
||||
(channel id). Optional: `--message-id`, `--message`, `--auto-archive-min`.
|
||||
- `thread list`: channels Discord. Required: `--guild-id`. Optional:
|
||||
`--channel-id`, `--include-archived`, `--before`, `--limit`.
|
||||
- `thread reply`: channels Discord. Required: `--target` (thread id),
|
||||
`--message`. Optional: `--media`, `--reply-to`.
|
||||
|
||||
### Emojis
|
||||
|
||||
- `emoji list`: Discord (`--guild-id`), Slack (no extra flags).
|
||||
- `emoji upload`: Discord. Required: `--guild-id`, `--emoji-name`, `--media`.
|
||||
Optional: `--role-ids` (repeat).
|
||||
|
||||
### Stickers
|
||||
|
||||
- `sticker send`: Discord. Required: `--target`, `--sticker-id` (repeat).
|
||||
Optional: `--message`.
|
||||
- `sticker upload`: Discord. Required: `--guild-id`, `--sticker-name`,
|
||||
`--sticker-desc`, `--sticker-tags`, `--media`.
|
||||
|
||||
### Roles, channels, voice, events (Discord)
|
||||
|
||||
- `role info`: `--guild-id`.
|
||||
- `role add` / `role remove`: `--guild-id`, `--user-id`, `--role-id`.
|
||||
- `channel info`: `--target`.
|
||||
- `channel list`: `--guild-id`.
|
||||
- `voice status`: `--guild-id`, `--user-id`.
|
||||
- `event list`: `--guild-id`.
|
||||
- `event create`: required `--guild-id`, `--event-name`, `--start-time`;
|
||||
optional `--end-time`, `--desc`, `--channel-id`, `--location`,
|
||||
`--event-type`, `--image <url-or-path>`.
|
||||
|
||||
### Moderation (Discord)
|
||||
|
||||
- `timeout`: `--guild-id`, `--user-id`; optional `--duration-min` or
|
||||
`--until` (omit both to clear the timeout), `--reason`.
|
||||
- `kick`: `--guild-id`, `--user-id`, `--reason`.
|
||||
- `ban`: `--guild-id`, `--user-id`, `--delete-days`, `--reason`.
|
||||
|
||||
### Broadcast
|
||||
|
||||
```bash
|
||||
openclaw message broadcast --targets <target...> [--channel all] [--message <text>] [--media <url>] [--dry-run]
|
||||
```
|
||||
|
||||
Sends one payload to multiple targets. `--targets` takes a space-separated
|
||||
list. Use `--channel all` to target every configured provider.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Agent send](/tools/agent-send)
|
||||
- [Message Presentation](/plugins/message-presentation)
|
||||
235
docs/cli/migrate.md
Normal file
235
docs/cli/migrate.md
Normal file
@@ -0,0 +1,235 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw migrate` (import state from another agent system)"
|
||||
read_when:
|
||||
- You want to migrate from Hermes or another agent system into OpenClaw
|
||||
- You are adding a plugin-owned migration provider
|
||||
title: "Migrate"
|
||||
---
|
||||
|
||||
# `openclaw migrate`
|
||||
|
||||
Import state from another agent system through a plugin-owned migration provider. Bundled providers cover Claude, Codex CLI, and [Hermes](/install/migrating-hermes); plugins can register additional providers.
|
||||
|
||||
<Tip>
|
||||
For user-facing walkthroughs, see [Migrating from Claude](/install/migrating-claude) and [Migrating from Hermes](/install/migrating-hermes). The [migration hub](/install/migrating) lists all paths.
|
||||
</Tip>
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
openclaw migrate list
|
||||
openclaw migrate claude --dry-run
|
||||
openclaw migrate codex --dry-run
|
||||
openclaw migrate codex --skill gog-vault77-google-workspace
|
||||
openclaw migrate codex --plugin google-calendar --dry-run
|
||||
openclaw migrate codex --plugin google-calendar --verify-plugin-apps --dry-run
|
||||
openclaw migrate hermes --dry-run
|
||||
openclaw migrate hermes
|
||||
openclaw migrate apply codex --yes --skill gog-vault77-google-workspace
|
||||
openclaw migrate apply codex --yes --plugin google-calendar
|
||||
openclaw migrate apply codex --yes
|
||||
openclaw migrate apply claude --yes
|
||||
openclaw migrate apply hermes --yes
|
||||
openclaw migrate apply hermes --include-secrets --yes
|
||||
openclaw onboard --flow import
|
||||
openclaw onboard --import-from claude --import-source ~/.claude
|
||||
openclaw onboard --import-from hermes --import-source ~/.hermes
|
||||
```
|
||||
|
||||
Running `openclaw migrate <provider>` with no other flags plans, previews, and (in a TTY) prompts before applying. `openclaw migrate plan <provider>` and `openclaw migrate apply <provider>` split preview and apply into separate subcommands with the same flags.
|
||||
|
||||
<ParamField path="<provider>" type="string">
|
||||
Name of a registered migration provider, for example `hermes`. Run `openclaw migrate list` to see installed providers.
|
||||
</ParamField>
|
||||
<ParamField path="--dry-run" type="boolean">
|
||||
Build the plan and exit without changing state.
|
||||
</ParamField>
|
||||
<ParamField path="--from <path>" type="string">
|
||||
Override the source state directory. Hermes defaults to `~/.hermes`, Codex defaults to `~/.codex` (or `$CODEX_HOME`), Claude defaults to `~/.claude`.
|
||||
</ParamField>
|
||||
<ParamField path="--include-secrets" type="boolean">
|
||||
Import supported credentials without prompting. Interactive apply asks before importing detected auth credentials, with yes selected by default; non-interactive `--yes` requires `--include-secrets` to import them.
|
||||
</ParamField>
|
||||
<ParamField path="--no-auth-credentials" type="boolean">
|
||||
Skip auth credential import, including the interactive prompt.
|
||||
</ParamField>
|
||||
<ParamField path="--overwrite" type="boolean">
|
||||
Allow apply to replace existing targets when the plan reports conflicts.
|
||||
</ParamField>
|
||||
<ParamField path="--yes" type="boolean">
|
||||
Skip the confirmation prompt. Required in non-interactive mode.
|
||||
</ParamField>
|
||||
<ParamField path="--skill <name>" type="string">
|
||||
Select one skill copy item by skill name or item id. Repeat the flag to migrate multiple skills. When omitted, interactive Codex migrations show a checkbox selector and non-interactive migrations keep all planned skills.
|
||||
</ParamField>
|
||||
<ParamField path="--plugin <name>" type="string">
|
||||
Select one Codex plugin install item by plugin name or item id. Repeat the flag to migrate multiple Codex plugins. When omitted, interactive Codex migrations show a native Codex plugin checkbox selector and non-interactive migrations keep all planned plugins. Applies only to source-installed `openai-curated` Codex plugins discovered by the Codex app-server inventory.
|
||||
</ParamField>
|
||||
<ParamField path="--verify-plugin-apps" type="boolean">
|
||||
Codex only. Forces a fresh source Codex app-server `app/list` traversal before planning native plugin activation. Off by default to keep migration planning fast.
|
||||
</ParamField>
|
||||
<ParamField path="--backup-output <path>" type="string">
|
||||
Pre-migration backup archive path or directory. Passed through to `openclaw backup create`.
|
||||
</ParamField>
|
||||
<ParamField path="--no-backup" type="boolean">
|
||||
Skip the pre-apply backup. Requires `--force` when local OpenClaw state exists.
|
||||
</ParamField>
|
||||
<ParamField path="--force" type="boolean">
|
||||
Required alongside `--no-backup` when apply would otherwise refuse to skip the backup.
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
Print the plan or apply result as JSON. With `--json` and no `--yes`, apply prints the plan and does not mutate state.
|
||||
</ParamField>
|
||||
|
||||
## Safety model
|
||||
|
||||
`openclaw migrate` is preview-first.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Preview before apply">
|
||||
The provider returns an itemized plan before anything changes, including conflicts, skipped items, and sensitive items. JSON plans, apply output, and migration reports redact nested secret-looking keys such as API keys, tokens, authorization headers, cookies, and passwords.
|
||||
|
||||
`openclaw migrate apply <provider>` previews the plan and prompts before changing state unless `--yes` is set. In non-interactive mode, apply requires `--yes`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Backups">
|
||||
Apply creates and verifies an OpenClaw backup before applying the migration. If no local OpenClaw state exists yet, the backup step is skipped and the migration continues. To skip a backup when state exists, pass both `--no-backup` and `--force`.
|
||||
</Accordion>
|
||||
<Accordion title="Conflicts">
|
||||
Apply refuses to continue when the plan has conflicts. Review the plan, then rerun with `--overwrite` if replacing existing targets is intentional. Providers may still write item-level backups for overwritten files in the migration report directory.
|
||||
</Accordion>
|
||||
<Accordion title="Secrets">
|
||||
Interactive apply asks whether to import detected auth credentials, with yes selected by default. Use `--no-auth-credentials` to skip them, or `--include-secrets` for unattended credential import with `--yes`.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Claude provider
|
||||
|
||||
The bundled Claude provider detects Claude Code state at `~/.claude` by default. Use `--from <path>` to import a specific Claude Code home or project root.
|
||||
|
||||
<Tip>
|
||||
For a user-facing walkthrough, see [Migrating from Claude](/install/migrating-claude).
|
||||
</Tip>
|
||||
|
||||
### What Claude imports
|
||||
|
||||
- Project `CLAUDE.md` and `.claude/CLAUDE.md` into the OpenClaw agent workspace (`AGENTS.md`).
|
||||
- User `~/.claude/CLAUDE.md` appended to workspace `USER.md`.
|
||||
- MCP server definitions from project `.mcp.json`, Claude Code `~/.claude.json` (including its per-project entries), and Claude Desktop `claude_desktop_config.json`.
|
||||
- Claude skill directories that include `SKILL.md` (user `~/.claude/skills` and project `.claude/skills`).
|
||||
- Claude command Markdown files (user `~/.claude/commands` and project `.claude/commands`) converted into OpenClaw skills with manual invocation only.
|
||||
|
||||
### Archive and manual-review state
|
||||
|
||||
Claude hooks, permissions, environment defaults, project `CLAUDE.local.md`, `.claude/rules`, user and project `agents/` directories, and project history (`projects`, `cache`, `plans` under `~/.claude`) are preserved in the migration report or reported as manual-review items. OpenClaw does not execute hooks, copy broad allowlists, or import OAuth/Desktop credential state automatically.
|
||||
|
||||
## Codex provider
|
||||
|
||||
The bundled Codex provider detects Codex CLI state at `~/.codex` by default, or at `CODEX_HOME` when that environment variable is set. Use `--from <path>` to inventory a specific Codex home.
|
||||
|
||||
Use this provider when moving to the OpenClaw Codex harness and you want to promote useful personal Codex CLI assets deliberately. Local Codex app-server launches use a per-agent `CODEX_HOME`, so they do not read your personal `~/.codex` by default. The normal process `HOME` is still inherited, so Codex can see shared `$HOME/.agents/*` skills/plugin marketplace entries and subprocesses can find user-home config and tokens.
|
||||
|
||||
Running `openclaw migrate codex` in an interactive terminal previews the full plan, then opens checkbox selectors before the final apply confirmation. Skill copy items are prompted first. Use `Toggle all on` or `Toggle all off` for bulk selection. Press Space to toggle rows, or Enter to activate the highlighted row and continue. Planned skills start checked, conflict skills start unchecked, and `Skip for now` skips skill copies for this run while still continuing to plugin selection. When source-installed curated Codex plugins are migratable and `--plugin` was not supplied, migration then prompts for native Codex plugin activation by plugin name. Plugin items start checked unless the target OpenClaw Codex plugin config already has that plugin. Existing target plugins start unchecked and show a conflict hint such as `conflict: plugin exists`; choose `Toggle all off` to migrate no native Codex plugins in that run, or `Skip for now` to stop before applying.
|
||||
|
||||
For scripted or exact runs, select one or more skills or plugins explicitly:
|
||||
|
||||
```bash
|
||||
openclaw migrate codex --dry-run --skill gog-vault77-google-workspace
|
||||
openclaw migrate apply codex --yes --skill gog-vault77-google-workspace
|
||||
openclaw migrate codex --dry-run --plugin google-calendar
|
||||
openclaw migrate apply codex --yes --plugin google-calendar
|
||||
```
|
||||
|
||||
### What Codex imports
|
||||
|
||||
- Codex CLI skill directories under `$CODEX_HOME/skills`, excluding Codex's `.system` cache.
|
||||
- Personal AgentSkills under `$HOME/.agents/skills`, copied into the current OpenClaw agent workspace for per-agent ownership.
|
||||
- Source-installed `openai-curated` Codex plugins discovered through Codex app-server `plugin/list`. Planning reads `plugin/read` for each enabled installed plugin.
|
||||
|
||||
App-backed plugin migration has extra gates:
|
||||
|
||||
- App-backed plugins require the source Codex app-server account to be a ChatGPT subscription account. Non-ChatGPT or missing account responses are skipped with `codex_subscription_required`.
|
||||
- By default, migration does not call source `app/list`, so app-backed plugins that pass the account gate are planned without source app-accessibility verification, and account-lookup transport failures skip with `codex_account_unavailable`.
|
||||
- Pass `--verify-plugin-apps` to force a fresh source `app/list` snapshot and require every owned app to be present, enabled, and accessible before planning native activation. In that mode, account-lookup transport failures fall through to source app-inventory verification. The snapshot is kept in memory for the current process only; it is never written to migration output or target config.
|
||||
|
||||
Disabled plugins, unreadable plugin details, subscription-gated source accounts, and (when `--verify-plugin-apps` is set) missing, disabled, or inaccessible apps become manual skipped items with typed reasons instead of target config entries. Apply calls app-server `plugin/install` for each selected eligible plugin, even if the target app-server already reports that plugin as installed and enabled. Migrated Codex plugins are usable only in sessions that select the native Codex harness; they are not exposed to OpenClaw provider runs, ACP conversation bindings, or other harnesses.
|
||||
|
||||
### Manual-review Codex state
|
||||
|
||||
Codex `config.toml`, native `hooks/hooks.json`, non-curated marketplaces, cached plugin bundles that are not source-installed curated plugins, and source-installed plugins that fail the source subscription gate are not activated automatically. When `--verify-plugin-apps` is set, plugins that fail the source app-inventory gate are also skipped. All of these are copied or reported in the migration report for manual review.
|
||||
|
||||
For migrated source-installed curated plugins, apply writes:
|
||||
|
||||
- `plugins.entries.codex.enabled: true`
|
||||
- `plugins.entries.codex.config.codexPlugins.enabled: true`
|
||||
- `plugins.entries.codex.config.codexPlugins.allow_destructive_actions: true`
|
||||
- one explicit plugin entry with `marketplaceName: "openai-curated"` and `pluginName` for each selected plugin
|
||||
|
||||
Migration never writes `plugins["*"]` and never stores local marketplace cache paths.
|
||||
|
||||
Skipped plugins are not written to target config. Source-side subscription failures are reported on manual items with typed reasons: `codex_subscription_required`, `codex_account_unavailable`, `plugin_disabled`, or `plugin_read_unavailable`. With `--verify-plugin-apps`, source app-inventory failures can also appear as `app_inaccessible`, `app_disabled`, `app_missing`, or `app_inventory_unavailable`. Target-side auth-required installs are reported on the affected plugin item with `status: "skipped"`, `reason: "auth_required"`, and sanitized app identifiers; their explicit config entries are written disabled until you reauthorize and enable them. Other install failures are item-scoped `error` results.
|
||||
|
||||
If Codex app-server plugin inventory is unavailable during planning, migration falls back to cached bundle advisory items instead of failing the whole migration.
|
||||
|
||||
## Hermes provider
|
||||
|
||||
The bundled Hermes provider detects state at `~/.hermes` by default. Use `--from <path>` when Hermes lives elsewhere.
|
||||
|
||||
### What Hermes imports
|
||||
|
||||
- Default model configuration from `config.yaml`.
|
||||
- Configured model providers and custom OpenAI-compatible endpoints from `providers` and `custom_providers`.
|
||||
- MCP server definitions from `mcp_servers` or `mcp.servers`.
|
||||
- `SOUL.md` and `AGENTS.md` into the OpenClaw agent workspace.
|
||||
- `memories/MEMORY.md` and `memories/USER.md` appended to workspace memory files.
|
||||
- Memory config defaults for OpenClaw file memory, plus archive or manual-review items for external memory providers such as Honcho.
|
||||
- Skills that include a `SKILL.md` file under `skills/<name>/`.
|
||||
- Per-skill config values from `skills.config`.
|
||||
- OpenCode OpenAI OAuth credentials from OpenCode `auth.json` when interactive credential migration is accepted, or when `--include-secrets` is set. Hermes `auth.json` OAuth entries are legacy state reported for manual OpenAI reauth or doctor repair.
|
||||
- Supported API keys and tokens from Hermes `.env` and OpenCode `auth.json` when interactive credential migration is accepted, or when `--include-secrets` is set.
|
||||
|
||||
### Supported `.env` keys
|
||||
|
||||
`AI_GATEWAY_API_KEY`, `ALIBABA_API_KEY`, `ANTHROPIC_API_KEY`, `ARCEEAI_API_KEY`, `CEREBRAS_API_KEY`, `CHUTES_API_KEY`, `CLOUDFLARE_AI_GATEWAY_API_KEY`, `COPILOT_GITHUB_TOKEN`, `DASHSCOPE_API_KEY`, `DEEPINFRA_API_KEY`, `DEEPSEEK_API_KEY`, `FIREWORKS_API_KEY`, `GEMINI_API_KEY`, `GH_TOKEN`, `GITHUB_TOKEN`, `GLM_API_KEY`, `GOOGLE_API_KEY`, `GROQ_API_KEY`, `HF_TOKEN`, `HUGGINGFACE_HUB_TOKEN`, `KILOCODE_API_KEY`, `KIMICODE_API_KEY`, `KIMI_API_KEY`, `MINIMAX_API_KEY`, `MINIMAX_CODING_API_KEY`, `MISTRAL_API_KEY`, `MODELSTUDIO_API_KEY`, `MOONSHOT_API_KEY`, `NVIDIA_API_KEY`, `OPENAI_API_KEY`, `OPENCODE_API_KEY`, `OPENCODE_GO_API_KEY`, `OPENCODE_ZEN_API_KEY`, `OPENROUTER_API_KEY`, `QIANFAN_API_KEY`, `QWEN_API_KEY`, `TOGETHER_API_KEY`, `VENICE_API_KEY`, `XAI_API_KEY`, `XIAOMI_API_KEY`, `ZAI_API_KEY`, `Z_AI_API_KEY`.
|
||||
|
||||
### Archive-only state
|
||||
|
||||
Hermes state that OpenClaw cannot safely interpret is copied into the migration report for manual review, but it is not loaded into live OpenClaw config or credentials. This preserves opaque or unsafe state without pretending OpenClaw can execute or trust it automatically: `plugins/`, `sessions/`, `logs/`, `cron/`, `mcp-tokens/`, `state.db`.
|
||||
|
||||
### After applying
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
## Plugin contract
|
||||
|
||||
Migration sources are plugins. A plugin declares its provider ids in `openclaw.plugin.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"contracts": {
|
||||
"migrationProviders": ["hermes"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
At runtime the plugin calls `api.registerMigrationProvider(...)`. The provider implements `detect`, `plan`, and `apply`. Core owns CLI orchestration, backup policy, prompts, JSON output, and conflict preflight. Core passes the reviewed plan into `apply(ctx, plan)`, and providers may rebuild the plan only when that argument is absent for compatibility.
|
||||
|
||||
Provider plugins can use `openclaw/plugin-sdk/migration` for item construction and summary counts, plus `openclaw/plugin-sdk/migration-runtime` for conflict-aware file copies, archive-only report copies, cached config-runtime wrappers, and migration reports.
|
||||
|
||||
## Onboarding integration
|
||||
|
||||
Onboarding can offer migration when a provider detects a known source. Both `openclaw onboard --flow import` and `openclaw setup --wizard --import-from hermes` use the same plugin migration provider and still show a preview before applying.
|
||||
|
||||
<Note>
|
||||
Onboarding imports require a fresh OpenClaw setup. Reset config, credentials, sessions, and the workspace first if you already have local state. Backup-plus-overwrite or merge imports are feature-gated for existing setups.
|
||||
</Note>
|
||||
|
||||
## Related
|
||||
|
||||
- [Migrating from Hermes](/install/migrating-hermes): user-facing walkthrough.
|
||||
- [Migrating from Claude](/install/migrating-claude): user-facing walkthrough.
|
||||
- [Migrating](/install/migrating): move OpenClaw to a new machine.
|
||||
- [Doctor](/gateway/doctor): health check after applying a migration.
|
||||
- [Plugins](/tools/plugin): plugin install and registration.
|
||||
186
docs/cli/models.md
Normal file
186
docs/cli/models.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw models` (status/list/set/scan, aliases, fallbacks, auth)"
|
||||
read_when:
|
||||
- You want to change default models or view provider auth status
|
||||
- You want to scan available models/providers and debug auth profiles
|
||||
title: "Models"
|
||||
---
|
||||
|
||||
# `openclaw models`
|
||||
|
||||
Model discovery, scanning, and configuration (default model, fallbacks, auth profiles).
|
||||
|
||||
Related:
|
||||
|
||||
- Providers + models: [Models](/providers/models)
|
||||
- Model selection concepts + `/models` slash command: [Models concept](/concepts/models)
|
||||
- Provider auth setup: [Getting started](/start/getting-started)
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
openclaw models status
|
||||
openclaw models list
|
||||
openclaw models set <model-or-alias>
|
||||
openclaw models set-image <model-or-alias>
|
||||
openclaw models scan
|
||||
```
|
||||
|
||||
`status` and `auth` subcommands accept `--agent <id>` to target a configured agent; `list`, `scan`, `aliases`, and `fallbacks`/`image-fallbacks` always use the configured default agent, and `set`/`set-image` reject `--agent` outright. When omitted, `--agent`-aware commands use `OPENCLAW_AGENT_DIR` if set, otherwise the configured default agent.
|
||||
|
||||
### Status
|
||||
|
||||
`openclaw models status` shows the resolved default/fallbacks plus an auth overview. When provider usage snapshots are available, the OAuth/API-key status section includes provider usage windows and quota snapshots. Current usage-window providers: Anthropic, GitHub Copilot, Gemini CLI, OpenAI, MiniMax, Xiaomi, and z.ai. Usage auth comes from provider-specific hooks when available; otherwise OpenClaw falls back to matching OAuth/API-key credentials from auth profiles, env, or config.
|
||||
|
||||
In `--json` output, `auth.providers` is the env/config/store-aware provider overview, while `auth.oauth` is auth-store profile health only.
|
||||
|
||||
Options:
|
||||
|
||||
| Flag | Effect |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `--json` | JSON output; auth-profile, provider, and startup diagnostics go to stderr so stdout stays pipeable into `jq`. |
|
||||
| `--plain` | Plain text output. |
|
||||
| `--check` | Exit non-zero if auth is expiring/expired: `1` = expired/missing, `2` = expiring. |
|
||||
| `--probe` | Live probe of configured auth profiles. Real requests; may consume tokens and trigger rate limits. |
|
||||
| `--probe-provider <name>` | Probe one provider only. |
|
||||
| `--probe-profile <id>` | Probe specific auth profile ids (repeat or comma-separated). |
|
||||
| `--probe-timeout <ms>` | Per-probe timeout. |
|
||||
| `--probe-concurrency <n>` | Concurrent probes. |
|
||||
| `--probe-max-tokens <n>` | Probe max tokens (best effort). |
|
||||
| `--agent <id>` | Configured agent id; overrides `OPENCLAW_AGENT_DIR`. |
|
||||
|
||||
Probe rows can come from auth profiles, env credentials, or `models.json`. Probe status buckets: `ok`, `auth`, `rate_limit`, `billing`, `timeout`, `format`, `unknown`, `no_model`.
|
||||
|
||||
Probe detail/reason codes to expect when a probe never reaches a model call:
|
||||
|
||||
- `excluded_by_auth_order`: a stored profile exists, but explicit `auth.order.<provider>` omitted it, so probe reports the exclusion instead of trying it.
|
||||
- `missing_credential`, `invalid_expires`, `expired`, `unresolved_ref`: profile is present but not eligible or resolvable.
|
||||
- `ineligible_profile`: profile is incompatible with provider config for another reason.
|
||||
- `no_model`: provider auth exists, but OpenClaw could not resolve a probeable model candidate for that provider.
|
||||
|
||||
For OpenAI ChatGPT/Codex OAuth troubleshooting, `openclaw models status`, `openclaw models auth list --provider openai`, and `openclaw config get agents.defaults.model --json` are the quickest way to confirm whether an agent has a usable `openai` OAuth profile for `openai/*` through the native Codex runtime. See [OpenAI provider setup](/providers/openai#check-and-recover-codex-oauth-routing).
|
||||
|
||||
### List
|
||||
|
||||
`openclaw models list` is read-only: it reads config, auth profiles, existing catalog state, and provider-owned catalog rows, but never rewrites `models.json`.
|
||||
|
||||
Options: `--all` (full catalog), `--local` (filter to local models), `--provider <id>`, `--json`, `--plain`.
|
||||
|
||||
Notes:
|
||||
|
||||
- The `Auth` column is provider-level and read-only. It is computed from local auth profile metadata, env markers, configured provider keys, local-provider markers, AWS Bedrock env/profile markers, and plugin synthetic-auth metadata; it does not load provider runtime, read keychain secrets, call provider APIs, or prove exact per-model execution readiness.
|
||||
- `models list --all --provider <id>` can include provider-owned static catalog rows from plugin manifests or bundled provider catalog metadata even when you have not authenticated with that provider yet. Those rows still show as unavailable until matching auth is configured.
|
||||
- `models list` keeps the control plane responsive while provider catalog discovery is slow. The default and configured views fall back to configured or synthetic model rows after a short wait and let discovery finish in the background. Use `--all` when you need the exact full discovered catalog and are willing to wait for provider discovery.
|
||||
- Broad `models list --all` merges manifest catalog rows over registry rows without loading provider runtime supplement hooks. Provider-filtered manifest fast paths use only providers marked `static`; providers marked `refreshable` stay registry/cache-backed and append manifest rows as supplements, while providers marked `runtime` stay on registry/runtime discovery.
|
||||
- `models list` keeps native model metadata and runtime caps distinct. In table output, `Ctx` shows `contextTokens/contextWindow` when an effective runtime cap differs from the native context window; JSON rows include `contextTokens` when a provider exposes that cap.
|
||||
- `models list --provider <id>` filters by provider id, such as `moonshot` or `openai`. It does not accept display labels from interactive provider pickers, such as `Moonshot AI`.
|
||||
- Model refs are parsed by splitting on the **first** `/`. If the model ID includes `/` (OpenRouter-style), include the provider prefix (example: `openrouter/moonshotai/kimi-k2`).
|
||||
- If you omit the provider, OpenClaw resolves the input as an alias first, then as a unique configured-provider match for that exact model id, and only then falls back to the configured default provider with a deprecation warning. If that provider no longer exposes the configured default model, OpenClaw falls back to the first configured provider/model instead of surfacing a stale removed-provider default.
|
||||
- `models status` may show `marker(<value>)` in auth output for non-secret placeholders (for example `OPENAI_API_KEY`, `secretref-managed`, `minimax-oauth`, `oauth:chutes`, `ollama-local`) instead of masking them as secrets.
|
||||
|
||||
### Set default / image model
|
||||
|
||||
```bash
|
||||
openclaw models set <model-or-alias>
|
||||
openclaw models set-image <model-or-alias>
|
||||
```
|
||||
|
||||
`set` writes `agents.defaults.model.primary`; `set-image` writes `agents.defaults.imageModel.primary`. Both accept `provider/model` or a configured alias. `set` also repairs Codex/Copilot runtime plugin installs when the newly selected model needs one; `set-image` does not. Neither command accepts `--agent`; they always write agent defaults.
|
||||
|
||||
### Scan
|
||||
|
||||
`models scan` reads OpenRouter's public `:free` catalog and ranks candidates for fallback use. The catalog itself is public, so metadata-only scans do not need an OpenRouter key.
|
||||
|
||||
By default OpenClaw tries to probe tool and image support with live model calls. If no OpenRouter key is configured, the command falls back to metadata-only output and explains that `:free` models still require `OPENROUTER_API_KEY` for probes and inference.
|
||||
|
||||
Options:
|
||||
|
||||
- `--no-probe` (metadata only; no config/secrets lookup)
|
||||
- `--min-params <b>`
|
||||
- `--max-age-days <days>`
|
||||
- `--provider <name>`
|
||||
- `--max-candidates <n>`
|
||||
- `--timeout <ms>` (catalog request and per-probe timeout)
|
||||
- `--concurrency <n>`
|
||||
- `--yes`
|
||||
- `--no-input`
|
||||
- `--set-default`
|
||||
- `--set-image`
|
||||
- `--json`
|
||||
|
||||
`--set-default` and `--set-image` require live probes; metadata-only scan results are informational and are not applied to config.
|
||||
|
||||
## Aliases
|
||||
|
||||
```bash
|
||||
openclaw models aliases list [--json] [--plain]
|
||||
openclaw models aliases add <alias> <model-or-alias>
|
||||
openclaw models aliases remove <alias>
|
||||
```
|
||||
|
||||
Aliases are stored per model entry as `agents.defaults.models.<key>.alias`. `add` resolves `<model-or-alias>` to a canonical provider/model key first, so aliasing an alias repoints it rather than chaining.
|
||||
|
||||
## Fallbacks
|
||||
|
||||
```bash
|
||||
openclaw models fallbacks list [--json] [--plain]
|
||||
openclaw models fallbacks add <model-or-alias>
|
||||
openclaw models fallbacks remove <model-or-alias>
|
||||
openclaw models fallbacks clear
|
||||
```
|
||||
|
||||
Manages `agents.defaults.model.fallbacks`. `openclaw models image-fallbacks list|add|remove|clear` manages the parallel `agents.defaults.imageModel.fallbacks` list with the same subcommand shape.
|
||||
|
||||
## Auth profiles
|
||||
|
||||
```bash
|
||||
openclaw models auth add
|
||||
openclaw models auth list [--provider <id>] [--json]
|
||||
openclaw models auth login --provider <id>
|
||||
openclaw models auth login --provider openai --profile-id openai:work
|
||||
openclaw models auth login-github-copilot
|
||||
openclaw models auth paste-api-key --provider <id>
|
||||
openclaw models auth setup-token --provider <id>
|
||||
openclaw models auth paste-token --provider <id>
|
||||
openclaw models auth order get --provider <id>
|
||||
openclaw models auth order set --provider <id> <profileIds...>
|
||||
openclaw models auth order clear --provider <id>
|
||||
```
|
||||
|
||||
`models auth add` is the interactive auth helper. It can launch a provider auth flow (OAuth/API key) or guide you into manual token paste, depending on the provider you choose.
|
||||
|
||||
`models auth list` lists saved auth profiles for the selected agent without printing token, API-key, or OAuth secret material. Use `--provider <id>` to filter to one provider, such as `openai`, and `--json` for scripting.
|
||||
|
||||
`models auth login` runs a provider plugin's auth flow (OAuth/API key). Use `openclaw plugins list` to see which providers are installed. `login` accepts `--profile-id <id>` for providers that support named profiles during login (use this to keep multiple logins for the same provider separate), `--method <id>` to pick a specific auth method, `--device-code` as a shortcut for `--method device-code`, `--set-default` to apply the provider's recommended default model, and `--force` to remove existing profiles for that provider first (use when a cached OAuth profile is stuck or you want to switch accounts).
|
||||
|
||||
`models auth login-github-copilot` is a shortcut for `models auth login --provider github-copilot --method device` (GitHub device flow); it accepts `--yes` to overwrite an existing profile without prompting.
|
||||
|
||||
Use `openclaw models auth --agent <id> <subcommand>` to write auth results to a specific configured agent store. The parent `--agent` flag is honored by `add`, `list`, `login`, `paste-api-key`, `setup-token`, `paste-token`, `login-github-copilot`, and `order get`/`set`/`clear`.
|
||||
|
||||
For OpenAI models, `--provider openai` defaults to ChatGPT/Codex account login. Use `--method api-key` only when you want to add an OpenAI API-key profile, usually as a backup for Codex subscription limits. Run `openclaw doctor --fix` to migrate older legacy OpenAI Codex prefix auth/profile state to `openai`.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai --set-default
|
||||
openclaw models auth login --provider openai --method api-key
|
||||
openclaw models auth paste-api-key --provider openai
|
||||
openclaw models auth list --provider openai
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `paste-api-key` accepts API keys generated elsewhere, prompts for the key value, and writes it to the default profile id `<provider>:manual` unless you pass `--profile-id`. In automation, pipe the key on stdin, for example `printf "%s\n" "$OPENAI_API_KEY" | openclaw models auth paste-api-key --provider openai`.
|
||||
- `setup-token` and `paste-token` remain generic token commands for providers that expose token auth methods.
|
||||
- `setup-token` requires an interactive TTY and runs the provider's token-auth method (defaulting to that provider's `setup-token` method when it exposes one).
|
||||
- `paste-token` requires `--provider`, prompts for the token value by default, and writes it to the default profile id `<provider>:manual` unless you pass `--profile-id`. In automation, pipe the token on stdin instead of passing it as an argument so provider credentials do not appear in shell history or process lists.
|
||||
- `paste-token --expires-in <duration>` stores an absolute token expiry from a relative duration such as `365d` or `12h`.
|
||||
- For `openai`, OpenAI API keys and ChatGPT/OAuth token material are different auth shapes. Use `paste-api-key` for `sk-...` OpenAI API keys and `paste-token` only for token auth material.
|
||||
- Anthropic: `setup-token`/`paste-token` are supported OpenClaw auth paths for `anthropic`, but OpenClaw prefers reusing the Claude CLI (`claude -p`) on the host when it is available.
|
||||
- `auth order get/set/clear` manages a per-agent auth profile order override for one provider, stored in `auth-state.json` (separate from the `auth.order.<provider>` config key). `set` takes one or more profile ids in priority order; `clear` falls back to config/round-robin ordering.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Model selection](/concepts/model-providers)
|
||||
- [Model failover](/concepts/model-failover)
|
||||
183
docs/cli/node.md
Normal file
183
docs/cli/node.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw node` (headless node host)"
|
||||
read_when:
|
||||
- Running the headless node host
|
||||
- Pairing a non-macOS node for system.run
|
||||
title: "Node"
|
||||
---
|
||||
|
||||
# `openclaw node`
|
||||
|
||||
Run a **headless node host** that connects to the Gateway WebSocket and exposes
|
||||
`system.run` / `system.which` on this machine.
|
||||
|
||||
## Why use a node host?
|
||||
|
||||
Use a node host when you want agents to **run commands on other machines** in your
|
||||
network without installing a full macOS companion app there.
|
||||
|
||||
Common use cases:
|
||||
|
||||
- Run commands on remote Linux/Windows boxes (build servers, lab machines, NAS).
|
||||
- Keep exec **sandboxed** on the gateway, but delegate approved runs to other hosts.
|
||||
- Provide a lightweight, headless execution target for automation or CI nodes.
|
||||
|
||||
Execution is still guarded by **exec approvals** and per-agent allowlists on the
|
||||
node host, so you can keep command access scoped and explicit.
|
||||
|
||||
## Browser proxy (zero-config)
|
||||
|
||||
Node hosts automatically advertise a browser proxy if `browser.enabled` is not
|
||||
disabled on the node. This lets the agent use browser automation on that node
|
||||
without extra configuration.
|
||||
|
||||
By default, the proxy exposes the node's normal browser profile surface. If you
|
||||
set `nodeHost.browserProxy.allowProfiles`, the proxy becomes restrictive:
|
||||
non-allowlisted profile targeting is rejected, and persistent profile
|
||||
create/delete routes are blocked through the proxy.
|
||||
|
||||
Disable it on the node if needed:
|
||||
|
||||
```json5
|
||||
{
|
||||
nodeHost: {
|
||||
browserProxy: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Run (foreground)
|
||||
|
||||
```bash
|
||||
openclaw node run --host <gateway-host> --port 18789
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--host <host>`: Gateway WebSocket host (default: `127.0.0.1`)
|
||||
- `--port <port>`: Gateway WebSocket port (default: `18789`)
|
||||
- `--context-path <path>`: Gateway WebSocket context path (e.g. `/openclaw-gw`). Appended to the WebSocket URL.
|
||||
- `--tls`: Use TLS for the gateway connection
|
||||
- `--tls-fingerprint <sha256>`: Expected TLS certificate fingerprint (sha256)
|
||||
- `--node-id <id>`: Override node id (clears pairing token)
|
||||
- `--display-name <name>`: Override the node display name
|
||||
|
||||
## Gateway auth for node host
|
||||
|
||||
`openclaw node run` and `openclaw node install` resolve gateway auth from config/env (no `--token`/`--password` flags on node commands):
|
||||
|
||||
- `OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` are checked first.
|
||||
- Then local config fallback: `gateway.auth.token` / `gateway.auth.password`.
|
||||
- In local mode, node host intentionally does not inherit `gateway.remote.token` / `gateway.remote.password`.
|
||||
- If `gateway.auth.token` / `gateway.auth.password` is explicitly configured via SecretRef and unresolved, node auth resolution fails closed (no remote fallback masking).
|
||||
- In `gateway.mode=remote`, remote client fields (`gateway.remote.token` / `gateway.remote.password`) are also eligible per remote precedence rules.
|
||||
- Node host auth resolution only honors `OPENCLAW_GATEWAY_*` env vars.
|
||||
|
||||
For a node connecting to a plaintext `ws://` Gateway, loopback, private IP
|
||||
literals, `.local`, and Tailnet `*.ts.net` hosts are accepted. For other
|
||||
trusted private-DNS names, set `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`; without
|
||||
it, node startup fails closed and asks you to use `wss://`, an SSH tunnel, or
|
||||
Tailscale. This is a process-environment opt-in, not an `openclaw.json` config
|
||||
key.
|
||||
`openclaw node install` persists it into the supervised node service when it is
|
||||
present in the install command environment.
|
||||
|
||||
## Service (background)
|
||||
|
||||
Install a headless node host as a user service (launchd on macOS, systemd on
|
||||
Linux, Windows Task Scheduler on Windows).
|
||||
|
||||
```bash
|
||||
openclaw node install --host <gateway-host> --port 18789
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--host <host>`: Gateway WebSocket host (default: `127.0.0.1`)
|
||||
- `--port <port>`: Gateway WebSocket port (default: `18789`)
|
||||
- `--context-path <path>`: Gateway WebSocket context path (e.g. `/openclaw-gw`). Appended to the WebSocket URL.
|
||||
- `--tls`: Use TLS for the gateway connection
|
||||
- `--tls-fingerprint <sha256>`: Expected TLS certificate fingerprint (sha256)
|
||||
- `--node-id <id>`: Override node id (clears pairing token)
|
||||
- `--display-name <name>`: Override the node display name
|
||||
- `--runtime <runtime>`: Service runtime (`node` or `bun`)
|
||||
- `--force`: Reinstall/overwrite if already installed
|
||||
|
||||
Manage the service:
|
||||
|
||||
```bash
|
||||
openclaw node status
|
||||
openclaw node start
|
||||
openclaw node stop
|
||||
openclaw node restart
|
||||
openclaw node uninstall
|
||||
```
|
||||
|
||||
Use `openclaw node run` for a foreground node host (no service).
|
||||
|
||||
Service commands accept `--json` for machine-readable output.
|
||||
|
||||
The node host retries Gateway restart and network closes in-process. If the
|
||||
Gateway reports a terminal token/password/bootstrap auth pause, the node host
|
||||
logs the close detail and exits non-zero so launchd/systemd/Task Scheduler can
|
||||
restart it with fresh config and credentials. Pairing-required pauses stay in
|
||||
the foreground flow so the pending request can be approved.
|
||||
|
||||
## Pairing
|
||||
|
||||
The first connection creates a pending device pairing request (`role: node`) on the Gateway.
|
||||
Approve it via:
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
On tightly controlled node networks, the Gateway operator can explicitly opt in
|
||||
to auto-approving first-time node pairing from trusted CIDRs:
|
||||
|
||||
```json5
|
||||
{
|
||||
gateway: {
|
||||
nodes: {
|
||||
pairing: {
|
||||
autoApproveCidrs: ["192.168.1.0/24"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
This is disabled by default (`autoApproveCidrs` is unset). It only applies to
|
||||
fresh `role: node` pairing with no requested scopes, from a client IP the
|
||||
Gateway trusts. Operator/browser clients, Control UI, WebChat, and role,
|
||||
scope, metadata, or public-key upgrades still require manual approval.
|
||||
|
||||
If the node retries pairing with changed auth details (role/scopes/public key),
|
||||
the previous pending request is superseded and a new `requestId` is created.
|
||||
Run `openclaw devices list` again before approval.
|
||||
|
||||
The node host stores its node id, token, display name, and gateway connection
|
||||
info in `node.json` in the OpenClaw state directory (`~/.openclaw` by default,
|
||||
or `$OPENCLAW_STATE_DIR` when set).
|
||||
|
||||
## Exec approvals
|
||||
|
||||
`system.run` is gated by local exec approvals:
|
||||
|
||||
- `$OPENCLAW_STATE_DIR/exec-approvals.json`, or
|
||||
`~/.openclaw/exec-approvals.json` when the variable is unset
|
||||
- [Exec approvals](/tools/exec-approvals)
|
||||
- `openclaw approvals --node <id|name|ip>` (edit from the Gateway)
|
||||
|
||||
For approved async node exec, OpenClaw prepares a canonical `systemRunPlan`
|
||||
before prompting. The later approved `system.run` forward reuses that stored
|
||||
plan, so edits to command/cwd/session fields after the approval request was
|
||||
created are rejected instead of changing what the node executes.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Nodes](/nodes)
|
||||
84
docs/cli/nodes.md
Normal file
84
docs/cli/nodes.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw nodes` (status, pairing, invoke, camera/canvas/screen/location/notify)"
|
||||
read_when:
|
||||
- You're managing paired nodes (cameras, screen, canvas)
|
||||
- You need to approve requests or invoke node commands
|
||||
title: "Nodes"
|
||||
---
|
||||
|
||||
# `openclaw nodes`
|
||||
|
||||
Manage paired nodes (devices) and invoke node capabilities.
|
||||
|
||||
Related: [Nodes overview](/nodes) - [Camera nodes](/nodes/camera) - [Image nodes](/nodes/images)
|
||||
|
||||
Common options on every subcommand: `--url <url>`, `--token <token>`, `--timeout <ms>` (default `10000`), `--json`.
|
||||
|
||||
## Status
|
||||
|
||||
```bash
|
||||
openclaw nodes status
|
||||
openclaw nodes status --connected
|
||||
openclaw nodes status --last-connected 24h
|
||||
openclaw nodes list
|
||||
openclaw nodes describe --node <idOrNameOrIp>
|
||||
```
|
||||
|
||||
`status` and `list` both accept `--connected` (only connected nodes) and `--last-connected <duration>` (e.g. `24h`, `7d`; only nodes that connected within the duration). `list` shows pending and paired nodes in separate tables, with paired rows including the most recent connect age (Last Connect); `status` shows one merged table with per-node capability and version detail. `describe` prints one node's capabilities, permissions, and effective/pending invoke commands.
|
||||
|
||||
## Pairing
|
||||
|
||||
```bash
|
||||
openclaw nodes pending
|
||||
openclaw nodes approve <requestId>
|
||||
openclaw nodes reject <requestId>
|
||||
openclaw nodes remove --node <id|name|ip>
|
||||
openclaw nodes rename --node <id|name|ip> --name <displayName>
|
||||
```
|
||||
|
||||
These commands drive the gateway-owned `node.pair.*` store, separate from device pairing (`openclaw devices approve`) that gates the node's WS `connect` handshake. See [Nodes](/nodes) for how the two relate.
|
||||
|
||||
- `remove` revokes the node's paired-role entry. For a device-backed node this revokes the `node` role in the device pairing store and disconnects its node-role sessions: a mixed-role device keeps its row and only loses the `node` role, a node-only device row is deleted. It also clears any matching legacy gateway-owned node pairing record.
|
||||
- `pending` only needs `operator.pairing` scope.
|
||||
- `gateway.nodes.pairing.autoApproveCidrs` can skip the pending step for explicitly trusted, first-time `role: node` device pairing. Off by default; does not approve role upgrades.
|
||||
- `approve` scope requirements follow the pending request's declared commands:
|
||||
- commandless request: `operator.pairing`
|
||||
- non-exec node commands: `operator.pairing` + `operator.write`
|
||||
- `system.run` / `system.run.prepare` / `system.which`: `operator.pairing` + `operator.admin`
|
||||
- `remove` scope: `operator.pairing` can remove non-operator node rows; a device-token caller revoking its own node role on a mixed-role device additionally needs `operator.admin`.
|
||||
|
||||
## Invoke
|
||||
|
||||
```bash
|
||||
openclaw nodes invoke --node <id> --command system.which --params '{"name":"uname"}'
|
||||
```
|
||||
|
||||
Flags:
|
||||
|
||||
- `--command <command>` (required): e.g. `canvas.eval`.
|
||||
- `--params <json>`: JSON object string (default `{}`).
|
||||
- `--invoke-timeout <ms>`: node invoke timeout (default `15000`).
|
||||
- `--idempotency-key <key>`: optional idempotency key.
|
||||
|
||||
`system.run` and `system.run.prepare` are blocked here; use the `exec` tool with `host=node` for shell execution instead. `system.which` is allowed through `invoke`.
|
||||
|
||||
## Notify, push, location, screen
|
||||
|
||||
```bash
|
||||
openclaw nodes notify --node <id> --title "Build" --body "Done" --priority timeSensitive
|
||||
openclaw nodes push --node <id> --title "OpenClaw" --environment sandbox
|
||||
openclaw nodes location get --node <id> --accuracy precise
|
||||
openclaw nodes screen record --node <id> --duration 10s --fps 10 --out ./clip.mp4
|
||||
```
|
||||
|
||||
- `notify` sends a local notification on a node (macOS only). Requires `--title` or `--body`. Options: `--sound <name>`, `--priority <passive|active|timeSensitive>`, `--delivery <system|overlay|auto>` (default `system`), `--invoke-timeout <ms>` (default `15000`).
|
||||
- `push` sends an APNs test push to an iOS node. Options: `--title <text>` (default `OpenClaw`), `--body <text>`, `--environment <sandbox|production>` to override the detected APNs environment.
|
||||
- `location get` fetches the node's current location. Options: `--max-age <ms>` (reuse a cached fix), `--accuracy <coarse|balanced|precise>`, `--location-timeout <ms>` (default `10000`), `--invoke-timeout <ms>` (default `20000`).
|
||||
- `screen record` captures a short clip and prints the saved path (or writes JSON with `--json`). Options: `--screen <index>` (default `0`), `--duration <ms|10s>` (default `10000`), `--fps <fps>` (default `10`), `--no-audio`, `--out <path>`, `--invoke-timeout <ms>` (default `120000`).
|
||||
|
||||
Camera and Canvas commands have their own docs: [Camera nodes](/nodes/camera), [Canvas](/platforms/mac/canvas). Canvas is implemented by the bundled experimental Canvas plugin; core keeps `openclaw nodes canvas` as a compatibility mount point.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Nodes](/nodes)
|
||||
244
docs/cli/onboard.md
Normal file
244
docs/cli/onboard.md
Normal file
@@ -0,0 +1,244 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw onboard` (interactive onboarding)"
|
||||
read_when:
|
||||
- You want guided setup for gateway, workspace, auth, channels, and skills
|
||||
title: "Onboard"
|
||||
---
|
||||
|
||||
# `openclaw onboard`
|
||||
|
||||
Guided setup for model auth, workspace, gateway, channels, skills, and health in one flow. `openclaw setup` is the same entry point; `openclaw setup --baseline` only writes the baseline config/workspace.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="CLI onboarding hub" href="/start/wizard" icon="rocket">
|
||||
Walkthrough of the interactive CLI flow.
|
||||
</Card>
|
||||
<Card title="Onboarding overview" href="/start/onboarding-overview" icon="map">
|
||||
How OpenClaw onboarding fits together.
|
||||
</Card>
|
||||
<Card title="CLI setup reference" href="/start/wizard-cli-reference" icon="book">
|
||||
Outputs, internals, and per-step behavior.
|
||||
</Card>
|
||||
<Card title="CLI automation" href="/start/wizard-cli-automation" icon="terminal">
|
||||
Non-interactive flags and scripted setups.
|
||||
</Card>
|
||||
<Card title="macOS app onboarding" href="/start/onboarding" icon="apple">
|
||||
Onboarding flow for the macOS menu bar app.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw onboard
|
||||
openclaw onboard --modern
|
||||
openclaw onboard --flow quickstart
|
||||
openclaw onboard --flow manual
|
||||
openclaw onboard --flow import
|
||||
openclaw onboard --import-from hermes --import-source ~/.hermes
|
||||
openclaw onboard --skip-bootstrap
|
||||
openclaw onboard --mode remote --remote-url wss://gateway-host:18789
|
||||
```
|
||||
|
||||
- `--flow quickstart`: minimal prompts, auto-generates a gateway token.
|
||||
- `--flow manual` (alias `advanced`): full prompts for port, bind, and auth.
|
||||
- `--flow import`: runs a detected migration provider (for example Hermes via `--import-from hermes`), previews the plan, then applies after confirmation. Import only runs against a fresh OpenClaw setup - reset config, credentials, sessions, and workspace state first if any exist. Use [`openclaw migrate`](/cli/migrate) for dry-run plans, overwrite mode, reports, and exact mappings.
|
||||
- `--modern` starts the Crestodian conversational setup/repair assistant instead of the classic flow.
|
||||
|
||||
In an interactive terminal, bare `openclaw` (no subcommand) routes by config
|
||||
state:
|
||||
|
||||
- If the active config file is missing or has no authored settings (empty or
|
||||
metadata-only), it starts this classic onboarding flow.
|
||||
- If the config file exists but fails validation, it starts
|
||||
[Crestodian](/cli/crestodian) for repair.
|
||||
- If the config file is valid, it opens the normal agent TUI, either locally
|
||||
or connected to a reachable configured Gateway. On a configured install,
|
||||
reach Crestodian with `/crestodian` inside the TUI or `openclaw crestodian`.
|
||||
|
||||
Plaintext `ws://` is accepted for loopback, private IP literals, `.local`, and Tailnet `*.ts.net` gateway URLs. For other trusted private-DNS names, set `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` in the onboarding process environment.
|
||||
|
||||
## Reset
|
||||
|
||||
```bash
|
||||
openclaw onboard --reset
|
||||
openclaw onboard --reset --reset-scope full
|
||||
```
|
||||
|
||||
`--reset` wipes state before running setup. `--reset-scope` controls how much: `config` (config only), `config+creds+sessions` (default when `--reset` is passed without a scope), or `full` (also resets the workspace). Workspace reset only happens with `--reset-scope full`.
|
||||
|
||||
## Locale
|
||||
|
||||
Interactive onboarding uses the CLI wizard locale for fixed setup copy. Resolve order:
|
||||
|
||||
1. `OPENCLAW_LOCALE`
|
||||
2. `LC_ALL`
|
||||
3. `LC_MESSAGES`
|
||||
4. `LANG`
|
||||
5. English fallback
|
||||
|
||||
Supported wizard locales are `en`, `zh-CN`, and `zh-TW`. Locale values may use underscore or POSIX suffix forms such as `zh_CN.UTF-8`. Product names, command names, config keys, URLs, provider IDs, model IDs, and plugin/channel labels remain literal.
|
||||
|
||||
```bash
|
||||
OPENCLAW_LOCALE=zh-CN openclaw onboard
|
||||
```
|
||||
|
||||
## Non-interactive setup
|
||||
|
||||
`--non-interactive` requires `--accept-risk` (acknowledges that agents are powerful and full system access is risky). `--mode` defaults to `local`.
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice custom-api-key \
|
||||
--custom-base-url "https://llm.example.com/v1" \
|
||||
--custom-model-id "foo-large" \
|
||||
--custom-api-key "$CUSTOM_API_KEY" \
|
||||
--secret-input-mode plaintext \
|
||||
--custom-compatibility openai \
|
||||
--custom-image-input
|
||||
```
|
||||
|
||||
`--custom-api-key` is optional; if omitted, onboarding checks `CUSTOM_API_KEY` in env. OpenClaw marks common vision model IDs (GPT-4o/4.1/5.x, Claude 3/4, Gemini, Qwen-VL, LLaVA, Pixtral, and similar) as image-capable automatically. Pass `--custom-image-input` for unknown custom vision IDs, or `--custom-text-input` to force text-only metadata. Use `--custom-compatibility openai-responses` for OpenAI-compatible endpoints that support `/v1/responses` but not `/v1/chat/completions`; valid values are `openai` (default), `openai-responses`, `anthropic`.
|
||||
|
||||
LM Studio also has a provider-specific key flag:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice lmstudio \
|
||||
--custom-base-url "http://localhost:1234/v1" \
|
||||
--custom-model-id "qwen/qwen3.5-9b" \
|
||||
--lmstudio-api-key "$LM_API_TOKEN" \
|
||||
--accept-risk
|
||||
```
|
||||
|
||||
Non-interactive Ollama:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice ollama \
|
||||
--custom-base-url "http://ollama-host:11434" \
|
||||
--custom-model-id "qwen3.5:27b" \
|
||||
--accept-risk
|
||||
```
|
||||
|
||||
`--custom-base-url` defaults to `http://127.0.0.1:11434`. `--custom-model-id` is optional; if omitted, onboarding uses Ollama's suggested defaults. Cloud model IDs such as `kimi-k2.5:cloud` also work here.
|
||||
|
||||
Store provider keys as refs instead of plaintext:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice openai-api-key \
|
||||
--secret-input-mode ref \
|
||||
--accept-risk
|
||||
```
|
||||
|
||||
With `--secret-input-mode ref`, onboarding writes env-backed refs instead of plaintext key values: for auth-profile-backed providers this writes `keyRef: { source: "env", provider: "default", id: <envVar> }`; for custom providers it writes `models.providers.<id>.apiKey` the same way (for example `{ source: "env", provider: "default", id: "CUSTOM_API_KEY" }`). Contract: set the provider env var in the onboarding process environment (for example `OPENAI_API_KEY`) and do not also pass an inline key flag unless that env var is set - a flag value without the matching env var fails fast with guidance.
|
||||
|
||||
### Gateway auth (non-interactive)
|
||||
|
||||
- `--gateway-auth token --gateway-token <token>` stores a plaintext token. `token` is the default auth mode.
|
||||
- `--gateway-auth token --gateway-token-ref-env <name>` stores `gateway.auth.token` as an env SecretRef. Requires a non-empty env var of that name in the onboarding process environment.
|
||||
- `--gateway-token` and `--gateway-token-ref-env` are mutually exclusive.
|
||||
- With `--install-daemon`: a SecretRef-managed `gateway.auth.token` is validated but not persisted as resolved plaintext in supervisor service environment metadata; if the ref is unresolved, install fails closed with remediation guidance. If both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, install blocks until mode is set explicitly.
|
||||
- Local onboarding writes `gateway.mode="local"` into the config. A later config file missing `gateway.mode` indicates config damage or an incomplete manual edit, not a valid local-mode shortcut.
|
||||
- Local onboarding installs downloadable plugins the chosen setup path requires (for example a Codex or Copilot runtime plugin for those auth choices). Remote onboarding only writes connection info for the remote Gateway - it never installs local plugin packages.
|
||||
- `--allow-unconfigured` is a separate `openclaw gateway run` escape hatch; it does not let onboarding skip `gateway.mode`.
|
||||
|
||||
```bash
|
||||
export OPENCLAW_GATEWAY_TOKEN="your-token"
|
||||
openclaw onboard --non-interactive \
|
||||
--mode local \
|
||||
--auth-choice skip \
|
||||
--gateway-auth token \
|
||||
--gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN \
|
||||
--accept-risk
|
||||
```
|
||||
|
||||
### Local gateway health
|
||||
|
||||
- Unless you pass `--skip-health`, onboarding waits for a reachable local gateway before exiting successfully.
|
||||
- `--install-daemon` starts the managed gateway install path first. Without it, a local gateway must already be running (for example `openclaw gateway run`).
|
||||
- `--skip-health` skips the wait if you only want config/workspace/bootstrap writes in automation.
|
||||
- `--skip-bootstrap` sets `agents.defaults.skipBootstrap: true` and skips creating `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, and `BOOTSTRAP.md`.
|
||||
- On native Windows, `--install-daemon` tries Scheduled Tasks first and falls back to a per-user Startup-folder login item if task creation is denied.
|
||||
|
||||
### Interactive ref mode
|
||||
|
||||
- Choose **Use secret reference** when prompted, then either **Environment variable** or a configured secret provider (`file` or `exec`).
|
||||
- Onboarding runs a fast preflight validation before saving the ref and lets you retry on failure.
|
||||
|
||||
### Z.AI endpoint choices
|
||||
|
||||
<Note>
|
||||
`--auth-choice zai-api-key` auto-detects the best Z.AI endpoint and model for your key: Coding Plan endpoints prefer `zai/glm-5.2` (falling back to `glm-5.1` if unavailable); general API endpoints default to `zai/glm-5.1`. To force a Coding Plan endpoint, pick `zai-coding-global` or `zai-coding-cn` directly.
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
# Promptless endpoint selection
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice zai-coding-global \
|
||||
--zai-api-key "$ZAI_API_KEY"
|
||||
|
||||
# Other Z.AI endpoint choices: zai-coding-cn, zai-global, zai-cn
|
||||
```
|
||||
|
||||
Mistral:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--auth-choice mistral-api-key \
|
||||
--mistral-api-key "$MISTRAL_API_KEY"
|
||||
```
|
||||
|
||||
## Additional non-interactive flags
|
||||
|
||||
Token-based model auth (used with `--auth-choice token`):
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--token-provider <id>` | Token provider id issuing the token |
|
||||
| `--token <token>` | Token value for model authentication |
|
||||
| `--token-profile-id <id>` | Auth profile id (default `<provider>:manual`; some provider-owned flows use their own default, such as `anthropic:default`) |
|
||||
| `--token-expires-in <duration>` | Optional token expiry duration (e.g. `365d`, `12h`) |
|
||||
|
||||
Cloudflare AI Gateway: `--cloudflare-ai-gateway-account-id <id>`, `--cloudflare-ai-gateway-gateway-id <id>`.
|
||||
|
||||
Daemon install control: `--no-install-daemon` / `--skip-daemon` (aliases; skip gateway service install), `--daemon-runtime <node|bun>`.
|
||||
|
||||
Skills: `--node-manager <npm|pnpm|bun>` (default `npm`), `--skip-skills`.
|
||||
|
||||
UI and hook setup: `--skip-ui` (skip Control UI/TUI prompts), `--skip-hooks` (skip webhook/hook setup), `--skip-channels`, `--skip-search`.
|
||||
|
||||
Output: `--suppress-gateway-token-output` suppresses token-bearing Gateway/UI output (token hints, auto-login URL with embedded token, and automatic Control UI launch) - useful in shared terminals and CI.
|
||||
|
||||
<Note>
|
||||
`--json` does not imply non-interactive mode. Use `--non-interactive` for scripts.
|
||||
</Note>
|
||||
|
||||
## Provider prefiltering
|
||||
|
||||
When an auth choice implies a preferred provider, onboarding prefilters the default-model and allowlist pickers to that provider's models. The filter also matches other providers owned by the same plugin, which covers coding-plan variants such as `volcengine`/`volcengine-plan` and `byteplus`/`byteplus-plan`. If the preferred-provider filter yields no loaded models, onboarding falls back to the unfiltered catalog instead of leaving the picker empty.
|
||||
|
||||
## Web-search follow-ups
|
||||
|
||||
Some web-search providers trigger provider-specific follow-up prompts during onboarding:
|
||||
|
||||
- **Grok** can offer optional `x_search` setup with the same xAI auth and an `x_search` model choice.
|
||||
- **Kimi** can ask for the Moonshot API region (`api.moonshot.ai` vs `api.moonshot.cn`) and the default Kimi web-search model.
|
||||
|
||||
## Other behaviors
|
||||
|
||||
- Local onboarding DM scope behavior: [CLI setup reference](/start/wizard-cli-reference#outputs-and-internals).
|
||||
- Fastest first chat: `openclaw dashboard` (Control UI, no channel setup).
|
||||
- Custom provider: connect any OpenAI- or Anthropic-compatible endpoint, including hosted providers not listed. Use **Unknown** compatibility to auto-detect via a live probe.
|
||||
- If Hermes state is detected, onboarding offers a migration flow (see `--flow import` above).
|
||||
|
||||
## Common follow-up commands
|
||||
|
||||
Use `openclaw configure` later for targeted changes and `openclaw channels add` for channel-only setup.
|
||||
|
||||
```bash
|
||||
openclaw channels add
|
||||
openclaw configure
|
||||
openclaw agents add <name>
|
||||
```
|
||||
62
docs/cli/pairing.md
Normal file
62
docs/cli/pairing.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw pairing` (approve/list pairing requests)"
|
||||
read_when:
|
||||
- You're using pairing-mode DMs and need to approve senders
|
||||
title: "Pairing"
|
||||
---
|
||||
|
||||
# `openclaw pairing`
|
||||
|
||||
Approve or inspect DM pairing requests for channels that support pairing (chat DMs only - node/device pairing uses `openclaw devices`).
|
||||
|
||||
Related: [Pairing flow](/channels/pairing)
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
openclaw pairing list telegram
|
||||
openclaw pairing list --channel telegram --account work
|
||||
openclaw pairing list telegram --json
|
||||
|
||||
openclaw pairing approve <code>
|
||||
openclaw pairing approve telegram <code>
|
||||
openclaw pairing approve --channel telegram --account work <code> --notify
|
||||
```
|
||||
|
||||
## `pairing list`
|
||||
|
||||
List pending pairing requests for one channel.
|
||||
|
||||
| Option | Description |
|
||||
| ----------------------- | ------------------------------------- |
|
||||
| `[channel]` | positional channel id |
|
||||
| `--channel <channel>` | explicit channel id |
|
||||
| `--account <accountId>` | account id for multi-account channels |
|
||||
| `--json` | machine-readable output |
|
||||
|
||||
If multiple pairing-capable channels are configured, pass a channel positionally or with `--channel`. Extension channels work as long as the channel id is valid.
|
||||
|
||||
## `pairing approve`
|
||||
|
||||
Approve a pending pairing code and allow that sender.
|
||||
|
||||
Usage:
|
||||
|
||||
- `openclaw pairing approve <channel> <code>`
|
||||
- `openclaw pairing approve --channel <channel> <code>`
|
||||
- `openclaw pairing approve <code>` when exactly one pairing-capable channel is configured
|
||||
|
||||
Options: `--channel <channel>`, `--account <accountId>`, `--notify` (send a confirmation back to the requester on the same channel).
|
||||
|
||||
### Owner bootstrap
|
||||
|
||||
If `commands.ownerAllowFrom` is empty when you approve a pairing code, OpenClaw also records the approved sender as the command owner, using a channel-scoped entry such as `telegram:123456789`. This only bootstraps the first owner - later pairing approvals never replace or expand `commands.ownerAllowFrom`.
|
||||
|
||||
The command owner is the human operator account allowed to run owner-only commands and approve dangerous actions such as `/diagnostics`, `/export-trajectory`, `/config`, and exec approvals. Pairing only lets a sender talk to the agent; it does not by itself grant owner privileges beyond this one-time bootstrap.
|
||||
|
||||
If you approved a sender before this bootstrap existed, run `openclaw doctor`; it warns when no command owner is configured and shows the exact `openclaw config set commands.ownerAllowFrom ...` command to fix it.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Channel pairing](/channels/pairing)
|
||||
530
docs/cli/path.md
Normal file
530
docs/cli/path.md
Normal file
@@ -0,0 +1,530 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw path` (inspect and edit workspace files via the `oc://` addressing scheme)"
|
||||
read_when:
|
||||
- You want to read or write a leaf inside a workspace file from the terminal
|
||||
- You're scripting against workspace state and want a stable, kind-agnostic addressing scheme
|
||||
- You're debugging a `oc://` path (validate the syntax, see what it resolves to)
|
||||
title: "Path"
|
||||
---
|
||||
|
||||
# `openclaw path`
|
||||
|
||||
Shell access to the `oc://` addressing scheme: one kind-dispatched path syntax
|
||||
for inspecting and editing addressable workspace files (markdown, jsonc,
|
||||
jsonl, yaml/yml/lobster). Self-hosters, plugin authors, and editor extensions
|
||||
use it to read, find, or update a narrow location without hand-rolling a
|
||||
per-file parser.
|
||||
|
||||
`path` is provided by the bundled optional `oc-path` plugin. Enable it before
|
||||
first use:
|
||||
|
||||
```bash
|
||||
openclaw plugins enable oc-path
|
||||
```
|
||||
|
||||
The CLI verbs mirror the addressing model:
|
||||
|
||||
- `resolve` is concrete and single-match.
|
||||
- `find` is the multi-match verb for wildcards, unions, predicates, and
|
||||
positional expansion.
|
||||
- `set` only accepts concrete paths or insertion markers; wildcard patterns
|
||||
are rejected before writing.
|
||||
- `validate` parses a path with no filesystem access.
|
||||
- `emit` round-trips a file through parse + emit (byte-fidelity diagnostic).
|
||||
|
||||
## Why use it
|
||||
|
||||
OpenClaw state is spread across human-edited markdown, commented JSONC
|
||||
config, append-only JSONL logs, and YAML workflow/spec files. Scripts, hooks,
|
||||
and agents often need one small value from those files: a frontmatter key, a
|
||||
plugin setting, a log record field, a YAML step, or a bullet item under a
|
||||
named section.
|
||||
|
||||
`openclaw path` gives those callers a stable address instead of a one-off
|
||||
grep, regex, or parser per file kind. The same `oc://` path can be validated,
|
||||
resolved, searched, dry-run, and written from the terminal, which keeps narrow
|
||||
automation reviewable and replayable. It preserves the rest of the file, so
|
||||
writing one leaf does not disturb its comments, line endings, or nearby
|
||||
formatting.
|
||||
|
||||
Use it when the thing you want has a logical address, but the file shape
|
||||
varies:
|
||||
|
||||
- A hook reads one setting from commented JSONC without losing comments when
|
||||
it writes the value back.
|
||||
- A maintenance script finds every matching event field in a JSONL log
|
||||
without loading the whole log into a custom parser.
|
||||
- An editor jumps to a markdown section or bullet item by slug, then renders
|
||||
the exact line it resolved to.
|
||||
- An agent dry-runs a small workspace edit before applying it, with the
|
||||
changed bytes visible in review.
|
||||
|
||||
Skip `openclaw path` for ordinary whole-file edits, rich config migrations, or
|
||||
memory-specific writes; those should use the owner command or plugin. `path`
|
||||
is for small, addressable file operations where a repeatable terminal command
|
||||
beats another bespoke parser.
|
||||
|
||||
## How it is used
|
||||
|
||||
Read one value from a human-edited config file:
|
||||
|
||||
```bash
|
||||
openclaw path resolve 'oc://config.jsonc/plugins/github/enabled'
|
||||
```
|
||||
|
||||
Preview a write without touching disk:
|
||||
|
||||
```bash
|
||||
openclaw path set 'oc://config.jsonc/plugins/github/enabled' 'true' --dry-run
|
||||
```
|
||||
|
||||
Find matching records in an append-only JSONL log:
|
||||
|
||||
```bash
|
||||
openclaw path find 'oc://session.jsonl/[event=tool_call]/name'
|
||||
```
|
||||
|
||||
Address an instruction in markdown by section and item instead of by line
|
||||
number:
|
||||
|
||||
```bash
|
||||
openclaw path resolve 'oc://AGENTS.md/runtime-safety/openclaw-gateway'
|
||||
```
|
||||
|
||||
Validate a path in CI or a preflight script before the script reads or
|
||||
writes:
|
||||
|
||||
```bash
|
||||
openclaw path validate 'oc://AGENTS.md/tools/$last/risk'
|
||||
```
|
||||
|
||||
These commands are meant to be copyable into shell scripts. Use `--json` when
|
||||
a caller needs structured output and `--human` when a person is inspecting
|
||||
the result.
|
||||
|
||||
## How it works
|
||||
|
||||
1. Parses the `oc://` address into slots: file, section, item, field, and an
|
||||
optional session query.
|
||||
2. Chooses the file-kind adapter from the target extension (`.md`, `.jsonc`,
|
||||
`.json`, `.jsonl`, `.ndjson`, `.yaml`, `.yml`, `.lobster`).
|
||||
3. Resolves the slots against that file kind's structure: markdown
|
||||
headings/items, JSONC object keys/array indexes, JSONL line records, or
|
||||
YAML map/sequence nodes.
|
||||
4. For `set`, emits edited bytes through the same adapter so untouched parts
|
||||
of the file keep their comments, line endings, and nearby formatting where
|
||||
the kind supports it.
|
||||
|
||||
`resolve` and `set` require one concrete target. `find` is the exploratory
|
||||
verb: it expands wildcards, unions, predicates, and ordinals into the concrete
|
||||
matches you can inspect before choosing one to write.
|
||||
|
||||
## Subcommands
|
||||
|
||||
| Subcommand | Purpose |
|
||||
| ----------------------- | --------------------------------------------------------------------------- |
|
||||
| `resolve <oc-path>` | Print the concrete match at the path (or "not found"). |
|
||||
| `find <pattern>` | Enumerate matches for a wildcard / union / predicate path. |
|
||||
| `set <oc-path> <value>` | Write a leaf or insertion target at a concrete path. Supports `--dry-run`. |
|
||||
| `validate <oc-path>` | Parse-only; print the structural breakdown (file / section / item / field). |
|
||||
| `emit <file>` | Round-trip a file through parse + emit (byte-fidelity diagnostic). |
|
||||
|
||||
## Global flags
|
||||
|
||||
| Flag | Applies to | Purpose |
|
||||
| --------------- | -------------------------------- | ------------------------------------------------------------------------ |
|
||||
| `--cwd <dir>` | `resolve`, `find`, `set`, `emit` | Resolve the file slot against this directory (default: `process.cwd()`). |
|
||||
| `--file <path>` | `resolve`, `find`, `set`, `emit` | Override the file slot's resolved path (absolute access). |
|
||||
| `--json` | all | Force JSON output (default when stdout is not a TTY). |
|
||||
| `--human` | all | Force human output (default when stdout is a TTY). |
|
||||
| `--value-json` | `set` | Parse `<value>` as JSON for JSON/JSONC/JSONL leaf replacement. |
|
||||
| `--dry-run` | `set` | Print the bytes that would be written without writing. |
|
||||
| `--diff` | `set` (requires `--dry-run`) | Print a unified diff instead of the full bytes. |
|
||||
|
||||
`validate` takes only `--json` / `--human`; it does no filesystem access, so
|
||||
`--cwd` and `--file` do not apply.
|
||||
|
||||
## `oc://` syntax
|
||||
|
||||
```text
|
||||
oc://FILE/SECTION/ITEM/FIELD?session=SCOPE
|
||||
```
|
||||
|
||||
Slot rules: `field` requires `item`, and `item` requires `section`. Across
|
||||
all four slots:
|
||||
|
||||
- **Quoted segments** — `"a/b.c"` survives `/` and `.` separators. Content is
|
||||
byte-literal; `"` and `\` are not allowed inside quotes. The file slot is
|
||||
also quote-aware: `oc://"skills/email-drafter"/Tools/$last` treats
|
||||
`skills/email-drafter` as a single file path.
|
||||
- **Predicates** — `[k=v]`, `[k!=v]`, `[k<v]`, `[k<=v]`, `[k>v]`, `[k>=v]`.
|
||||
Numeric operators require both sides to coerce to finite numbers.
|
||||
- **Unions** — `{a,b,c}` matches any of the alternatives.
|
||||
- **Wildcards** — `*` (single sub-segment) and `**` (zero-or-more,
|
||||
recursive). `find` accepts these; `resolve` and `set` reject them as
|
||||
ambiguous.
|
||||
- **Positional** — `$first` / `$last` resolve to the first / last index or
|
||||
declared key.
|
||||
- **Ordinal** — `#N` for the Nth match by document order.
|
||||
- **Insertion markers** — `+`, `+key`, `+nnn` for keyed / indexed insertion
|
||||
(use with `set`).
|
||||
- **Session scope** — `?session=cron-daily` etc. Orthogonal to slot nesting.
|
||||
Session values are raw, not percent-decoded; they may not contain control
|
||||
characters or reserved query delimiters (`?`, `&`, `%`).
|
||||
|
||||
Reserved characters (`?`, `&`, `%`) outside quoted, predicate, or union
|
||||
segments are rejected. Control characters (U+0000-U+001F, U+007F) are
|
||||
rejected anywhere, including the `session` query value.
|
||||
|
||||
`formatOcPath(parseOcPath(path)) === path` is guaranteed for canonical paths.
|
||||
Non-canonical query parameters are ignored except for the first non-empty
|
||||
`session=` value.
|
||||
|
||||
Hard limits: a path caps at 4096 bytes, at most 4 slots (file/section/item/
|
||||
field), at most 64 dotted sub-segments per slot, and at most 256 nested
|
||||
traversal levels for deep JSON paths. Separately, any JSONC/JSON file input
|
||||
over 16 MiB is refused with a parse diagnostic instead of being parsed, for
|
||||
any verb that loads that file.
|
||||
|
||||
## Addressing by file kind
|
||||
|
||||
| Kind | File extensions | Addressing model |
|
||||
| ------------- | --------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| Markdown | `.md` | H2 sections by slug, bullet items by slug or `#N`, frontmatter via `[frontmatter]`. |
|
||||
| JSONC/JSON | `.jsonc`, `.json` | Object keys and array indexes; dots split nested sub-segments unless quoted. |
|
||||
| JSONL | `.jsonl`, `.ndjson` | Top-level line addresses (`L1`, `L2`, `$first`, `$last`), then JSONC-style descent inside the line. |
|
||||
| YAML/.lobster | `.yaml`, `.yml`, `.lobster` | Map keys and sequence indexes; comments and flow style are handled by the YAML document API. |
|
||||
|
||||
`resolve` returns a structured match: `root`, `node`, `leaf`, or
|
||||
`insertion-point`, with a 1-based line number. Leaf values are surfaced as
|
||||
text plus a `leafType` so plugin authors can render previews without
|
||||
depending on the per-kind AST shape.
|
||||
|
||||
## Mutation contract
|
||||
|
||||
`set` writes one concrete target:
|
||||
|
||||
- Markdown frontmatter values and `- key: value` item fields are string
|
||||
leaves. Markdown insertions append sections, frontmatter keys, or section
|
||||
items and render a canonical markdown shape for the changed file. Section
|
||||
bodies are not writable as a whole through `set`.
|
||||
- JSONC leaf writes coerce the string value to the existing leaf type
|
||||
(`string`, finite `number`, `true`/`false`, or `null`). Use `--value-json`
|
||||
when a JSONC/JSON/JSONL leaf replacement should parse `<value>` as JSON and
|
||||
may change shape, such as replacing a string secret-ref shorthand with an
|
||||
object. JSONC object and array insertions parse `<value>` as JSON and use
|
||||
the `jsonc-parser` edit path for ordinary leaf writes, preserving comments
|
||||
and nearby formatting.
|
||||
- JSONL leaf writes coerce like JSONC inside a line. Whole-line replacement
|
||||
and append parse `<value>` as JSON. Rendered JSONL preserves the file's
|
||||
dominant LF/CRLF line-ending convention (majority vote across the file's
|
||||
newlines, so a mostly-CRLF file stays CRLF even with a few stray LFs).
|
||||
- YAML leaf writes coerce to the existing scalar type (`string`, finite
|
||||
`number`, `true`/`false`, or `null`). YAML insertions use the bundled
|
||||
`yaml` package's document API for map/sequence updates. Malformed YAML
|
||||
documents with parser errors are refused before mutation with
|
||||
`parse-error`.
|
||||
|
||||
Use `--dry-run` before user-visible writes when the exact bytes matter. JSONC
|
||||
and YAML edits patch the existing document (via `jsonc-parser` or the `yaml`
|
||||
document API), so untouched bytes usually survive; markdown rebuilds the file
|
||||
from its parsed structure on any edit, which can normalize incidental
|
||||
formatting outside the changed leaf. Add `--diff` when you want the preview
|
||||
as a focused before/after patch instead of the full rendered file.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Validate a path (no filesystem access)
|
||||
openclaw path validate 'oc://AGENTS.md/Tools/$last/risk'
|
||||
|
||||
# Read a leaf
|
||||
openclaw path resolve 'oc://gateway.jsonc/version'
|
||||
|
||||
# Wildcard search
|
||||
openclaw path find 'oc://session.jsonl/*/event' --file ./logs/session.jsonl
|
||||
|
||||
# Dry-run a write
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run
|
||||
|
||||
# Dry-run a write as a unified diff
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run --diff
|
||||
|
||||
# Apply the write
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0'
|
||||
|
||||
# Byte-fidelity round-trip (diagnostic)
|
||||
openclaw path emit ./AGENTS.md
|
||||
```
|
||||
|
||||
More grammar examples:
|
||||
|
||||
```bash
|
||||
# Quote keys containing / or .
|
||||
openclaw path resolve 'oc://config.jsonc/agents.defaults.models/"anthropic/claude-opus-4-7"/alias'
|
||||
|
||||
# Deep JSON/JSONC paths can use slash segments; they normalize to dotted subsegments
|
||||
openclaw path set 'oc://openclaw.json/agents/list/0/tools/exec/security' 'allowlist' --dry-run
|
||||
|
||||
# Replace a JSONC leaf with a parsed object
|
||||
openclaw path set 'oc://openclaw.json/gateway/auth/token' '{"source":"file","provider":"secrets","id":"/test"}' --value-json --dry-run
|
||||
|
||||
# Predicate search over JSONC children
|
||||
openclaw path find 'oc://config.jsonc/plugins/[enabled=true]/id'
|
||||
|
||||
# Insert into a JSONC array
|
||||
openclaw path set 'oc://config.jsonc/items/+1' '{"id":"new","enabled":true}' --dry-run
|
||||
|
||||
# Insert a JSONC object key
|
||||
openclaw path set 'oc://config.jsonc/plugins/+github' '{"enabled":true}' --dry-run
|
||||
|
||||
# Append a JSONL event
|
||||
openclaw path set 'oc://session.jsonl/+' '{"event":"checkpoint","ok":true}' --file ./logs/session.jsonl
|
||||
|
||||
# Resolve the last JSONL value line
|
||||
openclaw path resolve 'oc://session.jsonl/$last/event' --file ./logs/session.jsonl
|
||||
|
||||
# Resolve a YAML workflow step
|
||||
openclaw path resolve 'oc://workflow.yaml/steps/0/id'
|
||||
|
||||
# Update a YAML scalar
|
||||
openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --dry-run
|
||||
|
||||
# Address markdown frontmatter
|
||||
openclaw path resolve 'oc://AGENTS.md/[frontmatter]/name'
|
||||
|
||||
# Insert markdown frontmatter
|
||||
openclaw path set 'oc://AGENTS.md/[frontmatter]/+description' 'Agent instructions' --dry-run
|
||||
|
||||
# Find markdown item fields
|
||||
openclaw path find 'oc://SKILL.md/Tools/*/send_email'
|
||||
|
||||
# Validate a session-scoped path
|
||||
openclaw path validate 'oc://AGENTS.md/Tools/$last/risk?session=cron-daily'
|
||||
```
|
||||
|
||||
## Recipes by file kind
|
||||
|
||||
The same five verbs work across kinds; the addressing scheme dispatches on
|
||||
the file extension.
|
||||
|
||||
### Markdown
|
||||
|
||||
```text
|
||||
<!-- frontmatter.md -->
|
||||
---
|
||||
name: drafter
|
||||
description: email drafting agent
|
||||
tier: core
|
||||
---
|
||||
## Tools
|
||||
- gh: GitHub CLI
|
||||
- curl: HTTP client
|
||||
- send_email: enabled
|
||||
```
|
||||
|
||||
```bash
|
||||
$ openclaw path resolve 'oc://x.md/[frontmatter]/tier' --file frontmatter.md --human
|
||||
leaf @ L4: "core" (string)
|
||||
|
||||
$ openclaw path resolve 'oc://x.md/tools/gh/gh' --file frontmatter.md --human
|
||||
leaf @ L9: "GitHub CLI" (string)
|
||||
|
||||
$ openclaw path find 'oc://x.md/tools/*' --file frontmatter.md --human
|
||||
3 matches for oc://x.md/tools/*:
|
||||
oc://x.md/tools/gh → node @ L9 [md-item]
|
||||
oc://x.md/tools/curl → node @ L10 [md-item]
|
||||
oc://x.md/tools/send-email → node @ L11 [md-item]
|
||||
```
|
||||
|
||||
The `[frontmatter]` predicate addresses the YAML frontmatter block; `tools`
|
||||
matches the `## Tools` heading via slug, and item leaves keep their slug form
|
||||
even when the source uses underscores (`send_email` becomes `send-email`).
|
||||
|
||||
### JSONC
|
||||
|
||||
```text
|
||||
// config.jsonc
|
||||
{
|
||||
"plugins": {
|
||||
"github": {"enabled": true, "role": "vcs"},
|
||||
"slack": {"enabled": false, "role": "chat"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ openclaw path resolve 'oc://config.jsonc/plugins/github/enabled' --file config.jsonc --human
|
||||
leaf @ L4: "true" (boolean)
|
||||
|
||||
$ openclaw path set 'oc://config.jsonc/plugins/slack/enabled' 'true' --file config.jsonc --dry-run
|
||||
--dry-run: would write 142 bytes to /…/config.jsonc
|
||||
{
|
||||
"plugins": {
|
||||
"github": {"enabled": true, "role": "vcs"},
|
||||
"slack": {"enabled": true, "role": "chat"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
JSONC edits go through `jsonc-parser`, so comments and whitespace survive a
|
||||
`set`. Run with `--dry-run` first to inspect the bytes before committing.
|
||||
`.json` files use the same adapter and edit path as `.jsonc`.
|
||||
|
||||
### JSONL
|
||||
|
||||
```text
|
||||
{"event":"start","userId":"u1","ts":1}
|
||||
{"event":"action","userId":"u1","ts":2}
|
||||
{"event":"end","userId":"u1","ts":3}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ openclaw path find 'oc://session.jsonl/[event=action]/userId' --file session.jsonl --human
|
||||
1 match for oc://session.jsonl/[event=action]/userId:
|
||||
oc://session.jsonl/L2/userId → leaf @ L2: "u1" (string)
|
||||
|
||||
$ openclaw path resolve 'oc://session.jsonl/L2/ts' --file session.jsonl --human
|
||||
leaf @ L2: "2" (number)
|
||||
```
|
||||
|
||||
Each line is a record. Address by predicate (`[event=action]`) when you do
|
||||
not know the line number, or by the canonical `LN` segment when you do.
|
||||
`.ndjson` files use the same adapter as `.jsonl`.
|
||||
|
||||
### YAML
|
||||
|
||||
```text
|
||||
# workflow.yaml
|
||||
name: inbox-triage
|
||||
steps:
|
||||
- id: fetch
|
||||
command: gmail.search
|
||||
- id: classify
|
||||
command: openclaw.invoke
|
||||
```
|
||||
|
||||
```bash
|
||||
$ openclaw path resolve 'oc://workflow.yaml/steps/0/id' --file workflow.yaml --human
|
||||
leaf @ L3: "fetch" (string)
|
||||
|
||||
$ openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --file workflow.yaml --dry-run
|
||||
--dry-run: would write 99 bytes to /…/workflow.yaml
|
||||
name: inbox-triage
|
||||
steps:
|
||||
- id: fetch
|
||||
command: gmail.search
|
||||
- id: classify-renamed
|
||||
command: openclaw.invoke
|
||||
```
|
||||
|
||||
YAML uses the `yaml` package's `Document` API rather than a hand-rolled
|
||||
parser, so ordinary parse/emit round-trips preserve comments and authoring
|
||||
shape while resolved paths use the same map-key / sequence-index model as
|
||||
JSONC. The same adapter handles `.yaml`, `.yml`, and `.lobster` files.
|
||||
|
||||
## Subcommand reference
|
||||
|
||||
### `resolve <oc-path>`
|
||||
|
||||
Read a single leaf or node. Wildcards are rejected — use `find` for those.
|
||||
Exits `0` on a match, `1` on a clean miss, `2` on a parse error or refused
|
||||
pattern.
|
||||
|
||||
```bash
|
||||
openclaw path resolve 'oc://AGENTS.md/tools/gh/risk' --human
|
||||
openclaw path resolve 'oc://gateway.jsonc/server/port' --json
|
||||
```
|
||||
|
||||
### `find <pattern>`
|
||||
|
||||
Enumerate every match for a wildcard / predicate / union pattern. Exits `0`
|
||||
on at least one match, `1` on zero. File-slot wildcards are rejected with
|
||||
`OC_PATH_FILE_WILDCARD_UNSUPPORTED` — pass a concrete file (multi-file
|
||||
globbing is a follow-up feature).
|
||||
|
||||
```bash
|
||||
openclaw path find 'oc://AGENTS.md/tools/**/risk'
|
||||
openclaw path find 'oc://session.jsonl/[event=action]/userId'
|
||||
openclaw path find 'oc://config.jsonc/plugins/{github,slack}/enabled'
|
||||
```
|
||||
|
||||
### `set <oc-path> <value>`
|
||||
|
||||
Write a leaf. Pair with `--dry-run` to preview the bytes that would be
|
||||
written without touching the file. Add `--diff` for a unified diff preview.
|
||||
Exits `0` on a successful write, `1` if the substrate refuses (for example, a
|
||||
sentinel guard hit), `2` on parse errors.
|
||||
|
||||
```bash
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run --diff
|
||||
openclaw path set 'oc://gateway.jsonc/version' '2.0'
|
||||
openclaw path set 'oc://AGENTS.md/Tools/+gh/risk' 'low'
|
||||
```
|
||||
|
||||
The `+key` insertion marker creates the named child if it does not already
|
||||
exist; `+nnn` and bare `+` work for indexed and append insertion
|
||||
respectively.
|
||||
|
||||
### `validate <oc-path>`
|
||||
|
||||
Parse-only check. No filesystem access. Useful when you want to confirm a
|
||||
template path is well-formed before substituting variables, or when you want
|
||||
the structural breakdown for debugging:
|
||||
|
||||
```bash
|
||||
$ openclaw path validate 'oc://AGENTS.md/tools/gh' --human
|
||||
valid: oc://AGENTS.md/tools/gh
|
||||
file: AGENTS.md
|
||||
section: tools
|
||||
item: gh
|
||||
```
|
||||
|
||||
Exits `0` when valid, `1` when invalid (with a structured `code` and
|
||||
`message`), `2` on argument errors.
|
||||
|
||||
### `emit <file>`
|
||||
|
||||
Round-trip a file through the per-kind parser and emitter. The output should
|
||||
be byte-identical to the input on a sound file; divergence indicates a
|
||||
parser bug or a sentinel hit. Useful for debugging substrate behavior on
|
||||
real-world inputs.
|
||||
|
||||
```bash
|
||||
openclaw path emit ./AGENTS.md
|
||||
openclaw path emit ./gateway.jsonc --json
|
||||
```
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
| ---- | -------------------------------------------------------------------------- |
|
||||
| `0` | Success. (`resolve` / `find`: at least one match. `set`: write succeeded.) |
|
||||
| `1` | No match, or `set` rejected by the substrate (no system-level error). |
|
||||
| `2` | Argument or parse error. |
|
||||
|
||||
## Output mode
|
||||
|
||||
`openclaw path` is TTY-aware: human-readable output on a terminal, JSON when
|
||||
stdout is piped or redirected. `--json` and `--human` override the
|
||||
auto-detection.
|
||||
|
||||
## Notes
|
||||
|
||||
- `set` writes bytes through the substrate's emit path, which applies the
|
||||
redaction-sentinel guard automatically. A leaf carrying
|
||||
`__OPENCLAW_REDACTED__` (verbatim or as a substring) is refused at write
|
||||
time.
|
||||
- JSONC parsing and leaf edits use the plugin-local `jsonc-parser`
|
||||
dependency, so comments and formatting are preserved on ordinary leaf
|
||||
writes instead of going through a hand-rolled parser/re-render path.
|
||||
- `path` is not aware of last-known-good (LKG) config tracking or recovery;
|
||||
that lifecycle is owned elsewhere. If a file you edit through `path` is
|
||||
also LKG-tracked, the next config read decides whether to promote or
|
||||
recover it; treat a `path` edit the same as any other direct write to
|
||||
that file.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
552
docs/cli/plugins.md
Normal file
552
docs/cli/plugins.md
Normal file
@@ -0,0 +1,552 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw plugins` (init, build, validate, list, install, marketplace, uninstall, enable/disable, doctor)"
|
||||
read_when:
|
||||
- You want to install or manage Gateway plugins or compatible bundles
|
||||
- You want to scaffold or validate a simple tool plugin
|
||||
- You want to debug plugin load failures
|
||||
title: "Plugins"
|
||||
sidebarTitle: "Plugins"
|
||||
---
|
||||
|
||||
Manage Gateway plugins, hook packs, and compatible bundles.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Plugin system" href="/tools/plugin">
|
||||
End-user guide for installing, enabling, and troubleshooting plugins.
|
||||
</Card>
|
||||
<Card title="Manage plugins" href="/plugins/manage-plugins">
|
||||
Quick examples for install, list, update, uninstall, and publishing.
|
||||
</Card>
|
||||
<Card title="Plugin bundles" href="/plugins/bundles">
|
||||
Bundle compatibility model.
|
||||
</Card>
|
||||
<Card title="Plugin manifest" href="/plugins/manifest">
|
||||
Manifest fields and config schema.
|
||||
</Card>
|
||||
<Card title="Security" href="/gateway/security">
|
||||
Security hardening for plugin installs.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
openclaw plugins list [--enabled] [--verbose] [--json]
|
||||
openclaw plugins search <query> [--limit <n>] [--json]
|
||||
openclaw plugins install <path-or-spec> [--link] [--force] [--pin] [--marketplace <source>]
|
||||
openclaw plugins inspect <id> [--runtime] [--json]
|
||||
openclaw plugins inspect --all [--runtime] [--json]
|
||||
openclaw plugins info <id> # alias for inspect
|
||||
openclaw plugins enable <id>
|
||||
openclaw plugins disable <id>
|
||||
openclaw plugins uninstall <id> [--dry-run] [--keep-files] [--force]
|
||||
openclaw plugins update <id-or-npm-spec> | --all [--dry-run]
|
||||
openclaw plugins registry [--refresh] [--json]
|
||||
openclaw plugins doctor
|
||||
openclaw plugins init <id> [--name <name>] [--type tool|provider] [--directory <path>]
|
||||
openclaw plugins build [--entry <path>] [--check]
|
||||
openclaw plugins validate [--entry <path>]
|
||||
openclaw plugins marketplace entries [--offline] [--feed-profile <name>] [--json]
|
||||
openclaw plugins marketplace list <source> [--json]
|
||||
openclaw plugins marketplace refresh [--feed-profile <name>] [--expected-sha256 <sha256>] [--json]
|
||||
```
|
||||
|
||||
For slow install, inspect, uninstall, or registry-refresh investigation, run the
|
||||
command with `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1`. The trace writes phase timings
|
||||
to stderr and keeps JSON output parseable. See [Debugging](/help/debugging#plugin-lifecycle-trace).
|
||||
|
||||
<Note>
|
||||
In Nix mode (`OPENCLAW_NIX_MODE=1`), `openclaw.json` is immutable. `install`, `update`, `uninstall`, `enable`, and `disable` all refuse to run. Edit the Nix source for this install instead (`programs.openclaw.config` or `instances.<name>.config` for nix-openclaw), then rebuild. See the agent-first [Quick Start](https://github.com/openclaw/nix-openclaw#quick-start).
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
Bundled plugins ship with OpenClaw. Some are enabled by default (for example bundled model providers, bundled speech providers, and the bundled browser plugin); others require `plugins enable`.
|
||||
|
||||
Native OpenClaw plugins ship `openclaw.plugin.json` with an inline JSON Schema (`configSchema`, even if empty). Compatible bundles use their own bundle manifests instead.
|
||||
|
||||
`plugins list` shows `Format: openclaw` or `Format: bundle`. Verbose list/info output also shows the bundle subtype (`codex`, `claude`, or `cursor`) plus detected bundle capabilities.
|
||||
</Note>
|
||||
|
||||
## Author
|
||||
|
||||
```bash
|
||||
openclaw plugins init stock-quotes --name "Stock Quotes"
|
||||
cd stock-quotes
|
||||
npm run plugin:build
|
||||
npm run plugin:validate
|
||||
```
|
||||
|
||||
`plugins init` creates a minimal TypeScript tool plugin by default. The first
|
||||
argument is the plugin id; `--name` sets the display name. OpenClaw uses the
|
||||
id for the default output directory and package naming. Tool scaffolds use
|
||||
`defineToolPlugin` and generate `package.json` scripts `plugin:build` and
|
||||
`plugin:validate` that build then call `openclaw plugins build`/`validate`.
|
||||
|
||||
`plugins build` imports the built entry, reads its static tool metadata, writes
|
||||
`openclaw.plugin.json`, and keeps `package.json`'s `openclaw.extensions` aligned.
|
||||
`plugins validate` checks that the generated manifest, package metadata, and
|
||||
current entry export still agree. See [Tool Plugins](/plugins/tool-plugins) for
|
||||
the full authoring workflow.
|
||||
|
||||
The scaffold writes TypeScript source but generates metadata from the built
|
||||
`./dist/index.js` entry, so the workflow also works with the published CLI. Use
|
||||
`--entry <path>` when the entry is not the default package entry. Use
|
||||
`plugins build --check` in CI to fail when generated metadata is stale without
|
||||
rewriting files.
|
||||
|
||||
### Provider scaffold
|
||||
|
||||
```bash
|
||||
openclaw plugins init acme-models --name "Acme Models" --type provider
|
||||
cd acme-models
|
||||
npm install
|
||||
npm run build
|
||||
npm test
|
||||
npm run validate
|
||||
```
|
||||
|
||||
Provider scaffolds create a generic OpenAI-compatible model provider plugin
|
||||
with API-key auth plumbing, a `npm run validate` script that runs
|
||||
`clawhub package validate`, ClawHub package metadata, and a manually
|
||||
dispatched GitHub Actions workflow for future trusted publishing via GitHub
|
||||
OIDC. Provider scaffolds do not generate skills and do not use
|
||||
`openclaw plugins build`/`validate`; those commands are for the tool
|
||||
scaffold's generated-metadata path.
|
||||
|
||||
Before publishing, replace the placeholder API base URL, model catalog, docs
|
||||
route, credential text, and README copy with real provider details. Use the
|
||||
generated README for first-time ClawHub publishing and trusted-publisher setup.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
openclaw plugins search "calendar" # search ClawHub plugins
|
||||
openclaw plugins install <package> # source auto-detection
|
||||
openclaw plugins install clawhub:<package> # ClawHub only
|
||||
openclaw plugins install npm:<package> # npm only
|
||||
openclaw plugins install npm-pack:<path.tgz> # local npm-pack tarball
|
||||
openclaw plugins install git:github.com/<owner>/<repo> # git repo
|
||||
openclaw plugins install git:github.com/<owner>/<repo>@<ref>
|
||||
openclaw plugins install <path> # local path or archive
|
||||
openclaw plugins install -l <path> # link instead of copy
|
||||
openclaw plugins install <plugin>@<marketplace> # marketplace shorthand
|
||||
openclaw plugins install <plugin> --marketplace <name> # marketplace (explicit)
|
||||
openclaw plugins install <package> --force # overwrite existing install
|
||||
openclaw plugins install <package> --pin # pin resolved npm version
|
||||
openclaw plugins install clawhub:<package> --acknowledge-clawhub-risk
|
||||
openclaw plugins install <package> --dangerously-force-unsafe-install
|
||||
```
|
||||
|
||||
Maintainers testing setup-time installs can override automatic plugin install
|
||||
sources with guarded environment variables. See
|
||||
[Plugin install overrides](/plugins/install-overrides).
|
||||
|
||||
<Warning>
|
||||
Bare package names install from npm by default during the launch cutover, unless they match a bundled or official plugin id, in which case OpenClaw uses that local/official copy instead of hitting the npm registry. Use `npm:<package>` when you deliberately want an external npm package instead. Use `clawhub:<package>` for ClawHub. Treat plugin installs like running code; prefer pinned versions.
|
||||
</Warning>
|
||||
|
||||
`plugins search` queries ClawHub for installable `code-plugin` and
|
||||
`bundle-plugin` packages (not skills; use `openclaw skills search` for those).
|
||||
Default `--limit` is 20, capped at 100. It only reads the remote catalog: no
|
||||
local state inspection, config mutation, package install, or plugin runtime
|
||||
load. Results include the ClawHub package name, family, channel, version,
|
||||
summary, and an install hint such as `openclaw plugins install clawhub:<package>`.
|
||||
|
||||
<Note>
|
||||
ClawHub is the primary distribution and discovery surface for most plugins. Npm
|
||||
remains a supported fallback and direct-install path. OpenClaw-owned
|
||||
`@openclaw/*` plugin packages are published on npm again; see the current list
|
||||
on [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) or the
|
||||
[plugin inventory](/plugins/plugin-inventory). Stable installs use `latest`.
|
||||
Beta-channel installs and updates prefer the npm `beta` dist-tag when available,
|
||||
falling back to `latest`.
|
||||
</Note>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Config includes and invalid-config repair">
|
||||
If your `plugins` section is backed by a single-file `$include`, `plugins install/update/enable/disable/uninstall` write through to that included file and leave `openclaw.json` untouched. Root includes, include arrays, and includes with sibling overrides fail closed instead of flattening. See [Config includes](/gateway/configuration) for the supported shapes.
|
||||
|
||||
If config is invalid during install, `plugins install` normally fails closed and tells you to run `openclaw doctor --fix` first. During Gateway startup and hot reload, invalid plugin config fails closed like any other invalid config; `openclaw doctor --fix` can quarantine the invalid plugin entry. The only documented install-time exception is a narrow bundled-plugin recovery path for plugins that explicitly opt into `openclaw.install.allowInvalidConfigRecovery`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--force and reinstall vs update">
|
||||
`--force` reuses the existing install target and overwrites an already-installed plugin or hook pack in place. Use it when intentionally reinstalling the same id from a new local path, archive, ClawHub package, or npm artifact. For routine upgrades of an already tracked npm plugin, prefer `openclaw plugins update <id-or-npm-spec>`.
|
||||
|
||||
If you run `plugins install` for a plugin id that is already installed, OpenClaw stops and points you at `plugins update <id-or-npm-spec>` for a normal upgrade, or at `plugins install <package> --force` when you genuinely want to overwrite the current install from a different source. `--force` is not supported with `--link`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--pin scope">
|
||||
`--pin` applies to npm installs only and records the resolved exact `<name>@<version>`. It is not supported with `git:` installs (pin the ref in the spec instead, e.g. `git:github.com/acme/plugin@v1.2.3`) or with `--marketplace` (marketplace installs persist marketplace source metadata instead of an npm spec).
|
||||
</Accordion>
|
||||
<Accordion title="--dangerously-force-unsafe-install">
|
||||
`--dangerously-force-unsafe-install` is deprecated and is now a no-op. OpenClaw no longer runs built-in install-time dangerous-code blocking for plugin installs.
|
||||
|
||||
Use the operator-owned `security.installPolicy` surface when host-specific install policy is required. Plugin `before_install` hooks are plugin-runtime lifecycle hooks, not the primary policy boundary for CLI installs.
|
||||
|
||||
If a plugin you published on ClawHub is hidden or blocked by a registry scan, use the publisher steps in [ClawHub publishing](/clawhub/publishing). `--dangerously-force-unsafe-install` does not ask ClawHub to rescan the plugin or make a blocked release public.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--acknowledge-clawhub-risk">
|
||||
Community ClawHub installs check the selected release's trust record before downloading. If ClawHub disables download for the release, reports malicious scan findings, or puts the release in a blocking moderation state (quarantined, revoked), OpenClaw refuses it outright regardless of this flag. For non-blocking risky scan statuses or moderation states, OpenClaw shows the trust details and asks for confirmation before continuing.
|
||||
|
||||
Use `--acknowledge-clawhub-risk` only after reviewing the ClawHub warning and deciding to continue without an interactive prompt. Pending or stale (not-yet-clean) scan results warn but do not require acknowledgement. Official ClawHub packages and bundled OpenClaw plugin sources bypass this release-trust check entirely.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Hook packs and npm specs">
|
||||
`plugins install` is also the install surface for hook packs that expose `openclaw.hooks` in `package.json`. Use `openclaw hooks` for filtered hook visibility and per-hook enablement, not package installation.
|
||||
|
||||
Npm specs are **registry-only** (package name plus optional **exact version** or **dist-tag**). Git/URL/file specs and semver ranges are rejected. Dependency installs run in one managed npm project per plugin with `--ignore-scripts` for safety, even when your shell has global npm install settings. Managed plugin npm projects inherit OpenClaw's package-level npm `overrides`, so host security pins apply to hoisted plugin dependencies too.
|
||||
|
||||
Use `npm:<package>` to make npm resolution explicit. Bare package specs also install directly from npm during the launch cutover unless they match an official plugin id.
|
||||
|
||||
Raw `@openclaw/*` specs that match bundled plugins resolve to the image-owned bundled copy before npm fallback. For example, `openclaw plugins install @openclaw/discord@2026.5.20 --pin` uses the bundled Discord plugin from the current OpenClaw build instead of creating a managed npm override. To force the external npm package, use `openclaw plugins install npm:@openclaw/discord@2026.5.20 --pin`.
|
||||
|
||||
Bare specs and `@latest` stay on the stable track. OpenClaw date-stamped correction versions such as `2026.5.3-1` count as stable for this check. If npm resolves either form to a prerelease, OpenClaw stops and asks you to opt in explicitly with a prerelease tag (`@beta`/`@rc`) or an exact prerelease version (`@1.2.3-beta.4`).
|
||||
|
||||
For npm installs without an exact version (`npm:<package>` or `npm:<package>@latest`), OpenClaw checks the resolved package metadata before install. If the latest stable package requires a newer OpenClaw plugin API or minimum host version, OpenClaw inspects older stable versions and installs the newest compatible release instead. Exact versions and explicit dist-tags stay strict: an incompatible selection fails and asks you to upgrade OpenClaw or choose a compatible version.
|
||||
|
||||
If a bare install spec matches an official plugin id (for example `diffs`), OpenClaw installs the catalog entry directly. To install an npm package with the same name, use an explicit scoped spec (for example `@scope/diffs`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Git repositories">
|
||||
Use `git:<repo>` to install directly from a git repository. Supported forms: `git:github.com/owner/repo`, `git:owner/repo`, full `https://`, `ssh://`, `git://`, `file://`, and `git@host:owner/repo.git` clone URLs. Add `@<ref>` or `#<ref>` to check out a branch, tag, or commit before install.
|
||||
|
||||
Git installs clone into a temporary directory, check out the requested ref when present, then use the normal plugin directory installer, so manifest validation, operator install policy, package-manager install work, and install records behave like npm installs. Recorded git installs include the source URL/ref plus the resolved commit so `openclaw plugins update` can re-resolve the source later.
|
||||
|
||||
After installing from git, use `openclaw plugins inspect <id> --runtime --json` to verify runtime registrations such as gateway methods and CLI commands. If the plugin registered a CLI root with `api.registerCli`, run that command directly through the OpenClaw root CLI, for example `openclaw demo-plugin ping`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Archives">
|
||||
Supported archives: `.zip`, `.tgz`, `.tar.gz`, `.tar`. Native OpenClaw plugin archives must contain a valid `openclaw.plugin.json` at the extracted plugin root; archives that only contain `package.json` are rejected before OpenClaw writes install records.
|
||||
|
||||
Use `npm-pack:<path.tgz>` when the file is an npm-pack tarball and you want
|
||||
the same per-plugin managed npm project path used by registry installs,
|
||||
including `package-lock.json` verification, hoisted dependency scanning,
|
||||
and npm install records. Plain archive paths still install as local
|
||||
archives under the plugin extensions root.
|
||||
|
||||
Claude marketplace installs are also supported.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
ClawHub installs use an explicit `clawhub:<package>` locator:
|
||||
|
||||
```bash
|
||||
openclaw plugins install clawhub:openclaw-codex-app-server
|
||||
openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3
|
||||
```
|
||||
|
||||
Bare npm-safe plugin specs install from npm by default during the launch cutover unless they match an official plugin id:
|
||||
|
||||
```bash
|
||||
openclaw plugins install openclaw-codex-app-server
|
||||
```
|
||||
|
||||
Use `npm:` to make npm-only resolution explicit:
|
||||
|
||||
```bash
|
||||
openclaw plugins install npm:openclaw-codex-app-server
|
||||
openclaw plugins install npm:@openclaw/discord@2026.5.20
|
||||
openclaw plugins install npm:@scope/plugin-name@1.0.1
|
||||
```
|
||||
|
||||
OpenClaw checks the advertised plugin API / minimum gateway compatibility before install. When the selected ClawHub version publishes a ClawPack artifact, OpenClaw downloads the versioned npm-pack `.tgz`, verifies the ClawHub digest header and the artifact digest, then installs it through the normal archive path. Older ClawHub versions without ClawPack metadata still install through the legacy package archive verification path. Recorded installs keep their ClawHub source metadata, artifact kind, npm integrity, npm shasum, tarball name, and ClawPack digest facts for later updates.
|
||||
Unversioned ClawHub installs keep an unversioned recorded spec so `openclaw plugins update` can follow newer ClawHub releases; explicit version or tag selectors such as `clawhub:pkg@1.2.3` and `clawhub:pkg@beta` remain pinned to that selector.
|
||||
|
||||
### Marketplace shorthand
|
||||
|
||||
Use `plugin@marketplace` shorthand when the marketplace name exists in Claude's local registry cache at `~/.claude/plugins/known_marketplaces.json`:
|
||||
|
||||
```bash
|
||||
openclaw plugins marketplace list <marketplace-name>
|
||||
openclaw plugins install <plugin-name>@<marketplace-name>
|
||||
```
|
||||
|
||||
Use `--marketplace` to pass the marketplace source explicitly:
|
||||
|
||||
```bash
|
||||
openclaw plugins install <plugin-name> --marketplace <marketplace-name>
|
||||
openclaw plugins install <plugin-name> --marketplace <owner/repo>
|
||||
openclaw plugins install <plugin-name> --marketplace https://github.com/<owner>/<repo>
|
||||
openclaw plugins install <plugin-name> --marketplace ./my-marketplace
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Marketplace sources">
|
||||
- a Claude known-marketplace name from `~/.claude/plugins/known_marketplaces.json`
|
||||
- a local marketplace root or `marketplace.json` path
|
||||
- a GitHub repo shorthand such as `owner/repo`
|
||||
- a GitHub repo URL such as `https://github.com/owner/repo`
|
||||
- a git URL
|
||||
|
||||
</Tab>
|
||||
<Tab title="Remote marketplace rules">
|
||||
For remote marketplaces loaded from GitHub or git, plugin entries must stay inside the cloned marketplace repo. OpenClaw accepts relative path sources from that repo and rejects HTTP(S), absolute-path, git, GitHub, and other non-path plugin sources from remote manifests.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
For local paths and archives, OpenClaw auto-detects:
|
||||
|
||||
- native OpenClaw plugins (`openclaw.plugin.json`)
|
||||
- Codex-compatible bundles (`.codex-plugin/plugin.json`)
|
||||
- Claude-compatible bundles (`.claude-plugin/plugin.json`, or the default Claude component layout when that manifest file is absent)
|
||||
- Cursor-compatible bundles (`.cursor-plugin/plugin.json`)
|
||||
|
||||
Managed local installs must be plugin directories or archives. Standalone `.js`,
|
||||
`.mjs`, `.cjs`, and `.ts` plugin files are not copied into the managed plugin
|
||||
root by `plugins install`, nor loaded by placing them directly in
|
||||
`~/.openclaw/extensions` or `<workspace>/.openclaw/extensions`; those
|
||||
auto-discovered roots load plugin package or bundle directories, and skip
|
||||
top-level script files as local helpers. List standalone files explicitly in
|
||||
`plugins.load.paths` instead.
|
||||
|
||||
<Note>
|
||||
Compatible bundles install into the normal plugin root and participate in the same list/info/enable/disable flow. Today, bundle skills, Claude command-skills, Claude `settings.json` defaults, Claude `.lsp.json` / manifest-declared `lspServers` defaults, Cursor command-skills, and compatible Codex hook directories are supported; other detected bundle capabilities are shown in diagnostics/info but are not yet wired into runtime execution.
|
||||
</Note>
|
||||
|
||||
Use `-l`/`--link` to point at a local plugin directory without copying it (adds
|
||||
to `plugins.load.paths`):
|
||||
|
||||
```bash
|
||||
openclaw plugins install -l ./my-plugin
|
||||
```
|
||||
|
||||
`--link` is not supported with `--force` (linked plugins point at the source
|
||||
path directly, so there is nothing to overwrite in place), `--marketplace`, or
|
||||
`git:` installs, and it requires a local path that already exists.
|
||||
|
||||
<Note>
|
||||
Workspace-origin plugins discovered from a workspace extensions root are not
|
||||
imported or executed until they are explicitly enabled. For local development,
|
||||
run `openclaw plugins enable <plugin-id>` or set
|
||||
`plugins.entries.<plugin-id>.enabled: true`; if your config uses
|
||||
`plugins.allow`, include the same plugin id there too. This fail-closed rule
|
||||
also applies when channel setup explicitly targets a workspace-origin plugin for
|
||||
setup-only loading, so local channel plugin setup code will not run while that
|
||||
workspace plugin remains disabled or excluded from the allowlist. Linked installs
|
||||
and explicit `plugins.load.paths` entries follow the normal policy for their
|
||||
resolved plugin origin. See
|
||||
[Configure plugin policy](/tools/plugin#configure-plugin-policy)
|
||||
and [Configuration reference](/gateway/configuration-reference#plugins).
|
||||
|
||||
Use `--pin` on npm installs to save the resolved exact spec (`name@version`) in the managed plugin index while keeping the default behavior unpinned.
|
||||
</Note>
|
||||
|
||||
## List
|
||||
|
||||
```bash
|
||||
openclaw plugins list
|
||||
openclaw plugins list --enabled
|
||||
openclaw plugins list --verbose
|
||||
openclaw plugins list --json
|
||||
```
|
||||
|
||||
<ParamField path="--enabled" type="boolean">
|
||||
Show only enabled plugins.
|
||||
</ParamField>
|
||||
<ParamField path="--verbose" type="boolean">
|
||||
Switch from the table view to per-plugin detail lines with format/source/origin/version/activation metadata.
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
Machine-readable inventory plus registry diagnostics and package dependency install state.
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
`plugins list` reads the persisted local plugin registry first, with a manifest-only derived fallback when the registry is missing or invalid. It is useful for checking whether a plugin is installed, enabled, and visible to cold startup planning, but it is not a live runtime probe of an already-running Gateway process. After changing plugin code, enablement, hook policy, or `plugins.load.paths`, restart the Gateway that serves the channel before expecting new `register(api)` code or hooks to run. For remote/container deployments, verify you are restarting the actual `openclaw gateway run` child, not only a wrapper process.
|
||||
|
||||
`plugins list --json` includes each plugin's `dependencyStatus` from `package.json`
|
||||
`dependencies` and `optionalDependencies`. OpenClaw checks whether those package
|
||||
names are present along the plugin's normal Node `node_modules` lookup path; it
|
||||
does not import plugin runtime code, run a package manager, or repair missing
|
||||
dependencies.
|
||||
</Note>
|
||||
|
||||
If startup logs `plugins.allow is empty; discovered non-bundled plugins may auto-load: ...`,
|
||||
run `openclaw plugins list --enabled --verbose` or
|
||||
`openclaw plugins inspect <id>` with a listed plugin id to confirm the plugin
|
||||
ids and copy trusted ids into `plugins.allow` in `openclaw.json`. When the
|
||||
warning can list every discovered plugin, it prints a ready-to-paste
|
||||
`plugins.allow` snippet that already includes those ids. If a plugin loads
|
||||
without install/load-path provenance, inspect that plugin id, then either pin
|
||||
the trusted id in `plugins.allow` or reinstall the plugin from a trusted source
|
||||
so OpenClaw records install provenance.
|
||||
|
||||
For bundled plugin work inside a packaged Docker image, bind-mount the plugin
|
||||
source directory over the matching packaged source path, such as
|
||||
`/app/extensions/synology-chat`. OpenClaw discovers that mounted source overlay
|
||||
before `/app/dist/extensions/synology-chat`; a plain copied source directory
|
||||
remains inert, so normal packaged installs still use compiled dist.
|
||||
|
||||
For runtime hook debugging:
|
||||
|
||||
- `openclaw plugins inspect <id> --runtime --json` shows registered hooks and diagnostics from a module-loaded inspection pass. Runtime inspection never installs dependencies; use `openclaw doctor --fix` to clean legacy dependency state or recover missing downloadable plugins that are referenced by config.
|
||||
- `openclaw gateway status --deep --require-rpc` confirms the reachable Gateway URL/profile, service/process hints, config path, and RPC health.
|
||||
- Non-bundled conversation hooks (`llm_input`, `llm_output`, `before_model_resolve`, `before_agent_reply`, `before_agent_run`, `before_agent_finalize`, `agent_end`) require `plugins.entries.<id>.hooks.allowConversationAccess=true`.
|
||||
|
||||
### Plugin index
|
||||
|
||||
Plugin install metadata is machine-managed state, not user config. Installs and updates write it to the shared SQLite state database under the active OpenClaw state directory. The `installed_plugin_index` row stores durable `installRecords` metadata, including records for broken or missing plugin manifests, plus a manifest-derived cold registry cache used by `openclaw plugins update`, uninstall, diagnostics, and the cold plugin registry.
|
||||
|
||||
When OpenClaw sees shipped legacy `plugins.installs` records in config, runtime reads treat them as compatibility input without rewriting `openclaw.json`. Explicit plugin writes and `openclaw doctor --fix` move those records into the plugin index and remove the config key when config writes are allowed; if either write fails, the config records are kept so the install metadata is not lost.
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
openclaw plugins uninstall <id>
|
||||
openclaw plugins uninstall <id> --dry-run
|
||||
openclaw plugins uninstall <id> --keep-files
|
||||
openclaw plugins uninstall <id> --force
|
||||
```
|
||||
|
||||
`uninstall` removes plugin records from `plugins.entries`, the persisted plugin index, plugin allow/deny list entries, and linked `plugins.load.paths` entries when applicable. Unless `--keep-files` is set, uninstall also removes the tracked managed install directory, but only when it resolves inside OpenClaw's plugin extensions root. If the plugin currently owns the `memory` or `contextEngine` slot, that slot resets to its default (`memory-core` for memory, `legacy` for context engine).
|
||||
|
||||
`uninstall` prints a preview of what will be removed, then prompts `Uninstall plugin "<id>"?` before making changes. Pass `--force` to skip the confirmation prompt (useful for scripts and non-interactive runs); without it, uninstall requires an interactive TTY. `--dry-run` prints the same preview and exits without prompting or changing anything.
|
||||
|
||||
<Note>
|
||||
`--keep-config` is supported as a deprecated alias for `--keep-files`.
|
||||
</Note>
|
||||
|
||||
## Update
|
||||
|
||||
```bash
|
||||
openclaw plugins update <id-or-npm-spec>
|
||||
openclaw plugins update --all
|
||||
openclaw plugins update <id-or-npm-spec> --dry-run
|
||||
openclaw plugins update @openclaw/voice-call
|
||||
openclaw plugins update openclaw-codex-app-server --acknowledge-clawhub-risk
|
||||
openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install
|
||||
```
|
||||
|
||||
Updates apply to tracked plugin installs in the managed plugin index and tracked hook-pack installs in `hooks.internal.installs`.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Resolving plugin id vs npm spec">
|
||||
When you pass a plugin id, OpenClaw reuses the recorded install spec for that plugin. That means previously stored dist-tags such as `@beta` and exact pinned versions continue to be used on later `update <id>` runs.
|
||||
|
||||
During `update <id> --dry-run`, exact pinned npm installs stay pinned. If OpenClaw can also resolve the package's registry default line and that default line is newer than the installed pinned version, the dry run reports the pin and prints the explicit `@latest` package update command to follow the registry default line.
|
||||
|
||||
That targeted-update rule differs from the bulk `openclaw plugins update --all` maintenance path. Bulk updates still respect ordinary tracked install specs, but trusted official OpenClaw plugin records can sync to the current official catalog target instead of staying on a stale exact official package. Use targeted `update <id>` when you intentionally want to keep an exact or tagged official spec untouched.
|
||||
|
||||
For npm installs, you can also pass an explicit npm package spec with a dist-tag or exact version. OpenClaw resolves that package name back to the tracked plugin record, updates that installed plugin, and records the new npm spec for future id-based updates.
|
||||
|
||||
Passing the npm package name without a version or tag also resolves back to the tracked plugin record. Use this when a plugin was pinned to an exact version and you want to move it back to the registry's default release line.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Beta channel updates">
|
||||
Targeted `openclaw plugins update <id-or-npm-spec>` reuses the tracked plugin spec unless you pass a new spec. Bulk `openclaw plugins update --all` uses the configured `update.channel` when it syncs trusted official plugin records to the official catalog target, so beta-channel installs can stay on the beta release line instead of being silently normalized to stable/latest.
|
||||
|
||||
`openclaw update` also knows the active OpenClaw update channel: on the beta channel, default-line npm and ClawHub plugin records try `@beta` first. They fall back to the recorded default/latest spec if no plugin beta release exists; npm plugins also fall back when the beta package exists but fails install validation. That fallback is reported as a warning and does not fail the core update. Exact versions and explicit tags stay pinned to that selector for targeted updates.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Version checks and integrity drift">
|
||||
Before a live npm update, OpenClaw checks the installed package version against the npm registry metadata. If the installed version and recorded artifact identity already match the resolved target, the update is skipped without downloading, reinstalling, or rewriting `openclaw.json`.
|
||||
|
||||
When a stored integrity hash exists and the fetched artifact hash changes, OpenClaw treats that as npm artifact drift. The interactive `openclaw plugins update` command prints the expected and actual hashes and asks for confirmation before proceeding. Non-interactive update helpers fail closed unless the caller supplies an explicit continuation policy.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--dangerously-force-unsafe-install on update">
|
||||
`--dangerously-force-unsafe-install` is also accepted on `plugins update` for compatibility, but it is deprecated and no longer changes plugin update behavior. Operator `security.installPolicy` can still block updates; plugin `before_install` hooks only apply in processes where plugin hooks are loaded.
|
||||
</Accordion>
|
||||
<Accordion title="--acknowledge-clawhub-risk on update">
|
||||
Community ClawHub-backed plugin updates run the same exact-release trust check as installs before downloading the replacement package. Use `--acknowledge-clawhub-risk` for reviewed automation that should continue when the selected ClawHub release has a risky trust warning. Official ClawHub packages and bundled OpenClaw plugin sources bypass this release-trust prompt.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Inspect
|
||||
|
||||
```bash
|
||||
openclaw plugins inspect <id>
|
||||
openclaw plugins inspect <id> --runtime
|
||||
openclaw plugins inspect <id> --json
|
||||
openclaw plugins inspect --all
|
||||
```
|
||||
|
||||
Inspect shows identity, load status, source, manifest capabilities, policy flags, diagnostics, install metadata, bundle capabilities, and any detected MCP or LSP server support without importing plugin runtime by default. JSON output includes the plugin manifest contracts, such as `contracts.agentToolResultMiddleware` and `contracts.trustedToolPolicies`, so operators can audit trusted-surface declarations before enabling or restarting a plugin. Add `--runtime` to load the plugin module and include registered hooks, tools, commands, services, gateway methods, and HTTP routes. Runtime inspection reports missing plugin dependencies directly; installs and repairs stay in `openclaw plugins install`, `openclaw plugins update`, and `openclaw doctor --fix`.
|
||||
|
||||
Plugin-owned CLI commands are usually installed as root `openclaw` command groups, but plugins may also register nested commands under a core parent such as `openclaw nodes`. After `inspect --runtime` shows a command under `cliCommands`, run it at the listed path; for example a plugin that registers `demo-git` can be verified with `openclaw demo-git ping`.
|
||||
|
||||
Each plugin is classified by what it actually registers at runtime:
|
||||
|
||||
| Shape | Meaning |
|
||||
| ------------------- | ----------------------------------------------------------------- |
|
||||
| `plain-capability` | exactly one capability type (e.g. a provider-only plugin) |
|
||||
| `hybrid-capability` | more than one capability type (e.g. text + speech + images) |
|
||||
| `hook-only` | only hooks, no capabilities, tools, commands, services, or routes |
|
||||
| `non-capability` | tools/commands/services but no capabilities |
|
||||
|
||||
See [Plugin shapes](/plugins/architecture#plugin-shapes) for more on the capability model.
|
||||
|
||||
<Note>
|
||||
The `--json` flag outputs a machine-readable report suitable for scripting and auditing. `inspect --all` renders a fleet-wide table with shape, capability kinds, compatibility notices, bundle capabilities, and hook summary columns. `info` is an alias for `inspect`.
|
||||
</Note>
|
||||
|
||||
## Doctor
|
||||
|
||||
```bash
|
||||
openclaw plugins doctor
|
||||
```
|
||||
|
||||
`doctor` reports plugin load errors, manifest/discovery diagnostics, compatibility notices, and stale plugin config references such as missing plugin slots. When the install tree and plugin config are clean it prints `No plugin issues detected.` If stale config remains but the install tree is otherwise healthy, the summary says so instead of implying full plugin health.
|
||||
|
||||
If a configured plugin is present on disk but blocked by the loader's path-safety checks, config validation keeps the plugin entry and reports it as `present but blocked`. Fix the preceding blocked-plugin diagnostic, such as path ownership or world-writable permissions, instead of removing the `plugins.entries.<id>` or `plugins.allow` config.
|
||||
|
||||
For module-shape failures such as missing `register`/`activate` exports, rerun with `OPENCLAW_PLUGIN_LOAD_DEBUG=1` to include a compact export-shape summary in the diagnostic output.
|
||||
|
||||
## Registry
|
||||
|
||||
```bash
|
||||
openclaw plugins registry
|
||||
openclaw plugins registry --refresh
|
||||
openclaw plugins registry --json
|
||||
```
|
||||
|
||||
The local plugin registry is OpenClaw's persisted cold read model for installed plugin identity, enablement, source metadata, and contribution ownership. Normal startup, provider owner lookup, channel setup classification, and plugin inventory can read it without importing plugin runtime modules.
|
||||
|
||||
Use `plugins registry` to inspect whether the persisted registry is present, current, or stale. Use `--refresh` to rebuild it from the persisted plugin index, config policy, and manifest/package metadata. This is a repair path, not a runtime activation path.
|
||||
|
||||
`openclaw doctor --fix` also repairs registry-adjacent managed npm drift: if an orphaned or recovered `@openclaw/*` package under a managed plugin npm project or the legacy flat managed npm root shadows a bundled plugin, doctor removes that stale package and rebuilds the registry so startup validates against the bundled manifest. Doctor also relinks the host `openclaw` package into managed npm plugins that declare `peerDependencies.openclaw`, so package-local runtime imports such as `openclaw/plugin-sdk/*` resolve after updates or npm repairs.
|
||||
|
||||
<Warning>
|
||||
`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` is a deprecated break-glass compatibility switch for registry read failures. Prefer `plugins registry --refresh` or `openclaw doctor --fix`; the env fallback is only for emergency startup recovery while the migration rolls out.
|
||||
</Warning>
|
||||
|
||||
## Marketplace
|
||||
|
||||
```bash
|
||||
openclaw plugins marketplace entries
|
||||
openclaw plugins marketplace entries --offline
|
||||
openclaw plugins marketplace entries --json
|
||||
openclaw plugins marketplace entries --feed-profile <name>
|
||||
openclaw plugins marketplace entries --feed-url <url>
|
||||
openclaw plugins marketplace list <source>
|
||||
openclaw plugins marketplace list <source> --json
|
||||
openclaw plugins marketplace refresh
|
||||
openclaw plugins marketplace refresh --feed-profile <name>
|
||||
openclaw plugins marketplace refresh --feed-url <url>
|
||||
openclaw plugins marketplace refresh --expected-sha256 <sha256> --json
|
||||
```
|
||||
|
||||
`plugins marketplace entries` lists entries from the configured OpenClaw marketplace feed. By default it attempts the hosted feed and falls back to the latest accepted snapshot or bundled data. Use `--feed-profile <name>` to read a specific configured profile, `--feed-url <url>` to read an explicit hosted feed URL, and `--offline` to read the latest accepted snapshot without fetching the feed.
|
||||
|
||||
`plugins marketplace refresh` refreshes the configured hosted feed snapshot and reports whether OpenClaw accepted hosted data, a hosted snapshot, or bundled fallback data. Use `--expected-sha256` when a caller needs the command to fail unless a fresh hosted payload matches a pinned checksum.
|
||||
|
||||
Marketplace `list` accepts a local marketplace path, a `marketplace.json` path, a GitHub shorthand like `owner/repo`, a GitHub repo URL, or a git URL. `--json` prints the resolved source label plus the parsed marketplace manifest and plugin entries.
|
||||
|
||||
Marketplace refresh loads a hosted OpenClaw marketplace feed and persists the
|
||||
validated response as the local hosted-feed snapshot. Without options, it uses
|
||||
the configured default feed profile. Use `--feed-profile <name>` to refresh a
|
||||
specific configured profile, `--feed-url <url>` to refresh an explicit hosted
|
||||
feed URL, `--expected-sha256 <sha256>` to require a matching payload checksum
|
||||
(`sha256:<hex>` or a bare 64-character hex digest), and `--json` for
|
||||
machine-readable output. Explicit hosted feed URLs must not include
|
||||
credentials, query strings, or fragments. Unpinned refreshes can report a
|
||||
hosted snapshot or bundled fallback result without failing the command. Pinned
|
||||
refreshes fail unless they accept a fresh hosted payload, and successful hosted
|
||||
refreshes fail if OpenClaw cannot persist the validated snapshot.
|
||||
|
||||
## Related
|
||||
|
||||
- [Building plugins](/plugins/building-plugins)
|
||||
- [CLI reference](/cli)
|
||||
- [ClawHub](/clawhub)
|
||||
970
docs/cli/policy.md
Normal file
970
docs/cli/policy.md
Normal file
@@ -0,0 +1,970 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw policy` conformance checks"
|
||||
read_when:
|
||||
- You want to check OpenClaw settings against an authored policy.jsonc
|
||||
- You want policy findings in doctor lint
|
||||
- You need a policy attestation hash for audit evidence
|
||||
title: "Policy"
|
||||
---
|
||||
|
||||
# `openclaw policy`
|
||||
|
||||
`openclaw policy` is provided by the bundled Policy plugin. It is an enterprise
|
||||
conformance layer over existing OpenClaw settings, not a second configuration
|
||||
system. You author requirements in `policy.jsonc`; OpenClaw observes the active
|
||||
workspace as evidence; policy reports drift through `doctor --lint`. Policy
|
||||
does not enforce tool calls or rewrite runtime behavior at request time, and it
|
||||
does not attest per-agent credential stores such as `auth-profiles.json`.
|
||||
|
||||
Policy checks configured channels, MCP servers, model providers, network SSRF
|
||||
posture, ingress/channel access, Gateway exposure and node command posture,
|
||||
agent workspace access, sandbox posture, data-handling posture, secret
|
||||
provider/auth profile posture, and governed tool metadata (`TOOLS.md`). Use it
|
||||
when a workspace needs a durable, checkable statement such as "Telegram must
|
||||
not be enabled" or "governed tools must declare risk and owner metadata." If
|
||||
you only need local behavior with no attestation or drift detection, plain
|
||||
config is enough.
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
openclaw plugins enable policy
|
||||
```
|
||||
|
||||
The plugin stays enabled even when `policy.jsonc` is missing, so doctor can
|
||||
report the missing artifact instead of silently skipping checks.
|
||||
|
||||
Author `policy.jsonc` by hand; it is not generated from current settings. Each
|
||||
top-level section is a rule namespace: a check only runs when a concrete rule
|
||||
is present under it (unsupported sections or keys fail as
|
||||
`policy/policy-jsonc-invalid` instead of being silently ignored). Minimal
|
||||
example covering every supported section:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"channels": {
|
||||
"denyRules": [
|
||||
{
|
||||
"id": "no-telegram",
|
||||
"when": { "provider": "telegram" },
|
||||
"reason": "Telegram is not approved for this workspace.",
|
||||
},
|
||||
],
|
||||
},
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"allow": ["docs"],
|
||||
"deny": ["untrusted"],
|
||||
},
|
||||
},
|
||||
"models": {
|
||||
"providers": {
|
||||
"allow": ["openai", "anthropic"],
|
||||
"deny": ["openrouter"],
|
||||
},
|
||||
},
|
||||
"network": {
|
||||
"privateNetwork": {
|
||||
"allow": false,
|
||||
},
|
||||
},
|
||||
"ingress": {
|
||||
"session": {
|
||||
"requireDmScope": "per-channel-peer",
|
||||
},
|
||||
"channels": {
|
||||
"allowDmPolicies": ["pairing", "allowlist", "disabled"],
|
||||
"denyOpenGroups": true,
|
||||
"requireMentionInGroups": true,
|
||||
},
|
||||
},
|
||||
"gateway": {
|
||||
"exposure": {
|
||||
"allowNonLoopbackBind": false,
|
||||
"allowTailscaleFunnel": false,
|
||||
},
|
||||
"auth": {
|
||||
"requireAuth": true,
|
||||
"requireExplicitRateLimit": true,
|
||||
},
|
||||
"controlUi": {
|
||||
"allowInsecure": false,
|
||||
},
|
||||
"remote": {
|
||||
"allow": false,
|
||||
},
|
||||
"http": {
|
||||
"denyEndpoints": ["chatCompletions", "responses"],
|
||||
"requireUrlAllowlists": true,
|
||||
},
|
||||
"nodes": {
|
||||
"denyCommands": ["system.run"],
|
||||
},
|
||||
},
|
||||
"agents": {
|
||||
"workspace": {
|
||||
"allowedAccess": ["none", "ro"],
|
||||
"denyTools": ["exec", "process", "write", "edit", "apply_patch"],
|
||||
},
|
||||
},
|
||||
"dataHandling": {
|
||||
"sensitiveLogging": {
|
||||
"requireRedaction": true,
|
||||
},
|
||||
"telemetry": {
|
||||
"denyContentCapture": true,
|
||||
},
|
||||
"retention": {
|
||||
"requireSessionMaintenance": true,
|
||||
},
|
||||
"memory": {
|
||||
"denySessionTranscriptIndexing": true,
|
||||
},
|
||||
},
|
||||
"secrets": {
|
||||
"requireManagedProviders": true,
|
||||
"denySources": ["exec"],
|
||||
"allowInsecureProviders": false,
|
||||
},
|
||||
"auth": {
|
||||
"profiles": {
|
||||
"requireMetadata": ["provider", "mode"],
|
||||
"allowModes": ["api_key", "token"],
|
||||
},
|
||||
},
|
||||
"execApprovals": {
|
||||
"requireFile": true,
|
||||
"defaults": { "allowSecurity": ["deny"] },
|
||||
"agents": {
|
||||
"allowSecurity": ["deny", "allowlist"],
|
||||
"allowAutoAllowSkills": false,
|
||||
"allowlist": { "expected": ["deploy", "status"] },
|
||||
},
|
||||
},
|
||||
"tools": {
|
||||
"requireMetadata": ["risk", "sensitivity", "owner"],
|
||||
"profiles": {
|
||||
"allow": ["messaging", "minimal"],
|
||||
},
|
||||
"fs": {
|
||||
"requireWorkspaceOnly": true,
|
||||
},
|
||||
"exec": {
|
||||
"allowSecurity": ["deny", "allowlist"],
|
||||
"requireAsk": ["always"],
|
||||
"allowHosts": ["sandbox"],
|
||||
},
|
||||
"elevated": {
|
||||
"allow": false,
|
||||
},
|
||||
"denyTools": ["group:runtime", "group:fs"],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Cross-cutting notes not obvious from the rule tables below:
|
||||
|
||||
- Omitting `gateway.bind` while denying non-loopback binds means you accept
|
||||
the runtime default; set `gateway.bind: "loopback"` for strict conformance.
|
||||
- For a read-only agent, set sandbox `mode` to `all` or `non-main` on the
|
||||
applicable defaults/agent and `workspaceAccess` to `none` or `ro`. Missing or
|
||||
`off` sandbox mode does not satisfy a read-only policy.
|
||||
- `agents.workspace.denyTools` accepts `exec`, `process`, `write`, `edit`,
|
||||
`apply_patch`. The config tool-deny groups `group:fs` (file mutation) and
|
||||
`group:runtime` (shell/process) satisfy the equivalent posture.
|
||||
- Exec-approvals checks read the live `exec-approvals.json` artifact only when
|
||||
an `execApprovals` rule is present; a missing or invalid artifact is
|
||||
unobservable evidence, not a synthetic pass.
|
||||
- Secret and auth-profile evidence records provider/source posture and
|
||||
SecretRef metadata only, never raw values. Policy does not read or attest
|
||||
per-agent credential stores such as `auth-profiles.json`.
|
||||
- Data-handling evidence is config-level posture only (redaction mode,
|
||||
telemetry capture toggle, session maintenance mode, transcript-indexing
|
||||
setting). It does not inspect logs, telemetry exports, transcripts, or
|
||||
memory files, and a clean result does not prove that no personal data or
|
||||
secrets exist in them.
|
||||
|
||||
### Policy rule reference
|
||||
|
||||
Every rule below is optional; a check runs only when the rule is present. The
|
||||
observed state is existing OpenClaw config or workspace metadata.
|
||||
|
||||
#### Scoped overlays
|
||||
|
||||
Use `scopes.<scopeName>` when specific agents or channels need stricter policy
|
||||
than the top-level baseline. The scope name is just a label; matching uses the
|
||||
selector inside the scope. Overlays are additive: the global rule still runs,
|
||||
and the scoped rule can add its own finding against the same evidence.
|
||||
|
||||
| Selector | Supported sections | Use when |
|
||||
| ------------ | ------------------------------------------------------------------------------ | ------------------------------------------------- |
|
||||
| `agentIds` | `tools`, `agents.workspace`, `sandbox`, `dataHandling.memory`, `execApprovals` | One or more runtime agents need stricter rules. |
|
||||
| `channelIds` | `ingress.channels` | One or more channels need stricter ingress rules. |
|
||||
|
||||
If an `agentIds` entry is not present in `agents.list[]`, OpenClaw evaluates
|
||||
the scoped rule against inherited global/default posture for that runtime
|
||||
agent id instead of skipping it.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"tools": {
|
||||
"exec": {
|
||||
"allowHosts": ["sandbox", "node"],
|
||||
},
|
||||
},
|
||||
"sandbox": {
|
||||
"requireMode": ["all", "non-main"],
|
||||
},
|
||||
"scopes": {
|
||||
"release-workspace": {
|
||||
"agentIds": ["release-agent", "review-agent"],
|
||||
"agents": {
|
||||
"workspace": {
|
||||
"allowedAccess": ["none", "ro"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"release-lockdown": {
|
||||
"agentIds": ["release-agent"],
|
||||
"tools": {
|
||||
"exec": {
|
||||
"allowHosts": ["sandbox"],
|
||||
"allowSecurity": ["deny", "allowlist"],
|
||||
"requireAsk": ["always"],
|
||||
},
|
||||
"denyTools": ["exec", "process", "write", "edit", "apply_patch"],
|
||||
},
|
||||
"sandbox": {
|
||||
"requireMode": ["all"],
|
||||
"allowBackends": ["docker"],
|
||||
},
|
||||
"dataHandling": {
|
||||
"memory": {
|
||||
"denySessionTranscriptIndexing": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"shell-sandbox": {
|
||||
"agentIds": ["shell-agent"],
|
||||
"sandbox": {
|
||||
"allowBackends": ["openshell"],
|
||||
"containers": {
|
||||
"requireReadOnlyMounts": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"telegram-ingress": {
|
||||
"channelIds": ["telegram"],
|
||||
"ingress": {
|
||||
"channels": {
|
||||
"allowDmPolicies": ["pairing"],
|
||||
"denyOpenGroups": true,
|
||||
"requireMentionInGroups": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The same agent can appear in multiple scopes if each scope governs a different
|
||||
field, as above. A repeated scoped field for the same agent must be equally or
|
||||
more restrictive; a weaker duplicate claim is rejected (allow-lists are
|
||||
subsets, deny-lists are supersets, required booleans are fixed).
|
||||
|
||||
Container posture rules (`sandbox.containers.*`) are checked only against
|
||||
evidence the matched agent's sandbox backend can expose. If a backend cannot
|
||||
observe a rule you enabled for it, policy reports
|
||||
`policy/sandbox-container-posture-unobservable` instead of passing; scope
|
||||
container rules to the agent groups that use a backend which can expose them.
|
||||
|
||||
Top-level `ingress.session.requireDmScope` stays global; `session.dmScope` is
|
||||
not channel-attributable evidence, so it cannot be scoped by `channelIds`.
|
||||
|
||||
Every scope present in `policy.jsonc` must be valid and enforceable.
|
||||
|
||||
#### Channels
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------------------ | --------------------------------------- | ------------------------------------------------------------ |
|
||||
| `channels.denyRules[].when.provider` | `channels.*` provider and enabled state | Deny configured channels from a provider such as `telegram`. |
|
||||
| `channels.denyRules[].reason` | Finding message and repair hint context | Explain why the provider is denied. |
|
||||
|
||||
#### MCP servers
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------- | ------------------- | ---------------------------------------------------------- |
|
||||
| `mcp.servers.allow` | `mcp.servers.*` ids | Require every configured MCP server to be in an allowlist. |
|
||||
| `mcp.servers.deny` | `mcp.servers.*` ids | Deny specific configured MCP server ids. |
|
||||
|
||||
#### Model providers
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------- |
|
||||
| `models.providers.allow` | `models.providers.*` ids and selected model refs | Require configured providers and selected model refs to use approved providers. |
|
||||
| `models.providers.deny` | `models.providers.*` ids and selected model refs | Deny configured providers and selected model refs by provider id. |
|
||||
|
||||
#### Network
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------------ | ----------------------------------- | ------------------------------------------------------------------ |
|
||||
| `network.privateNetwork.allow` | Private-network SSRF escape hatches | Set to `false` to require private-network access to stay disabled. |
|
||||
|
||||
#### Ingress and channel access
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ----------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| `ingress.session.requireDmScope` | `session.dmScope` | Require a reviewed direct-message isolation scope. |
|
||||
| `ingress.channels.allowDmPolicies` | `channels.*.dmPolicy` and legacy channel DM policy fields | Allow only reviewed direct-message channel policies. |
|
||||
| `ingress.channels.denyOpenGroups` | Channel, account, and group ingress policy | Deny open group ingress for configured channels and accounts. |
|
||||
| `ingress.channels.requireMentionInGroups` | Channel, account, group, guild, and nested mention gate config | Require mention gates when group ingress is open or mention-gated. |
|
||||
|
||||
#### Gateway
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| --------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| `gateway.exposure.allowNonLoopbackBind` | `gateway.bind` | Set to `false` to require loopback Gateway binding. |
|
||||
| `gateway.exposure.allowTailscaleFunnel` | Tailscale serve/funnel Gateway posture | Set to `false` to deny Tailscale Funnel exposure. |
|
||||
| `gateway.auth.requireAuth` | `gateway.auth.mode` | Set to `true` to reject disabled Gateway auth. |
|
||||
| `gateway.auth.requireExplicitRateLimit` | `gateway.auth.rateLimit` | Set to `true` to require explicit auth rate-limit config. |
|
||||
| `gateway.controlUi.allowInsecure` | Control UI insecure auth/device/origin toggles | Set to `false` to deny insecure Control UI exposure toggles. |
|
||||
| `gateway.remote.allow` | Remote Gateway mode/config | Set to `false` to deny remote Gateway mode. |
|
||||
| `gateway.http.denyEndpoints` | Gateway HTTP API endpoints | Deny endpoint ids such as `chatCompletions` or `responses`. |
|
||||
| `gateway.http.requireUrlAllowlists` | Gateway HTTP URL-fetch inputs | Set to `true` to require URL allowlists on URL-fetch inputs. |
|
||||
| `gateway.nodes.denyCommands` | `gateway.nodes.denyCommands` | Require exact node command ids such as `system.run` to be denied in OpenClaw config. |
|
||||
|
||||
`gateway.nodes.denyCommands` is an exact, case-sensitive deny-superset rule.
|
||||
Use it when policy must prove that privileged node commands are explicitly
|
||||
denied by OpenClaw config. A deployment that intentionally allows a privileged
|
||||
node command should update `policy.jsonc` after review instead of relying on
|
||||
`gateway.nodes.allowCommands` alone.
|
||||
|
||||
#### Agent workspace
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `agents.workspace.allowedAccess` | `agents.defaults.sandbox.workspaceAccess` and `agents.list[].sandbox.workspaceAccess` | Allow only sandbox workspace access values such as `none` or `ro`. |
|
||||
| `agents.workspace.denyTools` | Global and per-agent tool deny config | Require mutation tools (`exec`, `process`, `write`, `edit`, `apply_patch`) to be denied. |
|
||||
|
||||
#### Sandbox posture
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `sandbox.requireMode` | `agents.defaults.sandbox.mode` and per-agent mode | Allow only reviewed sandbox modes such as `all` or `non-main`. |
|
||||
| `sandbox.allowBackends` | `agents.defaults.sandbox.backend` and per-agent backend | Allow only reviewed sandbox backends such as `docker`. |
|
||||
| `sandbox.containers.denyHostNetwork` | Container-backed sandbox/browser network mode | Deny host network mode. |
|
||||
| `sandbox.containers.denyContainerNamespaceJoin` | Container-backed sandbox/browser network mode | Deny joining another container network namespace. |
|
||||
| `sandbox.containers.requireReadOnlyMounts` | Container-backed sandbox/browser mount mode | Require mounts to be read-only. |
|
||||
| `sandbox.containers.denyContainerRuntimeSocketMounts` | Container-backed sandbox/browser mount targets | Deny container runtime socket mounts. |
|
||||
| `sandbox.containers.denyUnconfinedProfiles` | Container security profile posture | Deny unconfined container security profiles. |
|
||||
| `sandbox.browser.requireCdpSourceRange` | Sandbox browser CDP source range | Require browser CDP exposure to declare a source range. |
|
||||
|
||||
Policy treats missing `sandbox.mode` as its implicit default `off`, so
|
||||
`sandbox.requireMode` reports a fresh or unconfigured sandbox as outside an
|
||||
allowlist such as `["all"]`.
|
||||
|
||||
#### Data Handling
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| --------------------------------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
||||
| `dataHandling.sensitiveLogging.requireRedaction` | `logging.redactSensitive` | Set to `true` to reject `logging.redactSensitive: "off"`. |
|
||||
| `dataHandling.telemetry.denyContentCapture` | `diagnostics.otel.captureContent` | Set to `true` to reject telemetry content capture. |
|
||||
| `dataHandling.retention.requireSessionMaintenance` | `session.maintenance.mode` | Set to `true` to require effective session maintenance mode `enforce`. |
|
||||
| `dataHandling.memory.denySessionTranscriptIndexing` | `memory.qmd.sessions.enabled` and `agents.*.memorySearch.experimental.sessionMemory` | Set to `true` to reject session transcript indexing into memory. |
|
||||
|
||||
#### Secrets
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| --------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `secrets.requireManagedProviders` | Config SecretRefs and `secrets.providers.*` declarations | Set to `true` to require SecretRefs to point at declared providers. |
|
||||
| `secrets.denySources` | Secret provider sources and SecretRef sources | Deny sources such as `exec`, `file`, or another configured source name. |
|
||||
| `secrets.allowInsecureProviders` | Insecure secret-provider posture flags | Set to `false` to reject providers that opt into insecure posture. |
|
||||
|
||||
#### Exec approvals
|
||||
|
||||
Exec-approvals checks read the runtime `exec-approvals.json` artifact:
|
||||
`~/.openclaw/exec-approvals.json` by default, or
|
||||
`$OPENCLAW_STATE_DIR/exec-approvals.json` when `OPENCLAW_STATE_DIR` is set.
|
||||
Posture rules under `execApprovals.defaults.*` or `execApprovals.agents.*`
|
||||
require readable artifact evidence; a missing or invalid artifact reports as
|
||||
unobservable evidence rather than a best-effort pass. Once readable, omitted
|
||||
fields inherit runtime defaults: missing `defaults.security` is `full`, and
|
||||
missing agent security inherits that default. Evidence includes `defaults`,
|
||||
`agents.*`, `agents.*.allowlist[].pattern`, optional `argPattern`, effective
|
||||
`autoAllowSkills` posture, and entry source — never socket path/token,
|
||||
`commandText`, `lastUsedCommand`, resolved paths, or timestamps.
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| `execApprovals.requireFile` | Active runtime `exec-approvals.json` path | Set to `true` to require the approvals artifact to exist and parse. |
|
||||
| `execApprovals.defaults.allowSecurity` | `defaults.security`, defaulting to `full` | Allow only approved default approval security modes. |
|
||||
| `execApprovals.agents.allowSecurity` | `agents.*.security`, inheriting defaults | Allow only approved per-agent effective approval security modes. |
|
||||
| `execApprovals.agents.allowAutoAllowSkills` | `defaults.autoAllowSkills` and `agents.*.autoAllowSkills`, inheriting runtime defaults | Set to `false` to require strict manual allowlists without implicit skill CLI approval. |
|
||||
| `execApprovals.agents.allowlist.expected` | Aggregate `agents.*.allowlist[]` pattern and optional argPattern entries | Require the approvals allowlist to match the reviewed pattern set. |
|
||||
|
||||
Example: require the approvals artifact, deny permissive defaults, and allow
|
||||
only reviewed exec approval posture for selected agents.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"execApprovals": {
|
||||
"requireFile": true,
|
||||
"defaults": {
|
||||
// Security modes: "deny", "allowlist", or "full".
|
||||
// This default permits only the locked-down deny posture.
|
||||
"allowSecurity": ["deny"],
|
||||
},
|
||||
},
|
||||
"scopes": {
|
||||
"restricted-shell": {
|
||||
"agentIds": ["family-agent", "groups-agent"],
|
||||
"execApprovals": {
|
||||
"agents": {
|
||||
// Selected agents may use reviewed allowlist posture, but not "full".
|
||||
"allowSecurity": ["allowlist"],
|
||||
// false means skill CLIs must appear in the reviewed allowlist instead of
|
||||
// being implicitly approved by autoAllowSkills.
|
||||
"allowAutoAllowSkills": false,
|
||||
"allowlist": {
|
||||
"expected": [
|
||||
// Simple entry: exact reviewed executable pattern with no argPattern.
|
||||
"travel-hub",
|
||||
// Constrained entry: pattern plus reviewed argument regex.
|
||||
{ "pattern": "calendar-cli", "argPattern": "^sync\\b" },
|
||||
"/bin/date",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
#### Auth profiles
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `auth.profiles.requireMetadata` | `auth.profiles.*` provider and mode metadata | Require metadata keys such as `provider` and `mode` on config auth profiles. |
|
||||
| `auth.profiles.allowModes` | `auth.profiles.*.mode` | Allow only supported auth profile modes such as `api_key`, `aws-sdk`, `oauth`, or `token`. |
|
||||
|
||||
#### Tool metadata
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ----------------------- | -------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `tools.requireMetadata` | Governed `TOOLS.md` declarations | Require governed tools to declare metadata keys such as `risk`, `sensitivity`, or `owner`. |
|
||||
|
||||
#### Tool posture
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `tools.profiles.allow` | `tools.profile` and `agents.list[].tools.profile` | Allow only tool profile ids such as `minimal`, `messaging`, or `coding`. |
|
||||
| `tools.fs.requireWorkspaceOnly` | `tools.fs.workspaceOnly` and per-agent `tools.fs` overrides | Set to `true` to require workspace-only filesystem tool posture. |
|
||||
| `tools.exec.allowSecurity` | `tools.exec.security` and per-agent exec security | Allow only exec security modes such as `deny` or `allowlist`. |
|
||||
| `tools.exec.requireAsk` | `tools.exec.ask` and per-agent exec ask mode | Require approval posture such as `always`. |
|
||||
| `tools.exec.allowHosts` | `tools.exec.host` and per-agent exec host routing | Allow only exec host routing modes such as `sandbox`. |
|
||||
| `tools.elevated.allow` | `tools.elevated.enabled` and per-agent elevated posture | Set to `false` to require elevated tool mode to stay disabled. |
|
||||
| `tools.alsoAllow.expected` | `tools.alsoAllow` and per-agent `tools.alsoAllow` | Require exact `alsoAllow` entries and report missing or unexpected additive tool grants. |
|
||||
| `tools.denyTools` | `tools.deny` and `agents.list[].tools.deny` | Require configured tool deny lists to include tool ids or groups such as `group:runtime` and `group:fs`. |
|
||||
|
||||
## Run checks
|
||||
|
||||
Run policy-only checks during authoring:
|
||||
|
||||
```bash
|
||||
openclaw policy check
|
||||
openclaw policy check --json
|
||||
openclaw policy check --severity-min error
|
||||
```
|
||||
|
||||
`policy check` runs only the policy check set and emits evidence, findings,
|
||||
and attestation hashes. The same findings also appear in
|
||||
`openclaw doctor --lint` when the Policy plugin is enabled.
|
||||
|
||||
Compare an operator policy file against an authored baseline:
|
||||
|
||||
```bash
|
||||
openclaw policy compare --baseline official.policy.jsonc
|
||||
openclaw policy compare --baseline official.policy.jsonc --policy policy.jsonc --json
|
||||
```
|
||||
|
||||
`policy compare` checks policy-file syntax against policy-file syntax; it does
|
||||
not inspect runtime state, evidence, credentials, or secrets. It uses the same
|
||||
rule metadata that governs scoped overlays: allowlists must stay equal or
|
||||
narrower, denylists must stay equal or broader, required booleans must keep
|
||||
their value, ordered strings may only move toward the stricter end of the
|
||||
configured order, and exact lists must match. The baseline can be an
|
||||
organization-authored policy; the checked policy may add stricter values or
|
||||
extra rules. A top-level checked rule can satisfy a scoped baseline rule when
|
||||
it is equally or more restrictive. Scope names do not need to match between
|
||||
files; comparison is keyed by selector (`agentIds`/`channelIds`) and field.
|
||||
|
||||
Clean compare (`--json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"baselinePath": "official.policy.jsonc",
|
||||
"policyPath": "policy.jsonc",
|
||||
"rulesChecked": 3,
|
||||
"findings": []
|
||||
}
|
||||
```
|
||||
|
||||
Clean `policy check --json` output includes stable hashes an operator or
|
||||
supervisor can record:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"attestation": {
|
||||
"policy": {
|
||||
"path": "policy.jsonc",
|
||||
"hash": "sha256:..."
|
||||
},
|
||||
"workspace": {
|
||||
"scope": "policy",
|
||||
"hash": "sha256:..."
|
||||
},
|
||||
"findingsHash": "sha256:...",
|
||||
"attestationHash": "sha256:..."
|
||||
},
|
||||
"checksRun": 5,
|
||||
"checksSkipped": 0,
|
||||
"findings": []
|
||||
}
|
||||
```
|
||||
|
||||
## Configure policy
|
||||
|
||||
Policy config lives under `plugins.entries.policy.config`.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"policy": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"path": "policy.jsonc",
|
||||
"workspaceRepairs": false,
|
||||
"expectedHash": "sha256:...",
|
||||
"expectedAttestationHash": "sha256:...",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
| Setting | Purpose |
|
||||
| ------------------------- | --------------------------------------------------------------- |
|
||||
| `enabled` | Enable policy checks even before `policy.jsonc` exists. |
|
||||
| `workspaceRepairs` | Allow `doctor --fix` to edit policy-managed workspace settings. |
|
||||
| `expectedHash` | Optional hash-lock for the approved policy artifact. |
|
||||
| `expectedAttestationHash` | Optional hash-lock for the last accepted clean policy check. |
|
||||
| `path` | Workspace-relative location of the policy artifact. |
|
||||
|
||||
Set `plugins.entries.policy.config.enabled` to `false` to disable policy
|
||||
checks for a workspace while leaving the plugin installed.
|
||||
|
||||
## Accept policy state
|
||||
|
||||
Example JSON output:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"attestation": {
|
||||
"checkedAt": "2026-05-10T20:00:00.000Z",
|
||||
"policy": {
|
||||
"path": "policy.jsonc",
|
||||
"hash": "sha256:..."
|
||||
},
|
||||
"workspace": {
|
||||
"scope": "policy",
|
||||
"hash": "sha256:..."
|
||||
},
|
||||
"findingsHash": "sha256:...",
|
||||
"attestationHash": "sha256:..."
|
||||
},
|
||||
"evidence": {
|
||||
"channels": [
|
||||
{
|
||||
"id": "telegram",
|
||||
"provider": "telegram",
|
||||
"source": "oc://openclaw.config/channels/telegram",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"mcpServers": [
|
||||
{
|
||||
"id": "docs",
|
||||
"transport": "stdio",
|
||||
"source": "oc://openclaw.config/mcp/servers/docs",
|
||||
"command": "npx"
|
||||
}
|
||||
],
|
||||
"modelProviders": [
|
||||
{
|
||||
"id": "openai",
|
||||
"source": "oc://openclaw.config/models/providers/openai"
|
||||
}
|
||||
],
|
||||
"modelRefs": [
|
||||
{
|
||||
"ref": "openai/gpt-5.5",
|
||||
"provider": "openai",
|
||||
"model": "gpt-5.5",
|
||||
"source": "oc://openclaw.config/agents/defaults/model"
|
||||
}
|
||||
],
|
||||
"network": [
|
||||
{
|
||||
"id": "browser-private-network",
|
||||
"source": "oc://openclaw.config/browser/ssrfPolicy/dangerouslyAllowPrivateNetwork",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"gatewayExposure": [
|
||||
{
|
||||
"id": "gateway-bind",
|
||||
"kind": "bind",
|
||||
"source": "oc://openclaw.config/gateway/bind",
|
||||
"value": "loopback",
|
||||
"nonLoopback": false,
|
||||
"explicit": true
|
||||
}
|
||||
],
|
||||
"agentWorkspace": [
|
||||
{
|
||||
"id": "agents-defaults-workspace-access",
|
||||
"kind": "workspaceAccess",
|
||||
"source": "oc://openclaw.config/agents/defaults/sandbox/workspaceAccess",
|
||||
"scope": "defaults",
|
||||
"value": "ro",
|
||||
"sandboxMode": "all",
|
||||
"sandboxModeSource": "oc://openclaw.config/agents/defaults/sandbox/mode",
|
||||
"sandboxEnabled": true,
|
||||
"explicit": true
|
||||
},
|
||||
{
|
||||
"id": "agents-defaults-tool-exec",
|
||||
"kind": "toolDeny",
|
||||
"source": "oc://openclaw.config/tools/deny",
|
||||
"scope": "defaults",
|
||||
"tool": "exec",
|
||||
"denied": true,
|
||||
"explicit": true
|
||||
}
|
||||
],
|
||||
"secrets": [
|
||||
{
|
||||
"id": "vault",
|
||||
"kind": "provider",
|
||||
"source": "oc://openclaw.config/secrets/providers/vault",
|
||||
"providerSource": "env"
|
||||
},
|
||||
{
|
||||
"id": "oc://openclaw.config/models/providers/openai/apiKey",
|
||||
"kind": "input",
|
||||
"source": "oc://openclaw.config/models/providers/openai/apiKey",
|
||||
"provenance": "secretRef",
|
||||
"refSource": "env",
|
||||
"refProvider": "vault"
|
||||
}
|
||||
],
|
||||
"authProfiles": [
|
||||
{
|
||||
"id": "github",
|
||||
"source": "oc://openclaw.config/auth/profiles/github",
|
||||
"validMetadata": true,
|
||||
"provider": "github",
|
||||
"mode": "token"
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"id": "deploy",
|
||||
"source": "oc://TOOLS.md/tools/deploy",
|
||||
"line": 12,
|
||||
"risk": "critical",
|
||||
"sensitivity": "restricted",
|
||||
"capabilities": ["IRREVERSIBLE_EXTERNAL"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"checksRun": 30,
|
||||
"checksSkipped": 0,
|
||||
"findings": []
|
||||
}
|
||||
```
|
||||
|
||||
`attestation.policy.hash` identifies the authored rule artifact. `evidence`
|
||||
records the observed OpenClaw state used by the checks, and
|
||||
`workspace.hash` identifies that evidence payload. `findingsHash` identifies
|
||||
the exact finding set. `checkedAt` records when the check ran.
|
||||
`attestationHash` identifies the stable claim (policy hash, evidence hash,
|
||||
findings hash, and clean/dirty state) and deliberately excludes `checkedAt`,
|
||||
so the same policy state always produces the same attestation hash. Together
|
||||
these four values form the audit tuple for one policy check.
|
||||
|
||||
If a gateway or supervisor uses policy to block, approve, or annotate a
|
||||
runtime action, it should record the attestation hash from the last clean
|
||||
check. `checkedAt` stays in JSON output for audit logs but is not part of the
|
||||
stable hash.
|
||||
|
||||
Lifecycle for accepting policy state:
|
||||
|
||||
1. Author or review `policy.jsonc`.
|
||||
2. Run `openclaw policy check --json`.
|
||||
3. If clean, record `attestation.policy.hash` as `expectedHash`.
|
||||
4. Record `attestation.attestationHash` as `expectedAttestationHash`.
|
||||
5. Re-run `openclaw doctor --lint` in CI or release gates.
|
||||
|
||||
If policy rules change intentionally, update both accepted hashes from a
|
||||
clean check. If only workspace settings change (policy stays the same),
|
||||
typically only `expectedAttestationHash` changes.
|
||||
|
||||
Enabling or upgrading `agents.workspace` rules adds `agentWorkspace` evidence
|
||||
to the workspace hash and attestation hash; review the new evidence and
|
||||
refresh accepted attestation hashes after enabling. Enabling or upgrading
|
||||
tool posture rules adds `toolPosture` evidence the same way.
|
||||
|
||||
`openclaw policy watch` re-runs the check and reports when current evidence no
|
||||
longer matches `expectedAttestationHash`:
|
||||
|
||||
```bash
|
||||
openclaw policy watch --json
|
||||
```
|
||||
|
||||
Use `--once` in CI or scripts that need a single drift evaluation. Without
|
||||
`--once`, it polls every two seconds by default; use `--interval-ms` to change
|
||||
the interval.
|
||||
|
||||
## Findings
|
||||
|
||||
| Check id | Finding |
|
||||
| -------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
|
||||
| `policy/policy-jsonc-invalid` | Policy cannot be parsed or contains malformed rule entries. |
|
||||
| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
|
||||
| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
|
||||
| `policy/policy-conformance-invalid` | A baseline or checked policy file has invalid comparison syntax. |
|
||||
| `policy/policy-conformance-missing` | A checked policy file is missing a rule required by the baseline policy file. |
|
||||
| `policy/policy-conformance-weaker` | A checked policy file has a weaker value than the baseline policy file. |
|
||||
| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
|
||||
| `policy/mcp-denied-server` | A configured MCP server is denied by policy. |
|
||||
| `policy/mcp-unapproved-server` | A configured MCP server is outside the allowlist. |
|
||||
| `policy/models-denied-provider` | A configured model provider or model ref uses a denied provider. |
|
||||
| `policy/models-unapproved-provider` | A configured model provider or model ref is outside the allowlist. |
|
||||
| `policy/network-private-access-enabled` | A private-network SSRF escape hatch is enabled when policy denies it. |
|
||||
| `policy/ingress-dm-policy-unapproved` | A channel DM policy is outside the policy allowlist. |
|
||||
| `policy/ingress-dm-scope-unapproved` | `session.dmScope` does not match the policy-required DM isolation scope. |
|
||||
| `policy/ingress-open-groups-denied` | A channel group policy is `open` while policy denies open group ingress. |
|
||||
| `policy/ingress-group-mention-required` | A channel or group entry disables mention gates while policy requires them. |
|
||||
| `policy/gateway-non-loopback-bind` | Gateway bind posture permits non-loopback exposure when policy denies it. |
|
||||
| `policy/gateway-auth-disabled` | Gateway authentication is disabled when policy requires auth. |
|
||||
| `policy/gateway-rate-limit-missing` | Gateway auth rate-limit posture is not explicit when policy requires it. |
|
||||
| `policy/gateway-control-ui-insecure` | Gateway Control UI insecure exposure toggles are enabled. |
|
||||
| `policy/gateway-tailscale-funnel` | Gateway Tailscale Funnel exposure is enabled when policy denies it. |
|
||||
| `policy/gateway-remote-enabled` | Gateway remote mode is active when policy denies it. |
|
||||
| `policy/gateway-http-endpoint-enabled` | A Gateway HTTP API endpoint is enabled while denied by policy. |
|
||||
| `policy/gateway-http-url-fetch-unrestricted` | Gateway HTTP URL-fetch input lacks a required URL allowlist. |
|
||||
| `policy/gateway-node-command-denied` | A node command denied by policy is not denied by OpenClaw config. |
|
||||
| `policy/agents-workspace-access-denied` | Agent sandbox mode or workspace access is outside the policy allowlist. |
|
||||
| `policy/agents-tool-not-denied` | An agent or default config does not deny a tool required by policy. |
|
||||
| `policy/tools-profile-unapproved` | A configured global or per-agent tool profile is outside the allowlist. |
|
||||
| `policy/tools-fs-workspace-only-required` | Filesystem tools are not configured with workspace-only path posture. |
|
||||
| `policy/tools-exec-security-unapproved` | Exec security mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-ask-unapproved` | Exec ask mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-host-unapproved` | Exec host routing is outside the policy allowlist. |
|
||||
| `policy/tools-elevated-enabled` | Elevated tool mode is enabled when policy denies it. |
|
||||
| `policy/tools-also-allow-missing` | A configured `alsoAllow` list is missing an entry required by policy. |
|
||||
| `policy/tools-also-allow-unexpected` | A configured `alsoAllow` list includes an entry not expected by policy. |
|
||||
| `policy/tools-required-deny-missing` | A global or per-agent tool deny list does not include a required denied tool. |
|
||||
| `policy/sandbox-mode-unapproved` | Sandbox mode is outside the policy allowlist. |
|
||||
| `policy/sandbox-backend-unapproved` | Sandbox backend is outside the policy allowlist. |
|
||||
| `policy/sandbox-container-posture-unobservable` | A container posture rule is enabled for a backend that cannot observe it. |
|
||||
| `policy/sandbox-container-host-network-denied` | A container-backed sandbox or browser uses host network mode. |
|
||||
| `policy/sandbox-container-namespace-join-denied` | A container-backed sandbox or browser joins another container namespace. |
|
||||
| `policy/sandbox-container-mount-mode-required` | A container-backed sandbox or browser mount is not read-only. |
|
||||
| `policy/sandbox-container-runtime-socket-mount` | A container-backed sandbox or browser mount exposes the container runtime socket. |
|
||||
| `policy/sandbox-container-unconfined-profile` | Container sandbox profile is unconfined when policy denies it. |
|
||||
| `policy/sandbox-browser-cdp-source-range-missing` | Sandbox browser CDP source range is missing when policy requires one. |
|
||||
| `policy/data-handling-redaction-disabled` | Sensitive logging redaction is disabled when policy requires it. |
|
||||
| `policy/data-handling-telemetry-content-capture` | Telemetry content capture is enabled when policy denies it. |
|
||||
| `policy/data-handling-session-retention-not-enforced` | Session retention maintenance is not enforced when policy requires it. |
|
||||
| `policy/data-handling-session-transcript-memory-enabled` | Session transcript memory indexing is enabled when policy denies it. |
|
||||
| `policy/secrets-unmanaged-provider` | A config SecretRef references a provider not declared under `secrets.providers`. |
|
||||
| `policy/secrets-denied-provider-source` | A config secret provider or SecretRef uses a source denied by policy. |
|
||||
| `policy/secrets-insecure-provider` | A secret provider opts into insecure posture when policy denies it. |
|
||||
| `policy/auth-profile-invalid-metadata` | A config auth profile is missing valid provider or mode metadata. |
|
||||
| `policy/auth-profile-unapproved-mode` | A config auth profile mode is outside the policy allowlist. |
|
||||
| `policy/exec-approvals-missing` | Policy requires `exec-approvals.json`, but the artifact is missing. |
|
||||
| `policy/exec-approvals-invalid` | The configured exec approvals artifact cannot be parsed. |
|
||||
| `policy/exec-approvals-default-security-unapproved` | Exec approval defaults use a security mode outside the policy allowlist. |
|
||||
| `policy/exec-approvals-agent-security-unapproved` | A per-agent effective exec approval security mode is outside the allowlist. |
|
||||
| `policy/exec-approvals-auto-allow-skills-enabled` | An exec approval agent implicitly auto-allows skill CLIs when policy denies it. |
|
||||
| `policy/exec-approvals-allowlist-missing` | The approvals allowlist is missing a pattern required by policy. |
|
||||
| `policy/exec-approvals-allowlist-unexpected` | The approvals allowlist includes a pattern not expected by policy. |
|
||||
| `policy/tools-missing-risk-level` | A governed tool declaration is missing risk metadata. |
|
||||
| `policy/tools-unknown-risk-level` | A governed tool declaration uses an unknown risk value. |
|
||||
| `policy/tools-missing-sensitivity-token` | A governed tool declaration is missing sensitivity metadata. |
|
||||
| `policy/tools-missing-owner` | A governed tool declaration is missing owner metadata. |
|
||||
| `policy/tools-unknown-sensitivity-token` | A governed tool declaration uses an unknown sensitivity value. |
|
||||
|
||||
A finding can include both `target` (the observed workspace thing that does
|
||||
not conform) and `requirement` (the authored rule that made it a finding).
|
||||
Both are `oc://` address strings today, but the field names describe policy
|
||||
role rather than address format.
|
||||
|
||||
Example findings:
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/channels-denied-provider",
|
||||
"severity": "error",
|
||||
"message": "Channel 'telegram' uses denied provider 'telegram'.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/channels/telegram",
|
||||
"target": "oc://openclaw.config/channels/telegram",
|
||||
"requirement": "oc://policy.jsonc/channels/denyRules/#0",
|
||||
"fixHint": "Telegram is not approved for this workspace."
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/tools-missing-risk-level",
|
||||
"severity": "error",
|
||||
"message": "TOOLS.md tool 'deploy' has no explicit risk classification.",
|
||||
"source": "policy",
|
||||
"path": "TOOLS.md",
|
||||
"line": 12,
|
||||
"ocPath": "oc://TOOLS.md/tools/deploy",
|
||||
"target": "oc://TOOLS.md/tools/deploy",
|
||||
"requirement": "oc://policy.jsonc/tools/requireMetadata"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/mcp-unapproved-server",
|
||||
"severity": "error",
|
||||
"message": "MCP server 'remote' is not in the policy allowlist.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/mcp/servers/remote",
|
||||
"target": "oc://openclaw.config/mcp/servers/remote",
|
||||
"requirement": "oc://policy.jsonc/mcp/servers/allow"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/models-unapproved-provider",
|
||||
"severity": "error",
|
||||
"message": "Model ref 'anthropic/claude-sonnet-4.7' uses unapproved provider 'anthropic'.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/agents/defaults/model/fallbacks/#0",
|
||||
"target": "oc://openclaw.config/agents/defaults/model/fallbacks/#0",
|
||||
"requirement": "oc://policy.jsonc/models/providers/allow"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/network-private-access-enabled",
|
||||
"severity": "error",
|
||||
"message": "Network setting 'browser-private-network' allows private-network access.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/browser/ssrfPolicy/dangerouslyAllowPrivateNetwork",
|
||||
"target": "oc://openclaw.config/browser/ssrfPolicy/dangerouslyAllowPrivateNetwork",
|
||||
"requirement": "oc://policy.jsonc/network/privateNetwork/allow"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/gateway-non-loopback-bind",
|
||||
"severity": "error",
|
||||
"message": "Gateway bind setting 'gateway-bind' permits non-loopback exposure.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/gateway/bind",
|
||||
"target": "oc://openclaw.config/gateway/bind",
|
||||
"requirement": "oc://policy.jsonc/gateway/exposure/allowNonLoopbackBind"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/gateway-node-command-denied",
|
||||
"severity": "error",
|
||||
"message": "Gateway node command 'system.run' is denied by policy but not denied by OpenClaw config.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/gateway/nodes/denyCommands",
|
||||
"target": "oc://openclaw.config/gateway/nodes/denyCommands",
|
||||
"requirement": "oc://policy.jsonc/gateway/nodes/denyCommands",
|
||||
"fixHint": "Add 'system.run' to gateway.nodes.denyCommands or update policy after review."
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"checkId": "policy/agents-workspace-access-denied",
|
||||
"severity": "error",
|
||||
"message": "agents.defaults sandbox workspaceAccess 'rw' is not allowed by policy.",
|
||||
"source": "policy",
|
||||
"path": "openclaw config",
|
||||
"ocPath": "oc://openclaw.config/agents/defaults/sandbox/workspaceAccess",
|
||||
"target": "oc://openclaw.config/agents/defaults/sandbox/workspaceAccess",
|
||||
"requirement": "oc://policy.jsonc/agents/workspace/allowedAccess"
|
||||
}
|
||||
```
|
||||
|
||||
## Repair
|
||||
|
||||
`doctor --lint` and `policy check` are read-only.
|
||||
|
||||
`doctor --fix` only edits policy-managed workspace settings when
|
||||
`workspaceRepairs` is explicitly enabled; otherwise checks report what they
|
||||
would repair and leave settings unchanged.
|
||||
|
||||
Currently, repair can disable channels that are enabled in OpenClaw config but
|
||||
denied by `channels.denyRules`. Enable `workspaceRepairs` only after the
|
||||
policy file has been reviewed, since a valid deny rule can turn off a
|
||||
configured channel:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"policy": {
|
||||
"config": {
|
||||
"workspaceRepairs": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Command | `0` | `1` | `2` |
|
||||
| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------------- | ---------------------------- |
|
||||
| `policy check` | No findings at the threshold. | One or more findings met the threshold. | Argument or runtime failure. |
|
||||
| `policy compare` | The policy file is at least as strict as the baseline. | The policy file is invalid, missing, or weaker than baseline rules. | Argument or runtime failure. |
|
||||
| `policy watch` | No findings and accepted hash is current. | Findings exist or accepted attestation is stale. | Argument or runtime failure. |
|
||||
|
||||
## Related
|
||||
|
||||
- [Doctor lint mode](/cli/doctor#lint-mode)
|
||||
- [Path CLI](/cli/path)
|
||||
88
docs/cli/proxy.md
Normal file
88
docs/cli/proxy.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw proxy`, including operator-managed proxy validation and the local debug proxy capture inspector"
|
||||
read_when:
|
||||
- You need to validate operator-managed proxy routing before deployment
|
||||
- You need to capture OpenClaw transport traffic locally for debugging
|
||||
- You want to inspect debug proxy sessions, blobs, or built-in query presets
|
||||
title: "Proxy"
|
||||
---
|
||||
|
||||
# `openclaw proxy`
|
||||
|
||||
Validate operator-managed proxy routing, or run the local explicit debug proxy and inspect captured traffic.
|
||||
|
||||
```bash
|
||||
openclaw proxy validate [--json] [--proxy-url <url>] [--proxy-ca-file <path>] [--allowed-url <url>] [--denied-url <url>] [--apns-reachable] [--apns-authority <url>] [--timeout-ms <ms>]
|
||||
openclaw proxy start [--host <host>] [--port <port>]
|
||||
openclaw proxy run [--host <host>] [--port <port>] -- <cmd...>
|
||||
openclaw proxy coverage
|
||||
openclaw proxy sessions [--limit <count>]
|
||||
openclaw proxy query --preset <name> [--session <id>]
|
||||
openclaw proxy blob --id <blobId>
|
||||
openclaw proxy purge
|
||||
```
|
||||
|
||||
`validate` preflights an operator-managed forward proxy. The rest are debugging tools for transport-level investigation: start a local capturing proxy, run a child command through it, list capture sessions, query traffic patterns, read captured blobs, and purge local capture data.
|
||||
|
||||
## Validate
|
||||
|
||||
Checks the effective operator-managed proxy URL from `--proxy-url`, config (`proxy.proxyUrl`), or `OPENCLAW_PROXY_URL`, in that precedence order. Reports a config problem if no proxy is enabled and configured; pass `--proxy-url` for a one-off preflight without touching config.
|
||||
|
||||
Managed proxy URLs use `http://` for a plain forward-proxy listener, or `https://` when OpenClaw must open TLS to the proxy endpoint itself before sending proxy requests. Use `--proxy-ca-file` to trust a private CA for that TLS connection.
|
||||
|
||||
By default it runs:
|
||||
|
||||
- one **allowed** check against `https://example.com/` (override/add with `--allowed-url`, repeatable)
|
||||
- one **denied** check against a temporary loopback canary (override with `--denied-url`, repeatable)
|
||||
|
||||
Custom `--denied-url` targets are fail-closed: both HTTP responses and ambiguous transport failures count as failures unless you can independently verify a deployment-specific denial signal. The built-in loopback canary is the only target where a transport error is treated as proof of blocking.
|
||||
|
||||
Add `--apns-reachable` to also open an APNs HTTP/2 CONNECT tunnel through the proxy and confirm sandbox APNs responds. The probe sends an intentionally invalid provider token, so an APNs `403 InvalidProviderToken` response counts as a successful reachability signal (not a failure).
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Effect |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| `--json` | print machine-readable JSON |
|
||||
| `--proxy-url <url>` | validate this `http://`/`https://` proxy URL instead of config or env |
|
||||
| `--proxy-ca-file <path>` | trust this PEM CA file for TLS verification of an HTTPS proxy endpoint |
|
||||
| `--allowed-url <url>` | destination expected to succeed through the proxy (repeatable) |
|
||||
| `--denied-url <url>` | destination expected to be blocked by the proxy (repeatable) |
|
||||
| `--apns-reachable` | also verify sandbox APNs HTTP/2 is reachable through the proxy |
|
||||
| `--apns-authority <url>` | APNs authority to probe (default `https://api.sandbox.push.apple.com`; production is `https://api.push.apple.com`) |
|
||||
| `--timeout-ms <ms>` | per-request timeout |
|
||||
|
||||
Exits with code 1 when proxy config or destination checks fail.
|
||||
|
||||
See [Network Proxy](/security/network-proxy) for deployment guidance and denial semantics.
|
||||
|
||||
## Debug proxy
|
||||
|
||||
`start` launches a local capturing proxy and prints its URL, CA cert path, and capture DB path; stop with Ctrl+C. Defaults to binding `127.0.0.1` unless `--host` is set.
|
||||
|
||||
`run` starts a local debug proxy, then runs `<cmd...>` (after `--`) with the proxy env applied, under its own capture session.
|
||||
|
||||
The debug proxy's direct upstream forwarding opens upstream sockets for diagnostics. When OpenClaw managed proxy mode is active, direct forwarding for proxy requests and CONNECT tunnels is disabled by default; set `OPENCLAW_DEBUG_PROXY_ALLOW_DIRECT_CONNECT_WITH_MANAGED_PROXY=1` only for approved local diagnostics.
|
||||
|
||||
`coverage` prints a JSON report (`summary` + per-transport `entries`) of which transports are captured, proxy-only, or uncovered.
|
||||
|
||||
`sessions` lists recent capture sessions (`--limit`, default 20).
|
||||
|
||||
`query --preset <name>` runs a built-in query against captured traffic, optionally scoped to `--session <id>`. Presets:
|
||||
|
||||
- `double-sends`
|
||||
- `retry-storms`
|
||||
- `cache-busting`
|
||||
- `ws-duplicate-frames`
|
||||
- `missing-ack`
|
||||
- `error-bursts`
|
||||
|
||||
`blob --id <blobId>` prints a captured payload blob's raw content.
|
||||
|
||||
`purge` deletes all captured traffic metadata and blobs. Captures are local debugging data; purge when finished.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Network Proxy](/security/network-proxy)
|
||||
- [Trusted proxy auth](/gateway/trusted-proxy-auth)
|
||||
80
docs/cli/qr.md
Normal file
80
docs/cli/qr.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw qr` (generate mobile pairing QR + setup code)"
|
||||
read_when:
|
||||
- You want to pair a mobile node app with a gateway quickly
|
||||
- You need setup-code output for remote/manual sharing
|
||||
title: "QR"
|
||||
---
|
||||
|
||||
# `openclaw qr`
|
||||
|
||||
Generate a mobile pairing QR and setup code from your current Gateway configuration.
|
||||
|
||||
```bash
|
||||
openclaw qr
|
||||
openclaw qr --setup-code-only
|
||||
openclaw qr --json
|
||||
openclaw qr --remote
|
||||
openclaw qr --url wss://gateway.example/ws
|
||||
```
|
||||
|
||||
Official OpenClaw iOS and Android apps connect automatically when their
|
||||
setup-code metadata matches. If a request remains pending (for example, for a
|
||||
non-official client or mismatched metadata), review and approve it:
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `--remote`: prefer `gateway.remote.url`; falls back to `gateway.tailscale.mode=serve|funnel` if that URL is unset. Ignores `device-pair` plugin `publicUrl`.
|
||||
- `--url <url>`: override the gateway URL used in the payload
|
||||
- `--public-url <url>`: override the public URL used in the payload
|
||||
- `--token <token>`: override the gateway token the bootstrap flow authenticates against
|
||||
- `--password <password>`: override the gateway password the bootstrap flow authenticates against
|
||||
- `--setup-code-only`: print only the setup code
|
||||
- `--no-ascii`: skip ASCII QR rendering
|
||||
- `--json`: emit JSON (`setupCode`, `gatewayUrl`, `auth`, `urlSource`)
|
||||
|
||||
`--token` and `--password` are mutually exclusive.
|
||||
|
||||
## Setup code contents
|
||||
|
||||
The setup code carries an opaque, short-lived `bootstrapToken`, not the shared gateway token/password. The built-in bootstrap flow issues:
|
||||
|
||||
- a primary `node` token with `scopes: []`
|
||||
- a bounded `operator` handoff token limited to `operator.approvals`, `operator.read`, `operator.talk.secrets`, and `operator.write`
|
||||
|
||||
Pairing-mutation scopes and `operator.admin` still require a separate approved operator pairing or token flow.
|
||||
|
||||
## Gateway URL resolution
|
||||
|
||||
Mobile pairing fails closed for Tailscale/public `ws://` gateway URLs: use Tailscale Serve/Funnel or a `wss://` gateway URL for those. Private LAN addresses and `.local` Bonjour hosts remain supported over plain `ws://`.
|
||||
|
||||
With `--remote`, one of `gateway.remote.url` or `gateway.tailscale.mode=serve|funnel` is required.
|
||||
|
||||
## Auth resolution (no `--remote`)
|
||||
|
||||
When no CLI auth override is passed, local gateway auth SecretRefs resolve as follows:
|
||||
|
||||
| Condition | Resolves |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| `gateway.auth.mode="token"`, or inferred mode with no winning password source | `gateway.auth.token` |
|
||||
| `gateway.auth.mode="password"`, or inferred mode with no winning token from auth/env | `gateway.auth.password` |
|
||||
| Both `gateway.auth.token` and `gateway.auth.password` are configured (including SecretRefs) and `gateway.auth.mode` is unset | fails; set `gateway.auth.mode` explicitly |
|
||||
|
||||
## Auth resolution (`--remote`)
|
||||
|
||||
If effectively active remote credentials are configured as SecretRefs and neither `--token` nor `--password` is passed, the command resolves them from the active gateway snapshot. If the gateway is unavailable, the command fails fast.
|
||||
|
||||
<Note>
|
||||
This command path requires a gateway that supports the `secrets.resolve` RPC method. Older gateways return an unknown-method error.
|
||||
</Note>
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Devices](/cli/devices)
|
||||
- [Pairing](/cli/pairing)
|
||||
47
docs/cli/reset.md
Normal file
47
docs/cli/reset.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw reset` (reset local state/config)"
|
||||
read_when:
|
||||
- You want to wipe local state while keeping the CLI installed
|
||||
- You want a dry-run of what would be removed
|
||||
title: "Reset"
|
||||
---
|
||||
|
||||
# `openclaw reset`
|
||||
|
||||
Reset local config/state (keeps the CLI installed).
|
||||
|
||||
```bash
|
||||
openclaw reset
|
||||
openclaw reset --dry-run
|
||||
openclaw reset --scope config --yes --non-interactive
|
||||
openclaw reset --scope config+creds+sessions --yes --non-interactive
|
||||
openclaw reset --scope full --yes --non-interactive
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `--scope <scope>`: `config`, `config+creds+sessions`, or `full`
|
||||
- `--yes`: skip confirmation prompts
|
||||
- `--non-interactive`: disable prompts; requires `--scope` and `--yes`
|
||||
- `--dry-run`: print actions without removing files
|
||||
|
||||
## Scopes
|
||||
|
||||
| Scope | Removes | Stops gateway first |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------- | ------------------- |
|
||||
| `config` | config file only | no |
|
||||
| `config+creds+sessions` | config file, OAuth/credentials dir, per-agent session directories | yes |
|
||||
| `full` | state dir (including config/creds if nested inside it) plus workspace dirs and workspace attestations | yes |
|
||||
|
||||
`config+creds+sessions` and `full` stop a running managed gateway service before deleting state.
|
||||
|
||||
## Notes
|
||||
|
||||
- Run `openclaw backup create` first for a restorable snapshot before removing local state.
|
||||
- Without `--scope`, `openclaw reset` prompts interactively for the scope to remove.
|
||||
- `--non-interactive` is only valid when both `--scope` and `--yes` are set.
|
||||
- `config+creds+sessions` and `full` print `Next: openclaw onboard --install-daemon` when done.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
123
docs/cli/sandbox.md
Normal file
123
docs/cli/sandbox.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
summary: "Manage sandbox runtimes and inspect effective sandbox policy"
|
||||
title: Sandbox CLI
|
||||
read_when: "You are managing sandbox runtimes or debugging sandbox/tool-policy behavior."
|
||||
status: active
|
||||
---
|
||||
|
||||
Manage sandbox runtimes for isolated agent execution: Docker containers, SSH targets, or OpenShell backends.
|
||||
|
||||
## Commands
|
||||
|
||||
### `openclaw sandbox list`
|
||||
|
||||
List sandbox runtimes with status, backend, config match, age, idle time, and associated session/agent.
|
||||
|
||||
```bash
|
||||
openclaw sandbox list
|
||||
openclaw sandbox list --browser # browser containers only
|
||||
openclaw sandbox list --json
|
||||
```
|
||||
|
||||
### `openclaw sandbox recreate`
|
||||
|
||||
Remove sandbox runtimes to force recreation with current config. Runtimes are recreated automatically the next time the agent is used.
|
||||
|
||||
```bash
|
||||
openclaw sandbox recreate --all
|
||||
openclaw sandbox recreate --agent mybot # includes agent:mybot:* sub-sessions
|
||||
openclaw sandbox recreate --session "agent:main:main"
|
||||
openclaw sandbox recreate --browser --all # only browser containers
|
||||
openclaw sandbox recreate --all --force # skip confirmation
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `--all`: recreate all sandbox containers
|
||||
- `--session <key>`: recreate the runtime with this exact scope key (as shown by `sandbox list`); no short-name expansion
|
||||
- `--agent <id>`: recreate runtimes for one agent (matches `agent:<id>` and `agent:<id>:*`)
|
||||
- `--browser`: only affect browser containers
|
||||
- `--force`: skip the confirmation prompt
|
||||
|
||||
Pass exactly one of `--all`, `--session`, or `--agent`.
|
||||
|
||||
For `ssh` and OpenShell `remote`, recreate matters more than with Docker: the remote workspace is canonical after the initial seed, `recreate` deletes that canonical remote workspace for the selected scope, and the next run reseeds it from the current local workspace.
|
||||
|
||||
### `openclaw sandbox explain`
|
||||
|
||||
Inspect the effective sandbox mode/scope/workspace access, sandbox tool policy, and elevated-tool gates (with fix-it config key paths).
|
||||
|
||||
```bash
|
||||
openclaw sandbox explain
|
||||
openclaw sandbox explain --session agent:main:main
|
||||
openclaw sandbox explain --agent work
|
||||
openclaw sandbox explain --json
|
||||
```
|
||||
|
||||
Unlike `recreate --session`, this accepts short session names (for example `main`) and expands them against the resolved agent.
|
||||
|
||||
## Why recreate is needed
|
||||
|
||||
Updating sandbox config does not affect running containers: existing runtimes keep their old settings, and idle runtimes are only pruned after `prune.idleHours` (default 24h). Regularly used agents can keep stale runtimes alive indefinitely. `openclaw sandbox recreate` removes the old runtime so the next use rebuilds it from current config.
|
||||
|
||||
<Tip>
|
||||
Prefer `openclaw sandbox recreate` over manual backend-specific cleanup. It uses the Gateway's runtime registry and avoids mismatches when scope or session keys change.
|
||||
</Tip>
|
||||
|
||||
## Common triggers
|
||||
|
||||
| Change | Command |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Docker image update (`agents.defaults.sandbox.docker.image`) | `openclaw sandbox recreate --all` |
|
||||
| Sandbox config (`agents.defaults.sandbox.*`) | `openclaw sandbox recreate --all` |
|
||||
| SSH target/auth (`agents.defaults.sandbox.ssh.{target,workspaceRoot,identityFile,certificateFile,knownHostsFile,identityData,certificateData,knownHostsData}`) | `openclaw sandbox recreate --all` |
|
||||
| OpenShell source/policy/mode (`plugins.entries.openshell.config.{from,mode,policy}`) | `openclaw sandbox recreate --all` |
|
||||
| `setupCommand` | `openclaw sandbox recreate --all` (or `--agent <id>` for one agent) |
|
||||
|
||||
<Note>
|
||||
Runtimes are automatically recreated when the agent is next used.
|
||||
</Note>
|
||||
|
||||
## Registry migration
|
||||
|
||||
Sandbox runtime metadata lives in the shared SQLite state database. Older installs may have legacy registry files that regular reads no longer rewrite:
|
||||
|
||||
- `~/.openclaw/sandbox/containers.json`
|
||||
- `~/.openclaw/sandbox/browsers.json`
|
||||
- one JSON shard per container/browser under `~/.openclaw/sandbox/containers/` or `~/.openclaw/sandbox/browsers/`
|
||||
|
||||
Run `openclaw doctor --fix` to migrate valid legacy entries into SQLite. Invalid legacy files are quarantined so a corrupt old registry cannot hide current runtime entries.
|
||||
|
||||
## Configuration
|
||||
|
||||
Sandbox settings live in `~/.openclaw/openclaw.json` under `agents.defaults.sandbox` (per-agent overrides go in `agents.list[].sandbox`):
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"sandbox": {
|
||||
"mode": "all", // off, non-main, all
|
||||
"backend": "docker", // docker, ssh, openshell (plugin-provided)
|
||||
"scope": "agent", // session, agent, shared
|
||||
"docker": {
|
||||
"image": "openclaw-sandbox:bookworm-slim",
|
||||
"containerPrefix": "openclaw-sbx-",
|
||||
// ... more Docker options
|
||||
},
|
||||
"prune": {
|
||||
"idleHours": 24, // auto-prune after 24h idle
|
||||
"maxAgeDays": 7, // auto-prune after 7 days
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Sandboxing](/gateway/sandboxing)
|
||||
- [Agent workspace](/concepts/agent-workspace)
|
||||
- [Doctor](/gateway/doctor): checks sandbox setup.
|
||||
157
docs/cli/secrets.md
Normal file
157
docs/cli/secrets.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw secrets` (reload, audit, configure, apply)"
|
||||
read_when:
|
||||
- Re-resolving secret refs at runtime
|
||||
- Auditing plaintext residues and unresolved refs
|
||||
- Configuring SecretRefs and applying one-way scrub changes
|
||||
title: "Secrets"
|
||||
---
|
||||
|
||||
# `openclaw secrets`
|
||||
|
||||
Manage SecretRefs and keep the active runtime snapshot healthy.
|
||||
|
||||
| Command | Role |
|
||||
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `reload` | Gateway RPC (`secrets.reload`): re-resolves refs and swaps the runtime snapshot only on full success (no config writes) |
|
||||
| `audit` | Read-only scan of config/auth/generated-model stores and legacy residues for plaintext, unresolved refs, and precedence drift (exec refs skipped unless `--allow-exec`) |
|
||||
| `configure` | Interactive planner for provider setup, target mapping, and preflight (requires a TTY) |
|
||||
| `apply` | Executes a saved plan (`--dry-run` validates only and skips exec checks by default; write mode rejects exec-containing plans unless `--allow-exec`), then scrubs targeted plaintext residues |
|
||||
|
||||
Recommended operator loop:
|
||||
|
||||
```bash
|
||||
openclaw secrets audit --check
|
||||
openclaw secrets configure
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
|
||||
openclaw secrets audit --check
|
||||
openclaw secrets reload
|
||||
```
|
||||
|
||||
If your plan includes `exec` SecretRefs/providers, pass `--allow-exec` on both the dry-run and write `apply` commands.
|
||||
|
||||
Exit codes for CI/gates:
|
||||
|
||||
- `audit --check` returns `1` on findings.
|
||||
- Unresolved refs return `2` (regardless of `--check`).
|
||||
|
||||
Related: [Secrets Management](/gateway/secrets) · [SecretRef Credential Surface](/reference/secretref-credential-surface) · [Security](/gateway/security)
|
||||
|
||||
## Reload runtime snapshot
|
||||
|
||||
```bash
|
||||
openclaw secrets reload
|
||||
openclaw secrets reload --json
|
||||
openclaw secrets reload --url ws://127.0.0.1:18789 --token <token>
|
||||
```
|
||||
|
||||
Uses gateway RPC method `secrets.reload`. If resolution fails, the gateway keeps its last-known-good snapshot and returns an error (no partial activation). JSON response includes `warningCount`.
|
||||
|
||||
Options: `--url <url>`, `--token <token>`, `--timeout <ms>`, `--json`.
|
||||
|
||||
## Audit
|
||||
|
||||
Scans OpenClaw state for:
|
||||
|
||||
- plaintext secret storage
|
||||
- unresolved refs
|
||||
- precedence drift (`auth-profiles.json` credentials shadowing `openclaw.json` refs)
|
||||
- generated `agents/*/agent/models.json` residues (provider `apiKey` values and sensitive provider headers)
|
||||
- legacy residues (legacy auth store entries, OAuth reminders)
|
||||
|
||||
Sensitive provider header detection is name-heuristic based: it flags headers whose name matches common auth/credential fragments (`authorization`, `x-api-key`, `token`, `secret`, `password`, `credential`).
|
||||
|
||||
```bash
|
||||
openclaw secrets audit
|
||||
openclaw secrets audit --check
|
||||
openclaw secrets audit --json
|
||||
openclaw secrets audit --allow-exec
|
||||
```
|
||||
|
||||
Report shape:
|
||||
|
||||
- `status`: `clean | findings | unresolved`
|
||||
- `resolution`: `refsChecked`, `skippedExecRefs`, `resolvabilityComplete`
|
||||
- `summary`: `plaintextCount`, `unresolvedRefCount`, `shadowedRefCount`, `legacyResidueCount`
|
||||
- finding codes: `PLAINTEXT_FOUND`, `REF_UNRESOLVED`, `REF_SHADOWED`, `LEGACY_RESIDUE`
|
||||
|
||||
## Configure (interactive helper)
|
||||
|
||||
Build provider and SecretRef changes interactively, run preflight, and optionally apply:
|
||||
|
||||
```bash
|
||||
openclaw secrets configure
|
||||
openclaw secrets configure --plan-out /tmp/openclaw-secrets-plan.json
|
||||
openclaw secrets configure --apply --yes
|
||||
openclaw secrets configure --providers-only
|
||||
openclaw secrets configure --skip-provider-setup
|
||||
openclaw secrets configure --agent ops
|
||||
openclaw secrets configure --json
|
||||
```
|
||||
|
||||
Flow: provider setup first (add/edit/remove `secrets.providers` aliases), then credential mapping (select fields, assign `{source, provider, id}` refs), then preflight and optional apply.
|
||||
|
||||
Flags:
|
||||
|
||||
- `--providers-only`: configure `secrets.providers` only, skip credential mapping
|
||||
- `--skip-provider-setup`: skip provider setup, map credentials to existing providers
|
||||
- `--agent <id>`: scope `auth-profiles.json` target discovery and writes to one agent store
|
||||
- `--allow-exec`: allow exec SecretRef checks during preflight/apply (may execute provider commands)
|
||||
|
||||
`--providers-only` and `--skip-provider-setup` cannot be combined.
|
||||
|
||||
Notes:
|
||||
|
||||
- Requires an interactive TTY.
|
||||
- Targets secret-bearing fields in `openclaw.json` plus `auth-profiles.json` for the selected agent scope; canonical supported surface: [SecretRef Credential Surface](/reference/secretref-credential-surface).
|
||||
- Supports creating new `auth-profiles.json` mappings directly in the picker flow.
|
||||
- Runs preflight resolution before apply.
|
||||
- Generated plans default to scrub options enabled (`scrubEnv`, `scrubAuthProfilesForProviderTargets`, `scrubLegacyAuthJson`). Apply is one-way for scrubbed plaintext values.
|
||||
- Without `--apply`, the CLI still prompts `Apply this plan now?` after preflight.
|
||||
- With `--apply` (and no `--yes`), the CLI prompts an extra irreversible-migration confirmation.
|
||||
- `--json` prints the plan + preflight report, but still requires an interactive TTY.
|
||||
|
||||
### Exec provider safety
|
||||
|
||||
Homebrew installs often expose symlinked binaries under `/opt/homebrew/bin/*`. Set `allowSymlinkCommand: true` only when needed for trusted package-manager paths, paired with `trustedDirs` (for example `["/opt/homebrew"]`). On Windows, if ACL verification is unavailable for a provider path, OpenClaw fails closed; for trusted paths only, set `allowInsecurePath: true` on that provider to bypass the path security check.
|
||||
|
||||
## Apply a saved plan
|
||||
|
||||
```bash
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --allow-exec
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run --allow-exec
|
||||
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --json
|
||||
```
|
||||
|
||||
`--dry-run` validates preflight without writing files; exec SecretRef checks are skipped by default in dry-run. Write mode rejects plans containing exec SecretRefs/providers unless `--allow-exec`. Use `--allow-exec` to opt in to exec provider checks/execution in either mode.
|
||||
|
||||
What `apply` may update:
|
||||
|
||||
- `openclaw.json` (SecretRef targets + provider upserts/deletes)
|
||||
- `auth-profiles.json` (provider-target scrubbing)
|
||||
- legacy `auth.json` residues
|
||||
- `~/.openclaw/.env` known secret keys whose values were migrated
|
||||
|
||||
Plan contract details (allowed target paths, validation rules, failure semantics): [Secrets Apply Plan Contract](/gateway/secrets-plan-contract).
|
||||
|
||||
### Why no rollback backups
|
||||
|
||||
`secrets apply` intentionally does not write rollback backups containing old plaintext values. Safety comes from strict preflight plus atomic-ish apply, with best-effort in-memory restore on failure.
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
openclaw secrets audit --check
|
||||
openclaw secrets configure
|
||||
openclaw secrets audit --check
|
||||
```
|
||||
|
||||
If `audit --check` still reports plaintext findings, update the remaining reported target paths and rerun audit.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Secrets management](/gateway/secrets)
|
||||
141
docs/cli/security.md
Normal file
141
docs/cli/security.md
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw security` (audit and fix common security footguns)"
|
||||
read_when:
|
||||
- You want to run a quick security audit on config/state
|
||||
- You want to apply safe "fix" suggestions (permissions, tighten defaults)
|
||||
title: "Security"
|
||||
---
|
||||
|
||||
# `openclaw security`
|
||||
|
||||
Security tools: audit plus optional safe fixes. Related: [Security](/gateway/security).
|
||||
|
||||
```bash
|
||||
openclaw security audit
|
||||
openclaw security audit --deep
|
||||
openclaw security audit --deep --password <password>
|
||||
openclaw security audit --deep --token <token>
|
||||
openclaw security audit --auth password --password <password>
|
||||
openclaw security audit --fix
|
||||
openclaw security audit --json
|
||||
```
|
||||
|
||||
## Audit modes
|
||||
|
||||
Plain `security audit` stays on the cold config/filesystem/read-only path: it does not discover plugin runtime security collectors, so routine audits do not load every installed plugin runtime. `--deep` adds best-effort live Gateway probes and plugin-owned security audit collectors (explicit internal callers may also opt into those collectors when they already have an appropriate runtime scope).
|
||||
|
||||
If Gateway password auth is supplied only at startup, pass the same value with `--auth password --password <password>` so the audit can check it against `hooks.token`.
|
||||
|
||||
## What it checks
|
||||
|
||||
**DM/trust model**
|
||||
|
||||
- Warns when multiple DM senders share the main session and recommends secure DM mode: `session.dmScope="per-channel-peer"` (or `per-account-channel-peer` for multi-account channels) for shared inboxes. This is cooperative/shared-inbox hardening, not isolation for mutually untrusted operators; split trust boundaries with separate gateways (or separate OS users/hosts) for that.
|
||||
- Emits `security.trust_model.multi_user_heuristic` when config suggests likely shared-user ingress (for example open DM/group policy, configured group targets, or wildcard sender rules) — OpenClaw's default trust model is personal-assistant (one operator), not hostile multi-tenant isolation. For intentional shared-user setups: sandbox all sessions, keep filesystem access workspace-scoped, and keep personal/private identities or credentials off that runtime.
|
||||
- Warns when small models (`<=300B` parameters) are used without sandboxing and with web/browser tools enabled.
|
||||
|
||||
**Webhook/hooks**
|
||||
|
||||
Startup logs a non-fatal security warning, and audit flags `hooks.token` reuse of active Gateway shared-secret auth values (`gateway.auth.token` / `OPENCLAW_GATEWAY_TOKEN`, `gateway.auth.password` / `OPENCLAW_GATEWAY_PASSWORD`). Also warns when:
|
||||
|
||||
- `hooks.token` is short
|
||||
- `hooks.path="/"`
|
||||
- `hooks.defaultSessionKey` is unset
|
||||
- `hooks.allowedAgentIds` is unrestricted
|
||||
- request `sessionKey` overrides are enabled
|
||||
- overrides are enabled without `hooks.allowedSessionKeyPrefixes`
|
||||
|
||||
Run `openclaw doctor --fix` to rotate a persisted reused `hooks.token`, then update external hook senders to use the new token.
|
||||
|
||||
**Sandbox/tools**
|
||||
|
||||
- Warns when sandbox Docker settings are configured while sandbox mode is off.
|
||||
- Warns when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries (matching is exact node command-name only, not shell-text filtering).
|
||||
- Warns when `gateway.nodes.allowCommands` explicitly enables dangerous node commands.
|
||||
- Warns when global `tools.profile="minimal"` is overridden by agent tool profiles.
|
||||
- Warns when write/edit tools are disabled but `exec` is still available without a constraining sandbox filesystem boundary.
|
||||
- Warns when open DMs or groups expose runtime/filesystem tools without sandbox/workspace guards.
|
||||
- Warns when installed plugin tools may be reachable under permissive tool policy.
|
||||
|
||||
**Sandbox browser**
|
||||
|
||||
- Warns when sandbox browser uses Docker `bridge` network without `sandbox.browser.cdpSourceRange`.
|
||||
- Flags dangerous sandbox Docker network modes, including `host` and `container:*` namespace joins.
|
||||
- Warns when existing sandbox browser Docker containers have missing/stale hash labels (for example pre-migration containers missing `openclaw.browserConfigEpoch`) and recommends `openclaw sandbox recreate --browser --all`.
|
||||
|
||||
**Network/discovery**
|
||||
|
||||
- Flags `gateway.allowRealIpFallback=true` (header-spoofing risk if proxies are misconfigured).
|
||||
- Flags `discovery.mdns.mode="full"` (metadata leakage via mDNS TXT records).
|
||||
- Warns when `gateway.auth.mode="none"` leaves Gateway HTTP APIs reachable without a shared secret (`/tools/invoke` plus any enabled `/v1/*` endpoint).
|
||||
|
||||
**Plugins/channels**
|
||||
|
||||
- Warns when npm-based plugin/hook install records are unpinned, missing integrity metadata, or drift from currently installed package versions.
|
||||
- Warns when channel allowlists rely on mutable names/emails/tags instead of stable IDs (Discord, Slack, Google Chat, Microsoft Teams, Mattermost, IRC scopes where applicable).
|
||||
|
||||
Settings prefixed with `dangerous`/`dangerously` are explicit break-glass operator overrides; enabling one is not, by itself, a security vulnerability report. For the complete dangerous-parameter inventory, see "Insecure or dangerous flags summary" in [Security](/gateway/security).
|
||||
|
||||
## SecretRef behavior
|
||||
|
||||
`security audit` resolves supported SecretRefs in read-only mode for its targeted paths. If a SecretRef is unavailable in the current command path, audit continues and reports `secretDiagnostics` instead of crashing. `--token` and `--password` only override deep-probe auth for that command invocation; they do not rewrite config or SecretRef mappings.
|
||||
|
||||
## Suppressions
|
||||
|
||||
Accept intentional standing findings with `security.audit.suppressions`. Each suppression matches an exact `checkId` and can be narrowed with case-insensitive `titleIncludes` and/or `detailIncludes` substrings:
|
||||
|
||||
```json
|
||||
{
|
||||
"security": {
|
||||
"audit": {
|
||||
"suppressions": [
|
||||
{
|
||||
"checkId": "plugins.tools_reachable_permissive_policy",
|
||||
"detailIncludes": "Enabled extension plugins: gbrain",
|
||||
"reason": "trusted local operator plugin"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Suppressed findings are removed from the active `summary` and `findings` list. JSON output keeps them under `suppressedFindings` for auditability. When suppressions are configured, active output also keeps an unsuppressible `security.audit.suppressions.active` info finding so readers can tell the audit was filtered. Dangerous config flags are emitted one flag per finding, so accepting one dangerous flag does not hide other enabled flags that share the same `config.insecure_or_dangerous_flags` checkId.
|
||||
|
||||
Because suppressions can hide standing risk, adding or removing them through agent-run shell commands requires exec approval unless exec is already running with `security="full"` and `ask="off"` for trusted local automation.
|
||||
|
||||
## JSON output
|
||||
|
||||
```bash
|
||||
openclaw security audit --json | jq '.summary'
|
||||
openclaw security audit --deep --json | jq '.findings[] | select(.severity=="critical") | .checkId'
|
||||
```
|
||||
|
||||
With `--fix --json`, output includes both fix actions and the final report:
|
||||
|
||||
```bash
|
||||
openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summary}'
|
||||
```
|
||||
|
||||
## What `--fix` changes
|
||||
|
||||
Applies safe, deterministic remediations:
|
||||
|
||||
- flips common `groupPolicy="open"` to `groupPolicy="allowlist"` (including account variants in supported channels)
|
||||
- when WhatsApp group policy flips to `allowlist`, seeds `groupAllowFrom` from the stored `allowFrom` file when that list exists and config does not already define `allowFrom`
|
||||
- sets `logging.redactSensitive` from `"off"` to `"tools"`
|
||||
- tightens permissions for state/config and common sensitive files (`credentials/*.json`, `auth-profiles.json`, `sessions.json`, session `*.jsonl`)
|
||||
- also tightens config include files referenced from `openclaw.json`
|
||||
- uses `chmod` on POSIX hosts and `icacls` resets on Windows
|
||||
|
||||
`--fix` does **not**:
|
||||
|
||||
- rotate tokens/passwords/API keys
|
||||
- disable tools (`gateway`, `cron`, `exec`, etc.)
|
||||
- change gateway bind/auth/network exposure choices
|
||||
- remove or rewrite plugins/skills
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Security audit](/gateway/security)
|
||||
265
docs/cli/sessions.md
Normal file
265
docs/cli/sessions.md
Normal file
@@ -0,0 +1,265 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw sessions` (list stored sessions + usage)"
|
||||
read_when:
|
||||
- You want to list stored sessions and see recent activity
|
||||
title: "Sessions"
|
||||
---
|
||||
|
||||
# `openclaw sessions`
|
||||
|
||||
List stored conversation sessions.
|
||||
|
||||
Session lists are not channel/provider liveness checks. They show persisted
|
||||
conversation rows from session stores. A quiet Discord, Slack, Telegram, or
|
||||
other channel can reconnect successfully without creating a new session row
|
||||
until a message is processed. Use `openclaw channels status --probe`,
|
||||
`openclaw status --deep`, or `openclaw health --verbose` when you need live
|
||||
channel connectivity.
|
||||
|
||||
```bash
|
||||
openclaw sessions
|
||||
openclaw sessions --agent work
|
||||
openclaw sessions --all-agents
|
||||
openclaw sessions --active 120
|
||||
openclaw sessions --limit 25
|
||||
openclaw sessions --store ./tmp/sessions.json
|
||||
openclaw sessions --json
|
||||
```
|
||||
|
||||
Flags:
|
||||
|
||||
| Flag | Description |
|
||||
| -------------------- | ---------------------------------------------------------------------- |
|
||||
| `--agent <id>` | One configured agent store (default: configured default agent). |
|
||||
| `--all-agents` | Aggregate all configured agent stores. |
|
||||
| `--store <path>` | Explicit store path (cannot combine with `--agent` or `--all-agents`). |
|
||||
| `--active <minutes>` | Only show sessions updated within the past N minutes. |
|
||||
| `--limit <n\|all>` | Max rows to output (default `100`; `all` restores full output). |
|
||||
| `--json` | Machine-readable output. |
|
||||
| `--verbose` | Verbose logging. |
|
||||
|
||||
`openclaw sessions` and the Gateway `sessions.list` RPC are bounded by default
|
||||
so large long-lived stores cannot monopolize the CLI process or Gateway event
|
||||
loop. The CLI returns the newest 100 sessions by default; pass `--limit <n>`
|
||||
for a smaller/larger window or `--limit all` when you intentionally need the
|
||||
full store. JSON responses include `totalCount`, `limitApplied`, and `hasMore`
|
||||
when callers need to show that more rows exist.
|
||||
|
||||
RPC clients can pass `configuredAgentsOnly: true` to keep the broad combined
|
||||
discovery source but return only rows for agents currently present in config.
|
||||
Control UI uses that mode by default so deleted or disk-only agent stores do
|
||||
not reappear in the Sessions view.
|
||||
|
||||
`--all-agents` reads configured agent stores. Gateway and ACP session
|
||||
discovery are broader: they also include disk-only stores found under the
|
||||
default `agents/` root or a templated `session.store` root. Those discovered
|
||||
stores must resolve to regular `sessions.json` files inside the agent root;
|
||||
symlinks and out-of-root paths are skipped.
|
||||
|
||||
`openclaw sessions --all-agents --json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"path": null,
|
||||
"stores": [
|
||||
{ "agentId": "main", "path": "/home/user/.openclaw/agents/main/sessions/sessions.json" },
|
||||
{ "agentId": "work", "path": "/home/user/.openclaw/agents/work/sessions/sessions.json" }
|
||||
],
|
||||
"allAgents": true,
|
||||
"count": 2,
|
||||
"totalCount": 2,
|
||||
"limitApplied": 100,
|
||||
"hasMore": false,
|
||||
"activeMinutes": null,
|
||||
"sessions": [
|
||||
{ "agentId": "main", "key": "agent:main:main", "model": "openai/gpt-5.5" },
|
||||
{ "agentId": "work", "key": "agent:work:main", "model": "anthropic/claude-sonnet-4-6" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Tail trajectory progress
|
||||
|
||||
```bash
|
||||
openclaw sessions tail
|
||||
openclaw sessions tail --follow
|
||||
openclaw sessions tail --session-key "agent:main:telegram:direct:123" --tail 25
|
||||
openclaw sessions --agent work tail --follow
|
||||
openclaw sessions --all-agents tail --follow
|
||||
```
|
||||
|
||||
`openclaw sessions tail` renders recent trajectory JSONL events as compact
|
||||
progress lines. Without `--session-key`, it tails running sessions first, then
|
||||
the latest stored session. `--tail <count>` controls how many existing events
|
||||
print before follow mode; default `80`, and `0` starts at the current end.
|
||||
`--follow` keeps watching the selected trajectory files, including relocated
|
||||
files referenced by `<session>.trajectory-path.json`.
|
||||
|
||||
The progress view is intentionally conservative: prompt text, tool arguments,
|
||||
and tool result bodies are not printed. Tool calls show the tool name with
|
||||
`{...redacted...}`; tool results show status such as `ok`, `error`, or `done`;
|
||||
model completion lines show provider/model and terminal status.
|
||||
|
||||
## Export a trajectory bundle
|
||||
|
||||
```bash
|
||||
openclaw sessions export-trajectory --session-key "agent:main:telegram:direct:123" --workspace .
|
||||
openclaw sessions export-trajectory --session-key "agent:main:telegram:direct:123" --output bug-123 --json
|
||||
```
|
||||
|
||||
This is the command path used by the `/export-trajectory` slash command after
|
||||
the owner approves the exec request. The output directory is always resolved
|
||||
inside `.openclaw/trajectory-exports/` under the selected workspace.
|
||||
|
||||
## Cleanup maintenance
|
||||
|
||||
Run maintenance now instead of waiting for the next write cycle:
|
||||
|
||||
```bash
|
||||
openclaw sessions cleanup --dry-run
|
||||
openclaw sessions cleanup --agent work --dry-run
|
||||
openclaw sessions cleanup --all-agents --dry-run
|
||||
openclaw sessions cleanup --enforce
|
||||
openclaw sessions cleanup --enforce --active-key "agent:main:telegram:direct:123"
|
||||
openclaw sessions cleanup --dry-run --fix-dm-scope
|
||||
openclaw sessions cleanup --json
|
||||
```
|
||||
|
||||
`openclaw sessions cleanup` uses `session.maintenance` settings from config
|
||||
([Configuration reference](/gateway/config-agents#session)):
|
||||
|
||||
- Scope note: `openclaw sessions cleanup` maintains session stores,
|
||||
transcripts, and trajectory sidecars. It does not prune cron run history,
|
||||
which is managed by `cron.runLog.keepLines`
|
||||
([Cron configuration](/automation/cron-jobs#configuration)).
|
||||
- Cleanup also prunes unreferenced primary transcripts, compaction
|
||||
checkpoints, and trajectory sidecars older than `session.maintenance.pruneAfter`;
|
||||
files still referenced by `sessions.json` are preserved.
|
||||
- Cleanup reports short-lived Gateway model-run probe cleanup separately as
|
||||
`modelRunPruned`. This only matches strict explicit keys shaped like
|
||||
`agent:*:explicit:model-run-<uuid>`. Retention is a fixed `24h` and is
|
||||
pressure-gated: it only removes stale probe rows when session-entry
|
||||
maintenance/cap pressure is reached. When it runs, model-run cleanup
|
||||
happens before global stale cleanup and capping.
|
||||
|
||||
Flags:
|
||||
|
||||
| Flag | Description |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--dry-run` | Preview how many entries would be pruned/capped without writing. In text mode, prints a per-session action table (`Action`, `Key`, `Age`, `Model`, `Flags`) plus a summary grouped by session label. |
|
||||
| `--enforce` | Apply maintenance even when `session.maintenance.mode` is `warn`. |
|
||||
| `--fix-missing` | Remove entries whose transcript files are missing or header-only/empty, even if they would not normally age/count out yet. |
|
||||
| `--fix-dm-scope` | When `session.dmScope` is `main`, retire stale peer-keyed direct-DM rows left behind by earlier `per-peer`, `per-channel-peer`, or `per-account-channel-peer` routing. Use `--dry-run` first; applying removes those rows from `sessions.json` and preserves their transcripts as deleted archives. |
|
||||
| `--active-key <key>` | Protect a specific active key from disk-budget eviction. Durable external conversation pointers, such as group sessions and thread-scoped chat sessions, are also kept by age/count/disk-budget maintenance. |
|
||||
| `--agent <id>` | Run cleanup for one configured agent store. |
|
||||
| `--all-agents` | Run cleanup for all configured agent stores. |
|
||||
| `--store <path>` | Run against a specific `sessions.json` file. |
|
||||
| `--json` | Print a JSON summary. With `--all-agents`, output includes one summary per store. |
|
||||
|
||||
When a Gateway is reachable, non-dry-run cleanup for configured agent stores is
|
||||
sent through the Gateway so it shares the same session-store writer as runtime
|
||||
traffic. Use `--store <path>` for explicit offline repair of a store file.
|
||||
|
||||
`openclaw sessions cleanup --all-agents --dry-run --json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"allAgents": true,
|
||||
"mode": "warn",
|
||||
"dryRun": true,
|
||||
"stores": [
|
||||
{
|
||||
"agentId": "main",
|
||||
"storePath": "/home/user/.openclaw/agents/main/sessions/sessions.json",
|
||||
"beforeCount": 120,
|
||||
"afterCount": 80,
|
||||
"missing": 0,
|
||||
"dmScopeRetired": 0,
|
||||
"pruned": 40,
|
||||
"capped": 0
|
||||
},
|
||||
{
|
||||
"agentId": "work",
|
||||
"storePath": "/home/user/.openclaw/agents/work/sessions/sessions.json",
|
||||
"beforeCount": 18,
|
||||
"afterCount": 18,
|
||||
"missing": 0,
|
||||
"dmScopeRetired": 0,
|
||||
"pruned": 0,
|
||||
"capped": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Compact a session
|
||||
|
||||
Reclaim context budget for a wedged or oversized session. `openclaw sessions
|
||||
compact <key>` is the first-class wrapper around the `sessions.compact`
|
||||
Gateway RPC and requires a running Gateway.
|
||||
|
||||
```bash
|
||||
openclaw sessions compact "agent:main:main"
|
||||
openclaw sessions compact "agent:main:main" --max-lines 200
|
||||
openclaw sessions compact "agent:work:main" --agent work --json
|
||||
```
|
||||
|
||||
- Without `--max-lines`, the Gateway LLM-summarizes the transcript. The CLI
|
||||
does not impose a client deadline by default; the Gateway owns the
|
||||
configured compaction lifecycle.
|
||||
- With `--max-lines <n>`, it truncates to the last `n` transcript lines and
|
||||
archives the prior transcript as a `.bak` sidecar.
|
||||
- `--agent <id>`: agent that owns the session; required for `global` keys.
|
||||
- `--url` / `--token` / `--password`: Gateway connection overrides.
|
||||
- `--timeout <ms>`: optional client-side RPC timeout in milliseconds.
|
||||
- `--json`: print the raw RPC payload.
|
||||
|
||||
The command exits non-zero when the Gateway reports a failed compaction or is
|
||||
unreachable, so crons and scripts never mistake a silent no-op for success.
|
||||
|
||||
<Note>
|
||||
`openclaw agent --message '/compact ...'` is **not** a compaction path. Slash
|
||||
commands from the CLI are rejected by the authorized-sender check; that
|
||||
invocation exits non-zero with guidance pointing here instead of silently
|
||||
no-opping.
|
||||
</Note>
|
||||
|
||||
### sessions.compact RPC
|
||||
|
||||
`openclaw gateway call sessions.compact --params '<json>'` accepts:
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| ---------- | ----------- | -------- | ---------------------------------------------------------- |
|
||||
| `key` | string | yes | Session key to compact (for example `agent:main:main`). |
|
||||
| `agentId` | string | no | Agent id that owns the session (for `global` keys). |
|
||||
| `maxLines` | integer ≥ 1 | no | Truncate to the last N lines instead of LLM summarization. |
|
||||
|
||||
Example LLM-summarize response:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"key": "agent:main:main",
|
||||
"compacted": true,
|
||||
"result": { "tokensBefore": 243868, "tokensAfter": 34941 }
|
||||
}
|
||||
```
|
||||
|
||||
Example truncate response (`--max-lines 200`):
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"key": "agent:main:main",
|
||||
"compacted": true,
|
||||
"archived": "/home/user/.openclaw/agents/main/sessions/transcripts/<id>.jsonl.bak",
|
||||
"kept": 200
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Session config](/gateway/config-agents#session)
|
||||
- [Session management](/concepts/session)
|
||||
- [Compaction](/concepts/compaction)
|
||||
- [CLI reference](/cli)
|
||||
78
docs/cli/setup.md
Normal file
78
docs/cli/setup.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw setup` (alias for onboarding, with baseline setup available by flag)"
|
||||
read_when:
|
||||
- You're doing first-run setup with the CLI onboarding wizard
|
||||
- You want to set the default workspace path
|
||||
- You need the baseline-only setup flag for scripts
|
||||
title: "Setup"
|
||||
---
|
||||
|
||||
# `openclaw setup`
|
||||
|
||||
`openclaw setup` runs the same guided onboarding flow as `openclaw onboard`
|
||||
(auth, workspace, Gateway, channels, skills, health). Use `--baseline` when you
|
||||
only need to initialize config/workspace folders without the wizard.
|
||||
|
||||
`setup` accepts the same onboarding flags as `openclaw onboard`, including
|
||||
auth (`--auth-choice`, `--token`, provider key flags), Gateway
|
||||
(`--gateway-port`, `--gateway-bind`, `--gateway-auth`, `--install-daemon`),
|
||||
Tailscale (`--tailscale`), reset (`--reset`, `--reset-scope`), flow
|
||||
(`--flow quickstart|advanced|manual|import`), and skip flags
|
||||
(`--skip-channels`, `--skip-skills`, `--skip-bootstrap`, `--skip-search`,
|
||||
`--skip-health`, `--skip-ui`, `--skip-hooks`). See [Onboard](/cli/onboard) and
|
||||
[CLI automation](/start/wizard-cli-automation) for the full flag reference and
|
||||
non-interactive examples; `openclaw onboard --modern` (the Crestodian
|
||||
conversational assistant) has no `setup` equivalent.
|
||||
|
||||
<Note>
|
||||
`openclaw setup` is for mutable config installs. In Nix mode (`OPENCLAW_NIX_MODE=1`) OpenClaw refuses setup writes because the config file is managed by Nix. Use the first-party [nix-openclaw Quick Start](https://github.com/openclaw/nix-openclaw#quick-start) or the equivalent source config for another Nix package.
|
||||
</Note>
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Description |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `--workspace <dir>` | Agent workspace directory (default `~/.openclaw/workspace`; stored as `agents.defaults.workspace`). |
|
||||
| `--baseline` | Create baseline config/workspace/session folders without onboarding. |
|
||||
| `--wizard` | Accepted for compatibility; setup runs onboarding by default. |
|
||||
| `--non-interactive` | Run onboarding without prompts. |
|
||||
| `--accept-risk` | Acknowledge full-system agent access risk; required with `--non-interactive`. |
|
||||
| `--mode <mode>` | Onboarding mode: `local` or `remote`. |
|
||||
| `--flow <flow>` | Onboard flow: `quickstart`, `advanced`, `manual`, or `import`. |
|
||||
| `--reset` | Reset config + credentials + sessions before onboarding (workspace only with `--reset-scope full`). |
|
||||
| `--reset-scope <scope>` | Reset scope: `config`, `config+creds+sessions`, or `full`. |
|
||||
| `--import-from <provider>` | Migration provider to run during onboarding. |
|
||||
| `--import-source <path>` | Source agent home for `--import-from`. |
|
||||
| `--import-secrets` | Import supported secrets during onboarding migration. |
|
||||
| `--remote-url <url>` | Remote Gateway WebSocket URL. |
|
||||
| `--remote-token <token>` | Remote Gateway token (optional). |
|
||||
| `--json` | Output a JSON summary. |
|
||||
|
||||
### Baseline mode
|
||||
|
||||
`openclaw setup --baseline` preserves the older baseline-only behavior: it
|
||||
creates the config, workspace, and session directories, then exits without
|
||||
running onboarding.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw setup
|
||||
openclaw setup --baseline
|
||||
openclaw setup --workspace ~/.openclaw/workspace
|
||||
openclaw setup --import-from hermes --import-source ~/.hermes
|
||||
openclaw setup --non-interactive --accept-risk --mode remote --remote-url wss://gateway-host:18789 --remote-token <token>
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- After baseline setup, run `openclaw setup` or `openclaw onboard` for the full guided journey, `openclaw configure` for targeted changes, or `openclaw channels add` to add channel accounts.
|
||||
- If Hermes state is detected, interactive onboarding can offer migration automatically. Import onboarding requires a fresh setup; use [Migrate](/cli/migrate) for dry-run plans, backups, and overwrite mode outside onboarding.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Onboard](/cli/onboard)
|
||||
- [Onboarding (CLI)](/start/wizard)
|
||||
- [Getting started](/start/getting-started)
|
||||
- [Install overview](/install)
|
||||
159
docs/cli/skills.md
Normal file
159
docs/cli/skills.md
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw skills` (search/install/update/verify/list/info/check/workshop)"
|
||||
read_when:
|
||||
- You want to see which skills are available and ready to run
|
||||
- You want to search ClawHub or install skills from ClawHub, Git, or local directories
|
||||
- You want to verify a ClawHub skill with ClawHub
|
||||
- You want to debug missing binaries/env/config for skills
|
||||
title: "Skills"
|
||||
---
|
||||
|
||||
# `openclaw skills`
|
||||
|
||||
Inspect local skills, search ClawHub, install skills from ClawHub/Git/local
|
||||
directories, verify ClawHub skills, and update ClawHub-tracked installs.
|
||||
|
||||
Related:
|
||||
|
||||
- Skills system: [Skills](/tools/skills)
|
||||
- Skill Workshop: [Skill Workshop](/tools/skill-workshop)
|
||||
- Skills config: [Skills config](/tools/skills-config)
|
||||
- ClawHub installs: [ClawHub](/clawhub/cli)
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
openclaw skills search "calendar"
|
||||
openclaw skills search --limit 20 --json
|
||||
openclaw skills install @owner/<slug>
|
||||
openclaw skills install @owner/<slug> --version <version>
|
||||
openclaw skills install git:owner/repo
|
||||
openclaw skills install git:owner/repo@main
|
||||
openclaw skills install ./path/to/skill --as custom-name
|
||||
openclaw skills install @owner/<slug> --force
|
||||
openclaw skills install @owner/<slug> --force-install
|
||||
openclaw skills install @owner/<slug> --acknowledge-clawhub-risk
|
||||
openclaw skills install @owner/<slug> --agent <id>
|
||||
openclaw skills install @owner/<slug> --global
|
||||
openclaw skills update @owner/<slug>
|
||||
openclaw skills update @owner/<slug> --force-install
|
||||
openclaw skills update @owner/<slug> --acknowledge-clawhub-risk
|
||||
openclaw skills update @owner/<slug> --global
|
||||
openclaw skills update --all
|
||||
openclaw skills update --all --agent <id>
|
||||
openclaw skills update --all --global
|
||||
openclaw skills verify @owner/<slug>
|
||||
openclaw skills verify @owner/<slug> --version <version>
|
||||
openclaw skills verify @owner/<slug> --tag <tag>
|
||||
openclaw skills verify @owner/<slug> --card
|
||||
openclaw skills verify @owner/<slug> --global
|
||||
openclaw skills list
|
||||
openclaw skills list --eligible
|
||||
openclaw skills list --json
|
||||
openclaw skills list --verbose
|
||||
openclaw skills list --agent <id>
|
||||
openclaw skills info <name>
|
||||
openclaw skills info <name> --json
|
||||
openclaw skills info <name> --agent <id>
|
||||
openclaw skills check
|
||||
openclaw skills check --agent <id>
|
||||
openclaw skills check --json
|
||||
openclaw skills workshop propose-create --name "qa-check" --description "QA checklist" --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop list
|
||||
openclaw skills workshop inspect <proposal-id>
|
||||
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop apply <proposal-id>
|
||||
openclaw skills workshop reject <proposal-id> --reason "Not reusable"
|
||||
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"
|
||||
```
|
||||
|
||||
`search`, `update`, and `verify` use ClawHub directly. `install @owner/<slug>`
|
||||
installs a ClawHub skill, `install git:owner/repo[@ref]` clones a Git skill,
|
||||
and `install ./path` copies a local skill directory. By default, `install`,
|
||||
`update`, and `verify` target the active workspace `skills/` directory; with
|
||||
`--global`, they target the shared managed skills directory. `list`/`info`/`check`
|
||||
still inspect the local skills visible to the current workspace and config.
|
||||
Workspace-backed commands resolve the target workspace from `--agent <id>`,
|
||||
then the current working directory when it is inside a configured agent
|
||||
workspace, then the default agent.
|
||||
|
||||
Git and local directory installs expect `SKILL.md` at the source root. The
|
||||
install slug comes from `SKILL.md` frontmatter `name` when it is valid, then
|
||||
the source directory or repository name; use `--as <slug>` to override it.
|
||||
`--version` is ClawHub-only. Skill installs do not support npm package specs
|
||||
or zip/archive paths, and `openclaw skills update` updates ClawHub-tracked
|
||||
installs only.
|
||||
|
||||
Gateway-backed skill dependency installs triggered from onboarding or Skills
|
||||
settings use the separate `skills.install` request path instead.
|
||||
|
||||
Notes:
|
||||
|
||||
| Flag/behavior | Description |
|
||||
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `search [query...]` | Optional query; omit it to browse the default ClawHub search feed. |
|
||||
| `search --limit <n>` | Caps returned results. |
|
||||
| `install git:owner/repo[@ref]` | Installs a Git skill. Branch refs may contain slashes, such as `git:owner/repo@feature/foo`. |
|
||||
| `install ./path/to/skill` | Installs a local directory whose root contains `SKILL.md`. |
|
||||
| `install --as <slug>` | Overrides the inferred slug for Git and local directory installs. |
|
||||
| `install --version <version>` | Applies only to ClawHub skill refs. |
|
||||
| `install --force` | Overwrites an existing workspace skill folder for the same slug. |
|
||||
| `install/update --force-install` | Installs a pending GitHub-backed ClawHub skill before ClawHub's scan completes. |
|
||||
| `--global` | Targets the shared managed skills directory; cannot combine with `--agent <id>`. |
|
||||
| `--agent <id>` | Targets one configured agent workspace; overrides current working directory inference. |
|
||||
| `update @owner/<slug>` | Updates a single tracked skill. Add `--global` to target the shared managed skills directory instead of the workspace. |
|
||||
| `update --all` | Updates tracked ClawHub installs in the selected workspace, or the shared managed skills directory with `--global`. |
|
||||
| `verify @owner/<slug>` | Prints ClawHub's `clawhub.skill.verify.v1` JSON envelope by default. There is no `--json` flag because JSON is already the default. Bare slugs are accepted for compatibility when the skill is already installed or unambiguous; owner-qualified refs avoid publisher ambiguity. |
|
||||
| `verify` provenance | When ClawHub returns server-resolved source provenance, verify JSON also includes a commit-pinned `openclaw.verifiedSourceUrl`. Unavailable or self-declared source URLs stay only in the raw provenance envelope and are not promoted. |
|
||||
| `verify` version selector | `verify` uses `.clawhub/origin.json` for installed ClawHub skills, so it verifies the installed version against the registry it came from. `--version` and `--tag` override the version selector but keep that installed registry when origin metadata exists. |
|
||||
| `verify --card` | Prints the generated Skill Card Markdown instead of JSON. Exits non-zero when ClawHub returns `ok: false` or `decision: "fail"`; unsigned signatures are informational unless ClawHub policy changes. |
|
||||
| Skill Card fingerprint | Installed ClawHub bundles can include a generated `skill-card.md`. OpenClaw treats verification as a ClawHub server decision and does not reject an installed skill just because that generated card changes the bundle fingerprint. |
|
||||
| `check --agent <id>` | Checks the selected agent's workspace and reports which ready skills are actually visible to that agent's prompt or command surface. |
|
||||
| `list` | Default action when no subcommand is provided. |
|
||||
| `list`/`info`/`check` output | Rendered output goes to stdout. With `--json`, the machine-readable payload stays on stdout for pipes and scripts. |
|
||||
|
||||
Community ClawHub skill installs and updates check trust before downloading.
|
||||
Versioned community archive releases use exact-release trust metadata.
|
||||
Resolver-backed GitHub skills rely on ClawHub's install resolver to enforce
|
||||
scan and force-install policy before it returns a pinned commit; use
|
||||
`--force-install` to install a pending GitHub-backed skill before that scan
|
||||
completes. Malicious or blocked community releases are refused. Risky
|
||||
community releases require review and `--acknowledge-clawhub-risk` when a
|
||||
non-interactive command should continue after that review. Official ClawHub
|
||||
skill publishers and bundled OpenClaw skill sources bypass this release-trust
|
||||
prompt.
|
||||
|
||||
## Skill Workshop
|
||||
|
||||
`openclaw skills workshop` manages pending skill proposals in the selected
|
||||
workspace. Proposals are not active skills until applied. For proposal
|
||||
storage, support-file safeguards, Gateway methods, and approval policy, see
|
||||
[Skill Workshop](/tools/skill-workshop).
|
||||
|
||||
```bash
|
||||
openclaw skills workshop propose-create \
|
||||
--name "qa-check" \
|
||||
--description "Repeatable QA checklist" \
|
||||
--proposal ./PROPOSAL.md
|
||||
openclaw skills workshop propose-create \
|
||||
--name "qa-check" \
|
||||
--description "Repeatable QA checklist" \
|
||||
--proposal-dir ./qa-check-proposal
|
||||
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop list
|
||||
openclaw skills workshop inspect <proposal-id>
|
||||
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop apply <proposal-id>
|
||||
openclaw skills workshop reject <proposal-id> --reason "Duplicate"
|
||||
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"
|
||||
```
|
||||
|
||||
`propose-create`, `propose-update`, and `revise` also accept `--goal <text>`
|
||||
and `--evidence <text>` to record the proposal's motivation and supporting
|
||||
notes alongside the `--proposal`/`--proposal-dir` content.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Skills](/tools/skills)
|
||||
104
docs/cli/status.md
Normal file
104
docs/cli/status.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw status` (diagnostics, probes, usage snapshots)"
|
||||
read_when:
|
||||
- You want a quick diagnosis of channel health + recent session recipients
|
||||
- You want a pasteable "all" status for debugging
|
||||
title: "openclaw status"
|
||||
---
|
||||
|
||||
Diagnostics for channels + sessions.
|
||||
|
||||
```bash
|
||||
openclaw status
|
||||
openclaw status --all
|
||||
openclaw status --deep
|
||||
openclaw status --usage
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| `--all` | Full diagnosis (read-only, pasteable). Includes security audit, plugin compatibility, and memory-vector probes. |
|
||||
| `--deep` | Runs live probes (WhatsApp Web + Telegram + Discord + Slack + Signal). Also enables the security audit. |
|
||||
| `--usage` | Prints normalized provider usage windows as `X% left`. |
|
||||
| `--json` | Machine-readable output. |
|
||||
| `--verbose` / `--debug` | Also print the raw Gateway target resolution before the report. |
|
||||
|
||||
Plain `openclaw status` stays on the fast read-only path and marks memory as
|
||||
`not checked` instead of unavailable when it skips memory inspection. Heavy
|
||||
security audit, plugin compatibility, and memory-vector probes are left to
|
||||
`openclaw status --all`, `openclaw status --deep`, `openclaw security audit`,
|
||||
and `openclaw memory status --deep`.
|
||||
|
||||
## Session and model resolution
|
||||
|
||||
- Session status output separates `Execution:` from `Runtime:`. `Execution`
|
||||
is the sandbox path (`direct`, `docker/*`), while `Runtime` tells you
|
||||
whether the session is using `OpenClaw Default`, `OpenAI Codex`, a CLI
|
||||
backend, or an ACP backend such as `codex (acp/acpx)`. See
|
||||
[Agent runtimes](/concepts/agent-runtimes) for the provider/model/runtime
|
||||
distinction.
|
||||
- When the current session snapshot is sparse, `/status` can backfill token
|
||||
and cache counters from the most recent transcript usage log. Existing
|
||||
nonzero live values still win over transcript fallback values.
|
||||
- Transcript fallback can also recover the active runtime model label when
|
||||
the live session entry is missing it. If that transcript model differs
|
||||
from the selected model, status resolves the context window against the
|
||||
recovered runtime model instead of the selected one.
|
||||
- For prompt-size accounting, transcript fallback prefers the larger
|
||||
prompt-oriented total when session metadata is missing or smaller, so
|
||||
custom-provider sessions do not collapse to `0` token displays.
|
||||
- When a session is pinned to a model that differs from the configured
|
||||
primary, status prints both values, the reason (`session override`), and
|
||||
the hint `/model default`. The configured primary applies to new or
|
||||
unpinned sessions; existing pinned sessions keep their session selection
|
||||
until cleared.
|
||||
- Output includes per-agent session stores when multiple agents are
|
||||
configured.
|
||||
|
||||
## Usage and quota
|
||||
|
||||
- `--usage` prints normalized provider usage windows as `X% left`.
|
||||
- MiniMax's raw `usage_percent` / `usagePercent` fields are remaining quota,
|
||||
so OpenClaw inverts them before display; count-based fields win when
|
||||
present. `model_remains` responses prefer the chat-model entry, derive the
|
||||
window label from timestamps when needed, and include the model name in
|
||||
the plan label.
|
||||
- Model pricing refresh failures are shown as optional pricing warnings.
|
||||
They do not mean the Gateway or channels are unhealthy.
|
||||
|
||||
## Overview and update status
|
||||
|
||||
- Overview includes Gateway + node host service install/runtime status when
|
||||
available, plus compact Gateway process uptime and host system uptime.
|
||||
- Overview includes update channel + git SHA (for source checkouts).
|
||||
- Update info surfaces in the Overview; if an update is available, status
|
||||
prints a hint to run `openclaw update` (see [Updating](/install/updating)).
|
||||
|
||||
## Secrets
|
||||
|
||||
- Read-only status surfaces (`status`, `status --json`, `status --all`)
|
||||
resolve supported SecretRefs for their targeted config paths when
|
||||
possible.
|
||||
- If a supported channel SecretRef is configured but unavailable in the
|
||||
current command path, status stays read-only and reports degraded output
|
||||
instead of crashing. Human output shows warnings such as "configured token
|
||||
unavailable in this command path", and JSON output includes
|
||||
`secretDiagnostics`.
|
||||
- When command-local SecretRef resolution succeeds, status prefers the
|
||||
resolved snapshot and clears transient "secret unavailable" channel
|
||||
markers from the final output.
|
||||
- `status --all` includes a Secrets overview row and a diagnosis section
|
||||
that summarizes secret diagnostics (truncated for readability) without
|
||||
stopping report generation.
|
||||
|
||||
## Memory
|
||||
|
||||
`status --json --all` reports memory details from the active memory plugin
|
||||
runtime selected by `plugins.slots.memory`. Custom memory plugins can leave
|
||||
built-in `agents.defaults.memorySearch.enabled` disabled and still report
|
||||
their own files, chunks, vector, and FTS state.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Doctor](/gateway/doctor)
|
||||
82
docs/cli/system.md
Normal file
82
docs/cli/system.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw system` (system events, heartbeat, presence)"
|
||||
read_when:
|
||||
- You want to enqueue a system event without creating a cron job
|
||||
- You need to enable or disable heartbeats
|
||||
- You want to inspect system presence entries
|
||||
title: "System"
|
||||
---
|
||||
|
||||
# `openclaw system`
|
||||
|
||||
System-level helpers for the Gateway: enqueue system events, control
|
||||
heartbeats, and view presence.
|
||||
|
||||
All `system` subcommands use Gateway RPC and accept the shared client flags:
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `--url <url>` | `gateway.remote.url` when configured | Gateway WebSocket URL. |
|
||||
| `--token <token>` | none | Gateway token (if required). |
|
||||
| `--timeout <ms>` | `30000` | RPC timeout in milliseconds. |
|
||||
| `--expect-final` | off | Wait for final response (agent). |
|
||||
| `--json` | off | Output JSON. `heartbeat last/enable/disable` and `system presence` always print the raw RPC JSON payload regardless of this flag; `system event` uses it to switch between JSON and a plain `ok` line. |
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
openclaw system event --text "Check for urgent follow-ups" --mode now
|
||||
openclaw system event --text "Check for urgent follow-ups" --url ws://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
openclaw system heartbeat enable
|
||||
openclaw system heartbeat last
|
||||
openclaw system presence
|
||||
```
|
||||
|
||||
## `system event`
|
||||
|
||||
Enqueue a system event on the **main** session by default. The next
|
||||
heartbeat injects it as a `System:` line in the prompt. Use `--mode now` to
|
||||
trigger the heartbeat immediately; `next-heartbeat` (default) waits for the
|
||||
next scheduled tick.
|
||||
|
||||
Pass `--session-key` to target a specific session, for example to relay an
|
||||
async-task completion back to the channel that started it.
|
||||
|
||||
<Note>
|
||||
**Timing exception with `--session-key`:** when `--session-key` is supplied,
|
||||
`--mode next-heartbeat` collapses to an immediate targeted wake instead of
|
||||
waiting for the next scheduled tick. Targeted wakes use heartbeat intent
|
||||
`immediate` so they bypass the runner's not-due gate that would otherwise
|
||||
defer (and effectively drop) an `event`-intent wake. If you want delayed
|
||||
delivery, omit `--session-key` so the event lands on the main session and
|
||||
rides the next regular heartbeat.
|
||||
</Note>
|
||||
|
||||
Flags:
|
||||
|
||||
- `--text <text>`: required system event text.
|
||||
- `--mode <mode>`: `now` or `next-heartbeat` (default).
|
||||
- `--session-key <sessionKey>`: optional; target a specific agent session
|
||||
instead of the agent's main session. Keys that do not belong to the
|
||||
resolved agent fall back to the agent's main session.
|
||||
|
||||
## `system heartbeat last|enable|disable`
|
||||
|
||||
- `last`: show the last heartbeat event.
|
||||
- `enable`: turn heartbeats back on (use this if they were disabled).
|
||||
- `disable`: pause heartbeats.
|
||||
|
||||
## `system presence`
|
||||
|
||||
List the current system presence entries the Gateway knows about (nodes,
|
||||
instances, and similar status lines).
|
||||
|
||||
## Notes
|
||||
|
||||
- Requires a running Gateway reachable by your current config (local or
|
||||
remote).
|
||||
- System events are ephemeral and not persisted across restarts.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
128
docs/cli/tasks.md
Normal file
128
docs/cli/tasks.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw tasks` (background task ledger and Task Flow state)"
|
||||
read_when:
|
||||
- You want to inspect, audit, or cancel background task records
|
||||
- You are documenting Task Flow commands under `openclaw tasks flow`
|
||||
title: "`openclaw tasks`"
|
||||
---
|
||||
|
||||
Inspect durable background tasks and Task Flow state. With no subcommand,
|
||||
`openclaw tasks` is equivalent to `openclaw tasks list`.
|
||||
|
||||
See [Background Tasks](/automation/tasks) for the lifecycle and delivery
|
||||
model, and its `tasks audit` section for full finding descriptions.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw tasks
|
||||
openclaw tasks list
|
||||
openclaw tasks list --runtime acp
|
||||
openclaw tasks list --status running
|
||||
openclaw tasks show <lookup>
|
||||
openclaw tasks notify <lookup> state_changes
|
||||
openclaw tasks cancel <lookup>
|
||||
openclaw tasks audit
|
||||
openclaw tasks maintenance
|
||||
openclaw tasks maintenance --apply
|
||||
openclaw tasks flow list
|
||||
openclaw tasks flow show <lookup>
|
||||
openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
## Root Options
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------- |
|
||||
| `--json` | Output JSON. |
|
||||
| `--runtime <name>` | Filter by kind: `subagent`, `acp`, `cron`, or `cli`. |
|
||||
| `--status <name>` | Filter by status: `queued`, `running`, `succeeded`, `failed`, `timed_out`, `cancelled`, or `lost`. |
|
||||
|
||||
## Subcommands
|
||||
|
||||
### `list`
|
||||
|
||||
```bash
|
||||
openclaw tasks list [--runtime <name>] [--status <name>] [--json]
|
||||
```
|
||||
|
||||
Lists tracked background tasks newest first.
|
||||
|
||||
### `show`
|
||||
|
||||
```bash
|
||||
openclaw tasks show <lookup> [--json]
|
||||
```
|
||||
|
||||
Shows one task by task ID, run ID, or session key.
|
||||
|
||||
### `notify`
|
||||
|
||||
```bash
|
||||
openclaw tasks notify <lookup> <done_only|state_changes|silent>
|
||||
```
|
||||
|
||||
Changes the notification policy for a running task.
|
||||
|
||||
### `cancel`
|
||||
|
||||
```bash
|
||||
openclaw tasks cancel <lookup>
|
||||
```
|
||||
|
||||
Cancels a running background task.
|
||||
|
||||
### `audit`
|
||||
|
||||
```bash
|
||||
openclaw tasks audit [--severity <warn|error>] [--code <name>] [--limit <n>] [--json]
|
||||
```
|
||||
|
||||
Surfaces stale, lost, delivery-failed, or otherwise inconsistent task and
|
||||
Task Flow records. Lost tasks retained until `cleanupAfter` are warnings;
|
||||
expired or unstamped lost tasks are errors.
|
||||
|
||||
`--code` accepts task codes (`stale_queued`, `stale_running`, `lost`,
|
||||
`delivery_failed`, `missing_cleanup`, `inconsistent_timestamps`) and Task
|
||||
Flow codes (`restore_failed`, `stale_waiting`, `stale_blocked`,
|
||||
`cancel_stuck`, `missing_linked_tasks`, `blocked_task_missing`). See
|
||||
[Background Tasks](/automation/tasks) for severity and trigger detail per
|
||||
code.
|
||||
|
||||
### `maintenance`
|
||||
|
||||
```bash
|
||||
openclaw tasks maintenance [--apply] [--json]
|
||||
```
|
||||
|
||||
Previews or applies task and Task Flow reconciliation, cleanup stamping,
|
||||
pruning, and stale cron run session registry cleanup.
|
||||
|
||||
For cron tasks, reconciliation uses persisted run logs/job state before
|
||||
marking an old active task `lost`, so completed cron runs do not become
|
||||
false audit errors just because the in-memory Gateway runtime state is gone.
|
||||
Offline CLI audit is not authoritative for the Gateway's process-local cron
|
||||
active-job set. CLI tasks with a run id/source id are marked `lost` when
|
||||
their live Gateway run context is gone, even if an old child-session row
|
||||
remains.
|
||||
|
||||
When applied, maintenance also prunes `cron:<jobId>:run:<uuid>` session
|
||||
registry rows older than 7 days while preserving currently running cron
|
||||
jobs and leaving non-cron session rows untouched.
|
||||
|
||||
### `flow`
|
||||
|
||||
```bash
|
||||
openclaw tasks flow list [--status <name>] [--json]
|
||||
openclaw tasks flow show <lookup> [--json]
|
||||
openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
Inspects or cancels durable Task Flow state under the task ledger.
|
||||
`flow list --status` accepts `queued`, `running`, `waiting`, `blocked`,
|
||||
`succeeded`, `failed`, `cancelled`, or `lost`.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Background tasks](/automation/tasks)
|
||||
142
docs/cli/transcripts.md
Normal file
142
docs/cli/transcripts.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw transcripts` (list, show, and locate stored transcripts)"
|
||||
read_when:
|
||||
- You want to read stored transcript summaries from the terminal
|
||||
- You need the path to a transcripts markdown summary
|
||||
- You are debugging the core transcripts storage layout
|
||||
title: "Transcripts CLI"
|
||||
---
|
||||
|
||||
# `openclaw transcripts`
|
||||
|
||||
Read-only inspector for transcripts written by the `transcripts` agent tool.
|
||||
Capture, import, and summarization run through that tool, not this CLI.
|
||||
|
||||
Artifacts live under the state directory:
|
||||
|
||||
```text
|
||||
$OPENCLAW_STATE_DIR/transcripts/YYYY-MM-DD/<session>/
|
||||
metadata.json
|
||||
transcript.jsonl
|
||||
summary.json
|
||||
summary.md
|
||||
```
|
||||
|
||||
Default state directory is `~/.openclaw`; override with `OPENCLAW_STATE_DIR`.
|
||||
The date directory comes from the session start time; the session directory is
|
||||
a filesystem-safe slug derived from the session id.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
openclaw transcripts list
|
||||
openclaw transcripts show <session>
|
||||
openclaw transcripts show YYYY-MM-DD/<session>
|
||||
openclaw transcripts path <session>
|
||||
openclaw transcripts path YYYY-MM-DD/<session>
|
||||
openclaw transcripts path <session> --dir
|
||||
openclaw transcripts path <session> --metadata
|
||||
openclaw transcripts path <session> --transcript
|
||||
openclaw transcripts list --json
|
||||
openclaw transcripts show <session> --json
|
||||
openclaw transcripts path <session> --json
|
||||
```
|
||||
|
||||
| Command | Description |
|
||||
| ----------------------------- | ----------------------------------------------- |
|
||||
| `list` | List stored sessions. |
|
||||
| `show <session>` | Print the stored `summary.md`. |
|
||||
| `path <session>` | Print the `summary.md` path. |
|
||||
| `path <session> --dir` | Print the session directory. |
|
||||
| `path <session> --metadata` | Print `metadata.json`. |
|
||||
| `path <session> --transcript` | Print `transcript.jsonl`. |
|
||||
| `--json` | Print machine-readable output (any subcommand). |
|
||||
|
||||
`<session>` accepts either a bare session id or a date-qualified selector
|
||||
(`YYYY-MM-DD/<session>`). Use the qualified form when the same session id
|
||||
occurs on more than one day, for example `openclaw transcripts show
|
||||
2026-05-22/standup`. Default session ids include a timestamp and random
|
||||
suffix; give a session a fixed id only when that id is unique within the day.
|
||||
|
||||
## Output
|
||||
|
||||
`list` prints one tab-separated line per session: selector, start time, title,
|
||||
summary path.
|
||||
|
||||
```text
|
||||
2026-05-22/standup 2026-05-22T09:00:00.000Z Weekly standup /Users/user/.openclaw/transcripts/2026-05-22/standup/summary.md
|
||||
```
|
||||
|
||||
The selector is the safest value to pass back to `show` or `path`.
|
||||
|
||||
`list --json` returns objects with `sessionId`, `selector`, `date`, `title`,
|
||||
`startedAt`, `stoppedAt`, `source`, `path`, `summaryPath`, `hasSummary`.
|
||||
|
||||
`show --json` returns the stored session metadata, selector, session
|
||||
directory, summary path, and summary Markdown text.
|
||||
|
||||
`path --json` returns the selected path and whether that file exists.
|
||||
|
||||
## Many sessions per day
|
||||
|
||||
Sessions group by date, then by session id. Ten meetings on one day become
|
||||
ten sibling folders:
|
||||
|
||||
```text
|
||||
~/.openclaw/transcripts/2026-05-22/
|
||||
transcript-2026-05-22T09-00-00-000Z-a1b2c3d4/
|
||||
transcript-2026-05-22T10-30-00-000Z-b2c3d4e5/
|
||||
standup/
|
||||
```
|
||||
|
||||
Use default generated ids for automation. Use a fixed id like `standup` only
|
||||
when it will not repeat on the same date.
|
||||
|
||||
## Missing summaries
|
||||
|
||||
Live sessions write `summary.md` when the session stops; imported transcripts
|
||||
write it immediately after import. A session can appear in `list` without a
|
||||
summary while capture is still active, if a provider failed during stop, or if
|
||||
metadata was written before any utterances arrived.
|
||||
|
||||
Use `path <session> --transcript` to inspect the raw append-only transcript,
|
||||
or run the `transcripts` tool's `summarize` action to regenerate the Markdown
|
||||
summary.
|
||||
|
||||
## Configuration
|
||||
|
||||
Capture is opt-in (live sources can join and record meeting audio). Enable it
|
||||
with:
|
||||
|
||||
```json
|
||||
{
|
||||
"transcripts": {
|
||||
"enabled": true,
|
||||
"maxUtterances": 2000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled` (default `false`): turn the tool on.
|
||||
- `maxUtterances` (default `2000`, clamped 1-10000): utterance buffer size per
|
||||
session.
|
||||
|
||||
Configure auto-start sources with `transcripts.autoStart`. Each entry is
|
||||
enabled by being present; omit an entry to disable that source. `discord-voice`
|
||||
is the bundled auto-start-capable source and requires `guildId` and
|
||||
`channelId`:
|
||||
|
||||
```json
|
||||
{
|
||||
"transcripts": {
|
||||
"enabled": true,
|
||||
"autoStart": [
|
||||
{
|
||||
"providerId": "discord-voice",
|
||||
"guildId": "1234567890",
|
||||
"channelId": "2345678901"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
98
docs/cli/tui.md
Normal file
98
docs/cli/tui.md
Normal file
@@ -0,0 +1,98 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw tui` (Gateway-backed or local embedded terminal UI)"
|
||||
read_when:
|
||||
- You want a terminal UI for the Gateway (remote-friendly)
|
||||
- You want to pass url/token/session from scripts
|
||||
- You want to run the TUI in local embedded mode without a Gateway
|
||||
- You want to use openclaw chat or openclaw tui --local
|
||||
title: "TUI"
|
||||
---
|
||||
|
||||
# `openclaw tui`
|
||||
|
||||
Open the terminal UI connected to the Gateway, or run it in local embedded
|
||||
mode.
|
||||
|
||||
Related guide: [TUI](/web/tui)
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| `--local` | `false` | Run against the local embedded agent runtime instead of a Gateway. |
|
||||
| `--url <url>` | `gateway.remote.url` from config | Gateway WebSocket URL. |
|
||||
| `--token <token>` | (none) | Gateway token if required. |
|
||||
| `--password <pass>` | (none) | Gateway password if required. |
|
||||
| `--session <key>` | `main` (or `global` when scope is global) | Session key. Inside an agent workspace it auto-selects that agent unless prefixed. |
|
||||
| `--deliver` | `false` | Deliver assistant replies through configured channels. |
|
||||
| `--thinking <level>` | (model default) | Thinking level override. |
|
||||
| `--message <text>` | (none) | Send an initial message after connecting. |
|
||||
| `--timeout-ms <ms>` | `agents.defaults.timeoutSeconds` | Agent timeout. Invalid values log a warning and are ignored. |
|
||||
| `--history-limit <n>` | `200` | History entries to load on attach. |
|
||||
|
||||
Aliases: `openclaw chat` and `openclaw terminal` invoke this command with
|
||||
`--local` implied.
|
||||
|
||||
## Notes
|
||||
|
||||
- `--local` cannot combine with `--url`, `--token`, or `--password`.
|
||||
- `tui` resolves configured Gateway auth SecretRefs for token/password auth
|
||||
when possible (`env`/`file`/`exec` providers).
|
||||
- Launched from inside a configured agent workspace directory, TUI auto-selects
|
||||
that agent for the session key default (unless `--session` is explicitly
|
||||
`agent:<id>:...`).
|
||||
- To show the Gateway hostname in the footer for non-local URL-backed
|
||||
connections, run `openclaw config set tui.footer.showRemoteHost true`. Off by
|
||||
default; never shown for loopback or embedded local connections.
|
||||
- Local mode uses the embedded agent runtime directly. Most local tools work,
|
||||
but Gateway-only features are unavailable.
|
||||
- Local mode adds `/auth [provider]` to the TUI command surface.
|
||||
- Plugin approval gates still apply in local mode: tools that require approval
|
||||
prompt for a decision in the terminal, nothing is silently auto-approved.
|
||||
- Session [goals](/tools/goal) appear in the footer and can be managed with
|
||||
`/goal`.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw chat
|
||||
openclaw tui --local
|
||||
openclaw tui
|
||||
openclaw tui --url ws://127.0.0.1:18789 --token <token>
|
||||
openclaw tui --session main --deliver
|
||||
openclaw chat --message "Compare my config to the docs and tell me what to fix"
|
||||
# when run inside an agent workspace, infers that agent automatically
|
||||
openclaw tui --session bugfix
|
||||
```
|
||||
|
||||
## Config repair loop
|
||||
|
||||
Use local mode to have the embedded agent inspect the current config, compare
|
||||
it against the docs, and help repair it from the same terminal.
|
||||
|
||||
If `openclaw config validate` is already failing, run `openclaw configure` or
|
||||
`openclaw doctor --fix` first; `openclaw chat` does not bypass the
|
||||
invalid-config guard.
|
||||
|
||||
```bash
|
||||
openclaw chat
|
||||
```
|
||||
|
||||
Then inside the TUI:
|
||||
|
||||
```text
|
||||
!openclaw config file
|
||||
!openclaw docs gateway auth token secretref
|
||||
!openclaw config validate
|
||||
!openclaw doctor
|
||||
```
|
||||
|
||||
Apply targeted fixes with `openclaw config set` or `openclaw configure`, then
|
||||
rerun `openclaw config validate`. See [TUI](/web/tui) and
|
||||
[Config](/cli/config).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [TUI](/web/tui)
|
||||
- [Goal](/tools/goal)
|
||||
51
docs/cli/uninstall.md
Normal file
51
docs/cli/uninstall.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw uninstall` (remove gateway service + local data)"
|
||||
read_when:
|
||||
- You want to remove the gateway service and/or local state
|
||||
- You want a dry-run first
|
||||
title: "Uninstall"
|
||||
---
|
||||
|
||||
# `openclaw uninstall`
|
||||
|
||||
Uninstall the Gateway service and/or local data. The CLI itself is not
|
||||
removed; uninstall it via npm/pnpm separately.
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ------------------- | ------- | ---------------------------------------------------- |
|
||||
| `--service` | `false` | Remove the Gateway service. |
|
||||
| `--state` | `false` | Remove state and config. |
|
||||
| `--workspace` | `false` | Remove workspace directories. |
|
||||
| `--app` | `false` | Remove the macOS app. |
|
||||
| `--all` | `false` | Shorthand for `--service --state --workspace --app`. |
|
||||
| `--yes` | `false` | Skip confirmation prompts. |
|
||||
| `--non-interactive` | `false` | Disable prompts; requires `--yes`. |
|
||||
| `--dry-run` | `false` | Print planned actions without removing files. |
|
||||
|
||||
With no scope flags, an interactive multiselect prompts for which components
|
||||
to remove (defaults to service, state, workspace preselected).
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
openclaw uninstall
|
||||
openclaw uninstall --service --yes --non-interactive
|
||||
openclaw uninstall --state --workspace --yes --non-interactive
|
||||
openclaw uninstall --all --yes
|
||||
openclaw uninstall --dry-run
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Run `openclaw backup create` first for a restorable snapshot before removing
|
||||
state or workspaces.
|
||||
- `--state` preserves configured workspace directories unless `--workspace` is
|
||||
also selected.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Uninstall](/install/uninstall)
|
||||
305
docs/cli/update.md
Normal file
305
docs/cli/update.md
Normal file
@@ -0,0 +1,305 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw update` (safe-ish source update + gateway auto-restart)"
|
||||
read_when:
|
||||
- You want to update a source checkout safely
|
||||
- You are debugging `openclaw update` output or options
|
||||
- You need to understand `--update` shorthand behavior
|
||||
title: "Update"
|
||||
---
|
||||
|
||||
# `openclaw update`
|
||||
|
||||
Update OpenClaw and switch between stable/extended-stable/beta/dev channels.
|
||||
|
||||
If you installed via **npm/pnpm/bun** (global install, no git metadata),
|
||||
updates go through the package-manager flow described in
|
||||
[Updating](/install/updating).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw update
|
||||
openclaw update status
|
||||
openclaw update repair
|
||||
openclaw update wizard
|
||||
openclaw update --channel extended-stable
|
||||
openclaw update --channel beta
|
||||
openclaw update --channel dev
|
||||
openclaw update --tag beta
|
||||
openclaw update --tag main
|
||||
openclaw update --dry-run
|
||||
openclaw update --no-restart
|
||||
openclaw update --yes
|
||||
openclaw update --acknowledge-clawhub-risk
|
||||
openclaw update --json
|
||||
openclaw --update
|
||||
```
|
||||
|
||||
`openclaw --update` rewrites to `openclaw update` (useful for shells and
|
||||
launcher scripts).
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--no-restart` | Skip restarting the Gateway service after a successful update. Package-manager updates that do restart verify the restarted service reports the expected version before the command succeeds. |
|
||||
| `--channel <stable\|extended-stable\|beta\|dev>` | Set the update channel and persist it after core update success. Extended-stable is package-only. |
|
||||
| `--tag <dist-tag\|version\|spec>` | Override the package target for this update only. It cannot be combined with an effective `extended-stable` channel, whose verified exact target is mandatory. For other package installs, `main` maps to `github:openclaw/openclaw#main`; GitHub/git source specs are packed into a temporary tarball before the staged global npm install. |
|
||||
| `--dry-run` | Preview planned actions (channel/tag/target/restart flow) without writing config, installing, syncing plugins, or restarting. |
|
||||
| `--json` | Print machine-readable `UpdateRunResult` JSON. Includes `postUpdate.plugins.warnings` when a managed plugin needs repair, beta-channel plugin fallback details, and `postUpdate.plugins.integrityDrifts` when npm plugin artifact drift is detected during post-update sync. |
|
||||
| `--timeout <seconds>` | Per-step timeout. Default `1800`. |
|
||||
| `--yes` | Skip confirmation prompts (for example downgrade confirmation). |
|
||||
| `--acknowledge-clawhub-risk` | Allow post-update plugin sync to continue past community ClawHub trust warnings without an interactive prompt. Without it, risky community releases are skipped and left unchanged when OpenClaw cannot prompt. Official ClawHub packages and bundled plugin sources bypass this prompt. |
|
||||
|
||||
There is no `--verbose` flag. Use `--dry-run` to preview planned actions,
|
||||
`--json` for machine-readable results, and `openclaw update status --json`
|
||||
for channel/availability only. Gateway console verbosity (`--verbose`) and
|
||||
file log level (`logging.level: "debug"`/`"trace"`) are independent knobs; see
|
||||
[Gateway logging](/gateway/logging).
|
||||
|
||||
<Note>
|
||||
In Nix mode (`OPENCLAW_NIX_MODE=1`), mutating `openclaw update` runs are disabled. Update the Nix source or flake input for this install instead; for nix-openclaw, use the agent-first [Quick Start](https://github.com/openclaw/nix-openclaw#quick-start). `openclaw update status` and `openclaw update --dry-run` remain read-only.
|
||||
</Note>
|
||||
|
||||
<Warning>
|
||||
Downgrades require confirmation because older versions can break configuration.
|
||||
</Warning>
|
||||
|
||||
## `update status`
|
||||
|
||||
Show the active update channel, git tag/branch/SHA (source checkouts only),
|
||||
and update availability.
|
||||
|
||||
```bash
|
||||
openclaw update status
|
||||
openclaw update status --json
|
||||
openclaw update status --timeout 10
|
||||
```
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------------- | ------- | ----------------------------------- |
|
||||
| `--json` | `false` | Print machine-readable status JSON. |
|
||||
| `--timeout <seconds>` | `3` | Timeout for checks. |
|
||||
|
||||
For extended-stable package installs, status performs the same public selector
|
||||
and exact-package verification as foreground update. It can report
|
||||
`ahead of extended-stable` when the installed version is newer. JSON failures
|
||||
include `registry.reason` (`selector_missing`, `selector_query_failed`,
|
||||
`exact_package_mismatch`, or `unsupported_git_channel`).
|
||||
|
||||
## `update repair`
|
||||
|
||||
Rerun update finalization after the core package already changed but later
|
||||
repair work did not finish cleanly. This is the supported recovery path when
|
||||
`openclaw update` installed the new core package but post-core plugin sync,
|
||||
managed npm plugin metadata, registry refresh, or doctor repair did not
|
||||
converge.
|
||||
|
||||
```bash
|
||||
openclaw update repair
|
||||
openclaw update repair --channel beta
|
||||
openclaw update repair --acknowledge-clawhub-risk
|
||||
openclaw update repair --json
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--channel <stable\|extended-stable\|beta\|dev>` | Persist the core update channel before repair. For extended-stable, plugin convergence temporarily targets the stable/latest plugin line. Extended-stable repair is rejected on Git checkouts without changing config. |
|
||||
| `--json` | Print machine-readable finalization JSON. |
|
||||
| `--timeout <seconds>` | Timeout for repair steps. Default `1800`. |
|
||||
| `--yes` | Skip confirmation prompts. |
|
||||
| `--acknowledge-clawhub-risk` | Same behavior as on `openclaw update`. |
|
||||
| `--no-restart` | Accepted for parity; repair never restarts the Gateway. |
|
||||
|
||||
`update repair` runs `openclaw doctor --fix`, reloads the repaired config and
|
||||
install records, syncs tracked plugins for the active update channel, updates
|
||||
managed npm plugin installs, repairs missing configured plugin payloads,
|
||||
refreshes the plugin registry, and writes converged install-record metadata.
|
||||
It does not install a new core package and does not restart the Gateway.
|
||||
|
||||
## `update wizard`
|
||||
|
||||
Interactive flow to pick an update channel and confirm whether to restart the
|
||||
Gateway afterward (defaults to restart). Selecting `dev` without a git
|
||||
checkout offers to create one.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------------- | ------- | ----------------------------- |
|
||||
| `--timeout <seconds>` | `1800` | Timeout for each update step. |
|
||||
|
||||
## What it does
|
||||
|
||||
Switching channels explicitly (`--channel ...`) also keeps the install method
|
||||
aligned:
|
||||
|
||||
- `dev` -> ensures a git checkout (default `~/openclaw`, or
|
||||
`$OPENCLAW_HOME/openclaw` when `OPENCLAW_HOME` is set; override with
|
||||
`OPENCLAW_GIT_DIR`), updates it, and installs the global CLI from that
|
||||
checkout.
|
||||
- `stable` -> installs from npm using `latest`.
|
||||
- `extended-stable` -> resolves the public npm `extended-stable` selector,
|
||||
verifies the exact selected package, and installs that exact version. It
|
||||
does not fall back to another selector and is rejected for Git checkouts.
|
||||
- `beta` -> prefers npm dist-tag `beta`, falling back to `latest` when beta is
|
||||
missing or older than the current stable release.
|
||||
|
||||
### Restart handoff
|
||||
|
||||
The Gateway core auto-updater (when enabled via config) launches the CLI
|
||||
update path outside the live Gateway request handler. Control-plane
|
||||
`update.run` package-manager updates and supervised git-checkout updates use
|
||||
the same managed-service handoff instead of replacing the package tree or
|
||||
rebuilding `dist/` inside the live Gateway process: the Gateway starts a
|
||||
detached helper and exits, and that helper runs `openclaw update --yes --json`
|
||||
from outside the Gateway process tree. If the handoff is unavailable,
|
||||
`update.run` returns a structured response with the safe shell command to run
|
||||
manually.
|
||||
|
||||
Extended-stable is deliberately excluded from startup checks and background
|
||||
auto-update scheduling. Explicit foreground updates, bare foreground updates
|
||||
with stored `update.channel: "extended-stable"`, on-demand status, and managed
|
||||
Gateway handoff remain supported.
|
||||
|
||||
When a local managed Gateway service is installed and restart is enabled,
|
||||
package-manager and git-checkout updates stop the running service before
|
||||
replacing the package tree or mutating the checkout/build output. The updater
|
||||
then refreshes service metadata, restarts the service, and verifies the
|
||||
restarted Gateway before reporting `Gateway: restarted and verified.`.
|
||||
Package-manager updates additionally verify the restarted Gateway reports the
|
||||
expected package version; git-checkout updates verify gateway health and
|
||||
service readiness after the rebuild.
|
||||
|
||||
On macOS, the post-update check also verifies the LaunchAgent is
|
||||
loaded/running for the active profile and the configured loopback port is
|
||||
healthy. If the plist is installed but launchd is not supervising it, OpenClaw
|
||||
re-bootstraps the LaunchAgent automatically and reruns the health/version/
|
||||
channel readiness checks (a fresh bootstrap loads the `RunAtLoad` job directly,
|
||||
so recovery does not immediately `kickstart -k` the newly spawned Gateway). If
|
||||
the Gateway still does not become healthy, the command exits non-zero and
|
||||
prints the restart log path plus restart, reinstall, and package rollback
|
||||
instructions.
|
||||
|
||||
If restart cannot run, the command prints `Gateway: restart skipped (...)` or
|
||||
`Gateway: restart failed: ...` with a manual `openclaw gateway restart` hint.
|
||||
With `--no-restart`, package replacement or git rebuild still runs, but the
|
||||
managed service is not stopped or restarted, so the running Gateway keeps old
|
||||
code until you restart it manually.
|
||||
|
||||
### Control-plane response shape
|
||||
|
||||
When `update.run` runs through the Gateway control plane on a package-manager
|
||||
install or supervised git checkout, the handler reports handoff initiation
|
||||
separately from the CLI update that continues after the Gateway exits:
|
||||
|
||||
- `ok: true`, `result.status: "skipped"`,
|
||||
`result.reason: "managed-service-handoff-started"`, and
|
||||
`handoff.status: "started"`: the Gateway created the managed-service handoff
|
||||
and scheduled its own restart so the detached helper can run
|
||||
`openclaw update --yes --json` outside the live service process.
|
||||
- `ok: false`, `result.reason: "managed-service-handoff-unavailable"`, and
|
||||
`handoff.status: "unavailable"`: OpenClaw could not find a supervising
|
||||
service boundary and durable service identity for a safe handoff (for
|
||||
example, systemd handoff requires the `OPENCLAW_SYSTEMD_UNIT` unit identity,
|
||||
not just ambient systemd process markers). The response includes
|
||||
`handoff.command`, the shell command to run from outside the Gateway.
|
||||
- `ok: false`, `result.reason: "managed-service-handoff-failed"`: the Gateway
|
||||
tried to create the handoff but could not spawn the detached helper.
|
||||
|
||||
The `sentinel` payload is written before the Gateway exits, and the CLI
|
||||
handoff updates that same restart sentinel after the managed-service restart
|
||||
health checks complete. During the handoff, the sentinel can carry
|
||||
`stats.reason: "restart-health-pending"` with no success continuation; the
|
||||
restarted Gateway polls it and fires the continuation only after the CLI has
|
||||
verified service health and rewritten the sentinel with the final `ok` result.
|
||||
`openclaw status` and `openclaw status --all` show an `Update restart` row
|
||||
while that sentinel is pending or failed, and `update.status` refreshes and
|
||||
returns the latest sentinel.
|
||||
|
||||
## Git checkout flow
|
||||
|
||||
### Channel selection
|
||||
|
||||
- `stable`: checkout the latest non-beta tag, then build and doctor.
|
||||
- `beta`: prefer the latest `-beta` tag, falling back to the latest stable tag
|
||||
when beta is missing or older.
|
||||
- `dev`: checkout `main`, then fetch and rebase.
|
||||
- `extended-stable`: unsupported for Git checkouts; no checkout mutation
|
||||
occurs.
|
||||
|
||||
### Update steps
|
||||
|
||||
<Steps>
|
||||
<Step title="Verify clean worktree">
|
||||
Requires no uncommitted changes.
|
||||
</Step>
|
||||
<Step title="Switch channel">
|
||||
Switches to the selected channel (tag or branch).
|
||||
</Step>
|
||||
<Step title="Fetch upstream">
|
||||
Dev only.
|
||||
</Step>
|
||||
<Step title="Preflight build (dev only)">
|
||||
Runs the TypeScript build in a temp worktree. If the tip fails, walks back up to 10 commits to find the newest buildable commit. Set `OPENCLAW_UPDATE_PREFLIGHT_LINT=1` to also run lint during this preflight; lint runs in constrained serial mode because user update hosts are often smaller than CI runners.
|
||||
</Step>
|
||||
<Step title="Rebase">
|
||||
Rebases onto the selected commit (dev only).
|
||||
</Step>
|
||||
<Step title="Install dependencies">
|
||||
Uses the repo package manager. For pnpm checkouts, the updater bootstraps `pnpm` on demand (via `corepack` first, then a temporary `npm install pnpm@11` fallback) instead of running `npm run build` inside a pnpm workspace. If pnpm bootstrap still fails, the updater stops early with a package-manager-specific error instead of trying `npm run build` in the checkout.
|
||||
</Step>
|
||||
<Step title="Build Control UI">
|
||||
Builds the gateway and the Control UI.
|
||||
</Step>
|
||||
<Step title="Run doctor">
|
||||
`openclaw doctor` runs as the final safe-update check.
|
||||
</Step>
|
||||
<Step title="Sync plugins">
|
||||
Syncs plugins to the active channel. Dev uses bundled plugins; stable and beta use npm. Updates tracked plugin installs.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Plugin sync details
|
||||
|
||||
On the beta channel, tracked npm and ClawHub plugin installs that follow the
|
||||
default/latest line try a plugin `@beta` release first. If the plugin has no
|
||||
beta release, OpenClaw falls back to the recorded default/latest spec and
|
||||
reports a warning. For npm plugins, OpenClaw also falls back when the beta
|
||||
package exists but fails install validation. These fallback warnings do not
|
||||
fail the core update. Exact versions and explicit tags are never rewritten.
|
||||
|
||||
<Warning>
|
||||
If an exact pinned npm plugin update resolves to an artifact whose integrity differs from the stored install record, `openclaw update` aborts that plugin artifact update instead of installing it. Reinstall or update the plugin explicitly only after verifying you trust the new artifact.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
Post-update plugin sync failures that are scoped to a managed plugin and that the sync path can route around (for example an unreachable npm registry for a non-essential plugin) are reported as warnings after the core update succeeds. The JSON result keeps top-level update `status: "ok"` and reports `postUpdate.plugins.status: "warning"` with `openclaw update repair` and `openclaw plugins inspect <id> --runtime --json` guidance. Unexpected updater or sync exceptions still fail the update result. Fix the plugin install or update error, then rerun `openclaw update repair`.
|
||||
|
||||
After the per-plugin sync step, `openclaw update` runs a mandatory **post-core convergence** pass before the gateway restarts: it repairs missing configured plugin payloads, validates each _active_ tracked install record on disk, and statically verifies its `package.json` is parseable (and any explicitly declared `main` exists). Failures from this pass, and an invalid config snapshot, return `postUpdate.plugins.status: "error"` and flip the top-level update `status` to `"error"`, so `openclaw update` exits non-zero and the gateway is _not_ restarted with an unverified plugin set. The error includes structured `postUpdate.plugins.warnings[].guidance` lines pointing at `openclaw update repair` and `openclaw plugins inspect <id> --runtime --json`. Disabled plugin entries and records that are not trusted-source-linked official sync targets are skipped here (mirroring the `skipDisabledPlugins` policy used by the missing-payload check), so a stale disabled plugin record cannot block an otherwise valid update.
|
||||
|
||||
When the updated Gateway starts, plugin loading is verify-only: startup does not run package managers or mutate dependency trees. Package-manager `update.run` restarts are handed to the CLI managed-service path, so the package swap happens outside the old Gateway process and the service health checks decide whether the update can be reported as complete.
|
||||
</Note>
|
||||
|
||||
After an extended-stable core update succeeds, post-core plugin integrity and
|
||||
convergence still run, but official plugins temporarily target the
|
||||
stable/latest line. OpenClaw does not query plugin `@extended-stable`
|
||||
selectors in this release.
|
||||
|
||||
For package-manager installs, `openclaw update` resolves the target package
|
||||
version before invoking the package manager. npm global installs use a staged
|
||||
install: OpenClaw installs the new package into a temporary npm prefix,
|
||||
verifies the packaged `dist` inventory there, then swaps that clean package
|
||||
tree into the real global prefix. If verification fails, post-update doctor,
|
||||
plugin sync, and restart work do not run from the suspect tree. Even when the
|
||||
installed version already matches the target, the command refreshes the
|
||||
global package install, then runs plugin sync, a core-command completion
|
||||
refresh, and restart work. This keeps packaged sidecars and channel-owned
|
||||
plugin records aligned with the installed OpenClaw build, while leaving full
|
||||
plugin-command completion rebuilds to explicit
|
||||
`openclaw completion --write-state` runs.
|
||||
|
||||
## Related
|
||||
|
||||
- `openclaw doctor` (offers to run update first on git checkouts)
|
||||
- [Development channels](/install/development-channels)
|
||||
- [Updating](/install/updating)
|
||||
- [CLI reference](/cli)
|
||||
212
docs/cli/voicecall.md
Normal file
212
docs/cli/voicecall.md
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw voicecall` (voice-call plugin command surface)"
|
||||
read_when:
|
||||
- You use the voice-call plugin and want every CLI entry point
|
||||
- You need flag tables and defaults for setup, smoke, call, continue, speak, dtmf, end, status, tail, latency, expose, and start
|
||||
title: "Voicecall"
|
||||
---
|
||||
|
||||
# `openclaw voicecall`
|
||||
|
||||
`voicecall` is a plugin-provided command. It only appears when the voice-call
|
||||
plugin is installed and enabled.
|
||||
|
||||
When the Gateway is running, operational commands (`call`, `start`,
|
||||
`continue`, `speak`, `dtmf`, `end`, `status`) route to that Gateway's
|
||||
voice-call runtime. If no Gateway is reachable, they fall back to a standalone
|
||||
CLI runtime.
|
||||
|
||||
## Subcommands
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup [--json]
|
||||
openclaw voicecall smoke [-t <phone>] [--message <text>] [--mode <m>] [--yes] [--json]
|
||||
openclaw voicecall call -m <text> [-t <phone>] [--mode <m>]
|
||||
openclaw voicecall start --to <phone> [--message <text>] [--mode <m>]
|
||||
openclaw voicecall continue --call-id <id> --message <text>
|
||||
openclaw voicecall speak --call-id <id> --message <text>
|
||||
openclaw voicecall dtmf --call-id <id> --digits <digits>
|
||||
openclaw voicecall end --call-id <id>
|
||||
openclaw voicecall status [--call-id <id>] [--json]
|
||||
openclaw voicecall tail [--file <path>] [--since <n>] [--poll <ms>]
|
||||
openclaw voicecall latency [--file <path>] [--last <n>]
|
||||
openclaw voicecall expose [--mode <m>] [--path <p>] [--port <port>] [--serve-path <p>]
|
||||
```
|
||||
|
||||
| Subcommand | Description |
|
||||
| ---------- | --------------------------------------------------------------- |
|
||||
| `setup` | Show provider and webhook readiness checks. |
|
||||
| `smoke` | Run readiness checks; place a live test call only with `--yes`. |
|
||||
| `call` | Initiate an outbound voice call. |
|
||||
| `start` | Alias for `call` with `--to` required and `--message` optional. |
|
||||
| `continue` | Speak a message and wait for the next response. |
|
||||
| `speak` | Speak a message without waiting for a response. |
|
||||
| `dtmf` | Send DTMF digits to an active call. |
|
||||
| `end` | Hang up an active call. |
|
||||
| `status` | Inspect active calls (or one by `--call-id`). |
|
||||
| `tail` | Tail `calls.jsonl` (useful during provider tests). |
|
||||
| `latency` | Summarize turn-latency metrics from `calls.jsonl`. |
|
||||
| `expose` | Toggle Tailscale serve/funnel for the webhook endpoint. |
|
||||
|
||||
## Setup and smoke
|
||||
|
||||
### `setup`
|
||||
|
||||
Prints human-readable readiness checks by default. Pass `--json` for scripts.
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall setup --json
|
||||
```
|
||||
|
||||
### `smoke`
|
||||
|
||||
Runs the same readiness checks. Places a real phone call only when both
|
||||
`--to` and `--yes` are present.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ------------------ | --------------------------------- | --------------------------------------- |
|
||||
| `-t, --to <phone>` | (none) | Phone number to call for a live smoke. |
|
||||
| `--message <text>` | `OpenClaw voice call smoke test.` | Message to speak during the smoke call. |
|
||||
| `--mode <mode>` | `notify` | Call mode: `notify` or `conversation`. |
|
||||
| `--yes` | `false` | Actually place the live outbound call. |
|
||||
| `--json` | `false` | Print machine-readable JSON. |
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall smoke --to "+15555550123" # dry run
|
||||
openclaw voicecall smoke --to "+15555550123" --yes # live notify call
|
||||
```
|
||||
|
||||
<Note>
|
||||
For external providers (`plivo`, `telnyx`, `twilio`), `setup` and `smoke` require a public webhook URL from `publicUrl`, a tunnel, or Tailscale exposure. A loopback or private serve fallback is rejected because carriers cannot reach it.
|
||||
</Note>
|
||||
|
||||
## Call lifecycle
|
||||
|
||||
### `call`
|
||||
|
||||
Initiate an outbound voice call.
|
||||
|
||||
| Flag | Required | Default | Description |
|
||||
| ---------------------- | -------- | ----------------- | -------------------------------------------------------------------------- |
|
||||
| `-m, --message <text>` | yes | (none) | Message to speak when the call connects. |
|
||||
| `-t, --to <phone>` | no | config `toNumber` | E.164 phone number to call. |
|
||||
| `--mode <mode>` | no | `conversation` | Call mode: `notify` (hang up after message) or `conversation` (stay open). |
|
||||
|
||||
```bash
|
||||
openclaw voicecall call --to "+15555550123" --message "Hello"
|
||||
openclaw voicecall call -m "Heads up" --mode notify
|
||||
```
|
||||
|
||||
### `start`
|
||||
|
||||
Alias for `call` with a different default flag shape.
|
||||
|
||||
| Flag | Required | Default | Description |
|
||||
| ------------------ | -------- | -------------- | ---------------------------------------- |
|
||||
| `--to <phone>` | yes | (none) | Phone number to call. |
|
||||
| `--message <text>` | no | (none) | Message to speak when the call connects. |
|
||||
| `--mode <mode>` | no | `conversation` | Call mode: `notify` or `conversation`. |
|
||||
|
||||
### `continue`
|
||||
|
||||
Speak a message and wait for a response.
|
||||
|
||||
| Flag | Required | Description |
|
||||
| ------------------ | -------- | ----------------- |
|
||||
| `--call-id <id>` | yes | Call ID. |
|
||||
| `--message <text>` | yes | Message to speak. |
|
||||
|
||||
### `speak`
|
||||
|
||||
Speak a message without waiting for a response.
|
||||
|
||||
| Flag | Required | Description |
|
||||
| ------------------ | -------- | ----------------- |
|
||||
| `--call-id <id>` | yes | Call ID. |
|
||||
| `--message <text>` | yes | Message to speak. |
|
||||
|
||||
### `dtmf`
|
||||
|
||||
Send DTMF digits to an active call.
|
||||
|
||||
| Flag | Required | Description |
|
||||
| ------------------- | -------- | ------------------------------------------------ |
|
||||
| `--call-id <id>` | yes | Call ID. |
|
||||
| `--digits <digits>` | yes | DTMF digits (for example `ww123456#` for waits). |
|
||||
|
||||
### `end`
|
||||
|
||||
Hang up an active call.
|
||||
|
||||
| Flag | Required | Description |
|
||||
| ---------------- | -------- | ----------- |
|
||||
| `--call-id <id>` | yes | Call ID. |
|
||||
|
||||
### `status`
|
||||
|
||||
Inspect active calls.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ---------------- | ------- | ---------------------------- |
|
||||
| `--call-id <id>` | (none) | Restrict output to one call. |
|
||||
| `--json` | `false` | Print machine-readable JSON. |
|
||||
|
||||
```bash
|
||||
openclaw voicecall status
|
||||
openclaw voicecall status --json
|
||||
openclaw voicecall status --call-id <id>
|
||||
```
|
||||
|
||||
## Logs and metrics
|
||||
|
||||
### `tail`
|
||||
|
||||
Tail the voice-call JSONL log. Prints the last `--since` lines on start, then
|
||||
streams new lines as they are written.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------- | -------------------------- | ------------------------------ |
|
||||
| `--file <path>` | resolved from plugin store | Path to `calls.jsonl`. |
|
||||
| `--since <n>` | `25` | Lines to print before tailing. |
|
||||
| `--poll <ms>` | `250` (minimum 50) | Poll interval in milliseconds. |
|
||||
|
||||
### `latency`
|
||||
|
||||
Summarize turn-latency and listen-wait metrics from `calls.jsonl`. Output is
|
||||
JSON with `recordsScanned`, `turnLatency`, and `listenWait` summaries.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------- | -------------------------- | ------------------------------------ |
|
||||
| `--file <path>` | resolved from plugin store | Path to `calls.jsonl`. |
|
||||
| `--last <n>` | `200` (minimum 1) | Number of recent records to analyze. |
|
||||
|
||||
## Exposing webhooks
|
||||
|
||||
### `expose`
|
||||
|
||||
Enable, disable, or change the Tailscale serve/funnel configuration for the
|
||||
voice webhook.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------------- | ----------------------------------------- | ----------------------------------------------- |
|
||||
| `--mode <mode>` | `funnel` | `off`, `serve` (tailnet), or `funnel` (public). |
|
||||
| `--path <path>` | config `tailscale.path` or `--serve-path` | Tailscale path to expose. |
|
||||
| `--port <port>` | config `serve.port` or `3334` | Local webhook port. |
|
||||
| `--serve-path <path>` | config `serve.path` or `/voice/webhook` | Local webhook path. |
|
||||
|
||||
```bash
|
||||
openclaw voicecall expose --mode serve
|
||||
openclaw voicecall expose --mode funnel
|
||||
openclaw voicecall expose --mode off
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Only expose the webhook endpoint to networks you trust. Prefer Tailscale Serve over Funnel when possible.
|
||||
</Warning>
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Voice call plugin](/plugins/voice-call)
|
||||
117
docs/cli/webhooks.md
Normal file
117
docs/cli/webhooks.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw webhooks` (Gmail Pub/Sub setup and runner)"
|
||||
read_when:
|
||||
- You want to wire Gmail Pub/Sub events into OpenClaw
|
||||
- You need the full flag list and default values
|
||||
title: "Webhooks"
|
||||
---
|
||||
|
||||
# `openclaw webhooks`
|
||||
|
||||
Webhook helpers and integrations. Today this surface is scoped to Gmail Pub/Sub flows built on the bundled `gog` watcher.
|
||||
|
||||
## Subcommands
|
||||
|
||||
```bash
|
||||
openclaw webhooks gmail setup --account <email> [...]
|
||||
openclaw webhooks gmail run [--account <email>] [...]
|
||||
```
|
||||
|
||||
| Subcommand | Description |
|
||||
| ------------- | ------------------------------------------------------------------------------------- |
|
||||
| `gmail setup` | One-time wizard: Gmail watch, Pub/Sub topic/subscription, and OpenClaw hook delivery. |
|
||||
| `gmail run` | Run `gog watch serve` plus the watch auto-renew loop in the foreground. |
|
||||
|
||||
<Note>
|
||||
The Gateway also auto-starts `gog gmail watch serve` on boot once `hooks.enabled=true` and `hooks.gmail.account` is set (set by `gmail setup`). `gmail run` is the same logic in the foreground, useful for debugging or when the Gateway watcher is disabled. See [Gmail Pub/Sub integration](/automation/cron-jobs#gmail-pubsub-integration) for the auto-start details and `OPENCLAW_SKIP_GMAIL_WATCHER` opt-out.
|
||||
</Note>
|
||||
|
||||
## `webhooks gmail setup`
|
||||
|
||||
```bash
|
||||
openclaw webhooks gmail setup --account you@example.com
|
||||
openclaw webhooks gmail setup --account you@example.com --project my-gcp-project --json
|
||||
openclaw webhooks gmail setup --account you@example.com --hook-url https://gateway.example.com/hooks/gmail
|
||||
```
|
||||
|
||||
Installs `gcloud` and `gog` if missing, authenticates `gcloud`, creates the Pub/Sub topic and subscription, starts the Gmail watch, and writes `hooks.gmail` config with `hooks.enabled=true`. Prints `Next: openclaw webhooks gmail run`.
|
||||
|
||||
### Required
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------- | ----------------------- |
|
||||
| `--account <email>` | Gmail account to watch. |
|
||||
|
||||
### Pub/Sub options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ----------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--project <id>` | (none) | GCP project id (the OAuth client owner). Falls back to the topic's own project id, then to the project resolved from `gog` credentials. |
|
||||
| `--topic <name>` | `gog-gmail-watch` | Pub/Sub topic name. |
|
||||
| `--subscription <name>` | `gog-gmail-watch-push` | Pub/Sub subscription name. |
|
||||
| `--label <label>` | `INBOX` | Gmail label to watch. |
|
||||
| `--push-endpoint <url>` | (none) | Explicit Pub/Sub push endpoint. Overrides Tailscale. |
|
||||
|
||||
### OpenClaw delivery options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ---------------------- | -------------------------------------------- | ------------------------------------------ |
|
||||
| `--hook-url <url>` | Built from `hooks.path` and the Gateway port | OpenClaw webhook URL. |
|
||||
| `--hook-token <token>` | `hooks.token`, or a generated token | OpenClaw webhook token. |
|
||||
| `--push-token <token>` | Generated token | Push token forwarded to `gog watch serve`. |
|
||||
|
||||
### `gog watch serve` options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--bind <host>` | `127.0.0.1` | `gog watch serve` bind host. |
|
||||
| `--port <port>` | `8788` | `gog watch serve` port. |
|
||||
| `--path <path>` | `/gmail-pubsub` | `gog watch serve` path. Forced to `/` when Tailscale is enabled without an explicit target, since Tailscale strips the path before proxying. |
|
||||
| `--include-body` | `true` | Include email body snippets. There is no CLI flag to turn this off; set `hooks.gmail.includeBody: false` in config instead. |
|
||||
| `--max-bytes <n>` | `20000` | Max bytes per body snippet. |
|
||||
| `--renew-minutes <n>` | `720` (12h) | Renew Gmail watch every N minutes. |
|
||||
|
||||
### Tailscale exposure
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ------------------------- | -------- | ---------------------------------------------------------------- |
|
||||
| `--tailscale <mode>` | `funnel` | Expose push endpoint via tailscale: `funnel`, `serve`, or `off`. |
|
||||
| `--tailscale-path <path>` | (none) | Path for tailscale serve/funnel. |
|
||||
| `--tailscale-target <t>` | (none) | Tailscale serve/funnel target (port, `host:port`, or URL). |
|
||||
|
||||
### Output
|
||||
|
||||
| Flag | Description |
|
||||
| -------- | ------------------------------------------------- |
|
||||
| `--json` | Print a machine-readable summary instead of text. |
|
||||
|
||||
## `webhooks gmail run`
|
||||
|
||||
```bash
|
||||
openclaw webhooks gmail run --account you@example.com
|
||||
```
|
||||
|
||||
Runs `gog watch serve` plus the watch auto-renew loop in the foreground, restarting `gog watch serve` after a 2s delay if it exits unexpectedly.
|
||||
|
||||
`run` accepts the same Pub/Sub, OpenClaw delivery, `gog watch serve`, and Tailscale flags as `setup`, except:
|
||||
|
||||
- `--account` is **optional** on `run`; it falls back to `hooks.gmail.account`.
|
||||
- `run` does **not** accept `--project`, `--push-endpoint`, or `--json`.
|
||||
- Every flag falls back to the matching `hooks.gmail.*` config value (written by `setup`), then to the same built-in default `setup` uses, with one exception: `--tailscale` defaults to `off` on `run` (not `funnel`) when neither the flag nor `hooks.gmail.tailscale.mode` is set.
|
||||
|
||||
| Category | Flags |
|
||||
| ----------------- | -------------------------------------------------------------------------------- |
|
||||
| Pub/Sub | `--account`, `--topic`, `--subscription`, `--label` |
|
||||
| OpenClaw delivery | `--hook-url`, `--hook-token`, `--push-token` |
|
||||
| `gog watch serve` | `--bind`, `--port`, `--path`, `--include-body`, `--max-bytes`, `--renew-minutes` |
|
||||
| Tailscale | `--tailscale`, `--tailscale-path`, `--tailscale-target` |
|
||||
|
||||
<Note>
|
||||
For `run`, the `--topic` value is the full Pub/Sub topic path (`projects/.../topics/...`), not just the short topic name.
|
||||
</Note>
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Webhook automation](/automation/webhook)
|
||||
- [Gmail Pub/Sub integration](/automation/cron-jobs#gmail-pubsub-integration)
|
||||
228
docs/cli/wiki.md
Normal file
228
docs/cli/wiki.md
Normal file
@@ -0,0 +1,228 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw wiki` (memory-wiki vault status, search, compile, lint, apply, bridge, ChatGPT import, and Obsidian helpers)"
|
||||
read_when:
|
||||
- You want to use the memory-wiki CLI
|
||||
- You are documenting or changing `openclaw wiki`
|
||||
title: "Wiki"
|
||||
---
|
||||
|
||||
# `openclaw wiki`
|
||||
|
||||
Inspect and maintain the `memory-wiki` vault. Provided by the bundled `memory-wiki` plugin.
|
||||
|
||||
Related: [Memory Wiki plugin](/plugins/memory-wiki), [Memory Overview](/concepts/memory), [CLI: memory](/cli/memory)
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
openclaw wiki status
|
||||
openclaw wiki doctor
|
||||
openclaw wiki init
|
||||
openclaw wiki ingest ./notes/alpha.md
|
||||
openclaw wiki okf import ./knowledge-catalog/okf/bundles/ga4
|
||||
openclaw wiki compile
|
||||
openclaw wiki lint
|
||||
openclaw wiki search "alpha"
|
||||
openclaw wiki search "who should I ask about Teams?" --mode route-question
|
||||
openclaw wiki get entity.alpha --from 1 --lines 80
|
||||
|
||||
openclaw wiki apply synthesis "Alpha Summary" \
|
||||
--body "Short synthesis body" \
|
||||
--source-id source.alpha
|
||||
|
||||
openclaw wiki apply metadata entity.alpha \
|
||||
--source-id source.alpha \
|
||||
--status review \
|
||||
--question "Still active?"
|
||||
|
||||
openclaw wiki bridge import
|
||||
openclaw wiki unsafe-local import
|
||||
openclaw wiki chatgpt import --export ./chatgpt-export --dry-run
|
||||
openclaw wiki chatgpt rollback <run-id>
|
||||
|
||||
openclaw wiki obsidian status
|
||||
openclaw wiki obsidian search "alpha"
|
||||
openclaw wiki obsidian open syntheses/alpha-summary.md
|
||||
openclaw wiki obsidian command workspace:quick-switcher
|
||||
openclaw wiki obsidian daily
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### `wiki status`
|
||||
|
||||
Show vault mode, health, and Obsidian CLI availability. Use this first to check whether the vault is initialized, bridge mode is healthy, or Obsidian integration is available.
|
||||
|
||||
When bridge mode is active and configured to read memory artifacts, this command queries the running Gateway so it sees the same active memory plugin context as agent/runtime memory.
|
||||
|
||||
### `wiki doctor`
|
||||
|
||||
Run wiki health checks and report actionable fixes. Exits non-zero when unhealthy.
|
||||
|
||||
When bridge mode is active and configured to read memory artifacts, this command queries the running Gateway before building the report. Disabled bridge imports and bridge configs that do not read memory artifacts stay local/offline.
|
||||
|
||||
Typical issues:
|
||||
|
||||
- bridge mode enabled without public memory artifacts
|
||||
- invalid or missing vault layout
|
||||
- missing external Obsidian CLI when Obsidian mode is expected
|
||||
|
||||
### `wiki init`
|
||||
|
||||
Create the wiki vault layout and starter pages, including top-level indexes and cache directories.
|
||||
|
||||
### `wiki ingest <path>`
|
||||
|
||||
Import a local markdown or text file into the wiki `sources/` folder as a source page. `<path>` must be a local file path; there is no URL ingest today. Rejects binary files.
|
||||
|
||||
Imported source pages carry provenance frontmatter (`sourceType: local-file`, `sourcePath`, `ingestedAt`). Ingest always recompiles the vault afterward.
|
||||
|
||||
Flags: `--title <title>` overrides the source title (default: derived from the filename).
|
||||
|
||||
### `wiki okf import <path>`
|
||||
|
||||
Import an unpacked Open Knowledge Format bundle into wiki concept pages.
|
||||
|
||||
The importer reads every non-reserved `.md` concept document in the OKF directory tree, requires a non-empty `type` field, and treats unknown OKF `type` values as generic concepts. Reserved OKF `index.md` and `log.md` files are not imported as concepts.
|
||||
|
||||
Imported pages are flattened under `concepts/` so existing wiki compile, search, get, digest, and dashboard flows see them immediately. The original OKF concept ID, `type`, `resource`, `tags`, timestamp, source path, and full frontmatter are preserved in the page frontmatter. Internal OKF markdown links are rewritten to the generated wiki pages; broken or external links are left unchanged. Import always recompiles the vault afterward.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw wiki okf import ./bundles/ga4
|
||||
openclaw wiki okf import ./bundles/ga4 --json
|
||||
openclaw wiki search "BigQuery Table" --mode source-evidence --json
|
||||
openclaw wiki get <path-from-json-result>
|
||||
```
|
||||
|
||||
### `wiki compile`
|
||||
|
||||
Rebuild indexes, related blocks, dashboards, and compiled digests. Writes stable machine-facing artifacts under:
|
||||
|
||||
- `.openclaw-wiki/cache/agent-digest.json`
|
||||
- `.openclaw-wiki/cache/claims.jsonl`
|
||||
|
||||
If `render.createDashboards` is enabled, compile also refreshes report pages.
|
||||
|
||||
### `wiki lint`
|
||||
|
||||
Lint the vault and write a report covering:
|
||||
|
||||
- structural issues (broken links, missing/duplicate ids, missing page type or title, invalid frontmatter)
|
||||
- provenance gaps (missing source ids, missing import provenance)
|
||||
- contradictions (flagged contradictions, conflicting claims)
|
||||
- open questions
|
||||
- low-confidence pages and claims
|
||||
- stale pages and claims
|
||||
|
||||
Run this after meaningful wiki updates.
|
||||
|
||||
### `wiki search <query>`
|
||||
|
||||
Search wiki content. Behavior depends on config:
|
||||
|
||||
- `search.backend`: `shared` or `local`
|
||||
- `search.corpus`: `wiki`, `memory`, or `all`
|
||||
- `--mode`: `auto`, `find-person`, `route-question`, `source-evidence`, or `raw-claim`
|
||||
|
||||
Use `wiki search` for wiki-specific ranking and provenance. For one broad shared recall pass, prefer `openclaw memory search` when the active memory plugin exposes shared search.
|
||||
|
||||
Search modes:
|
||||
|
||||
- `find-person`: aliases, handles, socials, canonical IDs, and person pages
|
||||
- `route-question`: ask-for/best-used-for hints and relationship context
|
||||
- `source-evidence`: source pages and structured evidence fields
|
||||
- `raw-claim`: structured claim text with claim/evidence metadata
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw wiki search "bgroux" --mode find-person
|
||||
openclaw wiki search "who knows Teams rollout?" --mode route-question
|
||||
openclaw wiki search "maintainer-whois" --mode source-evidence
|
||||
openclaw wiki search "strong route Teams" --mode raw-claim --json
|
||||
```
|
||||
|
||||
Text output includes `Claim:` and `Evidence:` lines when a result matches a structured claim. JSON output additionally exposes `matchedClaimId`, `matchedClaimStatus`, `matchedClaimConfidence`, `evidenceKinds`, and `evidenceSourceIds` for agent-side drilldown.
|
||||
|
||||
### `wiki get <lookup>`
|
||||
|
||||
Read a wiki page by id or relative path.
|
||||
|
||||
```bash
|
||||
openclaw wiki get entity.alpha
|
||||
openclaw wiki get syntheses/alpha-summary.md --from 1 --lines 80
|
||||
```
|
||||
|
||||
### `wiki apply`
|
||||
|
||||
Apply narrow mutations without freeform page surgery:
|
||||
|
||||
- `apply synthesis <title>`: create or refresh a synthesis page with a managed summary body
|
||||
- `apply metadata <lookup>`: update metadata on an existing page
|
||||
|
||||
Both accept `--source-id`, `--contradiction`, `--question` (each repeatable), `--confidence <n>` (0-1), and `--status <status>`. `apply metadata` also accepts `--clear-confidence` to remove a stored confidence value. This is the supported way to evolve wiki pages so managed generated blocks stay intact.
|
||||
|
||||
### `wiki bridge import`
|
||||
|
||||
Import public memory artifacts from the active memory plugin into bridge-backed source pages. Use this in `bridge` mode to pull the latest exported memory artifacts into the wiki vault.
|
||||
|
||||
For active bridge artifact reads, the CLI routes the import through Gateway RPC so it uses the runtime memory plugin context. If bridge imports are disabled or artifact reads are off, the command keeps the local/offline zero-import behavior. Index refresh after import is gated by `ingest.autoCompile`.
|
||||
|
||||
### `wiki unsafe-local import`
|
||||
|
||||
Import from explicitly configured local paths (`unsafeLocal.paths`) in `unsafe-local` mode. Intentionally experimental and same-machine only. Index refresh after import is gated by `ingest.autoCompile`.
|
||||
|
||||
### `wiki chatgpt import`
|
||||
|
||||
Import a ChatGPT export into draft wiki source pages.
|
||||
|
||||
```bash
|
||||
openclaw wiki chatgpt import --export ./chatgpt-export
|
||||
openclaw wiki chatgpt import --export ./conversations.json --dry-run
|
||||
```
|
||||
|
||||
| Flag | Default | Description |
|
||||
| ----------------- | ---------- | ------------------------------------------------------------- |
|
||||
| `--export <path>` | (required) | ChatGPT export directory or `conversations.json` path. |
|
||||
| `--dry-run` | `false` | Preview created/updated/skipped counts without writing pages. |
|
||||
|
||||
A non-dry-run import that changes any page records an import run id, printed in the summary, needed for rollback.
|
||||
|
||||
### `wiki chatgpt rollback <run-id>`
|
||||
|
||||
Roll back a previously applied ChatGPT import run, removing pages it created and restoring pages it overwrote. No-ops (and reports `alreadyRolledBack`) if the run was already rolled back.
|
||||
|
||||
### `wiki obsidian ...`
|
||||
|
||||
Obsidian helper commands for vaults running in Obsidian-friendly mode: `status`, `search`, `open`, `command`, `daily`. These require the official `obsidian` CLI on `PATH` when `obsidian.useOfficialCli` is enabled.
|
||||
|
||||
## Practical usage guidance
|
||||
|
||||
- Use `wiki search` + `wiki get` when provenance and page identity matter.
|
||||
- Use `wiki apply` instead of hand-editing managed generated sections.
|
||||
- Use `wiki lint` before trusting contradictory or low-confidence content.
|
||||
- Use `wiki compile` after bulk imports or source changes when you want fresh dashboards and compiled digests immediately.
|
||||
- Use `wiki okf import` when a data catalog, documentation export, or agent enrichment pipeline already emits OKF markdown bundles.
|
||||
- Use `wiki bridge import` when bridge mode depends on newly exported memory artifacts.
|
||||
|
||||
## Configuration tie-ins
|
||||
|
||||
`openclaw wiki` behavior is shaped by:
|
||||
|
||||
- `plugins.entries.memory-wiki.config.vaultMode`
|
||||
- `plugins.entries.memory-wiki.config.search.backend`
|
||||
- `plugins.entries.memory-wiki.config.search.corpus`
|
||||
- `plugins.entries.memory-wiki.config.bridge.*`
|
||||
- `plugins.entries.memory-wiki.config.obsidian.*`
|
||||
- `plugins.entries.memory-wiki.config.ingest.autoCompile`
|
||||
- `plugins.entries.memory-wiki.config.render.*`
|
||||
- `plugins.entries.memory-wiki.config.context.includeCompiledDigestPrompt`
|
||||
|
||||
See [Memory Wiki plugin](/plugins/memory-wiki) for the full config model.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Memory wiki](/plugins/memory-wiki)
|
||||
186
docs/cli/workboard.md
Normal file
186
docs/cli/workboard.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw workboard` cards, dispatch, and worker runs"
|
||||
read_when:
|
||||
- You want to inspect or create Workboard cards from the terminal
|
||||
- You want to dispatch Workboard worker runs from the CLI
|
||||
- You are debugging Workboard CLI or slash command behavior
|
||||
title: "Workboard CLI"
|
||||
---
|
||||
|
||||
`openclaw workboard` is the terminal surface for the bundled [Workboard plugin](/plugins/workboard). It lets an operator list cards, create a card, inspect one card, and ask the running Gateway to dispatch ready work into subagent worker runs.
|
||||
|
||||
Enable the plugin before using the command:
|
||||
|
||||
```bash
|
||||
openclaw plugins enable workboard
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
openclaw workboard list [--board <id>] [--status <status>] [--include-archived] [--json]
|
||||
openclaw workboard create <title...> [--notes <text>] [--status <status>] [--priority <priority>] [--agent <id>] [--board <id>] [--labels <items>] [--json]
|
||||
openclaw workboard show <id> [--json]
|
||||
openclaw workboard dispatch [--url <url>] [--token <token>] [--timeout <ms>] [--json]
|
||||
```
|
||||
|
||||
The command reads and writes the same plugin-owned SQLite database used by the dashboard and Workboard agent tools. Card ids are UUIDs; commands that accept a card id also accept an unambiguous id prefix (the compact text output shows the first 8 characters).
|
||||
|
||||
Valid `status` values: `triage`, `backlog`, `todo`, `scheduled`, `ready`, `running`, `review`, `blocked`, `done`. Valid `priority` values: `low`, `normal`, `high`, `urgent`.
|
||||
|
||||
## `list`
|
||||
|
||||
```bash
|
||||
openclaw workboard list
|
||||
openclaw workboard list --board default --status ready
|
||||
openclaw workboard list --json
|
||||
```
|
||||
|
||||
Text output is compact:
|
||||
|
||||
```text
|
||||
7f4a2c10 ready high default agent-a Fix stale worker heartbeat
|
||||
```
|
||||
|
||||
Columns are id prefix, status, priority, board id, optional agent id, and title.
|
||||
|
||||
| Flag | Purpose |
|
||||
| -------------------- | --------------------------------------------- |
|
||||
| `--board <id>` | Limit results to one board namespace |
|
||||
| `--status <status>` | Limit results to one Workboard status |
|
||||
| `--include-archived` | Include archived cards in compact text output |
|
||||
| `--json` | Print the full card list as machine JSON |
|
||||
|
||||
Compact text output hides archived cards by default so the CLI matches `/workboard list`. Pass `--include-archived` to show them. JSON output always keeps the full card list, including archived cards, for existing automation.
|
||||
|
||||
## `create`
|
||||
|
||||
```bash
|
||||
openclaw workboard create "Fix stale worker heartbeat" --priority high --labels bug,workboard
|
||||
openclaw workboard create "Write Workboard docs" --status ready --agent docs-agent --board docs --notes "Cover CLI, slash command, dispatch, and SQLite state."
|
||||
```
|
||||
|
||||
| Flag | Purpose |
|
||||
| ----------------------- | --------------------------------------- |
|
||||
| `--notes <text>` | Initial card notes |
|
||||
| `--status <status>` | Initial status, default `todo` |
|
||||
| `--priority <priority>` | Priority, default `normal` |
|
||||
| `--agent <id>` | Assign the card to an agent or owner id |
|
||||
| `--board <id>` | Store the card on a board namespace |
|
||||
| `--labels <items>` | Comma-separated labels |
|
||||
| `--json` | Print the created card as machine JSON |
|
||||
|
||||
`create` writes directly to Workboard SQLite state. The card is immediately visible in the Control UI Workboard tab and to Workboard tools.
|
||||
|
||||
## `show`
|
||||
|
||||
```bash
|
||||
openclaw workboard show 7f4a2c10
|
||||
openclaw workboard show 7f4a2c10 --json
|
||||
```
|
||||
|
||||
Text output prints the compact card line and notes. JSON output returns the full card record, including execution metadata, attempts, comments, links, proof, artifacts, worker logs, protocol state, diagnostics, and automation metadata.
|
||||
|
||||
## `dispatch`
|
||||
|
||||
```bash
|
||||
openclaw workboard dispatch
|
||||
openclaw workboard dispatch --json
|
||||
openclaw workboard dispatch --url http://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
```
|
||||
|
||||
`dispatch` first calls the running Gateway RPC method `workboard.cards.dispatch`, which uses the same subagent runtime as the dashboard dispatch action, so ready cards become task-tracked worker runs with linked session keys. Cards with an assigned agent use agent-scoped subagent session keys; unassigned cards keep an unscoped subagent key so the Gateway's configured default agent is preserved.
|
||||
|
||||
The dispatch loop:
|
||||
|
||||
1. Promotes dependency-ready children to `ready`.
|
||||
2. Blocks expired claims or timed-out worker runs.
|
||||
3. Records dispatch metadata on ready cards.
|
||||
4. Selects a small batch of unclaimed ready cards.
|
||||
5. Claims each selected card for the dispatcher or assigned agent.
|
||||
6. Starts a subagent worker run with bounded card context and the card claim token.
|
||||
7. Stores the worker run id, session key, task linkage when the Gateway task ledger reports it, execution status, and worker log on the card.
|
||||
|
||||
Selection is conservative: one dispatch starts at most three workers by default, skips archived or already-claimed cards, and starts only one card per owner or agent in a single pass. Cards already owned by active running or review work are left for a later dispatch.
|
||||
|
||||
If worker start fails after a card is claimed, Workboard blocks that card, clears the claim, and records the failure in card execution and worker-log metadata, keeping failed starts visible instead of silently returning the card to the queue.
|
||||
|
||||
If no explicit Gateway target is given and the local Gateway is unavailable or does not expose the Workboard dispatch method yet, the CLI falls back to data-only dispatch against local Workboard state. Data-only dispatch can still promote dependencies, clean stale claims, and block timed-out runs, but it does not start workers. Auth, permission, and validation failures, and failures for an explicit `--url` or `--token` target, are reported directly instead of triggering the fallback.
|
||||
|
||||
Text output reports worker starts:
|
||||
|
||||
```text
|
||||
dispatch complete: started=2 failures=0
|
||||
```
|
||||
|
||||
Fallback output is explicit:
|
||||
|
||||
```text
|
||||
gateway unavailable; data dispatch only: promoted=1 blocked=0
|
||||
```
|
||||
|
||||
JSON output includes the dispatch result. Gateway-backed dispatch can include `started` and `startFailures`; data-only fallback includes `gatewayUnavailable: true`. Claim tokens are redacted from card JSON output.
|
||||
|
||||
In the dashboard, the same dispatch result is shown as a short summary so an operator can see how many cards started, promoted, blocked, reclaimed, or failed without opening card details.
|
||||
|
||||
## Slash command parity
|
||||
|
||||
Command-capable channels can use the matching slash command:
|
||||
|
||||
```text
|
||||
/workboard list
|
||||
/workboard show 7f4a2c10
|
||||
/workboard create Fix stale worker heartbeat
|
||||
/workboard dispatch
|
||||
```
|
||||
|
||||
Slash command dispatch also uses the Gateway subagent runtime, so it follows the same claim, worker-start, and failure behavior as the dashboard and CLI Gateway path.
|
||||
|
||||
`/workboard list` and `/workboard show` are read commands for authorized command senders. `/workboard create` and `/workboard dispatch` mutate board state and require owner status on chat surfaces or a Gateway client with `operator.write` or `operator.admin`.
|
||||
|
||||
## Permissions
|
||||
|
||||
The CLI dispatch path calls Gateway RPC with `operator.read` and `operator.write` scopes. A read-only Gateway token can inspect Workboard data through read methods, but it cannot create cards or dispatch workers.
|
||||
|
||||
Local `list`, `create`, and `show` commands operate on the local OpenClaw state directory used by the current profile. Use `--dev` or `--profile <name>` on the top-level `openclaw` command when you need a different state root.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### No cards appear
|
||||
|
||||
Confirm the plugin is enabled for the same profile and state root:
|
||||
|
||||
```bash
|
||||
openclaw plugins inspect workboard --runtime --json
|
||||
```
|
||||
|
||||
If the dashboard shows cards but the CLI does not, check that both commands use the same `--dev` or `--profile` setting.
|
||||
|
||||
### Dispatch says data-only
|
||||
|
||||
Start or restart the Gateway:
|
||||
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
openclaw gateway status --deep
|
||||
```
|
||||
|
||||
Then retry `openclaw workboard dispatch`. Data-only fallback is useful for local state cleanup, but worker runs need a live Gateway.
|
||||
|
||||
### Dispatch starts nothing
|
||||
|
||||
Check for at least one `ready` card without an active claim:
|
||||
|
||||
```bash
|
||||
openclaw workboard list --status ready
|
||||
```
|
||||
|
||||
Cards can also be skipped when the same owner already has running or review work. Move completed work to `done`, release stale claims through the Workboard tools, or run dispatch again after the active worker finishes.
|
||||
|
||||
## Related
|
||||
|
||||
- [Workboard plugin](/plugins/workboard)
|
||||
- [CLI reference](/cli)
|
||||
- [Slash commands](/tools/slash-commands)
|
||||
- [Control UI](/web/control-ui)
|
||||
Reference in New Issue
Block a user