chore(sync): mirror docs from openclaw/openclaw@f4d73e1dcd
This commit is contained in:
parent
41324cec2b
commit
5e7014e87d
@ -1,5 +1,5 @@
|
||||
{
|
||||
"repository": "openclaw/openclaw",
|
||||
"sha": "04066d246abc4e13a9507e1a93e12be75ae41753",
|
||||
"syncedAt": "2026-04-24T02:34:33.017Z"
|
||||
"sha": "f4d73e1dcdaaee30c863f75b35205fad3b8440cd",
|
||||
"syncedAt": "2026-04-24T02:37:18.500Z"
|
||||
}
|
||||
|
||||
@ -167,8 +167,8 @@ 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#plugin-tools-mcp-bridge) and
|
||||
[OpenClaw tools MCP bridge](/tools/acp-agents#openclaw-tools-mcp-bridge).
|
||||
[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)
|
||||
|
||||
|
||||
@ -1221,6 +1221,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"tools/browser",
|
||||
"tools/browser-control",
|
||||
"tools/browser-login",
|
||||
"tools/browser-linux-troubleshooting",
|
||||
"tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -1253,6 +1254,7 @@
|
||||
"tools/agent-send",
|
||||
"tools/subagents",
|
||||
"tools/acp-agents",
|
||||
"tools/acp-agents-setup",
|
||||
"tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -2615,6 +2617,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"ja-JP/tools/browser",
|
||||
"ja-JP/tools/browser-control",
|
||||
"ja-JP/tools/browser-login",
|
||||
"ja-JP/tools/browser-linux-troubleshooting",
|
||||
"ja-JP/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -2647,6 +2650,7 @@
|
||||
"ja-JP/tools/agent-send",
|
||||
"ja-JP/tools/subagents",
|
||||
"ja-JP/tools/acp-agents",
|
||||
"ja-JP/tools/acp-agents-setup",
|
||||
"ja-JP/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -3394,6 +3398,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"es/tools/browser",
|
||||
"es/tools/browser-control",
|
||||
"es/tools/browser-login",
|
||||
"es/tools/browser-linux-troubleshooting",
|
||||
"es/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -3426,6 +3431,7 @@
|
||||
"es/tools/agent-send",
|
||||
"es/tools/subagents",
|
||||
"es/tools/acp-agents",
|
||||
"es/tools/acp-agents-setup",
|
||||
"es/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -4173,6 +4179,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"pt-BR/tools/browser",
|
||||
"pt-BR/tools/browser-control",
|
||||
"pt-BR/tools/browser-login",
|
||||
"pt-BR/tools/browser-linux-troubleshooting",
|
||||
"pt-BR/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -4205,6 +4212,7 @@
|
||||
"pt-BR/tools/agent-send",
|
||||
"pt-BR/tools/subagents",
|
||||
"pt-BR/tools/acp-agents",
|
||||
"pt-BR/tools/acp-agents-setup",
|
||||
"pt-BR/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -4952,6 +4960,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"ko/tools/browser",
|
||||
"ko/tools/browser-control",
|
||||
"ko/tools/browser-login",
|
||||
"ko/tools/browser-linux-troubleshooting",
|
||||
"ko/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -4984,6 +4993,7 @@
|
||||
"ko/tools/agent-send",
|
||||
"ko/tools/subagents",
|
||||
"ko/tools/acp-agents",
|
||||
"ko/tools/acp-agents-setup",
|
||||
"ko/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -5731,6 +5741,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"de/tools/browser",
|
||||
"de/tools/browser-control",
|
||||
"de/tools/browser-login",
|
||||
"de/tools/browser-linux-troubleshooting",
|
||||
"de/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -5763,6 +5774,7 @@
|
||||
"de/tools/agent-send",
|
||||
"de/tools/subagents",
|
||||
"de/tools/acp-agents",
|
||||
"de/tools/acp-agents-setup",
|
||||
"de/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -6510,6 +6522,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"fr/tools/browser",
|
||||
"fr/tools/browser-control",
|
||||
"fr/tools/browser-login",
|
||||
"fr/tools/browser-linux-troubleshooting",
|
||||
"fr/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -6542,6 +6555,7 @@
|
||||
"fr/tools/agent-send",
|
||||
"fr/tools/subagents",
|
||||
"fr/tools/acp-agents",
|
||||
"fr/tools/acp-agents-setup",
|
||||
"fr/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -7289,6 +7303,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"ar/tools/browser",
|
||||
"ar/tools/browser-control",
|
||||
"ar/tools/browser-login",
|
||||
"ar/tools/browser-linux-troubleshooting",
|
||||
"ar/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -7321,6 +7336,7 @@
|
||||
"ar/tools/agent-send",
|
||||
"ar/tools/subagents",
|
||||
"ar/tools/acp-agents",
|
||||
"ar/tools/acp-agents-setup",
|
||||
"ar/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -8068,6 +8084,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"it/tools/browser",
|
||||
"it/tools/browser-control",
|
||||
"it/tools/browser-login",
|
||||
"it/tools/browser-linux-troubleshooting",
|
||||
"it/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -8100,6 +8117,7 @@
|
||||
"it/tools/agent-send",
|
||||
"it/tools/subagents",
|
||||
"it/tools/acp-agents",
|
||||
"it/tools/acp-agents-setup",
|
||||
"it/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -8847,6 +8865,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"tr/tools/browser",
|
||||
"tr/tools/browser-control",
|
||||
"tr/tools/browser-login",
|
||||
"tr/tools/browser-linux-troubleshooting",
|
||||
"tr/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -8879,6 +8898,7 @@
|
||||
"tr/tools/agent-send",
|
||||
"tr/tools/subagents",
|
||||
"tr/tools/acp-agents",
|
||||
"tr/tools/acp-agents-setup",
|
||||
"tr/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -9626,6 +9646,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"uk/tools/browser",
|
||||
"uk/tools/browser-control",
|
||||
"uk/tools/browser-login",
|
||||
"uk/tools/browser-linux-troubleshooting",
|
||||
"uk/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -9658,6 +9679,7 @@
|
||||
"uk/tools/agent-send",
|
||||
"uk/tools/subagents",
|
||||
"uk/tools/acp-agents",
|
||||
"uk/tools/acp-agents-setup",
|
||||
"uk/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -10405,6 +10427,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"id/tools/browser",
|
||||
"id/tools/browser-control",
|
||||
"id/tools/browser-login",
|
||||
"id/tools/browser-linux-troubleshooting",
|
||||
"id/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -10437,6 +10460,7 @@
|
||||
"id/tools/agent-send",
|
||||
"id/tools/subagents",
|
||||
"id/tools/acp-agents",
|
||||
"id/tools/acp-agents-setup",
|
||||
"id/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
@ -11184,6 +11208,7 @@
|
||||
"group": "Web Browser",
|
||||
"pages": [
|
||||
"pl/tools/browser",
|
||||
"pl/tools/browser-control",
|
||||
"pl/tools/browser-login",
|
||||
"pl/tools/browser-linux-troubleshooting",
|
||||
"pl/tools/browser-wsl2-windows-remote-cdp-troubleshooting"
|
||||
@ -11216,6 +11241,7 @@
|
||||
"pl/tools/agent-send",
|
||||
"pl/tools/subagents",
|
||||
"pl/tools/acp-agents",
|
||||
"pl/tools/acp-agents-setup",
|
||||
"pl/tools/multi-agent-sandbox-tools"
|
||||
]
|
||||
}
|
||||
|
||||
291
docs/tools/acp-agents-setup.md
Normal file
291
docs/tools/acp-agents-setup.md
Normal file
@ -0,0 +1,291 @@
|
||||
---
|
||||
summary: "Setting up ACP agents: acpx harness config, plugin setup, permissions"
|
||||
read_when:
|
||||
- Installing or configuring the acpx harness for Claude Code / Codex / Gemini CLI
|
||||
- Enabling the plugin-tools or OpenClaw-tools MCP bridge
|
||||
- Configuring ACP permission modes
|
||||
title: "ACP agents — setup"
|
||||
---
|
||||
|
||||
For the overview, operator runbook, and concepts, see [ACP agents](/tools/acp-agents).
|
||||
This page covers acpx harness config, plugin setup for the MCP bridges, and
|
||||
permission configuration.
|
||||
|
||||
## acpx harness support (current)
|
||||
|
||||
Current acpx built-in harness aliases:
|
||||
|
||||
- `claude`
|
||||
- `codex`
|
||||
- `copilot`
|
||||
- `cursor` (Cursor CLI: `cursor-agent acp`)
|
||||
- `droid`
|
||||
- `gemini`
|
||||
- `iflow`
|
||||
- `kilocode`
|
||||
- `kimi`
|
||||
- `kiro`
|
||||
- `openclaw`
|
||||
- `opencode`
|
||||
- `pi`
|
||||
- `qwen`
|
||||
|
||||
When OpenClaw uses the acpx backend, prefer these values for `agentId` unless your acpx config defines custom agent aliases.
|
||||
If your local Cursor install still exposes ACP as `agent acp`, override the `cursor` agent command in your acpx config instead of changing the built-in default.
|
||||
|
||||
Direct acpx CLI usage can also target arbitrary adapters via `--agent <command>`, but that raw escape hatch is an acpx CLI feature (not the normal OpenClaw `agentId` path).
|
||||
|
||||
## Required config
|
||||
|
||||
Core ACP baseline:
|
||||
|
||||
```json5
|
||||
{
|
||||
acp: {
|
||||
enabled: true,
|
||||
// Optional. Default is true; set false to pause ACP dispatch while keeping /acp controls.
|
||||
dispatch: { enabled: true },
|
||||
backend: "acpx",
|
||||
defaultAgent: "codex",
|
||||
allowedAgents: [
|
||||
"claude",
|
||||
"codex",
|
||||
"copilot",
|
||||
"cursor",
|
||||
"droid",
|
||||
"gemini",
|
||||
"iflow",
|
||||
"kilocode",
|
||||
"kimi",
|
||||
"kiro",
|
||||
"openclaw",
|
||||
"opencode",
|
||||
"pi",
|
||||
"qwen",
|
||||
],
|
||||
maxConcurrentSessions: 8,
|
||||
stream: {
|
||||
coalesceIdleMs: 300,
|
||||
maxChunkChars: 1200,
|
||||
},
|
||||
runtime: {
|
||||
ttlMinutes: 120,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Thread binding config is channel-adapter specific. Example for Discord:
|
||||
|
||||
```json5
|
||||
{
|
||||
session: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
idleHours: 24,
|
||||
maxAgeHours: 0,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
spawnAcpSessions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
If thread-bound ACP spawn does not work, verify the adapter feature flag first:
|
||||
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
|
||||
Current-conversation binds do not require child-thread creation. They require an active conversation context and a channel adapter that exposes ACP conversation bindings.
|
||||
|
||||
See [Configuration Reference](/gateway/configuration-reference).
|
||||
|
||||
## Plugin setup for acpx backend
|
||||
|
||||
Fresh installs ship the bundled `acpx` runtime plugin enabled by default, so ACP
|
||||
usually works without a manual plugin install step.
|
||||
|
||||
Start with:
|
||||
|
||||
```text
|
||||
/acp doctor
|
||||
```
|
||||
|
||||
If you disabled `acpx`, denied it via `plugins.allow` / `plugins.deny`, or want
|
||||
to switch to a local development checkout, use the explicit plugin path:
|
||||
|
||||
```bash
|
||||
openclaw plugins install acpx
|
||||
openclaw config set plugins.entries.acpx.enabled true
|
||||
```
|
||||
|
||||
Local workspace install during development:
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/acpx-plugin
|
||||
```
|
||||
|
||||
Then verify backend health:
|
||||
|
||||
```text
|
||||
/acp doctor
|
||||
```
|
||||
|
||||
### acpx command and version configuration
|
||||
|
||||
By default, the bundled `acpx` plugin uses its plugin-local pinned binary (`node_modules/.bin/acpx` inside the plugin package). Startup registers the backend as not-ready and a background job verifies `acpx --version`; if the binary is missing or mismatched, it runs `npm install --omit=dev --no-save acpx@<pinned>` and re-verifies. The gateway stays non-blocking throughout.
|
||||
|
||||
Override the command or version in plugin config:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"acpx": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"command": "../acpx/dist/cli.js",
|
||||
"expectedVersion": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `command` accepts an absolute path, relative path (resolved from the OpenClaw workspace), or command name.
|
||||
- `expectedVersion: "any"` disables strict version matching.
|
||||
- Custom `command` paths disable plugin-local auto-install.
|
||||
|
||||
See [Plugins](/tools/plugin).
|
||||
|
||||
### Automatic dependency install
|
||||
|
||||
When you install OpenClaw globally with `npm install -g openclaw`, the acpx
|
||||
runtime dependencies (platform-specific binaries) are installed automatically
|
||||
via a postinstall hook. If the automatic install fails, the gateway still starts
|
||||
normally and reports the missing dependency through `openclaw acp doctor`.
|
||||
|
||||
### Plugin tools MCP bridge
|
||||
|
||||
By default, ACPX sessions do **not** expose OpenClaw plugin-registered tools to
|
||||
the ACP harness.
|
||||
|
||||
If you want ACP agents such as Codex or Claude Code to call installed
|
||||
OpenClaw plugin tools such as memory recall/store, enable the dedicated bridge:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true
|
||||
```
|
||||
|
||||
What this does:
|
||||
|
||||
- Injects a built-in MCP server named `openclaw-plugin-tools` into ACPX session
|
||||
bootstrap.
|
||||
- Exposes plugin tools already registered by installed and enabled OpenClaw
|
||||
plugins.
|
||||
- Keeps the feature explicit and default-off.
|
||||
|
||||
Security and trust notes:
|
||||
|
||||
- This expands the ACP harness tool surface.
|
||||
- ACP agents get access only to plugin tools already active in the gateway.
|
||||
- Treat this as the same trust boundary as letting those plugins execute in
|
||||
OpenClaw itself.
|
||||
- Review installed plugins before enabling it.
|
||||
|
||||
Custom `mcpServers` still work as before. The built-in plugin-tools bridge is an
|
||||
additional opt-in convenience, not a replacement for generic MCP server config.
|
||||
|
||||
### OpenClaw tools MCP bridge
|
||||
|
||||
By default, ACPX sessions also do **not** expose built-in OpenClaw tools through
|
||||
MCP. Enable the separate core-tools bridge when an ACP agent needs selected
|
||||
built-in tools such as `cron`:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.openClawToolsMcpBridge true
|
||||
```
|
||||
|
||||
What this does:
|
||||
|
||||
- Injects a built-in MCP server named `openclaw-tools` into ACPX session
|
||||
bootstrap.
|
||||
- Exposes selected built-in OpenClaw tools. The initial server exposes `cron`.
|
||||
- Keeps core-tool exposure explicit and default-off.
|
||||
|
||||
### Runtime timeout configuration
|
||||
|
||||
The bundled `acpx` plugin defaults embedded runtime turns to a 120-second
|
||||
timeout. This gives slower harnesses such as Gemini CLI enough time to complete
|
||||
ACP startup and initialization. Override it if your host needs a different
|
||||
runtime limit:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.timeoutSeconds 180
|
||||
```
|
||||
|
||||
Restart the gateway after changing this value.
|
||||
|
||||
### Health probe agent configuration
|
||||
|
||||
The bundled `acpx` plugin probes one harness agent while deciding whether the
|
||||
embedded runtime backend is ready. It defaults to `codex`. If your deployment
|
||||
uses a different default ACP agent, set the probe agent to the same id:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.probeAgent claude
|
||||
```
|
||||
|
||||
Restart the gateway after changing this value.
|
||||
|
||||
## Permission configuration
|
||||
|
||||
ACP sessions run non-interactively — there is no TTY to approve or deny file-write and shell-exec permission prompts. The acpx plugin provides two config keys that control how permissions are handled:
|
||||
|
||||
These ACPX harness permissions are separate from OpenClaw exec approvals and separate from CLI-backend vendor bypass flags such as Claude CLI `--permission-mode bypassPermissions`. ACPX `approve-all` is the harness-level break-glass switch for ACP sessions.
|
||||
|
||||
### `permissionMode`
|
||||
|
||||
Controls which operations the harness agent can perform without prompting.
|
||||
|
||||
| Value | Behavior |
|
||||
| --------------- | --------------------------------------------------------- |
|
||||
| `approve-all` | Auto-approve all file writes and shell commands. |
|
||||
| `approve-reads` | Auto-approve reads only; writes and exec require prompts. |
|
||||
| `deny-all` | Deny all permission prompts. |
|
||||
|
||||
### `nonInteractivePermissions`
|
||||
|
||||
Controls what happens when a permission prompt would be shown but no interactive TTY is available (which is always the case for ACP sessions).
|
||||
|
||||
| Value | Behavior |
|
||||
| ------ | ----------------------------------------------------------------- |
|
||||
| `fail` | Abort the session with `AcpRuntimeError`. **(default)** |
|
||||
| `deny` | Silently deny the permission and continue (graceful degradation). |
|
||||
|
||||
### Configuration
|
||||
|
||||
Set via plugin config:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.permissionMode approve-all
|
||||
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail
|
||||
```
|
||||
|
||||
Restart the gateway after changing these values.
|
||||
|
||||
> **Important:** OpenClaw currently defaults to `permissionMode=approve-reads` and `nonInteractivePermissions=fail`. In non-interactive ACP sessions, any write or exec that triggers a permission prompt can fail with `AcpRuntimeError: Permission prompt unavailable in non-interactive mode`.
|
||||
>
|
||||
> If you need to restrict permissions, set `nonInteractivePermissions` to `deny` so sessions degrade gracefully instead of crashing.
|
||||
|
||||
## Related
|
||||
|
||||
- [ACP agents](/tools/acp-agents) — overview, operator runbook, concepts
|
||||
- [Sub-agents](/tools/subagents)
|
||||
- [Multi-agent routing](/concepts/multi-agent)
|
||||
@ -507,278 +507,11 @@ Equivalent operations:
|
||||
- Special case: `key=cwd` uses the cwd override path.
|
||||
- `/acp reset-options` clears all runtime overrides for target session.
|
||||
|
||||
## acpx harness support (current)
|
||||
## acpx harness, plugin setup, and permissions
|
||||
|
||||
Current acpx built-in harness aliases:
|
||||
|
||||
- `claude`
|
||||
- `codex`
|
||||
- `copilot`
|
||||
- `cursor` (Cursor CLI: `cursor-agent acp`)
|
||||
- `droid`
|
||||
- `gemini`
|
||||
- `iflow`
|
||||
- `kilocode`
|
||||
- `kimi`
|
||||
- `kiro`
|
||||
- `openclaw`
|
||||
- `opencode`
|
||||
- `pi`
|
||||
- `qwen`
|
||||
|
||||
When OpenClaw uses the acpx backend, prefer these values for `agentId` unless your acpx config defines custom agent aliases.
|
||||
If your local Cursor install still exposes ACP as `agent acp`, override the `cursor` agent command in your acpx config instead of changing the built-in default.
|
||||
|
||||
Direct acpx CLI usage can also target arbitrary adapters via `--agent <command>`, but that raw escape hatch is an acpx CLI feature (not the normal OpenClaw `agentId` path).
|
||||
|
||||
## Required config
|
||||
|
||||
Core ACP baseline:
|
||||
|
||||
```json5
|
||||
{
|
||||
acp: {
|
||||
enabled: true,
|
||||
// Optional. Default is true; set false to pause ACP dispatch while keeping /acp controls.
|
||||
dispatch: { enabled: true },
|
||||
backend: "acpx",
|
||||
defaultAgent: "codex",
|
||||
allowedAgents: [
|
||||
"claude",
|
||||
"codex",
|
||||
"copilot",
|
||||
"cursor",
|
||||
"droid",
|
||||
"gemini",
|
||||
"iflow",
|
||||
"kilocode",
|
||||
"kimi",
|
||||
"kiro",
|
||||
"openclaw",
|
||||
"opencode",
|
||||
"pi",
|
||||
"qwen",
|
||||
],
|
||||
maxConcurrentSessions: 8,
|
||||
stream: {
|
||||
coalesceIdleMs: 300,
|
||||
maxChunkChars: 1200,
|
||||
},
|
||||
runtime: {
|
||||
ttlMinutes: 120,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Thread binding config is channel-adapter specific. Example for Discord:
|
||||
|
||||
```json5
|
||||
{
|
||||
session: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
idleHours: 24,
|
||||
maxAgeHours: 0,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
spawnAcpSessions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
If thread-bound ACP spawn does not work, verify the adapter feature flag first:
|
||||
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
|
||||
Current-conversation binds do not require child-thread creation. They require an active conversation context and a channel adapter that exposes ACP conversation bindings.
|
||||
|
||||
See [Configuration Reference](/gateway/configuration-reference).
|
||||
|
||||
## Plugin setup for acpx backend
|
||||
|
||||
Fresh installs ship the bundled `acpx` runtime plugin enabled by default, so ACP
|
||||
usually works without a manual plugin install step.
|
||||
|
||||
Start with:
|
||||
|
||||
```text
|
||||
/acp doctor
|
||||
```
|
||||
|
||||
If you disabled `acpx`, denied it via `plugins.allow` / `plugins.deny`, or want
|
||||
to switch to a local development checkout, use the explicit plugin path:
|
||||
|
||||
```bash
|
||||
openclaw plugins install acpx
|
||||
openclaw config set plugins.entries.acpx.enabled true
|
||||
```
|
||||
|
||||
Local workspace install during development:
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/acpx-plugin
|
||||
```
|
||||
|
||||
Then verify backend health:
|
||||
|
||||
```text
|
||||
/acp doctor
|
||||
```
|
||||
|
||||
### acpx command and version configuration
|
||||
|
||||
By default, the bundled `acpx` plugin uses its plugin-local pinned binary (`node_modules/.bin/acpx` inside the plugin package). Startup registers the backend as not-ready and a background job verifies `acpx --version`; if the binary is missing or mismatched, it runs `npm install --omit=dev --no-save acpx@<pinned>` and re-verifies. The gateway stays non-blocking throughout.
|
||||
|
||||
Override the command or version in plugin config:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"acpx": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"command": "../acpx/dist/cli.js",
|
||||
"expectedVersion": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `command` accepts an absolute path, relative path (resolved from the OpenClaw workspace), or command name.
|
||||
- `expectedVersion: "any"` disables strict version matching.
|
||||
- Custom `command` paths disable plugin-local auto-install.
|
||||
|
||||
See [Plugins](/tools/plugin).
|
||||
|
||||
### Automatic dependency install
|
||||
|
||||
When you install OpenClaw globally with `npm install -g openclaw`, the acpx
|
||||
runtime dependencies (platform-specific binaries) are installed automatically
|
||||
via a postinstall hook. If the automatic install fails, the gateway still starts
|
||||
normally and reports the missing dependency through `openclaw acp doctor`.
|
||||
|
||||
### Plugin tools MCP bridge
|
||||
|
||||
By default, ACPX sessions do **not** expose OpenClaw plugin-registered tools to
|
||||
the ACP harness.
|
||||
|
||||
If you want ACP agents such as Codex or Claude Code to call installed
|
||||
OpenClaw plugin tools such as memory recall/store, enable the dedicated bridge:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true
|
||||
```
|
||||
|
||||
What this does:
|
||||
|
||||
- Injects a built-in MCP server named `openclaw-plugin-tools` into ACPX session
|
||||
bootstrap.
|
||||
- Exposes plugin tools already registered by installed and enabled OpenClaw
|
||||
plugins.
|
||||
- Keeps the feature explicit and default-off.
|
||||
|
||||
Security and trust notes:
|
||||
|
||||
- This expands the ACP harness tool surface.
|
||||
- ACP agents get access only to plugin tools already active in the gateway.
|
||||
- Treat this as the same trust boundary as letting those plugins execute in
|
||||
OpenClaw itself.
|
||||
- Review installed plugins before enabling it.
|
||||
|
||||
Custom `mcpServers` still work as before. The built-in plugin-tools bridge is an
|
||||
additional opt-in convenience, not a replacement for generic MCP server config.
|
||||
|
||||
### OpenClaw tools MCP bridge
|
||||
|
||||
By default, ACPX sessions also do **not** expose built-in OpenClaw tools through
|
||||
MCP. Enable the separate core-tools bridge when an ACP agent needs selected
|
||||
built-in tools such as `cron`:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.openClawToolsMcpBridge true
|
||||
```
|
||||
|
||||
What this does:
|
||||
|
||||
- Injects a built-in MCP server named `openclaw-tools` into ACPX session
|
||||
bootstrap.
|
||||
- Exposes selected built-in OpenClaw tools. The initial server exposes `cron`.
|
||||
- Keeps core-tool exposure explicit and default-off.
|
||||
|
||||
### Runtime timeout configuration
|
||||
|
||||
The bundled `acpx` plugin defaults embedded runtime turns to a 120-second
|
||||
timeout. This gives slower harnesses such as Gemini CLI enough time to complete
|
||||
ACP startup and initialization. Override it if your host needs a different
|
||||
runtime limit:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.timeoutSeconds 180
|
||||
```
|
||||
|
||||
Restart the gateway after changing this value.
|
||||
|
||||
### Health probe agent configuration
|
||||
|
||||
The bundled `acpx` plugin probes one harness agent while deciding whether the
|
||||
embedded runtime backend is ready. It defaults to `codex`. If your deployment
|
||||
uses a different default ACP agent, set the probe agent to the same id:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.probeAgent claude
|
||||
```
|
||||
|
||||
Restart the gateway after changing this value.
|
||||
|
||||
## Permission configuration
|
||||
|
||||
ACP sessions run non-interactively — there is no TTY to approve or deny file-write and shell-exec permission prompts. The acpx plugin provides two config keys that control how permissions are handled:
|
||||
|
||||
These ACPX harness permissions are separate from OpenClaw exec approvals and separate from CLI-backend vendor bypass flags such as Claude CLI `--permission-mode bypassPermissions`. ACPX `approve-all` is the harness-level break-glass switch for ACP sessions.
|
||||
|
||||
### `permissionMode`
|
||||
|
||||
Controls which operations the harness agent can perform without prompting.
|
||||
|
||||
| Value | Behavior |
|
||||
| --------------- | --------------------------------------------------------- |
|
||||
| `approve-all` | Auto-approve all file writes and shell commands. |
|
||||
| `approve-reads` | Auto-approve reads only; writes and exec require prompts. |
|
||||
| `deny-all` | Deny all permission prompts. |
|
||||
|
||||
### `nonInteractivePermissions`
|
||||
|
||||
Controls what happens when a permission prompt would be shown but no interactive TTY is available (which is always the case for ACP sessions).
|
||||
|
||||
| Value | Behavior |
|
||||
| ------ | ----------------------------------------------------------------- |
|
||||
| `fail` | Abort the session with `AcpRuntimeError`. **(default)** |
|
||||
| `deny` | Silently deny the permission and continue (graceful degradation). |
|
||||
|
||||
### Configuration
|
||||
|
||||
Set via plugin config:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.permissionMode approve-all
|
||||
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail
|
||||
```
|
||||
|
||||
Restart the gateway after changing these values.
|
||||
|
||||
> **Important:** OpenClaw currently defaults to `permissionMode=approve-reads` and `nonInteractivePermissions=fail`. In non-interactive ACP sessions, any write or exec that triggers a permission prompt can fail with `AcpRuntimeError: Permission prompt unavailable in non-interactive mode`.
|
||||
>
|
||||
> If you need to restrict permissions, set `nonInteractivePermissions` to `deny` so sessions degrade gracefully instead of crashing.
|
||||
For acpx harness configuration (Claude Code / Codex / Gemini CLI aliases), the
|
||||
plugin-tools and OpenClaw-tools MCP bridges, and ACP permission modes, see
|
||||
[ACP agents — setup](/tools/acp-agents-setup).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
343
docs/tools/browser-control.md
Normal file
343
docs/tools/browser-control.md
Normal file
@ -0,0 +1,343 @@
|
||||
---
|
||||
summary: "OpenClaw browser control API, CLI reference, and scripting actions"
|
||||
read_when:
|
||||
- Scripting or debugging the agent browser via the local control API
|
||||
- Looking for the `openclaw browser` CLI reference
|
||||
- Adding custom browser automation with snapshots and refs
|
||||
title: "Browser control API"
|
||||
---
|
||||
|
||||
For setup, configuration, and troubleshooting, see [Browser](/tools/browser).
|
||||
This page is the reference for the local control HTTP API, the `openclaw browser`
|
||||
CLI, and scripting patterns (snapshots, refs, waits, debug flows).
|
||||
|
||||
## Control API (optional)
|
||||
|
||||
For local integrations only, the Gateway exposes a small loopback HTTP API:
|
||||
|
||||
- Status/start/stop: `GET /`, `POST /start`, `POST /stop`
|
||||
- Tabs: `GET /tabs`, `POST /tabs/open`, `POST /tabs/focus`, `DELETE /tabs/:targetId`
|
||||
- Snapshot/screenshot: `GET /snapshot`, `POST /screenshot`
|
||||
- Actions: `POST /navigate`, `POST /act`
|
||||
- Hooks: `POST /hooks/file-chooser`, `POST /hooks/dialog`
|
||||
- Downloads: `POST /download`, `POST /wait/download`
|
||||
- Debugging: `GET /console`, `POST /pdf`
|
||||
- Debugging: `GET /errors`, `GET /requests`, `POST /trace/start`, `POST /trace/stop`, `POST /highlight`
|
||||
- Network: `POST /response/body`
|
||||
- State: `GET /cookies`, `POST /cookies/set`, `POST /cookies/clear`
|
||||
- State: `GET /storage/:kind`, `POST /storage/:kind/set`, `POST /storage/:kind/clear`
|
||||
- Settings: `POST /set/offline`, `POST /set/headers`, `POST /set/credentials`, `POST /set/geolocation`, `POST /set/media`, `POST /set/timezone`, `POST /set/locale`, `POST /set/device`
|
||||
|
||||
All endpoints accept `?profile=<name>`.
|
||||
|
||||
If shared-secret gateway auth is configured, browser HTTP routes require auth too:
|
||||
|
||||
- `Authorization: Bearer <gateway token>`
|
||||
- `x-openclaw-password: <gateway password>` or HTTP Basic auth with that password
|
||||
|
||||
Notes:
|
||||
|
||||
- This standalone loopback browser API does **not** consume trusted-proxy or
|
||||
Tailscale Serve identity headers.
|
||||
- If `gateway.auth.mode` is `none` or `trusted-proxy`, these loopback browser
|
||||
routes do not inherit those identity-bearing modes; keep them loopback-only.
|
||||
|
||||
### `/act` error contract
|
||||
|
||||
`POST /act` uses a structured error response for route-level validation and
|
||||
policy failures:
|
||||
|
||||
```json
|
||||
{ "error": "<message>", "code": "ACT_*" }
|
||||
```
|
||||
|
||||
Current `code` values:
|
||||
|
||||
- `ACT_KIND_REQUIRED` (HTTP 400): `kind` is missing or unrecognized.
|
||||
- `ACT_INVALID_REQUEST` (HTTP 400): action payload failed normalization or validation.
|
||||
- `ACT_SELECTOR_UNSUPPORTED` (HTTP 400): `selector` was used with an unsupported action kind.
|
||||
- `ACT_EVALUATE_DISABLED` (HTTP 403): `evaluate` (or `wait --fn`) is disabled by config.
|
||||
- `ACT_TARGET_ID_MISMATCH` (HTTP 403): top-level or batched `targetId` conflicts with request target.
|
||||
- `ACT_EXISTING_SESSION_UNSUPPORTED` (HTTP 501): action is not supported for existing-session profiles.
|
||||
|
||||
Other runtime failures may still return `{ "error": "<message>" }` without a
|
||||
`code` field.
|
||||
|
||||
### Playwright requirement
|
||||
|
||||
Some features (navigate/act/AI snapshot/role snapshot, element screenshots,
|
||||
PDF) require Playwright. If Playwright isn’t installed, those endpoints return
|
||||
a clear 501 error.
|
||||
|
||||
What still works without Playwright:
|
||||
|
||||
- ARIA snapshots
|
||||
- Page screenshots for the managed `openclaw` browser when a per-tab CDP
|
||||
WebSocket is available
|
||||
- Page screenshots for `existing-session` / Chrome MCP profiles
|
||||
- `existing-session` ref-based screenshots (`--ref`) from snapshot output
|
||||
|
||||
What still needs Playwright:
|
||||
|
||||
- `navigate`
|
||||
- `act`
|
||||
- AI snapshots / role snapshots
|
||||
- CSS-selector element screenshots (`--element`)
|
||||
- full browser PDF export
|
||||
|
||||
Element screenshots also reject `--full-page`; the route returns `fullPage is
|
||||
not supported for element screenshots`.
|
||||
|
||||
If you see `Playwright is not available in this gateway build`, repair the
|
||||
bundled browser plugin runtime dependencies so `playwright-core` is installed,
|
||||
then restart the gateway. For packaged installs, run `openclaw doctor --fix`.
|
||||
For Docker, also install the Chromium browser binaries as shown below.
|
||||
|
||||
#### Docker Playwright install
|
||||
|
||||
If your Gateway runs in Docker, avoid `npx playwright` (npm override conflicts).
|
||||
Use the bundled CLI instead:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli \
|
||||
node /app/node_modules/playwright-core/cli.js install chromium
|
||||
```
|
||||
|
||||
To persist browser downloads, set `PLAYWRIGHT_BROWSERS_PATH` (for example,
|
||||
`/home/node/.cache/ms-playwright`) and make sure `/home/node` is persisted via
|
||||
`OPENCLAW_HOME_VOLUME` or a bind mount. See [Docker](/install/docker).
|
||||
|
||||
## How it works (internal)
|
||||
|
||||
A small loopback control server accepts HTTP requests and connects to Chromium-based browsers via CDP. Advanced actions (click/type/snapshot/PDF) go through Playwright on top of CDP; when Playwright is missing, only non-Playwright operations are available. The agent sees one stable interface while local/remote browsers and profiles swap freely underneath.
|
||||
|
||||
## CLI quick reference
|
||||
|
||||
All commands accept `--browser-profile <name>` to target a specific profile, and `--json` for machine-readable output.
|
||||
|
||||
<AccordionGroup>
|
||||
|
||||
<Accordion title="Basics: status, tabs, open/focus/close">
|
||||
|
||||
```bash
|
||||
openclaw browser status
|
||||
openclaw browser start
|
||||
openclaw browser stop # also clears emulation on attach-only/remote CDP
|
||||
openclaw browser tabs
|
||||
openclaw browser tab # shortcut for current tab
|
||||
openclaw browser tab new
|
||||
openclaw browser tab select 2
|
||||
openclaw browser tab close 2
|
||||
openclaw browser open https://example.com
|
||||
openclaw browser focus abcd1234
|
||||
openclaw browser close abcd1234
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inspection: screenshot, snapshot, console, errors, requests">
|
||||
|
||||
```bash
|
||||
openclaw browser screenshot
|
||||
openclaw browser screenshot --full-page
|
||||
openclaw browser screenshot --ref 12 # or --ref e12
|
||||
openclaw browser snapshot
|
||||
openclaw browser snapshot --format aria --limit 200
|
||||
openclaw browser snapshot --interactive --compact --depth 6
|
||||
openclaw browser snapshot --efficient
|
||||
openclaw browser snapshot --labels
|
||||
openclaw browser snapshot --selector "#main" --interactive
|
||||
openclaw browser snapshot --frame "iframe#main" --interactive
|
||||
openclaw browser console --level error
|
||||
openclaw browser errors --clear
|
||||
openclaw browser requests --filter api --clear
|
||||
openclaw browser pdf
|
||||
openclaw browser responsebody "**/api" --max-chars 5000
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Actions: navigate, click, type, drag, wait, evaluate">
|
||||
|
||||
```bash
|
||||
openclaw browser navigate https://example.com
|
||||
openclaw browser resize 1280 720
|
||||
openclaw browser click 12 --double # or e12 for role refs
|
||||
openclaw browser type 23 "hello" --submit
|
||||
openclaw browser press Enter
|
||||
openclaw browser hover 44
|
||||
openclaw browser scrollintoview e12
|
||||
openclaw browser drag 10 11
|
||||
openclaw browser select 9 OptionA OptionB
|
||||
openclaw browser download e12 report.pdf
|
||||
openclaw browser waitfordownload report.pdf
|
||||
openclaw browser upload /tmp/openclaw/uploads/file.pdf
|
||||
openclaw browser fill --fields '[{"ref":"1","type":"text","value":"Ada"}]'
|
||||
openclaw browser dialog --accept
|
||||
openclaw browser wait --text "Done"
|
||||
openclaw browser wait "#main" --url "**/dash" --load networkidle --fn "window.ready===true"
|
||||
openclaw browser evaluate --fn '(el) => el.textContent' --ref 7
|
||||
openclaw browser highlight e12
|
||||
openclaw browser trace start
|
||||
openclaw browser trace stop
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="State: cookies, storage, offline, headers, geo, device">
|
||||
|
||||
```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 theme dark
|
||||
openclaw browser storage session clear
|
||||
openclaw browser set offline on
|
||||
openclaw browser set headers --headers-json '{"X-Debug":"1"}'
|
||||
openclaw browser set credentials user pass # --clear to remove
|
||||
openclaw browser set geo 37.7749 -122.4194 --origin "https://example.com"
|
||||
openclaw browser set media dark
|
||||
openclaw browser set timezone America/New_York
|
||||
openclaw browser set locale en-US
|
||||
openclaw browser set device "iPhone 14"
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
</AccordionGroup>
|
||||
|
||||
Notes:
|
||||
|
||||
- `upload` and `dialog` are **arming** calls; run them before the click/press that triggers the chooser/dialog.
|
||||
- `click`/`type`/etc require a `ref` from `snapshot` (numeric `12` or role ref `e12`). CSS selectors are intentionally not supported for actions.
|
||||
- Download, trace, and upload paths are constrained to OpenClaw temp roots: `/tmp/openclaw{,/downloads,/uploads}` (fallback: `${os.tmpdir()}/openclaw/...`).
|
||||
- `upload` can also set file inputs directly via `--input-ref` or `--element`.
|
||||
|
||||
Snapshot flags at a glance:
|
||||
|
||||
- `--format ai` (default with Playwright): AI snapshot with numeric refs (`aria-ref="<n>"`).
|
||||
- `--format aria`: accessibility tree, no refs; inspection only.
|
||||
- `--efficient` (or `--mode efficient`): compact role snapshot preset. Set `browser.snapshotDefaults.mode: "efficient"` to make this the default (see [Gateway configuration](/gateway/configuration-reference#browser)).
|
||||
- `--interactive`, `--compact`, `--depth`, `--selector` force a role snapshot with `ref=e12` refs. `--frame "<iframe>"` scopes role snapshots to an iframe.
|
||||
- `--labels` adds a viewport-only screenshot with overlayed ref labels (prints `MEDIA:<path>`).
|
||||
|
||||
## Snapshots and refs
|
||||
|
||||
OpenClaw supports two “snapshot” styles:
|
||||
|
||||
- **AI snapshot (numeric refs)**: `openclaw browser snapshot` (default; `--format ai`)
|
||||
- Output: a text snapshot that includes numeric refs.
|
||||
- Actions: `openclaw browser click 12`, `openclaw browser type 23 "hello"`.
|
||||
- Internally, the ref is resolved via Playwright’s `aria-ref`.
|
||||
|
||||
- **Role snapshot (role refs like `e12`)**: `openclaw browser snapshot --interactive` (or `--compact`, `--depth`, `--selector`, `--frame`)
|
||||
- Output: a role-based list/tree with `[ref=e12]` (and optional `[nth=1]`).
|
||||
- Actions: `openclaw browser click e12`, `openclaw browser highlight e12`.
|
||||
- Internally, the ref is resolved via `getByRole(...)` (plus `nth()` for duplicates).
|
||||
- Add `--labels` to include a viewport screenshot with overlayed `e12` labels.
|
||||
|
||||
Ref behavior:
|
||||
|
||||
- Refs are **not stable across navigations**; if something fails, re-run `snapshot` and use a fresh ref.
|
||||
- If the role snapshot was taken with `--frame`, role refs are scoped to that iframe until the next role snapshot.
|
||||
|
||||
## Wait power-ups
|
||||
|
||||
You can wait on more than just time/text:
|
||||
|
||||
- Wait for URL (globs supported by Playwright):
|
||||
- `openclaw browser wait --url "**/dash"`
|
||||
- Wait for load state:
|
||||
- `openclaw browser wait --load networkidle`
|
||||
- Wait for a JS predicate:
|
||||
- `openclaw browser wait --fn "window.ready===true"`
|
||||
- Wait for a selector to become visible:
|
||||
- `openclaw browser wait "#main"`
|
||||
|
||||
These can be combined:
|
||||
|
||||
```bash
|
||||
openclaw browser wait "#main" \
|
||||
--url "**/dash" \
|
||||
--load networkidle \
|
||||
--fn "window.ready===true" \
|
||||
--timeout-ms 15000
|
||||
```
|
||||
|
||||
## Debug workflows
|
||||
|
||||
When an action fails (e.g. “not visible”, “strict mode violation”, “covered”):
|
||||
|
||||
1. `openclaw browser snapshot --interactive`
|
||||
2. Use `click <ref>` / `type <ref>` (prefer role refs in interactive mode)
|
||||
3. If it still fails: `openclaw browser highlight <ref>` to see what Playwright is targeting
|
||||
4. If the page behaves oddly:
|
||||
- `openclaw browser errors --clear`
|
||||
- `openclaw browser requests --filter api --clear`
|
||||
5. For deep debugging: record a trace:
|
||||
- `openclaw browser trace start`
|
||||
- reproduce the issue
|
||||
- `openclaw browser trace stop` (prints `TRACE:<path>`)
|
||||
|
||||
## JSON output
|
||||
|
||||
`--json` is for scripting and structured tooling.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw browser status --json
|
||||
openclaw browser snapshot --interactive --json
|
||||
openclaw browser requests --filter api --json
|
||||
openclaw browser cookies --json
|
||||
```
|
||||
|
||||
Role snapshots in JSON include `refs` plus a small `stats` block (lines/chars/refs/interactive) so tools can reason about payload size and density.
|
||||
|
||||
## State and environment knobs
|
||||
|
||||
These are useful for “make the site behave like X” workflows:
|
||||
|
||||
- Cookies: `cookies`, `cookies set`, `cookies clear`
|
||||
- Storage: `storage local|session get|set|clear`
|
||||
- Offline: `set offline on|off`
|
||||
- Headers: `set headers --headers-json '{"X-Debug":"1"}'` (legacy `set headers --json '{"X-Debug":"1"}'` remains supported)
|
||||
- HTTP basic auth: `set credentials user pass` (or `--clear`)
|
||||
- Geolocation: `set geo <lat> <lon> --origin "https://example.com"` (or `--clear`)
|
||||
- Media: `set media dark|light|no-preference|none`
|
||||
- Timezone / locale: `set timezone ...`, `set locale ...`
|
||||
- Device / viewport:
|
||||
- `set device "iPhone 14"` (Playwright device presets)
|
||||
- `set viewport 1280 720`
|
||||
|
||||
## Security and privacy
|
||||
|
||||
- The openclaw browser profile may contain logged-in sessions; treat it as sensitive.
|
||||
- `browser act kind=evaluate` / `openclaw browser evaluate` and `wait --fn`
|
||||
execute arbitrary JavaScript in the page context. Prompt injection can steer
|
||||
this. Disable it with `browser.evaluateEnabled=false` if you do not need it.
|
||||
- For logins and anti-bot notes (X/Twitter, etc.), see [Browser login + X/Twitter posting](/tools/browser-login).
|
||||
- Keep the Gateway/node host private (loopback or tailnet-only).
|
||||
- Remote CDP endpoints are powerful; tunnel and protect them.
|
||||
|
||||
Strict-mode example (block private/internal destinations by default):
|
||||
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
ssrfPolicy: {
|
||||
dangerouslyAllowPrivateNetwork: false,
|
||||
hostnameAllowlist: ["*.example.com", "example.com"],
|
||||
allowedHostnames: ["localhost"], // optional exact allow
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Browser](/tools/browser) — overview, configuration, profiles, security
|
||||
- [Browser login](/tools/browser-login) — signing in to sites
|
||||
- [Browser Linux troubleshooting](/tools/browser-linux-troubleshooting)
|
||||
- [Browser WSL2 troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
|
||||
@ -516,327 +516,10 @@ Platforms:
|
||||
|
||||
## Control API (optional)
|
||||
|
||||
For local integrations only, the Gateway exposes a small loopback HTTP API:
|
||||
|
||||
- Status/start/stop: `GET /`, `POST /start`, `POST /stop`
|
||||
- Tabs: `GET /tabs`, `POST /tabs/open`, `POST /tabs/focus`, `DELETE /tabs/:targetId`
|
||||
- Snapshot/screenshot: `GET /snapshot`, `POST /screenshot`
|
||||
- Actions: `POST /navigate`, `POST /act`
|
||||
- Hooks: `POST /hooks/file-chooser`, `POST /hooks/dialog`
|
||||
- Downloads: `POST /download`, `POST /wait/download`
|
||||
- Debugging: `GET /console`, `POST /pdf`
|
||||
- Debugging: `GET /errors`, `GET /requests`, `POST /trace/start`, `POST /trace/stop`, `POST /highlight`
|
||||
- Network: `POST /response/body`
|
||||
- State: `GET /cookies`, `POST /cookies/set`, `POST /cookies/clear`
|
||||
- State: `GET /storage/:kind`, `POST /storage/:kind/set`, `POST /storage/:kind/clear`
|
||||
- Settings: `POST /set/offline`, `POST /set/headers`, `POST /set/credentials`, `POST /set/geolocation`, `POST /set/media`, `POST /set/timezone`, `POST /set/locale`, `POST /set/device`
|
||||
|
||||
All endpoints accept `?profile=<name>`.
|
||||
|
||||
If shared-secret gateway auth is configured, browser HTTP routes require auth too:
|
||||
|
||||
- `Authorization: Bearer <gateway token>`
|
||||
- `x-openclaw-password: <gateway password>` or HTTP Basic auth with that password
|
||||
|
||||
Notes:
|
||||
|
||||
- This standalone loopback browser API does **not** consume trusted-proxy or
|
||||
Tailscale Serve identity headers.
|
||||
- If `gateway.auth.mode` is `none` or `trusted-proxy`, these loopback browser
|
||||
routes do not inherit those identity-bearing modes; keep them loopback-only.
|
||||
|
||||
### `/act` error contract
|
||||
|
||||
`POST /act` uses a structured error response for route-level validation and
|
||||
policy failures:
|
||||
|
||||
```json
|
||||
{ "error": "<message>", "code": "ACT_*" }
|
||||
```
|
||||
|
||||
Current `code` values:
|
||||
|
||||
- `ACT_KIND_REQUIRED` (HTTP 400): `kind` is missing or unrecognized.
|
||||
- `ACT_INVALID_REQUEST` (HTTP 400): action payload failed normalization or validation.
|
||||
- `ACT_SELECTOR_UNSUPPORTED` (HTTP 400): `selector` was used with an unsupported action kind.
|
||||
- `ACT_EVALUATE_DISABLED` (HTTP 403): `evaluate` (or `wait --fn`) is disabled by config.
|
||||
- `ACT_TARGET_ID_MISMATCH` (HTTP 403): top-level or batched `targetId` conflicts with request target.
|
||||
- `ACT_EXISTING_SESSION_UNSUPPORTED` (HTTP 501): action is not supported for existing-session profiles.
|
||||
|
||||
Other runtime failures may still return `{ "error": "<message>" }` without a
|
||||
`code` field.
|
||||
|
||||
### Playwright requirement
|
||||
|
||||
Some features (navigate/act/AI snapshot/role snapshot, element screenshots,
|
||||
PDF) require Playwright. If Playwright isn’t installed, those endpoints return
|
||||
a clear 501 error.
|
||||
|
||||
What still works without Playwright:
|
||||
|
||||
- ARIA snapshots
|
||||
- Page screenshots for the managed `openclaw` browser when a per-tab CDP
|
||||
WebSocket is available
|
||||
- Page screenshots for `existing-session` / Chrome MCP profiles
|
||||
- `existing-session` ref-based screenshots (`--ref`) from snapshot output
|
||||
|
||||
What still needs Playwright:
|
||||
|
||||
- `navigate`
|
||||
- `act`
|
||||
- AI snapshots / role snapshots
|
||||
- CSS-selector element screenshots (`--element`)
|
||||
- full browser PDF export
|
||||
|
||||
Element screenshots also reject `--full-page`; the route returns `fullPage is
|
||||
not supported for element screenshots`.
|
||||
|
||||
If you see `Playwright is not available in this gateway build`, repair the
|
||||
bundled browser plugin runtime dependencies so `playwright-core` is installed,
|
||||
then restart the gateway. For packaged installs, run `openclaw doctor --fix`.
|
||||
For Docker, also install the Chromium browser binaries as shown below.
|
||||
|
||||
#### Docker Playwright install
|
||||
|
||||
If your Gateway runs in Docker, avoid `npx playwright` (npm override conflicts).
|
||||
Use the bundled CLI instead:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli \
|
||||
node /app/node_modules/playwright-core/cli.js install chromium
|
||||
```
|
||||
|
||||
To persist browser downloads, set `PLAYWRIGHT_BROWSERS_PATH` (for example,
|
||||
`/home/node/.cache/ms-playwright`) and make sure `/home/node` is persisted via
|
||||
`OPENCLAW_HOME_VOLUME` or a bind mount. See [Docker](/install/docker).
|
||||
|
||||
## How it works (internal)
|
||||
|
||||
A small loopback control server accepts HTTP requests and connects to Chromium-based browsers via CDP. Advanced actions (click/type/snapshot/PDF) go through Playwright on top of CDP; when Playwright is missing, only non-Playwright operations are available. The agent sees one stable interface while local/remote browsers and profiles swap freely underneath.
|
||||
|
||||
## CLI quick reference
|
||||
|
||||
All commands accept `--browser-profile <name>` to target a specific profile, and `--json` for machine-readable output.
|
||||
|
||||
<AccordionGroup>
|
||||
|
||||
<Accordion title="Basics: status, tabs, open/focus/close">
|
||||
|
||||
```bash
|
||||
openclaw browser status
|
||||
openclaw browser start
|
||||
openclaw browser stop # also clears emulation on attach-only/remote CDP
|
||||
openclaw browser tabs
|
||||
openclaw browser tab # shortcut for current tab
|
||||
openclaw browser tab new
|
||||
openclaw browser tab select 2
|
||||
openclaw browser tab close 2
|
||||
openclaw browser open https://example.com
|
||||
openclaw browser focus abcd1234
|
||||
openclaw browser close abcd1234
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inspection: screenshot, snapshot, console, errors, requests">
|
||||
|
||||
```bash
|
||||
openclaw browser screenshot
|
||||
openclaw browser screenshot --full-page
|
||||
openclaw browser screenshot --ref 12 # or --ref e12
|
||||
openclaw browser snapshot
|
||||
openclaw browser snapshot --format aria --limit 200
|
||||
openclaw browser snapshot --interactive --compact --depth 6
|
||||
openclaw browser snapshot --efficient
|
||||
openclaw browser snapshot --labels
|
||||
openclaw browser snapshot --selector "#main" --interactive
|
||||
openclaw browser snapshot --frame "iframe#main" --interactive
|
||||
openclaw browser console --level error
|
||||
openclaw browser errors --clear
|
||||
openclaw browser requests --filter api --clear
|
||||
openclaw browser pdf
|
||||
openclaw browser responsebody "**/api" --max-chars 5000
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Actions: navigate, click, type, drag, wait, evaluate">
|
||||
|
||||
```bash
|
||||
openclaw browser navigate https://example.com
|
||||
openclaw browser resize 1280 720
|
||||
openclaw browser click 12 --double # or e12 for role refs
|
||||
openclaw browser type 23 "hello" --submit
|
||||
openclaw browser press Enter
|
||||
openclaw browser hover 44
|
||||
openclaw browser scrollintoview e12
|
||||
openclaw browser drag 10 11
|
||||
openclaw browser select 9 OptionA OptionB
|
||||
openclaw browser download e12 report.pdf
|
||||
openclaw browser waitfordownload report.pdf
|
||||
openclaw browser upload /tmp/openclaw/uploads/file.pdf
|
||||
openclaw browser fill --fields '[{"ref":"1","type":"text","value":"Ada"}]'
|
||||
openclaw browser dialog --accept
|
||||
openclaw browser wait --text "Done"
|
||||
openclaw browser wait "#main" --url "**/dash" --load networkidle --fn "window.ready===true"
|
||||
openclaw browser evaluate --fn '(el) => el.textContent' --ref 7
|
||||
openclaw browser highlight e12
|
||||
openclaw browser trace start
|
||||
openclaw browser trace stop
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="State: cookies, storage, offline, headers, geo, device">
|
||||
|
||||
```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 theme dark
|
||||
openclaw browser storage session clear
|
||||
openclaw browser set offline on
|
||||
openclaw browser set headers --headers-json '{"X-Debug":"1"}'
|
||||
openclaw browser set credentials user pass # --clear to remove
|
||||
openclaw browser set geo 37.7749 -122.4194 --origin "https://example.com"
|
||||
openclaw browser set media dark
|
||||
openclaw browser set timezone America/New_York
|
||||
openclaw browser set locale en-US
|
||||
openclaw browser set device "iPhone 14"
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
</AccordionGroup>
|
||||
|
||||
Notes:
|
||||
|
||||
- `upload` and `dialog` are **arming** calls; run them before the click/press that triggers the chooser/dialog.
|
||||
- `click`/`type`/etc require a `ref` from `snapshot` (numeric `12` or role ref `e12`). CSS selectors are intentionally not supported for actions.
|
||||
- Download, trace, and upload paths are constrained to OpenClaw temp roots: `/tmp/openclaw{,/downloads,/uploads}` (fallback: `${os.tmpdir()}/openclaw/...`).
|
||||
- `upload` can also set file inputs directly via `--input-ref` or `--element`.
|
||||
|
||||
Snapshot flags at a glance:
|
||||
|
||||
- `--format ai` (default with Playwright): AI snapshot with numeric refs (`aria-ref="<n>"`).
|
||||
- `--format aria`: accessibility tree, no refs; inspection only.
|
||||
- `--efficient` (or `--mode efficient`): compact role snapshot preset. Set `browser.snapshotDefaults.mode: "efficient"` to make this the default (see [Gateway configuration](/gateway/configuration-reference#browser)).
|
||||
- `--interactive`, `--compact`, `--depth`, `--selector` force a role snapshot with `ref=e12` refs. `--frame "<iframe>"` scopes role snapshots to an iframe.
|
||||
- `--labels` adds a viewport-only screenshot with overlayed ref labels (prints `MEDIA:<path>`).
|
||||
|
||||
## Snapshots and refs
|
||||
|
||||
OpenClaw supports two “snapshot” styles:
|
||||
|
||||
- **AI snapshot (numeric refs)**: `openclaw browser snapshot` (default; `--format ai`)
|
||||
- Output: a text snapshot that includes numeric refs.
|
||||
- Actions: `openclaw browser click 12`, `openclaw browser type 23 "hello"`.
|
||||
- Internally, the ref is resolved via Playwright’s `aria-ref`.
|
||||
|
||||
- **Role snapshot (role refs like `e12`)**: `openclaw browser snapshot --interactive` (or `--compact`, `--depth`, `--selector`, `--frame`)
|
||||
- Output: a role-based list/tree with `[ref=e12]` (and optional `[nth=1]`).
|
||||
- Actions: `openclaw browser click e12`, `openclaw browser highlight e12`.
|
||||
- Internally, the ref is resolved via `getByRole(...)` (plus `nth()` for duplicates).
|
||||
- Add `--labels` to include a viewport screenshot with overlayed `e12` labels.
|
||||
|
||||
Ref behavior:
|
||||
|
||||
- Refs are **not stable across navigations**; if something fails, re-run `snapshot` and use a fresh ref.
|
||||
- If the role snapshot was taken with `--frame`, role refs are scoped to that iframe until the next role snapshot.
|
||||
|
||||
## Wait power-ups
|
||||
|
||||
You can wait on more than just time/text:
|
||||
|
||||
- Wait for URL (globs supported by Playwright):
|
||||
- `openclaw browser wait --url "**/dash"`
|
||||
- Wait for load state:
|
||||
- `openclaw browser wait --load networkidle`
|
||||
- Wait for a JS predicate:
|
||||
- `openclaw browser wait --fn "window.ready===true"`
|
||||
- Wait for a selector to become visible:
|
||||
- `openclaw browser wait "#main"`
|
||||
|
||||
These can be combined:
|
||||
|
||||
```bash
|
||||
openclaw browser wait "#main" \
|
||||
--url "**/dash" \
|
||||
--load networkidle \
|
||||
--fn "window.ready===true" \
|
||||
--timeout-ms 15000
|
||||
```
|
||||
|
||||
## Debug workflows
|
||||
|
||||
When an action fails (e.g. “not visible”, “strict mode violation”, “covered”):
|
||||
|
||||
1. `openclaw browser snapshot --interactive`
|
||||
2. Use `click <ref>` / `type <ref>` (prefer role refs in interactive mode)
|
||||
3. If it still fails: `openclaw browser highlight <ref>` to see what Playwright is targeting
|
||||
4. If the page behaves oddly:
|
||||
- `openclaw browser errors --clear`
|
||||
- `openclaw browser requests --filter api --clear`
|
||||
5. For deep debugging: record a trace:
|
||||
- `openclaw browser trace start`
|
||||
- reproduce the issue
|
||||
- `openclaw browser trace stop` (prints `TRACE:<path>`)
|
||||
|
||||
## JSON output
|
||||
|
||||
`--json` is for scripting and structured tooling.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw browser status --json
|
||||
openclaw browser snapshot --interactive --json
|
||||
openclaw browser requests --filter api --json
|
||||
openclaw browser cookies --json
|
||||
```
|
||||
|
||||
Role snapshots in JSON include `refs` plus a small `stats` block (lines/chars/refs/interactive) so tools can reason about payload size and density.
|
||||
|
||||
## State and environment knobs
|
||||
|
||||
These are useful for “make the site behave like X” workflows:
|
||||
|
||||
- Cookies: `cookies`, `cookies set`, `cookies clear`
|
||||
- Storage: `storage local|session get|set|clear`
|
||||
- Offline: `set offline on|off`
|
||||
- Headers: `set headers --headers-json '{"X-Debug":"1"}'` (legacy `set headers --json '{"X-Debug":"1"}'` remains supported)
|
||||
- HTTP basic auth: `set credentials user pass` (or `--clear`)
|
||||
- Geolocation: `set geo <lat> <lon> --origin "https://example.com"` (or `--clear`)
|
||||
- Media: `set media dark|light|no-preference|none`
|
||||
- Timezone / locale: `set timezone ...`, `set locale ...`
|
||||
- Device / viewport:
|
||||
- `set device "iPhone 14"` (Playwright device presets)
|
||||
- `set viewport 1280 720`
|
||||
|
||||
## Security and privacy
|
||||
|
||||
- The openclaw browser profile may contain logged-in sessions; treat it as sensitive.
|
||||
- `browser act kind=evaluate` / `openclaw browser evaluate` and `wait --fn`
|
||||
execute arbitrary JavaScript in the page context. Prompt injection can steer
|
||||
this. Disable it with `browser.evaluateEnabled=false` if you do not need it.
|
||||
- For logins and anti-bot notes (X/Twitter, etc.), see [Browser login + X/Twitter posting](/tools/browser-login).
|
||||
- Keep the Gateway/node host private (loopback or tailnet-only).
|
||||
- Remote CDP endpoints are powerful; tunnel and protect them.
|
||||
|
||||
Strict-mode example (block private/internal destinations by default):
|
||||
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
ssrfPolicy: {
|
||||
dangerouslyAllowPrivateNetwork: false,
|
||||
hostnameAllowlist: ["*.example.com", "example.com"],
|
||||
allowedHostnames: ["localhost"], // optional exact allow
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
For scripting and debugging, the Gateway exposes a small **loopback-only HTTP
|
||||
control API** plus a matching `openclaw browser` CLI (snapshots, refs, wait
|
||||
power-ups, JSON output, debug workflows). See
|
||||
[Browser control API](/tools/browser-control) for the full reference.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user