CLI commands

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

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). This is a browser-level option, so place it before the subcommand for an unambiguous form, such as openclaw browser --json status. Trailing placement such as openclaw browser status --json also works when the selected child command does not define its own --json.

Quick start (local)

bash
openclaw browser profilesopenclaw browser --browser-profile openclaw startopenclaw browser --browser-profile openclaw open https://example.comopenclaw 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 doctoropenclaw browser --browser-profile openclaw startopenclaw browser --browser-profile openclaw tabsopenclaw browser --browser-profile openclaw open https://example.com

Detailed guidance: Browser troubleshooting

Lifecycle

bash
openclaw browser statusopenclaw browser doctoropenclaw browser doctor --deepopenclaw browser startopenclaw browser start --headlessopenclaw browser stopopenclaw 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.
  • For a running local managed profile, status and doctor report cached graphics diagnostics from Chrome: hardware/software classification, renderer, backend, device/driver, feature and disabled-status details, and accelerated video capabilities. openclaw browser --json status returns the full structured payload. Passive status never launches Chrome just to collect these facts.
  • 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

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 profilesopenclaw browser system-profilesopenclaw browser system-profiles --browser braveopenclaw browser import-profile --browser chrome --system Default --into importedopenclaw browser import-profile --system "Profile 1" --into work --domains google.com,youtube.comopenclaw browser create-profile --name work --color "#FF5A36"openclaw browser create-profile --name chrome-live --driver existing-sessionopenclaw browser create-profile --name remote --cdp-url https://browser-host.example.comopenclaw browser delete-profile --name work

Use a specific profile with --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.

Tabs

bash
openclaw browser tabsopenclaw browser tab new --label docsopenclaw browser tab label t1 docsopenclaw browser tab select 2openclaw browser tab close 2openclaw browser open https://docs.openclaw.ai --label docsopenclaw browser focus docsopenclaw 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 snapshotopenclaw browser snapshot --urls

Screenshot:

bash
openclaw browser screenshotopenclaw browser screenshot --full-pageopenclaw browser screenshot --ref e12openclaw 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.comopenclaw browser click <ref>openclaw browser click-coords 120 340openclaw browser type <ref> "hello"openclaw browser press Enteropenclaw browser hover <ref>openclaw browser scrollintoview <ref>openclaw browser drag <startRef> <endRef>openclaw browser select <ref> OptionA OptionBopenclaw 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 waitfordownloadopenclaw browser download <ref> report.pdfopenclaw browser dialog --acceptopenclaw 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 720openclaw browser set viewport 1280 720openclaw browser set offline onopenclaw browser set media darkopenclaw browser set timezone Europe/Londonopenclaw browser set locale en-GBopenclaw browser set geo 51.5074 -0.1278 --accuracy 25openclaw browser set device "iPhone 14"openclaw browser set headers '{"x-test":"1"}'openclaw browser set credentials myuser mypass

Cookies + storage:

bash
openclaw browser cookiesopenclaw browser cookies set session abc123 --url https://example.comopenclaw browser cookies clearopenclaw browser storage local getopenclaw browser storage local set token abc123openclaw browser storage session clear

Debugging

bash
openclaw browser console --level erroropenclaw browser pdfopenclaw browser responsebody "**/api"openclaw browser highlight <ref>openclaw browser errors --clearopenclaw browser requests --filter apiopenclaw browser trace startopenclaw 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 tabsopenclaw browser create-profile --name chrome-live --driver existing-sessionopenclaw 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:9222openclaw 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, and fill reject per-call timeout overrides; evaluate accepts --timeout-ms.
  • 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, Remote access, Tailscale, Security

Was this useful?
On this page

On this page