OpenClaw-Managed Browser: Dedicated Agent-Only Profile
This page explains how OpenClaw launches a separate Chrome/Brave/Edge/Chromium profile for agent control. It covers deterministic tab management, agent actions, and managed downloads for developers integrating browser automation.
Read this when
- Adding agent-controlled browser automation
- Debugging why openclaw is interfering with your own Chrome
- Implementing browser settings + lifecycle in the macOS app
OpenClaw can launch a dedicated Chrome/Brave/Edge/Chromium profile under agent control. This runs via a small local control service inside the Gateway (loopback only) and stays separate from your personal browser.
- Treat it as a distinct, agent-only browser. The
openclawprofile never interacts with your personal browser profile. - Inside this isolated lane, the agent opens tabs, reads pages, clicks, and types.
- The built-in
userprofile, by contrast, connects to your actual signed-in Chrome session through Chrome DevTools MCP.
What you get
- A dedicated browser profile called openclaw (default orange accent).
- Deterministic tab management (list, open, focus, close).
- Agent operations (click, type, drag, select), snapshots, screenshots, PDFs.
- Playwright-backed profiles store direct attachment navigations under the managed downloads directory and return
{ url, suggestedFilename, path }metadata after final-URL policy validation. - When an action immediately starts one or more downloads, Playwright-backed agent actions return a
downloadsarray with the same managed metadata. - A bundled
browser-automationskill teaches agents the snapshot, stable-tab, stale-ref, and manual-blocker recovery loop when the browser plugin is enabled. - Optional multi-profile support (
openclaw,work,remote, ...).
This browser is not meant for everyday use. It provides a safe, isolated environment for agent automation and verification.
On macOS, you can explicitly copy cookies from a Chrome-family system profile into a separate managed profile. The managed browser still uses its own user data directory; only the selected cookies are copied, while local storage and IndexedDB remain behind. See Profiles or the openclaw browser CLI reference for import commands and limitations.
Quick start
openclaw browser --browser-profile openclaw doctor
openclaw browser --browser-profile openclaw doctor --deep
openclaw browser --browser-profile openclaw status
openclaw browser --browser-profile openclaw start
openclaw browser --browser-profile openclaw open https://example.com
openclaw browser --browser-profile openclaw snapshot
"Browser disabled" means the plugin or browser.enabled is turned off; see
Configuration and Plugin control.
If openclaw browser is completely absent, or the agent reports the browser tool
as unavailable, go to Missing browser command or tool.
Plugin control
The default browser tool is a bundled plugin. Disable it to swap it with another plugin that registers the same browser tool name:
{
plugins: {
entries: {
browser: {
enabled: false,
},
},
},
}
Defaults require both plugins.entries.browser.enabled and browser.enabled=true. Disabling only the plugin removes the openclaw browser CLI, browser.request gateway method, agent tool, and control service as a single unit; your browser.* config remains intact for a replacement.
Browser configuration changes need a Gateway restart so the plugin can re-register its service.
Agent guidance
Tool-profile note: tools.profile: "coding" includes web_search and
web_fetch, but not the full browser tool. To allow the agent or a
spawned sub-agent to use browser automation, add browser at the profile
stage:
{
tools: {
profile: "coding",
alsoAllow: ["browser"],
},
}
For a single agent, use agents.entries.*.tools.alsoAllow: ["browser"].
tools.subagents.tools.allow: ["browser"] alone is insufficient because sub-agent
policy is applied after profile filtering.
The browser plugin provides two levels of agent guidance:
- The
browsertool description contains the compact always-on contract: choose the right profile, keep refs on the same tab, usetabId/labels for tab targeting, and load the browser skill for multi-step work. - The bundled
browser-automationskill carries the longer operating loop: check status/tabs first, label task tabs, snapshot before acting, resnapshot after UI changes, recover stale refs once, and report login/2FA/captcha or camera/microphone blockers as manual action instead of guessing.
Plugin-bundled skills appear in the agent's available skills when the plugin is enabled. The full skill instructions load on demand, so routine turns do not incur the full token cost.
Missing browser command or tool
If openclaw browser is unknown after an upgrade, browser.request is missing, or the agent reports the browser tool as unavailable, the usual cause is a plugins.allow list that omits browser and no root browser config block exists. Add it:
{
plugins: {
allow: ["telegram", "browser"],
},
}
An explicit root browser block (any key under browser, such as
browser.enabled=true or browser.profiles.<name>) activates the bundled
browser plugin even under a restrictive plugins.allow, matching bundled
channel config behavior. plugins.entries.browser.enabled=true and
tools.alsoAllow: ["browser"] do not by themselves substitute for allowlist membership.
Removing plugins.allow entirely also restores the default.
Profiles: openclaw, user, chrome
openclaw: managed, isolated browser (no extension required).user: built-in Chrome DevTools MCP attach profile for your real signed-in Chrome session. Chrome shows a blocking "Allow remote debugging?" prompt the first time OpenClaw attaches, so someone must be at the computer.chrome: built-in Chrome extension profile for your real signed-in Chrome session. Works from a phone with nobody at the desk because it drives tabs through the OpenClaw browser extension instead of the remote-debugging port, so there is no "Allow remote debugging?" prompt.
For agent browser tool calls:
- The default is to use the isolated
openclawbrowser. - When the user is away from the computer (Telegram, WhatsApp, etc.) and existing logged-in sessions matter, prefer
profile="chrome"(extension). - When the user is at the computer to approve the attach prompt and existing logged-in sessions matter, prefer
profile="user"(Chrome MCP). profileserves as the explicit override when you need a particular browser mode.
Set browser.defaultProfile: "openclaw" to enable managed mode as the default.
Configuration
Browser settings are configured in ~/.openclaw/openclaw.json.
{
browser: {
enabled: true, // default: true
evaluateEnabled: true, // default: true; false disables act:evaluate (arbitrary JS)
ssrfPolicy: {
// dangerouslyAllowPrivateNetwork: true, // opt in only for trusted private-network access
// hostnameAllowlist: ["*.example.com", "example.com"],
// allowedHostnames: ["localhost"],
},
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
tabCleanup: {
enabled: true, // default: true
},
// snapshotDefaults: { mode: "efficient" }, // default snapshot mode when the caller omits one
defaultProfile: "openclaw",
color: "#FF4500",
headless: false,
noSandbox: false,
attachOnly: false,
executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
profiles: {
openclaw: { cdpPort: 18800, color: "#FF4500" },
work: {
cdpPort: 18801,
color: "#0066CC",
headless: true,
executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
},
user: {
driver: "existing-session",
attachOnly: true,
color: "#00AA00",
},
brave: {
driver: "existing-session",
attachOnly: true,
userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser",
color: "#FB542B",
},
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
},
},
}
If a caller does not supply an explicit snapshotFormat or mode, browser.snapshotDefaults.mode: "efficient" alters the default snapshot extraction mode; per-call snapshot options are documented in the Browser control API.
Tab cleanup ownership
Session tab cleanup applies exclusively to tabs created by the OpenClaw browser tool using action: "open". Tabs that were already open, opened manually, or have unknown ownership are not adopted by OpenClaw. The browser.tabCleanup block governs periodic idle and cap sweeps for primary sessions; disabling it does not turn off explicit session lifecycle cleanup.
For host-local opens, ownership with a stable native CDP target and browser identity is recorded in the shared SQLite state. These records persist through a Gateway restart and stay eligible for /new and other session lifecycle cleanup, which includes subagent, cron, and ACP session endings. Records whose tool-facing target matches the native CDP target also remain eligible for idle and per-session cap sweeps after a restart. Chrome MCP target handles are process-local, so cold existing-session records wait for lifecycle cleanup instead of risking an idle sweep against activity that cannot be safely attributed after a restart. This durable path can cover OpenClaw-managed profiles, regular remote CDP profiles, and existing-session profiles with an explicit cdpUrl, as long as OpenClaw can resolve both the native target and a stable browser identity. Before closing a durable record, OpenClaw confirms that the configured profile and browser instance still match.
Chrome MCP --autoConnect, CDP endpoints whose /json/version response lacks a stable browser identity, and opens whose native target cannot be resolved remain process-local best-effort tracking. They can be cleaned up while that Gateway process is active, but they are not automatically closed after a Gateway restart. Tabs left open before durable tracking was available are not retroactively adopted; close those tabs manually.
Cleanup operates on a best-effort basis, not a guarantee that every eligible tab closes immediately. A transient ownership check or close failure leaves durable cleanup pending for a later retry. Retries are not unbounded: when the browser remains unreachable and the tab has gone unused for over a day, the tracking row is retired so the durable store cannot fill up with tabs that can never be verified again.
Screenshot vision (text-only model support)
When the main model is text-only (no vision/multimodal support), browser screenshots return image blocks that the model cannot read. Browser screenshots reuse the existing image-understanding configuration, so an image model configured for media understanding can describe screenshots as text without any browser-specific model settings.
{
tools: {
media: {
image: {
models: [
{ provider: "bytedance", model: "doubao-seed-2.0-pro" },
// Add fallback candidates; first success wins
{ provider: "openai", model: "gpt-4o" },
],
},
// Shared media models also work when tagged for image support.
// models: [{ provider: "openai", model: "gpt-4o", capabilities: ["image"] }],
},
},
agents: {
defaults: {
// Existing image-model defaults are also honored.
// imageModel: { primary: "openai/gpt-4o" },
},
},
}
How it works:
- The agent calls
browser screenshotand an image is captured to disk as usual. - The browser tool asks the existing image-understanding runtime whether it can describe the screenshot using configured media image models, shared media models, image-model defaults, or an auth-backed image provider.
- The vision model returns a text description, which is wrapped with
wrapExternalContent(prompt injection guard) and returned to the agent as a text block instead of an image block. - If image understanding is unavailable, skipped, or fails, the browser falls back to returning the original image block.
Screenshot image blocks are private tool results: the agent can inspect them, but OpenClaw does not automatically attach them to channel replies. To share a screenshot, ask the agent to send it explicitly with the message tool.
Use the existing tools.media.image / tools.media.models fields for model fallbacks, timeouts, byte limits, profiles, and provider request settings.
If the active main model already supports vision and no explicit image understanding model is configured, OpenClaw keeps the normal image result so the main model can read the screenshot directly.
Ports and reachability
- The control service binds to loopback on a port derived from
gateway.port(default18791= gateway + 2).OPENCLAW_GATEWAY_PORTtakes priority overgateway.port; either shifts the derived ports in the same family. - Local
openclawprofiles auto-assigncdpPort/cdpUrlfrom a range starting 9 ports above the control port (default18800-18899); set those only for remote CDP profiles or existing-session endpoint attach.cdpUrldefaults to the managed local CDP port when unset. - Remote and
attachOnlyCDP reachability, WebSocket handshakes, and local managed-Chrome startup use built-in deadlines. - Repeated managed Chrome launch/readiness failures are circuit-broken per profile. After several consecutive failures, OpenClaw pauses new launch attempts briefly instead of spawning Chromium on every browser tool call. Fix the startup problem, disable the browser if it is not needed, or restart the Gateway after repair.
SSRF policy
- Browser navigation and open-tab requests are preflight checked. During the action and bounded post-action grace, guarded Playwright interactions (click, coordinate click, hover, drag, scroll, select, press, type, form fill, and evaluate) intercept policy-denied top-level and subframe document loads before HTTP request bytes, then best-effort re-check the final
http(s)URL. - Before each fresh OpenClaw-managed Chrome launch, OpenClaw best-effort disables network prediction, suppressing Chromium's observed speculative preconnect for those denied loads. This is defense in depth, not a policy boundary: a browser reused across a control-service restart and other browser backends may not share the hardening. Playwright routing is still not a network firewall and does not intercept redirect hops, a popup's first request, Service Worker traffic, page code that runs after the bounded guard window, or every background/subresource path. Complete egress isolation requires owner-side isolation or a policy-enforcing proxy.
- In strict SSRF mode, remote CDP endpoint discovery and
/json/versionprobes (cdpUrl) are checked too. - Gateway/provider
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY, andNO_PROXYenvironment variables do not automatically proxy the OpenClaw-managed browser. Managed Chrome launches direct by default so provider proxy settings do not weaken browser SSRF checks. - OpenClaw-managed local CDP readiness probes and DevTools WebSocket connections bypass the managed network proxy for the exact launched loopback endpoint, so
openclaw browser startstill works when an operator proxy blocks loopback egress. - To proxy the managed browser itself, pass explicit Chrome proxy flags through
browser.extraArgs, such as--proxy-server=...or--proxy-pac-url=.... Strict SSRF mode blocks explicit browser proxy routing unless private-network browser access is intentionally enabled. browser.ssrfPolicy.dangerouslyAllowPrivateNetworkis off by default; enable only when private-network browser access is intentionally trusted.browser.ssrfPolicy.allowPrivateNetworkremains supported as a legacy alias.
Profile behavior
attachOnly: trueprevents any local browser from being started; it only connects to an existing instance.headlesssupports configuration at either the global level or for individual local managed profiles. A profile-specific setting takes precedence overbrowser.headless, allowing one locally launched profile to operate headlessly while another remains visible.- Both
POST /start?headless=trueandopenclaw browser start --headlesstrigger a one-time headless launch for local managed profiles without modifyingbrowser.headlessor the profile's configuration. Profiles using existing sessions, attach-only mode, or remote CDP reject this override because OpenClaw does not start browser processes for them. - On Linux systems lacking
DISPLAYorWAYLAND_DISPLAY, local managed profiles automatically run headless when neither the environment nor profile or global configuration explicitly selects headed mode. Use the unambiguous browser-level formopenclaw browser --json status; trailingopenclaw browser status --jsonalso functions becausestatushas no--jsonof its own. The command outputsheadlessSourceasenv,profile,config,request,linux-display-fallback, ordefault. OPENCLAW_BROWSER_HEADLESS=1forces headless operation for all local managed launches in the current process.OPENCLAW_BROWSER_HEADLESS=0forces headed mode for normal starts and provides a meaningful error on Linux hosts without a display server; an explicitstart --headlessrequest still takes priority for that specific launch.- The browser-control route and programmatic client preserve the human-readable
errorfrom the no-display error and expose the stable reasonno_display_for_headed_profile. Itsdetailscontain onlyprofile,requestedHeadless,headlessSource, anddisplayPresent, enabling API clients to pick the right fix without parsing message text. - For an active local managed profile, status and doctor queries use Chrome's browser-level CDP endpoint to inspect renderer, backend, device and driver, feature status, driver workarounds, and accelerated video capabilities. The result is cached for that browser process and fully available through
openclaw browser --json status. A passive status call does not start Chrome. Existing-session, extension, remote CDP, and sandbox browsers are separate and not examined through this managed-host path. - Headless managed Chrome still applies the conservative
--disable-gpudefault. The diagnostics do not turn on acceleration, add a global acceleration setting, or give sandbox browsers device access. executablePathcan be set globally or for individual local managed profiles. Profile-specific values overridebrowser.executablePath, so different managed profiles can use different Chromium-based browsers. Both forms accept~for your operating system's home directory.color(both top-level and per-profile) colors the browser UI to indicate which profile is active.- The default profile is
openclaw(managed standalone). UsedefaultProfile: "user"to choose the signed-in user browser. - Auto-detection order: system default browser if it is Chromium-based; otherwise Chrome, Brave, Edge, Chromium, Chrome Canary.
driver: "existing-session"uses the Chrome DevTools MCP instead of raw CDP. It can attach through Chrome MCP auto-connect or throughcdpUrlwhen you already have a DevTools endpoint for the running browser.driver: "extension"controls your signed-in Chrome through the OpenClaw Chrome extension. The relay owns its loopback endpoint, so these profiles do not acceptcdpUrl. This is the only signed-in-browser mode that works without anyone at the computer.- Set
browser.profiles.<name>.userDataDirwhen an existing-session profile should attach to a non-default Chromium user profile (Brave, Edge, etc.). This path also accepts~for your operating system's home directory.
Use Brave or another Chromium-based browser
If your system default browser is Chromium-based (Chrome/Brave/Edge/etc),
OpenClaw uses it automatically. Set browser.executablePath to override
auto-detection. Top-level and per-profile executablePath values accept ~
for your OS home directory:
openclaw config set browser.executablePath "/usr/bin/google-chrome"
openclaw config set browser.profiles.work.executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
Or set it in config, per platform:
macOS
{
browser: {
executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
},
}
Windows
{
browser: {
executablePath: "C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe",
},
}
Linux
{
browser: {
executablePath: "/usr/bin/brave-browser",
},
}
Per-profile executablePath only affects local managed profiles that OpenClaw
launches. existing-session profiles attach to an already-running browser
instead, and remote CDP profiles use the browser behind cdpUrl.
Local vs remote control
- Local control (default): The Gateway activates the loopback control service and can start a local browser.
- Remote control (node host): Deploy a node host on the machine with the browser; the Gateway proxies browser commands to it.
- Remote CDP: Configure
browser.profiles.<name>.cdpUrl(orbrowser.cdpUrl) to connect to a remote Chromium-based browser. In this scenario, OpenClaw will not start a local browser. - For externally managed CDP services on loopback (such as Browserless in
Docker published to
127.0.0.1), also setattachOnly: true. A loopback CDP withoutattachOnlyis considered a local OpenClaw-managed browser profile. headlessapplies only to local managed profiles that OpenClaw starts. It does not restart or modify existing-session or remote CDP browsers.executablePathfollows the same rule for local managed profiles. Changing it on a running local managed profile flags that profile for restart/reconcile so the next launch uses the new binary.
Stopping behavior varies by profile mode:
- local managed profiles:
openclaw browser stopterminates the browser process that OpenClaw started - attach-only and remote CDP profiles:
openclaw browser stopends the active control session and releases Playwright/CDP emulation overrides (viewport, color scheme, locale, timezone, offline mode, and similar state), even though OpenClaw did not start any browser process
Remote CDP URLs can include authentication:
- Query tokens (for example,
https://provider.example?token=<token>) - HTTP Basic auth (for example,
https://user:pass@provider.example)
OpenClaw preserves the authentication when calling /json/* endpoints and when connecting
to the CDP WebSocket. Prefer environment variables or secrets managers for
tokens instead of committing them to config files.
Node browser proxy (zero-config default)
If you run a node host on the machine that has your browser, OpenClaw can automatically route browser tool calls to that node without any extra browser configuration. This is the default path for remote gateways.
Notes:
- The node host exposes its local browser control server through a proxy command.
- Profiles come from the node's own
browser.profilesconfiguration (same as local). - The proxy command never allows persistent profile mutations (
create-profile,delete-profile,reset-profile) regardless ofallowProfiles; apply those changes directly on the node. nodeHost.browserProxy.allowProfilesis optional. Leave it empty for the legacy/default behavior: all configured profiles remain reachable through the proxy.- If you set
nodeHost.browserProxy.allowProfiles, OpenClaw treats it as a least-privilege boundary limiting which profile names the proxy will target. - Disable if you do not want it:
- On the node:
nodeHost.browserProxy.enabled=false - On the gateway:
gateway.nodes.browser.mode="off"(also accepts"auto"to pick a single connected browser node, or"manual"to require an explicit node parameter)
- On the node:
Browserless (hosted remote CDP)
Browserless is a hosted Chromium service that exposes CDP connection URLs over HTTPS and WebSocket. OpenClaw can use either form, but for a remote browser profile the simplest option is the direct WebSocket URL from Browserless' connection documentation.
Example:
{
browser: {
enabled: true,
defaultProfile: "browserless",
profiles: {
browserless: {
cdpUrl: "wss://production-sfo.browserless.io?token=<BROWSERLESS_API_KEY>",
color: "#00AA00",
},
},
},
}
Notes:
- Replace
<BROWSERLESS_API_KEY>with your actual Browserless token. - Choose the region endpoint that matches your Browserless account (refer to their documentation).
- If Browserless gives you an HTTPS base URL, you can either convert it to
wss://for a direct CDP connection or keep the HTTPS URL and let OpenClaw discover/json/version.
Browserless Docker on the same host
When Browserless is self-hosted in Docker and OpenClaw runs on the host, treat Browserless as an externally managed CDP service:
{
browser: {
enabled: true,
defaultProfile: "browserless",
profiles: {
browserless: {
cdpUrl: "ws://127.0.0.1:3000",
attachOnly: true,
color: "#00AA00",
},
},
},
}
The address in browser.profiles.browserless.cdpUrl must be reachable from the
OpenClaw process. Browserless must also advertise a matching reachable endpoint;
set Browserless EXTERNAL to that same public-to-OpenClaw WebSocket base, such
as ws://127.0.0.1:3000, ws://browserless:3000, or a stable private Docker
network address. If /json/version returns webSocketDebuggerUrl pointing at
an address OpenClaw cannot reach, CDP HTTP can appear healthy while the WebSocket
attach still fails.
Do not leave attachOnly unset for a loopback Browserless profile. Without
attachOnly, OpenClaw treats the loopback port as a local managed browser
profile and may report that the port is in use but not owned by OpenClaw.
Direct WebSocket CDP providers
Some hosted browser services expose a direct WebSocket endpoint instead of
the standard HTTP-based CDP discovery (/json/version). OpenClaw accepts three
CDP URL formats and selects the correct connection strategy automatically:
- HTTP(S) discovery -
http://host[:port]orhttps://host[:port]. OpenClaw calls/json/versionto discover the WebSocket debugger URL, then connects. No WebSocket fallback. - Direct WebSocket endpoints -
ws://host[:port]/devtools/<kind>/<id>orwss://...with a/devtools/browser|page|worker|shared_worker|service_worker/<id>path. OpenClaw connects directly via a WebSocket handshake and skips/json/versionentirely. - Bare WebSocket roots -
ws://host[:port]orwss://host[:port]with no/devtools/...path (for example Browserless, Browserbase). OpenClaw tries HTTP/json/versiondiscovery first (normalising the scheme tohttp/https); if discovery returns awebSocketDebuggerUrlit is used, otherwise OpenClaw falls back to a direct WebSocket handshake at the bare root. If the advertised WebSocket endpoint rejects the CDP handshake but the configured bare root accepts it, OpenClaw falls back to that root as well. This lets a barews://pointed at a local Chrome still connect, since Chrome only accepts WebSocket upgrades on the specific per-target path from/json/version, while hosted providers can still use their root WebSocket endpoint when their discovery endpoint advertises a short-lived URL that is not suitable for Playwright CDP.
openclaw browser doctor applies the same discovery-first, WebSocket-fallback logic used for runtime attach, so a bare-root URL that connects successfully is not flagged as unreachable by diagnostics.
Browserbase
Browserbase is a cloud service for operating headless browsers. It includes built-in CAPTCHA solving, stealth mode, and residential proxies.
{
browser: {
enabled: true,
defaultProfile: "browserbase",
profiles: {
browserbase: {
cdpUrl: "wss://connect.browserbase.com?apiKey=<BROWSERBASE_API_KEY>",
color: "#F97316",
},
},
},
}
Notes:
- Register and retrieve your API Key from the Overview dashboard.
- Swap
<BROWSERBASE_API_KEY>with your actual Browserbase API key. - Browserbase automatically spawns a browser session upon WebSocket connection, so no manual session creation is required.
- Check pricing for current free-tier limits and paid plans.
- Consult the Browserbase documentation for the full API reference, SDK guides, and integration examples.
Notte
Notte is a cloud service for running headless browsers. It provides built-in stealth, residential proxies, and a CDP-native WebSocket gateway.
{
browser: {
enabled: true,
defaultProfile: "notte",
profiles: {
notte: {
cdpUrl: "wss://us-prod.notte.cc/sessions/connect?token=<NOTTE_API_KEY>",
color: "#7C3AED",
},
},
},
}
Notes:
- Register and copy your API Key from the console settings page.
- Replace
<NOTTE_API_KEY>with your actual Notte API key. - Notte automatically creates a browser session on WebSocket connect, so no manual session creation is needed. The session is terminated when the WebSocket disconnects.
- See pricing for current free-tier limits and paid plans.
- Refer to the Notte docs for the full API reference, SDK guides, and integration examples.
Security
Key ideas:
- Browser control operates only on loopback; access is routed through the Gateway's authentication or node pairing.
- The standalone loopback browser HTTP API relies exclusively on shared-secret authentication: gateway token bearer auth,
x-openclaw-password, or HTTP Basic auth using the configured gateway password. - Tailscale Serve identity headers and
gateway.auth.mode: "trusted-proxy"do not authenticate this standalone loopback browser API. - If browser control is enabled without any shared-secret auth configured, OpenClaw generates and stores a browser-control credential at startup: a token when
gateway.auth.modeisnone, or a password when it istrusted-proxy(persisted viagateway.auth.passwordso out-of-process loopback clients can resolve it). Auto-generation is skipped when an explicit string credential is already configured for that mode, or whengateway.auth.modeispassword. - Set
gateway.auth.token,gateway.auth.password,OPENCLAW_GATEWAY_TOKEN, orOPENCLAW_GATEWAY_PASSWORDexplicitly if you want a stable secret you control rather than the auto-generated one.
Remote CDP tips:
- Favor encrypted endpoints (HTTPS or WSS) and short-lived tokens whenever possible.
- Do not embed long-lived tokens directly in configuration files.
- Keep the Gateway and any node hosts on a private network (Tailscale); avoid exposing them publicly.
- Treat remote CDP URLs and tokens as secrets; use environment variables or a secrets manager.
Profiles (multi-browser)
OpenClaw supports multiple named profiles (routing configurations). Profiles can be:
- openclaw-managed: a dedicated Chromium-based browser instance with its own user data directory and CDP port
- remote: an explicit CDP URL pointing to a Chromium-based browser running elsewhere
- existing session: your current Chrome profile, accessed via Chrome DevTools MCP auto-connect
Defaults:
- The
openclawprofile is created automatically if it does not exist. - The
userprofile is built-in for Chrome MCP existing-session attachment. - Existing-session profiles are opt-in beyond
user; create them with--driver existing-session. - Local CDP ports are assigned from the 18800-18899 range by default.
- Deleting a profile moves its local data directory to the Trash.
All control endpoints accept ?profile=<name>; the CLI uses --browser-profile.
Existing session via Chrome DevTools MCP
OpenClaw can also connect to an already running Chromium-based browser profile through the official Chrome DevTools MCP server. This reuses the tabs and login state already open in that browser profile.
Official background and setup references:
Built-in profile: user. Create your own custom existing-session profile if you want a different name, color, or browser data directory.
By default, the built-in user profile uses Chrome MCP auto-connect, which targets the default local Google Chrome profile. Use userDataDir for Brave, Edge, Chromium, or a non-default Chrome profile. ~ expands to your OS home directory:
{
browser: {
profiles: {
brave: {
driver: "existing-session",
attachOnly: true,
userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser",
color: "#FB542B",
},
},
},
}
Then, in the matching browser:
- Open that browser's inspect page for remote debugging.
- Enable remote debugging.
- Keep the browser running and approve the connection prompt when OpenClaw attaches.
Common inspect pages:
- Chrome:
chrome://inspect/#remote-debugging - Brave:
brave://inspect/#remote-debugging - Edge:
edge://inspect/#remote-debugging
Live attach smoke test:
openclaw browser --browser-profile user start
openclaw browser --browser-profile user status
openclaw browser --browser-profile user tabs
openclaw browser --browser-profile user snapshot --format ai
What success looks like:
statusshowsdriver: existing-sessionstatusshowstransport: chrome-mcpstatusshowsrunning: truetabslists your already-open browser tabssnapshotreturns refs from the selected live tab
What to check if attach does not work:
- the target Chromium-based browser is version
144+ - remote debugging is enabled in that browser's inspect page
- the browser showed and you accepted the attach consent prompt
- if Chrome was started with an explicit
--remote-debugging-port, setbrowser.profiles.<name>.cdpUrlto that DevTools endpoint instead of relying on Chrome MCP auto-connect openclaw doctormigrates old extension-based browser config and checks that Chrome is installed locally for default auto-connect profiles, but it cannot enable browser-side remote debugging for you
Agent usage:
profile="user"is the right choice when you need the browser state the user is currently logged into.- If you are working with a custom existing-session profile, provide the exact profile name.
- Pick this mode only when the user is present to approve the attach dialog.
- Either the Gateway or the node host can start
npx chrome-devtools-mcp@latest --autoConnect.
Remarks:
- This method carries more risk than the isolated
openclawprofile, since it can operate inside your authenticated browser session. - OpenClaw does not start the browser for this driver; it only connects to an existing one.
- OpenClaw relies on the official Chrome DevTools MCP
--autoConnectprotocol here. WhenuserDataDiris configured, it is forwarded to point at that user data directory. - An existing-session profile can attach on the chosen host or through a linked browser node. If Chrome runs on a different machine and no browser node is linked, fall back to remote CDP or a node host.
- Chrome MCP targets and snapshot references are confined to a single MCP subprocess. After that process is restarted, execute
browser tabsagain, explicitly pick a new target before doing target-specific work, and capture a fresh snapshot before referencing anything. Each reference is only valid for its target and the most recent snapshot. Old aliases do not carry over to a replacement tab, even if its URL is identical. - Currently, Chrome DevTools MCP directs page tools using a numeric page ID local to the process. Process-scoped handles prevent reuse after a subprocess replacement, but swapping the browser context within the same process between consecutive tool calls can still redirect an action. Full atomic routing depends on upstream page-tool support for stable target identifiers.
Custom Chrome MCP launch
Replace the default spawned Chrome DevTools MCP server per profile when the standard npx chrome-devtools-mcp@latest workflow does not fit your needs (offline hosts, pinned versions, vendored binaries):
| Field | What it does |
|---|---|
mcpCommand | Binary to launch instead of npx. Used as given; absolute paths are respected. |
mcpArgs | Argument list passed directly to mcpCommand. Replaces the default chrome-devtools-mcp@latest --autoConnect arguments. |
When cdpUrl is defined on an existing-session profile, OpenClaw omits --autoConnect and automatically passes the endpoint to Chrome MCP:
http(s)://...→--browserUrl <url>(DevTools HTTP discovery endpoint).ws(s)://...→--wsEndpoint <url>(direct CDP WebSocket).
Endpoint flags and userDataDir are mutually exclusive: if cdpUrl is set, userDataDir is ignored when launching Chrome MCP, because Chrome MCP connects to the already running browser via the endpoint instead of opening a profile directory.
Existing-session feature limitations
Compared to the managed openclaw profile, existing-session drivers face more restrictions:
- Screenshots - Full page captures and
--refelement captures are supported; CSS--elementselectors are not. You do not need Playwright for page or ref-based element screenshots. (--full-pagecannot be used together with--refor--elementon any profile, including existing-session ones.) - Actions -
click,type,hover,scrollIntoView,drag, andselectrequire snapshot references (CSS selectors are not accepted).click-coordsclicks at visible viewport coordinates and does not need a snapshot ref.clickonly supports the left mouse button (no button overrides or modifier keys).typedoes not supportslowly=true; instead usefillorpress.pressdoes not supportdelayMs.type,hover,scrollIntoView,drag,select, andfilldo not allow per-calltimeoutMsoverrides;evaluatedoes.selectaccepts a single value.batchis unsupported; send actions one at a time. - Wait / upload / dialog -
wait --urlsupports exact, substring, and glob patterns (same as the managed path);wait --load networkidleis unsupported on existing-session profiles (it works on managed and raw/remote CDP profiles). Upload hooks needreforinputRef, one file per call, with no CSSelement. Dialog hooks do not support timeout overrides ordialogId. - Dialog visibility - Managed browser action responses include
blockedByDialogandbrowserState.dialogs.pendingwhen an action opens a modal dialog; snapshots also reflect pending dialog state. Respond withbrowser dialog --accept/--dismiss --dialog-id <id>while a dialog is pending. Dialogs handled outside OpenClaw appear underbrowserState.dialogs.recent. - Managed-only features - PDF export, download interception, and
responsebodystill require the managed browser path.
Isolation guarantees
- Dedicated user data dir: your personal browser profile is never touched.
- Dedicated ports:
9222is avoided to prevent conflicts with development workflows. - Deterministic tab control:
tabsreturnssuggestedTargetIdfirst, then stabletabIdhandles such ast1, optional labels, and the rawtargetId. Agents should reusesuggestedTargetId; raw ids remain available for debugging and compatibility.
Browser selection
When launching locally, OpenClaw picks the first available:
- Chrome
- Brave
- Edge
- Chromium
- Chrome Canary
You can override with browser.executablePath.
Platforms:
- macOS: checks
/Applicationsand~/Applications. - Linux: checks common Chrome/Brave/Edge/Chromium locations under
/usr/bin,/snap/bin,/opt/google,/opt/brave.com,/usr/lib/chromium, and/usr/lib/chromium-browser, plus Playwright-managed Chromium underPLAYWRIGHT_BROWSERS_PATHor~/.cache/ms-playwright. - Windows: checks common install locations.
Control API (optional)
For debugging and scripting, the Gateway offers a small loopback-only HTTP control API along with a corresponding openclaw browser command-line tool (snapshots, references, wait power-ups, JSON output, debug workflows). Consult the Browser control API for complete documentation.
Troubleshooting
For Linux-specific problems (particularly with snap Chromium), refer to Browser troubleshooting.
For configurations involving a WSL2 Gateway paired with Windows Chrome, see WSL2 + Windows + remote Chrome CDP troubleshooting.
CDP startup failure vs navigation SSRF block
These represent distinct failure categories, each pointing to separate code paths.
- CDP startup or readiness failure indicates OpenClaw cannot verify the browser control plane is operational.
- Navigation SSRF block means the browser control plane is functioning, but a page navigation request has been denied by policy.
Typical examples:
- CDP startup or readiness failure:
Chrome CDP websocket for profile "openclaw" is not reachable after startRemote CDP for profile "<name>" is not reachable at <cdpUrl>Port <port> is in use for profile "<name>" but not by openclawwhen a loopback external CDP service is configured withoutattachOnly: true
- Navigation SSRF block:
open,navigate, snapshot, or tab-opening operations fail with a browser or network policy error whilestartandtabsremain functional
Use this minimal procedure to distinguish between them:
openclaw browser --browser-profile openclaw start
openclaw browser --browser-profile openclaw tabs
openclaw browser --browser-profile openclaw open https://example.com
Interpreting the results:
- When
startfails withnot reachable after start, start by troubleshooting CDP readiness. - If
startsucceeds buttabsfails, the control plane is still not healthy. Treat this as a CDP connectivity issue, not a page navigation one. - When
startandtabssucceed butopenornavigatefails, the browser control plane is operational and the problem lies in navigation policy or the target page. - If
start,tabs, andopenall succeed, the basic managed-browser control path is healthy.
Important behavioral notes:
- Even without configuring
browser.ssrfPolicy, the browser configuration defaults to a fail-closed SSRF policy object. - For the local loopback
openclawmanaged profile, CDP health checks deliberately skip browser SSRF reachability enforcement for OpenClaw's own local control plane. - Navigation protection operates independently. A successful
startortabsresult does not guarantee that a subsequentopenornavigatetarget will be permitted.
Security recommendations:
- Do not relax browser SSRF policy by default.
- Favor narrow host exceptions such as
hostnameAllowlistorallowedHostnamesover broad private-network access. - Use
dangerouslyAllowPrivateNetwork: trueonly in intentionally trusted environments where private-network browser access is required and has been reviewed.
Agent tools + how control works
The agent receives one tool for browser automation:
browser- doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
How it maps:
browser snapshotprovides a stable UI tree (AI or ARIA).browser actuses snapshotrefidentifiers to click, type, drag, or select.browser screenshotcaptures pixel data (full page, element, or labeled references).browser doctorverifies Gateway, plugin, profile, browser, and tab readiness.browseraccepts:profileto select a named browser profile (openclaw, chrome, or remote CDP).target(sandbox|host|node) to specify the browser's location.- In sandboxed sessions,
target: "host"requiresagents.defaults.sandbox.browser.allowHostControl=true. - If
targetis omitted: sandboxed sessions default tosandbox, non-sandbox sessions default tohost. - When a browser-capable node is connected, the tool may auto-route to it unless you pin
target="host"ortarget="node".
This approach keeps the agent deterministic and avoids fragile selectors.
Related
- Tools Overview - a complete list of available agent tools
- Sandboxing - browser control within sandboxed environments
- Security - risks and hardening for browser control