OpenClaw Browser CLI Guide: Which Profile Your Agent Should Get, and the Traps in Each
openclaw browser drives a Chromium browser for your agent, and the one decision that matters is the profile. Give the agent the isolated openclaw profile by default, and use import-profile --domains when it needs a login. Attach the signed-in user profile only for jobs you are sitting in front of, because it needs you to approve the attach and it acts inside your real Chrome session.
The pages ranking for this are the official CLI reference, the docs.claw.so fork, and a couple of third-party walkthroughs. The reference lists every subcommand in one long scroll, which is useful once you know what you want. It does not say which profile to hand an agent that runs from cron at 3 a.m., or that one empty JSON object in your config cuts the agent off from your local dev server. Those are the parts below.
The profile is the whole decision
Every command takes --browser-profile, and every profile has a driver. The driver decides who launches the browser, whose cookies are in it, and which commands work at all. Here are the options people actually choose between:
| Profile | Driver | Who launches the browser | Your logins | Runs unattended | Key trade-off |
|---|---|---|---|---|---|
openclaw (default) | openclaw | OpenClaw, headless by default, CDP port from 18800 to 18899 | None | Yes | Logged out of everything until you give it cookies |
Imported (import-profile --into work) | openclaw | OpenClaw | A copy, limited by --domains | Yes | Copied sessions expire, so you re-import |
user | existing-session (Chrome DevTools MCP) | You. OpenClaw only attaches | All of them, live | No, you approve the attach prompt | Chrome 144+, a shorter command list, and full access to your real session |
| Custom existing-session (e.g. Brave) | existing-session | You | That browser's, live | No | Same limits as user, plus a userDataDir to get right |
create-profile --cdp-url | Remote CDP | Whoever runs that endpoint | Whatever that browser has | Yes | The URL and its token are secrets, and private-network rules get stricter |
One stale detail to ignore. Some third-party guides still describe an "Extension Relay" on port 18792 as the main way to drive your signed-in Chrome. The current docs lead with the user profile over Chrome DevTools MCP, and the extension driver is a separate path with its own openclaw browser extension setup flow. If a tutorial starts by telling you to open 18792, check its date.
Start with status, then doctor
openclaw browser status
openclaw browser doctor --deep
openclaw browser start
openclaw browser open https://docs.openclaw.ai --label docs
openclaw browser snapshotThe managed browser runs headless by default on every platform, which surprises people the first time they run start and nothing appears. Set OPENCLAW_BROWSER_HEADLESS=0 (Linux needs a display too) when you want to watch it work. I'd leave it headless on servers and visible on a laptop for the first week of any new automation. Watching an agent click the wrong button twice teaches you more than any log.
Ports, for anyone writing firewall rules. The browser control service sits on loopback, on a port derived from gateway.port (18791 with the default Gateway port). Managed profiles take CDP ports from 18800 to 18899. Running a second Gateway with --profile shifts the Gateway port, and the browser ports move with it. Space the two Gateways far enough apart that their ranges don't overlap.
Bring logins in with import-profile
Most agents that "need my real browser" actually need one login. Copy that one in.
openclaw browser system-profiles
openclaw browser import-profile --system "Profile 1" --into work --domains github.com,linear.app
openclaw browser --browser-profile work open https://github.com/notificationssystem-profiles lists the profiles on the machine (add --browser brave for Brave), and --domains keeps the copy to the sites you name. Skip the flag and the copy isn't limited to sites you named, so your bank and your email can end up in a browser an agent controls. The domain list is the security boundary. Keep it short.
Copied sessions do expire, and some sites will ask you to log in again from the managed profile. When that happens, do it once there with a visible browser and leave the profile alone afterward.
The user profile is for jobs you're watching
Attaching to your running Chrome takes three things: Chrome, Brave, or Edge at version 144 or later, remote debugging switched on at chrome://inspect/#remote-debugging, and you clicking approve when OpenClaw asks to attach. OpenClaw never launches this browser. If Chrome is closed, the profile is just unavailable.
That approval step is why I would never point a cron job at user. The docs say to use this mode only when the user is at the computer to approve the prompt, and a 3 a.m. job will sit waiting for a click that never comes.
You also lose a chunk of the command set. On existing-session profiles there is no batch, no pdf, no responsebody, and no download interception. click is left-click only, select takes a single value, wait --load networkidle is unsupported, and uploads need a --ref rather than a CSS selector, one file at a time. A script written against the managed profile will fail on several of these the moment you switch.
For a Brave install, the docs example looks like this:
{
browser: {
profiles: {
brave: {
driver: "existing-session",
attachOnly: true,
userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser",
},
},
},
}Refs go stale, tab ids don't
snapshot returns the page as a tree with refs like e12, and click, type, hover and friends take those refs. They are only good for the page they came from. Navigate, or let a single-page app re-render a modal, and the ref points at nothing.
openclaw browser snapshot
openclaw browser click e12
openclaw browser snapshot # again, after anything that changes the page
openclaw browser type e31 "hello"Tabs work the other way round. Use the stable tab id (t1), a label you set with --label, or suggestedTargetId. Raw targetId values get reassigned during navigation, so a script that stores them will eventually act on the wrong tab, and it won't error when it does.
Snapshots also cap out at 40,000 characters on the agent side. Long pages get cut. The query parameter keeps only lines containing every word you give it, which is the cheapest way to find one button on a heavy dashboard without paying for the whole tree in context.
An empty ssrfPolicy breaks localhost
This one is easy to walk into. With no browser.ssrfPolicy in config, an unrestricted agent using the managed local Chrome can reach loopback services, so http://localhost:3000 works. Add any explicit policy, even ssrfPolicy: {}, and that exception disappears. Your QA agent suddenly can't open the dev server, and the error reads like a network problem.
If you want a policy, write the hosts you need into allowedHostnames rather than reaching for dangerouslyAllowPrivateNetwork. Sandboxed agents, remote targets, and external browsers never got the loopback exception in the first place, and OpenClaw re-checks the policy on every navigation and redirect.
Turn off evaluate where the user profile is reachable
openclaw browser evaluate runs arbitrary JavaScript in the page. evaluateEnabled defaults to true. In the managed profile that is mostly a debugging convenience. On a Gateway where an agent can also attach to your signed-in Chrome, it is script execution inside your logged-in sessions, triggered by whatever text the agent just read on some web page. I set browser.evaluateEnabled: false on any Gateway with a user or existing-session profile, and pair it with exec approvals and a tight tool allowlist.
Writing that policy for a Gateway that never sleeps (who can attach to what, and where the tokens live) is most of what the Security Hardening Kit covers, and it is the next thing I'd read before giving any agent a browser that has your cookies.
When the browser lives on another machine
Gateway on a Linux box, Chrome on your Mac. Run a node host on the Mac and the Gateway proxies browser actions to it, controlled by gateway.nodes.browser.mode and gateway.nodes.browser.node. The alternative is a remote CDP profile:
openclaw browser create-profile --name remote --cdp-url https://browser-host.example.comTreat that URL as a secret. The docs recommend WSS or HTTPS, short-lived tokens, and keeping long-lived tokens out of config files, and they say to keep both ends on a private network. I'd go further and say a CDP endpoint should never be reachable from the public internet at all, because CDP is full control of the browser. Put it on a tailnet (the Tailscale guide covers it).
Debugging a run that went wrong
openclaw browser console --level error
openclaw browser errors --clear
openclaw browser requests --filter api
openclaw browser responsebody "**/api"
openclaw browser trace start
openclaw browser trace stop --out trace.zip
openclaw browser screenshot --labelsscreenshot --labels draws the refs onto the image, which is the fastest answer to "why did it click that?" A trace zip is heavier but shows the whole sequence. If your main model has no vision, set an image model under tools.media.models and screenshots come back as a text description instead of an image the model can't read.
Two smaller flags worth knowing: set credentials handles HTTP basic auth on staging sites, and reset-profile wipes a managed profile when its state gets weird.
Where each option fits (and where it does not)
The openclaw profile fits public-site research, QA against a dev server, screenshots, and anything scheduled. It does not fit a task that needs a login you haven't imported.
An imported profile fits recurring work on two or three logged-in sites. It loses to the user profile when a site keeps killing copied sessions.
The user profile fits one-off help while you're at the desk ("check the billing page in my dashboard"). It is the wrong choice for unattended jobs and for anything that needs batch, PDFs, or downloads.
Remote CDP fits a hosted browser fleet. For a single Mac on your desk, a node host is simpler and keeps the endpoint off the network.
For the agent-side view of the same tool (snapshot-first habits, tab hygiene), see how to use the browser tool in OpenClaw. And if the agent runs in a container, read the sandbox guide first, since sandboxed agents get their own browser target.
Final verdict
Default everything to the openclaw profile. Import cookies per domain when an agent needs a login, and keep that list short enough to read aloud. Attach the user profile only while you're watching, with evaluateEnabled off. Re-snapshot after every page change. And never write an empty ssrfPolicy.
Ready to build?
Get the OpenClaw Starter Kit — config templates, 5 production-ready skills, deployment checklist. Go from zero to running in under an hour.
$14 $6.99
Get the Starter Kit →Also in the OpenClaw store
Get the free OpenClaw quickstart guide
Step-by-step setup. Plain English. No jargon.