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
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, orbrowser.defaultProfile).--json: machine-readable output (where supported). This is a browser-level option, so place it before the subcommand for an unambiguous form, such asopenclaw browser --json status. Trailing placement such asopenclaw browser status --jsonalso works when the selected child command does not define its own--json.
Quick start (local)
browser({ action: "doctor" }).
Quick troubleshooting
Ifstart 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:
Lifecycle
doctor --deepadds a live snapshot probe: useful when basic CDP readiness is green but you want proof the current tab can be inspected.- For a running local managed profile,
statusanddoctorreport cached graphics diagnostics from Chrome: hardware/software classification, renderer, backend, device/driver, feature and disabled-status details, and accelerated video capabilities.openclaw browser --json statusreturns the full structured payload. Passive status never launches Chrome just to collect these facts. stopcloses the active control session and clears temporary emulation overrides even forattachOnlyand remote CDP profiles where OpenClaw did not launch the browser process itself. For local managed profiles,stopalso stops the spawned browser process.start --headlessapplies only to that start request, and only when OpenClaw launches a local managed browser. It does not rewritebrowser.headlessor profile config, and is a no-op for an already-running browser.- On Linux hosts without
DISPLAYorWAYLAND_DISPLAY, local managed profiles run headless automatically unlessOPENCLAW_BROWSER_HEADLESS=0,browser.headless=false, orbrowser.profiles.<name>.headless=falseexplicitly requests a visible browser.
If the command is missing
Ifopenclaw 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:
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
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.
--browser-profile <name> on any subcommand, for example openclaw browser --browser-profile work tabs.
On macOS, system-profiles lists real Chrome, Brave, Edge, or Chromium profiles available on the host. import-profile decrypts their cookies after one macOS Keychain/Touch ID consent prompt and injects them into a fresh OpenClaw-managed profile. It imports cookies only; local storage and IndexedDB are unchanged. Some Google sessions use device-bound session credentials (DBSC) and can still require re-authentication after import.
When the macOS app uses a local Gateway, it can offer this import once and make the isolated imported profile the default for agent browsing. Import always requires an explicit click; successful import or dismissal suppresses later automatic prompts, and Settings → General → Browser login remains available for re-import.
System-profile import is enabled by default. Set browser.allowSystemProfileImport=false to disable both CLI and agent-triggered imports. Import is host-local and cannot run through the browser node proxy.
Cookie sync to a remote Gateway
import-profile targets a managed profile on the same host. When your OpenClaw Gateway and agent browser run on a separate computer, use cookie-sync to decrypt cookies on this Mac and push them into a managed profile on that remote Gateway over the operator connection:
--domainsis required. Cookie sync copies live session cookies, so it never sends an unrestricted cookie jar; a missing or empty allowlist is a hard error.--intoselects the target managed profile on the Gateway (defaultimported);--gateway/--urlselects a remote Gateway (default is the configured/local one).--watchkeeps the command running and re-pushes when the source Cookies database changes. The macOS Keychain secret is read once per watch session, so you approve a single consent prompt rather than one per change.- Decryption is host-local (macOS only) and reuses the same allowlist and Keychain path as
import-profile. Cookies are decrypted on this Mac and shipped over the existing TLS-pinned Gateway connection; no cookie values are printed. - Some Google sessions use device-bound session credentials (DBSC) that stay tied to this Mac and can still require re-authentication after sync. For those sites, prefer driving the browser on the Mac itself through the browser node proxy.
cookie-sync --watch for you against the connected Gateway and shows a live status row.
Chrome extension relay
extension installpre-registers the origin-locked native bootstrap host in existing Chrome-family user-data roots. Run it first, then add OpenClaw from the Chrome Web Store. The stable Load unpacked path remains available as a development fallback.extension statusreports Store discovery separately from approved unpacked IDs and paths, plus owned-registration health and whether manual setup is required. JSON output never includes a pairing string or relay key.extension uninstall-hostremoves only verified OpenClaw-owned native-host manifests and launchers. It does not remove the extension from Chrome.extension pathis read-only. It prints the stable installed copy when present and the bundled source directory otherwise.extension pairremains the advanced manual flow.--gateway-urlcreates a direct remote-Gateway pairing URL; non-loopback URLs must usewss://.extension cdpprints non-secret Browser Relay Authentication v2 metadata: the loopback browser/CDP endpoints, protocol version, key ID, and fixed challenge/complete binding. It never prints the relay key or an authorization header by default.
/browser/extension route so the first authenticated extension connection
starts the lazy browser-control service. Keep openclaw gateway run or the
managed Gateway service running; no separate browser request or prewarm is
needed. Local OpenClaw and mcporter calls still use the profile relay port
reported by extension pair or extension cdp after that wakeup. Browser-node
pairings continue to use the relay on the browser-node host, while explicit
--gateway-url pairings remain direct-remote and manual-only.
The advanced manual extension pair command without --gateway-url retains
the host-local /extension relay URL. It does not wake Browser control, so the
selected profile relay must already be running before the extension connects.
extension cdp --legacy-bearer is a temporary migration escape hatch. It
prints the old Bearer header with a warning only while
browser.extensionRelay.allowLegacyAuth=true; otherwise it exits with an error
without printing a credential. Use --json for machine output; warnings remain
on stderr so stdout stays valid JSON.
Setup, security model, and recovery steps: Chrome extension.
If the extension already attempted automatic setup before the native host
existed, Chromium retains that miss for the running browser process. Restart
Chrome once, run extension install, then reopen the Store extension; popup
retries alone cannot recover that existing process.
Tabs
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:--full-pageis for page captures only; it cannot be combined with--refor--element.existing-session/userprofiles support page screenshots and--refscreenshots from snapshot output, but not CSS--elementscreenshots.--labelsoverlays 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 anannotationsarray (omitted when empty) with each ref’s bounding box:ref,number,role, optionalname, andbox: {x, y, width, height}in the captured image’s coordinate space (viewport / fullpage / element-relative).existing-sessionprofiles render a chrome-mcp overlay on page screenshots but do not use the Playwright projection helper and do not includeannotations; CSS--elementscreenshots are unsupported there. Without Playwright or chrome-mcp, labeled screenshots are not available.snapshot --urlsappends discovered link destinations to AI snapshots so agents can choose direct navigation targets instead of guessing from link text alone.
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:
/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.
Batch actions:
openclaw browser batch sends a kind="batch" /act request with nested BrowserActRequest actions (wait, click, type, evaluate, …) — not open/navigate/snapshot/screenshot, which are CLI subcommands, not /act kinds. --continue sets stopOnError=false (default stops on first error); --target-id scopes the whole batch to one tab. A failed nested action makes the command exit nonzero; use --json to retain the ordered results response. See Browser batch CLI for the full contract (ref lifecycle, target id conflicts, error summary). batch is not supported on profile="user" / existing-session profiles.
State and storage
Viewport + emulation:Debugging
Existing Chrome via MCP
Use the built-inuser profile, or create your own existing-session profile:
--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.
- Supported
actrequests use a built-in 60000 ms default when callers omittimeoutMs; per-calltimeoutMsstill wins. clickis left-click only.typedoes not supportslowly=true.pressdoes not supportdelayMs.hover,scrollintoview,drag,select, andfillreject per-call timeout overrides;evaluateaccepts--timeout-ms.selectsupports one value only.wait --load networkidleis 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. Usegateway.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, Remote access, Tailscale, Security