OpenClaw Managed Browser: Dedicated Agent Profile
Learn how OpenClaw launches a dedicated browser profile for agent-controlled browsing, including tab management, page interaction, and downloads. This page is for developers and users who need isolated 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 is able to launch its own dedicated Chrome/Brave/Edge/Chromium profile under agent control. This runs through a compact local control service inside the Gateway, restricted to loopback, and stays separate from your everyday browser.
- Treat this as a browser reserved for the agent alone. The
openclawprofile never comes into contact with your personal browsing profile. - Within this isolated lane, the agent can open tabs, read page content, perform clicks, and enter text.
- The built-in
userprofile, by contrast, connects to your actual signed-in Chrome session through Chrome DevTools MCP.
What you get
- A dedicated profile named openclaw (defaulting to an orange accent).
- Predictable tab management (list/open/focus/close).
- Agent operations (click/type/drag/select), page snapshots, screenshots, and PDF generation.
- Answering questions based on readable page text without sending back a complete snapshot.
- Playwright-backed profiles record direct attachment navigations under the managed downloads directory and return
{ url, suggestedFilename, path }metadata once final-URL policy validation passes. - When an action from a Playwright-backed agent immediately starts one or more downloads, it returns a
downloadsarray carrying the same managed metadata. - A bundled
browser-automationskill teaches agents the snapshot, stable-tab, stale-ref, and manual-blocker recovery loop whenever the browser plugin is active. - Optional support for multiple profiles (
openclaw,work,remote, and so on).
This browser is not meant for daily use. It provides a safe, separated surface for agent automation and verification tasks.
On macOS, you can explicitly pull cookies from a Chrome-family system profile into a separate managed profile. The managed browser keeps its own user data directory; only the chosen cookies get copied, while local storage and IndexedDB remain untouched. Refer to Profiles or the openclaw browser CLI reference for import commands and their 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
When the plugin or browser.enabled is switched off, that counts as "Browser disabled"; check Configuration and Plugin control for details.
If openclaw browser is absent altogether, or the agent indicates the browser tool is not reachable, head to Missing browser command or tool.
Plugin control
The default browser tool ships as a bundled plugin. To swap in a different plugin that registers the same browser tool name, disable it first:
{
plugins: {
entries: {
browser: {
enabled: false,
},
},
},
}
For defaults to work, both plugins.entries.browser.enabled and browser.enabled=true are required. Turning off only the plugin removes the openclaw browser CLI, the browser.request gateway method, the agent tool, and the control service as a single unit; your browser.* configuration remains intact for a replacement.
After changing browser config, restart the Gateway so the plugin can re-register its service.
Agent guidance
Tool-profile note: tools.profile: "coding" comes with web_search and web_fetch, but the full browser tool is not part of it. To give the agent or a spawned sub-agent browser automation capabilities, add browser at the profile stage:
{
tools: {
profile: "coding",
alsoAllow: ["browser"],
},
}
For a single agent, go with agents.entries.*.tools.alsoAllow: ["browser"]. Relying on tools.subagents.tools.allow: ["browser"] alone falls short, since sub-agent policy gets applied only after profile filtering.
The browser plugin provides agent guidance at two levels:
- The
browsertool description contains the compact always-on contract: choose the right profile, keep refs on the same tab, target tabs withtabId/labels, and load the browser skill for multi-step tasks. - The bundled
browser-automationskill carries the extended operating loop: check status/tabs first, label task tabs, snapshot before acting, resnapshot after UI changes, recover stale refs once, and flag login/2FA/captcha or camera/microphone blockers as manual action rather than guessing.
When the plugin is enabled, its bundled skills show up in the agent's available skills list. The full skill instructions load on demand, so routine turns avoid paying the entire token cost.
For page text, opt for a selector-scoped snapshot or act:evaluate that returns only the relevant text or structured data, then let the active agent model reason over that bounded result. Use efficient snapshots for controls and action discovery; they deliberately leave out most non-interactive prose.
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 typical culprit is a plugins.allow list that leaves out browser and no root browser config block exists. Add it:
{
plugins: {
allow: ["telegram", "browser"],
},
}
An explicit root browser block (any key under browser, like browser.enabled=true or browser.profiles.<name>) turns on the bundled browser plugin even under a restrictive plugins.allow, mirroring bundled channel config behavior. plugins.entries.browser.enabled=true and tools.alsoAllow: ["browser"] by themselves do not replace allowlist membership. Removing plugins.allow entirely also brings back the default.
Profiles: openclaw, user, chrome
openclaw: managed, isolated browser (no extension needed).user: built-in Chrome DevTools MCP attach profile for your real signed-in Chrome session. The first time OpenClaw attaches, Chrome displays a blocking "Allow remote debugging?" prompt, so someone needs to be present 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:
- By default, the isolated
openclawbrowser is used. - When existing logged-in sessions matter and the user is away from the computer (Telegram, WhatsApp, etc.), choose
profile="chrome"(extension). - When existing logged-in sessions matter and the user is at the computer to accept the attach prompt, choose
profile="user"(Chrome MCP). profileis the explicit override for forcing a particular browser mode.
To make managed mode the default, set browser.defaultProfile: "openclaw".
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
// allowedHostnames: ["localhost"],
// allowRfc2544BenchmarkRange: true, // trusted fake-IP proxy range
// allowIpv6UniqueLocalRange: true, // trusted fake-IP proxy IPv6 range
},
// 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" },
},
},
}
When a caller does not pass an explicit snapshotFormat or mode, the default snapshot extraction mode is changed by browser.snapshotDefaults.mode: "efficient"; per-call snapshot options are documented in the Browser control API.
On drivers with stable document identity, repeated AI or role snapshots of the same tab, document, and option family mark newly appeared ref-bearing elements with [new]. The first snapshot, and the first snapshot after navigation, establishes an unmarked baseline. Deltas are omitted from existing-session snapshots.
Tab cleanup ownership
Session tab cleanup only affects tabs created by the OpenClaw browser tool with action: "open". OpenClaw does not adopt tabs that were already open, opened by the user, or otherwise have unknown ownership. Periodic idle and cap sweeps for primary sessions are governed by the browser.tabCleanup block; disabling it does not disable explicit session lifecycle cleanup.
For host-local opens, ownership with a stable native CDP target and browser identity is stored in the shared SQLite state. Those records survive a Gateway restart and remain eligible for /new and other session lifecycle cleanup; session lifecycle cleanup includes subagent, cron, and ACP session endings. Records whose tool-facing target is the native CDP target also remain eligible for idle and per-session cap sweeps after restart. Chrome MCP target handles are process-local, so cold existing-session records wait for lifecycle cleanup rather than risking an idle sweep against activity that cannot be attributed safely after restart. This durable path can cover OpenClaw-managed profiles, regular remote CDP profiles, and existing-session profiles with an explicit cdpUrl, provided OpenClaw can resolve both the native target and a stable browser identity. Before closing a durable record, OpenClaw verifies 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 running, 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 is best-effort, 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 stays 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:
- 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
- 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.allowedHostnamesgrants exact hosts while the rest of the private network remains blocked.browser.ssrfPolicy.allowRfc2544BenchmarkRangeandbrowser.ssrfPolicy.allowIpv6UniqueLocalRangenarrowly allow trusted fake-IP proxy ranges.browser.ssrfPolicy.allowPrivateNetworkremains supported as a legacy alias.
Profile behavior
- Setting
attachOnly: truemeans a local browser is never started; OpenClaw only connects when one is already active. headlessworks either globally or for an individual local managed profile. A profile-level setting takes precedence overbrowser.headless, letting one locally launched profile run headless while another stays visible.POST /start?headless=trueandopenclaw browser start --headlessask for a single headless launch of local managed profiles without touchingbrowser.headlessor profile configuration. Existing-session, attach-only, and remote CDP profiles turn down this override, since OpenClaw does not start those browser processes.- On Linux machines lacking
DISPLAYorWAYLAND_DISPLAY, local managed profiles fall back to headless on their own when neither the environment nor profile/global config picks headed mode explicitly. Use the clear browser-level formopenclaw browser --json status; a trailingopenclaw browser status --jsonis accepted as well, becausestatushas no--jsonof its own. The command outputsheadlessSourceasenv,profile,config,request,linux-display-fallback, ordefault. OPENCLAW_BROWSER_HEADLESS=1forces headless operation for local managed launches in the current process.OPENCLAW_BROWSER_HEADLESS=0forces headed mode for normal starts and gives a useful error on Linux hosts with no display server; an explicitstart --headlessrequest still takes priority for that single launch.- The browser-control route and programmatic client keep the human-readable
errorfrom the no-display error and also expose the stable reasonno_display_for_headed_profile. Itsdetailshold onlyprofile,requestedHeadless,headlessSource, anddisplayPresent, so API clients can pick the right fix without matching message text. - For a running local managed profile, status and doctor query Chrome's browser-level CDP endpoint for renderer, backend, device/driver, feature status, driver workarounds, and accelerated video capabilities. That result is cached for the browser process and shown in full by
openclaw browser --json status. A passive status call does not start Chrome. Existing-session, extension, remote CDP, and sandbox browsers stay separate and are not checked through this managed-host path. - Headless managed Chrome still relies on the conservative
--disable-gpudefault. The diagnostics do not enable acceleration, add a global acceleration setting, or give sandbox browser device access. executablePathcan be set globally or per local managed profile. Profile-level values overridebrowser.executablePath, so different managed profiles can launch different Chromium-based browsers. Both forms accept~for your OS home directory.color(top-level and per-profile) colors the browser UI so you can tell which profile is active.- Default profile is
openclaw(managed standalone). UsedefaultProfile: "user"to opt into the signed-in user browser. - Auto-detect order: system default browser if Chromium-based; otherwise Chrome, Brave, Edge, Chromium, Chrome Canary.
driver: "existing-session"uses 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"drives 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 with nobody 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 OS 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 starts the loopback control service and can launch a local browser.
- Remote control (node host): run a node host on the machine that has the browser; the Gateway proxies browser actions to it.
- Remote CDP: set
browser.profiles.<name>.cdpUrl(orbrowser.cdpUrl) to attach to a remote Chromium-based browser. In this case, OpenClaw will not launch a local browser. - For externally managed CDP services on loopback (for example Browserless in
Docker published to
127.0.0.1), also setattachOnly: true. Loopback CDP withoutattachOnlyis treated as a local OpenClaw-managed browser profile. headlessonly affects local managed profiles that OpenClaw launches. It does not restart or change existing-session or remote CDP browsers.executablePathfollows the same local managed profile rule. Changing it on a running local managed profile marks that profile for restart/reconcile so the next launch uses the new binary.
Stopping behavior differs by profile mode:
- local managed profiles:
openclaw browser stopstops the browser process that OpenClaw launched - attach-only and remote CDP profiles:
openclaw browser stopcloses the active control session and releases Playwright/CDP emulation overrides (viewport, color scheme, locale, timezone, offline mode, and similar state), even though no browser process was launched by OpenClaw
Remote CDP URLs can include auth:
- Query tokens (e.g.,
https://provider.example?token=<token>) - HTTP Basic auth (e.g.,
https://user:pass@provider.example)
OpenClaw preserves the auth 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 auto-route browser tool calls to that node without any extra browser config. This is the default path for remote gateways.
Notes:
- The node host exposes its local browser control server via a proxy command.
- Profiles come from the node's own
browser.profilesconfig (same as local). - The proxy command never allows persistent profile mutations (
create-profile,delete-profile,reset-profile) regardless ofallowProfiles; make those changes on the node directly. 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 don't 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 param)
- 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 docs.
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 real Browserless token. - Choose the region endpoint that matches your Browserless account (see their docs).
- 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 look 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 rather than
the standard HTTP-based CDP discovery (/json/version). OpenClaw accepts three
CDP URL shapes and picks the right 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 (e.g. 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 approach as runtime attach, so a bare-root URL that establishes a connection will not be flagged as unreachable by diagnostics.
Browserbase
Browserbase offers a cloud service for operating headless browsers, featuring integrated CAPTCHA solving, stealth capabilities, 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 initiates a browser session automatically upon WebSocket connection, eliminating the need for manual session setup.
- Check pricing for current free-tier allowances and subscription options.
- Consult the Browserbase docs for the complete API reference, SDK guides, and integration examples.
Notte
Notte provides a cloud platform for headless browser execution, with built-in stealth features, 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:
- Sign up and copy your API Key from the console settings page.
- Replace
<NOTTE_API_KEY>with your real Notte API key. - Notte creates a browser session automatically on WebSocket connect, so manual session creation is unnecessary. The session terminates when the WebSocket closes.
- 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
Core concepts:
- Browser control is restricted to loopback; access is mediated by the Gateway's auth or node pairing.
- The standalone loopback browser HTTP API relies exclusively on shared-secret auth: 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"are not accepted for authenticating this standalone loopback browser API. - When browser control is active and no shared-secret auth is set, OpenClaw generates and stores a browser-control credential at startup: a token if
gateway.auth.modeequalsnone, or a password if it istrusted-proxy(saved viagateway.auth.passwordso out-of-process loopback clients can retrieve it). This auto-generation is bypassed when an explicit string credential already exists for that mode, or whengateway.auth.modeis set topassword. - Set
gateway.auth.token,gateway.auth.password,OPENCLAW_GATEWAY_TOKEN, orOPENCLAW_GATEWAY_PASSWORDexplicitly if you prefer a stable secret you manage rather than the auto-generated one.
Remote CDP guidance:
- Favor encrypted endpoints (HTTPS or WSS) and short-lived tokens whenever feasible.
- Do not embed long-lived tokens directly in configuration files.
- Place the Gateway and node hosts on a private network (Tailscale); avoid exposing them publicly.
- Handle remote CDP URLs and tokens as secrets; use environment variables or a secrets manager.
Profiles (multi-browser)
OpenClaw supports multiple named profiles (routing configs). Profiles fall into these categories:
- 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 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 attach. - Beyond
user, existing-session profiles are opt-in; create them with--driver existing-session. - Local CDP ports default to the 18800-18899 range.
- Removing a profile sends its local data directory to Trash.
All control endpoints accept ?profile=<name>; the CLI uses --browser-profile.
Existing session via Chrome DevTools MCP
OpenClaw can also connect to a running Chromium-based browser profile via the official Chrome DevTools MCP server. This reuses the tabs and login state already present in that browser profile.
Official background and setup references:
Built-in profile: user. Create your own custom existing-session profile if you need 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:
- Navigate to that browser's inspect page for remote debugging.
- Turn on remote debugging.
- Leave the browser running and accept 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
Signs of success:
statusdisplaysdriver: existing-sessionstatusdisplaystransport: chrome-mcpstatusdisplaysrunning: truetabslists your already-open browser tabssnapshotreturns refs from the selected live tab
Troubleshooting steps if attach fails:
- the target Chromium-based browser is version
144+ - remote debugging is enabled on that browser's inspect page
- the browser appeared and you approved the attach consent prompt
- if Chrome was launched 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 verifies that Chrome is installed locally for default auto-connect profiles, but it cannot enable browser-side remote debugging for you
Agent use:
- Pick
profile="user"whenever the user's signed-in browser state is what you need. - When relying on a custom existing-session profile, hand over that profile's explicit name.
- Reserve this mode for moments when the user is present to approve the attach prompt.
- Both the Gateway and the node host are able to start
npx chrome-devtools-mcp@latest --autoConnect.
Notes:
- This route carries more risk than the isolated
openclawprofile, since it can operate inside your signed-in browser session. - For this driver, OpenClaw never launches the browser; it only connects to one.
- OpenClaw follows the official Chrome DevTools MCP
--autoConnectprocedure here. IfuserDataDiris configured, it is forwarded to point at that user data directory. - Existing-session can connect either on the chosen host or through a linked browser node. When Chrome runs elsewhere and no browser node is linked, fall back to remote CDP or a node host.
- Chrome MCP targets and snapshot refs stay confined to a single MCP subprocess. After that process is restarted, rerun
browser tabs, explicitly choose a new target before any target-specific operation, and capture a fresh snapshot prior to using refs. A ref holds only for its own target and the latest snapshot. Old aliases never carry over to a replacement tab, even if the URL matches. - Chrome DevTools MCP currently dispatches page tools using a numeric page ID local to the process. Process-scoped handles block reuse across subprocess replacement, yet an in-process browser-context swap between consecutive tool calls can still redirect an action. Fully atomic routing depends on upstream page-tool support for stable target IDs.
Custom Chrome MCP launch
Override the spawned Chrome DevTools MCP server on a per-profile basis when the default npx chrome-devtools-mcp@latest flow does not fit (offline hosts, pinned versions, vendored binaries):
| Field | What it does |
|---|---|
mcpCommand | Executable to spawn instead of npx. Resolved as-is; absolute paths are honored. |
mcpArgs | Argument array passed verbatim to mcpCommand. Replaces the default chrome-devtools-mcp@latest --autoConnect arguments. |
When cdpUrl is set on an existing-session profile, OpenClaw bypasses --autoConnect and hands the endpoint to Chrome MCP on its own:
http(s)://...→--browserUrl <url>(DevTools HTTP discovery endpoint).ws(s)://...→--wsEndpoint <url>(direct CDP WebSocket).
Endpoint flags and userDataDir are mutually exclusive: once cdpUrl is set, userDataDir gets ignored for Chrome MCP launch, because Chrome MCP connects to the browser already running behind the endpoint instead of opening a profile directory.
Existing-session feature limitations
Existing-session drivers face tighter limits than the managed openclaw profile:
- Screenshots - full-page captures and element-level captures via
--refare supported; CSS--elementselectors are not. Neither page screenshots nor ref-based element screenshots require Playwright. (On any profile, including existing-session ones,--full-pagecannot be paired with--refor--element.) - Actions -
click,type,hover,scrollIntoView,drag, andselectall depend on snapshot refs; CSS selectors won't work for them.click-coordsoperates on visible viewport coordinates and skips the snapshot ref requirement.clickonly handles the left button, with no modifier keys or button overrides. Fortype,slowly=trueis unsupported; turn tofillorpressinstead.presslacks support fordelayMs. Whiletype,hover,scrollIntoView,drag,select, andfillreject per-calltimeoutMsoverrides,evaluateaccepts them.selecttakes just one value. Sincebatchis unavailable, dispatch actions one by one. - Wait / upload / dialog -
wait --urlhandles exact matches, substrings, and glob patterns, mirroring the managed path; existing-session profiles don't supportwait --load networkidle, though managed and raw/remote CDP profiles do. Upload hooks needreforinputRef, process a single file at a time, and ignore CSSelement. Dialog hooks can't accept timeout overrides ordialogId. - Dialog visibility - When an action triggers a modal dialog, managed browser action responses carry
blockedByDialogandbrowserState.dialogs.pending; snapshots also reflect the pending dialog state. While a dialog is waiting, reply withbrowser dialog --accept/--dismiss --dialog-id <id>. Dialogs that OpenClaw doesn't handle show up underbrowserState.dialogs.recent. - Managed-only features - PDF export, download interception, and
responsebodycontinue to require the managed browser route.
Isolation guarantees
- Dedicated user data dir: your personal browser profile stays untouched.
- Dedicated ports:
9222is avoided to keep dev workflows collision-free. - Deterministic tab control:
tabsgivessuggestedTargetIdfirst, followed by stabletabIdhandles liket1, optional labels, and the rawtargetId. Agents should stick withsuggestedTargetId; raw ids stay available for debugging and compatibility.
Browser selection
For local launches, OpenClaw selects the first free option from:
- Chrome
- Brave
- Edge
- Chromium
- Chrome Canary
browser.executablePath lets you override this.
Platforms:
- macOS: looks at
/Applicationsand~/Applications. - Linux: scans standard Chrome/Brave/Edge/Chromium paths 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: scans standard install directories.
Control API (optional)
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 for the full reference.
Troubleshooting
For Linux-specific issues (especially snap Chromium), see Browser troubleshooting.
For WSL2 Gateway + Windows Chrome split-host setups, see WSL2 + Windows + remote Chrome CDP troubleshooting.
CDP startup failure vs navigation SSRF block
These are different failure classes and they point to different code paths.
- CDP startup or readiness failure means OpenClaw cannot confirm that the browser control plane is healthy.
- Navigation SSRF block means the browser control plane is healthy, but a page navigation target is rejected by policy.
Common 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 flows fail with a browser/network policy error whilestartandtabsstill work
Use this minimal sequence to separate the two:
openclaw browser --browser-profile openclaw start
openclaw browser --browser-profile openclaw tabs
openclaw browser --browser-profile openclaw open https://example.com
How to read the results:
- If
startfails withnot reachable after start, troubleshoot CDP readiness first. - If
startsucceeds buttabsfails, the control plane is still unhealthy. Treat this as a CDP reachability problem, not a page-navigation problem. - If
startandtabssucceed butopenornavigatefails, the browser control plane is up and the failure is in navigation policy or the target page. - If
start,tabs, andopenall succeed, the basic managed-browser control path is healthy.
Important behavior details:
- Browser config defaults to a fail-closed SSRF policy object even when you do not configure
browser.ssrfPolicy. - For the local loopback
openclawmanaged profile, CDP health checks intentionally skip browser SSRF reachability enforcement for OpenClaw's own local control plane. - Navigation protection is separate. A successful
startortabsresult does not mean a lateropenornavigatetarget is allowed.
Security guidance:
- Do not relax browser SSRF policy by default.
- Prefer 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 reviewed.
Agent tools + how control works
The agent gets one tool for browser automation:
browser- doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
How it maps:
browser snapshotreturns a stable UI tree (AI or ARIA).browser navigatealso returns the loaded page's snapshot inline (efficient interactive tier, so the payload stays compact and bounded), so the agent does not need a follow-up snapshot call. Batchactresults that report a cross-document navigation include the same fresh page state. Navigations that resolve to a download skip it.browser actuses the snapshotrefIDs to click/type/drag/select.browser screenshotcaptures pixels (full page, element, or labeled refs).browser doctorchecks Gateway, plugin, profile, browser, and tab readiness.browseraccepts:profileto choose a named browser profile (openclaw, chrome, or remote CDP).target(sandbox|host|node) to select where the browser lives.- In sandboxed sessions,
target: "host"requiresagents.defaults.sandbox.browser.allowHostControl=true. - If
targetis omitted: sandboxed sessions default tosandbox, non-sandbox sessions default tohost. - If a browser-capable node is connected, the tool may auto-route to it unless you pin
target="host"ortarget="node".
This keeps the agent deterministic and avoids brittle selectors.
Related
- Tools Overview - a complete list of every tool the agent can use
- Sandboxing - managing browser control within sandboxed setups
- Security - threats tied to browser control and how to mitigate them