
Anyone building AI agents will sooner or later run into the same wall: letting an agent do work for you in the browser. Booking flights, posting content, scraping backend data, running a regression pass — as long as it involves web pages, browser automation is almost unavoidable.
Then you fall into the familiar trap.
Why Traditional Browser Automation Is So Painful
Playwright, Puppeteer, browser-use, and any newly launched browser spun up with --launch are all doing the same thing: opening a brand-new browser with a blank profile. That means:
- You have to log in again every time. ChatGPT, X, GitHub, your company’s internal dashboards — all the services you stay logged into in Chrome year-round — simply don’t exist in that empty browser. By default, it starts with a blank profile: cookies and sessions are all empty. (Of course, you can manually feed it a profile, but then you have to maintain the login state yourself.)
- CAPTCHAs can completely block the agent. An empty browser, unfamiliar fingerprint, and data-center IP make it obvious to websites that this is a script, so they throw up a CAPTCHA or Cloudflare challenge page. The agent gets stuck on the spot, with no one there to click through for it.
- The fingerprint is obviously fake.
navigator.webdriver, headless traces, CDP leaks... these are automation giveaways you can spot at a glance. Bot-detection vendors like Akamai, DataDome, and PerimeterX also score dozens of dimensions, so a default Playwright/Puppeteer setup is easy to expose. - You can’t see what it’s doing. It runs in another window in another process. You can’t step in, and when something goes wrong, all you can do is stare at logs and guess.
The root cause is simple: it opens “some other” browser, not yours.
chrome-use takes a different approach: open your real browser
chrome-use points any agent (Claude Code, Cursor, Codex, your own scripts) at the Chrome on your machine where you’re already logged into all kinds of sites.
Project homepage: https://chrome-use.leeguoo.com/
It clicks inside your window, so you can watch it work and take over the moment it hits 2FA or a CAPTCHA. And because it is your real browser (via a one-click store extension + native messaging channel, driving tabs with chrome.debugger and not exposing a TCP remote debugging port), what websites see at the fingerprinting layer is a real human browser, with no automation traces to catch (CreepJS stealth score 0%; see the “Anti-Detection” section below). Of course, IP reputation, account risk, and behavioral pacing are separate axes, and you still need to manage them yourself.
In one sentence: no new Chrome, no logging in again, no more slamming into the “are you a robot?” wall.
Traditional automation (Playwright / --launch) | chrome-use (connects to your Chrome) | |
|---|---|---|
| Browser | Launches a fresh empty browser | Connects to the Chrome you’re already using |
| Login state | Empty; you have to log in again | All your existing sessions |
| Fingerprint | Carries automation traces | Your real fingerprint |
| Collaboration | Opens a separate window | Same window, take over anytime |
| CAPTCHA | Agent gets stuck | You click once, agent continues |
What about Claude’s built-in Chrome extension, web-access, or CDP ports?
- Playwright / Puppeteer / browser-use? They launch an empty browser, so you have to redo every login and fight every CAPTCHA again, while still getting flagged as automation. chrome-use uses the session you already have.
- Claude’s built-in Chrome extension? Great, but it only drives Claude itself. chrome-use drives any agent or CLI.
- Raw
--remote-debugging-porttools (like web-access)? Chrome 136+ shows an interstitial prompt on connection asking “Allow remote debugging?” (it remains in effect for that Chrome session). chrome-use never does, because it goes through a one-click store extension + native messaging.
How It Works: Everything Stays on Your Machine, No Network

Your chrome-use CLI talks to a tiny browser extension through Chrome’s native messaging. This is a local inter-process channel: no network socket, no token, no remote server. The extension uses chrome.debugger to drive the tab you specify — inside your already-logged-in Chrome — then sends the results back to the CLI. Everything stays on your machine.
Why an Extension Instead of a Raw Debug Port
Other local tools use a raw --remote-debugging-port (CDP). Starting with Chrome 136, the first time this kind of connection is made, Chrome shows a blocking “Allow remote debugging?” authorization prompt (valid for that Chrome session), and the port must be opened ahead of time. chrome-use’s extension uses native messaging: install once, then zero confirmations every time after that.
| chrome-use (extension) | web-access (raw CDP port) | Claude built-in plugin | |
|---|---|---|---|
| Connection method | Native messaging, no port, no token | --remote-debugging-port | chrome.debugger |
| “Allow remote debugging?” prompt | Never ✅ | Appears (each session) 🔴 | None |
| Uses your real login | Yes | Yes | Yes |
Runtime.enable CDP leak | Off by default → clean ✅ | Domain already enabled | Not applicable |
| CreepJS stealth score | 0% stealth · 0% headless ✅ | Real Chrome | Real Chrome |
| Separate tab group per session / concurrent agents | Supported ✅ | No | No |
This authorization prompt is not fearmongering: raw-port tools show a blocking authorization prompt the first time they connect (attach), and it remains valid for that Chrome session. With the extension path, once it is installed, this blocking prompt does not appear again.
One point worth clarifying: don’t mistake this for “completely invisible.” Under the hood, the extension still drives tabs with
chrome.debugger, which is essentially CDP — it just goes through native messaging and does not open a TCP port. So what it avoids is the blocking “Allow remote debugging?” dialog and the externally exposed debugging port. But whenever chrome-use is driving your real Chrome, Chrome shows a non-blocking infobar at the top saying “chrome-use started debugging this browser,” with a Cancel button. This is inherent to thechrome.debuggerAPI and cannot be avoided; clicking Cancel disconnects it immediately. The accurate phrasing is: no blocking popup and no externally open debugging port, but there is a dismissible infobar — not “completely invisible.”
Agent-facing interface: glancing at a page costs only 200–400 tokens
Up to this point, we’ve been talking about “whose browser to connect to.” But for an AI agent, there’s another equally critical question: how many tokens does each glance at the page burn?
Many browser agents are screenshot-driven: they feed a full-page screenshot into a vision model and ask it to find buttons in the pixels. A single screenshot can easily cost thousands of tokens; click once or turn a page, and you need another one. Run a slightly longer workflow, and the tokens start burning fast. Others stuff the raw HTML/DOM into the context, which is likewise long and messy.
chrome-use takes a structure-first approach: snapshot -i gives the agent an accessibility tree snapshot, keeping only interactive elements, with each element assigned a compact @eN reference. A whole page usually costs only ~200–400 tokens, instead of parsing raw HTML — and certainly instead of feeding in a screenshot. The agent operates directly by reference:
chrome-use open <url>
chrome-use snapshot -i # only show interactive elements, each with an @eN reference
chrome-use click @e3 # operate by reference, not coordinates or screenshots
In chrome-use, screenshots are an output, not an input: you only take them when you need evidence or something for a human to inspect. The agent does not need them at all for locating / reading / clicking. Site adapters (see below) go one step further: they return clean JSON directly, skipping even the snapshot, making them the cheapest route for “reading structured data.”
The savings are real: for the same workflow, structured interfaces are often an order of magnitude cheaper than screenshot-driven ones, and the longer the task, the more obvious the difference becomes. That’s also why chrome-use positions itself as a CLI for agents, not a browser panel for humans.
Anti-Detection: No Patches, No Detectable Lie-Detector Traces

When connected to your real Chrome, chrome-use does not inject a single JavaScript patch. Your browser fingerprint is fully real. The guiding principle is to override at the native CDP/Chrome layer instead of faking it with JS: redefined getters are themselves detectable, while native-layer overrides leave no such traces.
navigator.webdriver = falsegoes throughEmulation.setAutomationOverride(a native override, unlike a redefined getter that can be caught immediately by “lie detectors” like CreepJS).Runtime.enableis off by default. A liveRuntimedomain is itself a detectable CDP signal (the “runtime leak” described by patchright/rebrowser), even when you are connected to a real Chrome. We enable it only when you explicitly turn on console/error capture.click,fill, andevalstill work normally without it.
Measured results (connected to real Chrome):
| Detection Site | Result |
|---|---|
| CreepJS | 0% stealth · 0% headless (no automation override traces) |
| bot.incolumitas.com | All OK: overflowTest, overrideTest, puppeteerExtraStealthUsed, worker consistency |
| bot.sannysoft.com | All green |
| BrowserScan | Webdriver · User-Agent · CDP all clean |
| Cloudflare Turnstile (nowsecure.nl passive challenge) | Passed |
The key number on CreepJS is 0% stealth: because the connection path does not patch anything, there is simply no override for a “lie detector” to catch. We also deliberately do not build our own bot detector. The most defensible benchmark is to take the strictest public detection sites (CreepJS, incolumitas) and test them against your real browser. Note that they measure fingerprints/traces; commercial behavior + IP reputation stacks are a separate and harder layer. Don’t take our word for it—verify it yourself.
Behavioral Stealth: Make Clicks Look Human
Fingerprinting is only half the story. Bot-detection vendors like Akamai, DataDome, and PerimeterX also score behavior. A click that teleports the cursor to the exact center of an element, with no approach path and zero press delay, is a giveaway, even if our CDP events are isTrusted.

With humanize enabled, cursor movement behaves like a real user: clicks follow a curved, decelerating Bézier path and land at a randomly jittered position inside the element (never dead center); typing uses variable keystroke intervals; scrolling is segmented and eased; dragging follows curves. It is also adaptive: on every navigation, it detects known anti-bot vendors (cookies / scripts / globals), and watched pages are automatically upgraded to human-like trajectories, removing low-level giveaways like “teleport clicks.” This can eliminate obvious machine traces, but behavioral risk engines also look at dwell time, rhythm, and whole-session entropy. Humanize is not a silver bullet; ordinary sites keep the original instant clicks (zero overhead).
Control it with --humanize off|fast|human or environment variables. The default is off, and the adaptive detector upgrades automatically based on the page.
Quiet Operation: Never Steal Your Foreground
Since it drives your own real Chrome, it should never interrupt what you’re doing. The agent runs entirely in the background: new tabs open without stealing focus (inside its own color-coded tab group), the agent never forcibly brings a tab to the foreground, and Emulation.setFocusEmulationEnabled keeps every agent tab rendering while making document.hasFocus() return true and visibilityState report visible. So screenshots still work, pages are not render-throttled, and the suspicious signal of “the session tab was invisible the whole time” is never triggered. You keep working in your active tab while the agent quietly works alongside it.
Multiple Agents Share One Chrome Without Stepping on Each Other
Each --session gets its own set of color-coded Chrome tabs, so multiple agents can concurrently share the same real browser without interfering with one another or touching your own tabs. A session only owns the tabs it created; it never takes over your tabs, nor does it take over tabs belonging to other agents. Command dispatch is also isolated by session. This means you can run several agents at the same time in a single real Chrome, each doing its own work.
Site Adapters: Turning a Website into a Structured Data CLI
Many tasks like “read GitHub issues,” “search Reddit,” or “fetch my Bilibili feed” don’t need clicks or screenshots at all. Behind the site, there is often already a JSON API; it just requires a logged-in session. A site adapter is a small piece of JS that calls that API inside the tab where you are already logged in using your cookies, same-origin fetch, and the site’s own modules, then returns clean JSON. To the website, this request is almost indistinguishable from one you triggered manually.
chrome-use does not bundle any adapters. site update fetches the community bb-sites package at runtime, like a package manager pulling dependencies, then runs them through chrome-use’s incognito transport:
chrome-use site update # fetch adapter package (~145 commands)
chrome-use site list # github/issues, reddit/search, bilibili/feed…
chrome-use site github/issues epiral/bb-browser --json
chrome-use site bilibili/feed --json # works because it uses your logged-in session
It also auto-syncs and auto-suggests: when you open/snapshot a domain that has an adapter, chrome-use prints a line like 💡 site adapters for <domain> directly in the output, nudging the agent to use the structured data adapter first instead of scraping the DOM.
Turn “Clicking Around” Into a Rerunnable Test Suite (chrome-use test)
That repetitive “open it, click around, check whether it’s right” work can become a rerunnable test suite—basically adding a smoke/regression testing layer to the frontend. Write cases in YAML, reuse chrome-use’s own commands for steps, and compile assertions into a single check:
# smoke.yaml
suite: chatgpt smoke
cases:
- name: home loads logged in
steps:
- open: https://chatgpt.com/
- wait: { load: networkidle }
assert:
- url: { contains: chatgpt.com }
- visible: "#prompt-textarea"
chrome-use test smoke.yaml # launches an isolated browser to run the case
chrome-use test smoke.yaml --session default # …or runs against the Chrome you connected
If any case fails, the exit code is non-zero (drop it straight into CI), and a screenshot is saved for the failed case. Assertions support url/visible/hidden/text/count/eval, and steps support open/click/fill/type/press/wait/scroll/eval. Found a regression? Just add a case—the more you use it, the more valuable this test suite becomes.
Quick Start: Install in One Line, Connect to Any Agent
curl -fsSL https://raw.githubusercontent.com/leeguooooo/chrome-use/main/install.sh | sh
Download the prebuilt binary for your platform from the latest GitHub Release, installing chrome-use along with the short alias abs. No npm, no token required.
Connect it to your Chrome (the extension path is recommended: one click, zero pop-ups): install the chrome-use extension from the Chrome Web Store, then register the local bridge once:
chrome-use extension install # register native messaging host (one-time)
chrome-use open https://x.com/home
After that, everything runs through native messaging to drive your real, logged-in Chrome: no debug port, no token, and no “Allow remote debugging?” pop-up ever.
Install the companion skill for your AI agent (Claude Code, Cursor, etc.):
npx skills add leeguooooo/chrome-use
This drops skills/chrome-use plus the specialized skill into your project, giving your agent correct usage examples and pre-authorized bash permissions.
Day to day, it looks like this—any agent can call it:
chrome-use open https://example.com
chrome-use click "Post"
chrome-use fill "Title" "Hello World"
chrome-use screenshot ./page.png
The agent operates inside your Chrome, and you can watch tabs open, pages load, and clicks happen in real time. You can take over at any moment (for example, to solve a CAPTCHA), then let the agent continue.
Don’t want to touch your real Chrome? Use chrome-use --launch open <url> to spin up a fresh isolated incognito browser (with the full anti-detection patch set enabled); CI uses this path automatically.
Why It’s Different
- Connects to your existing Chrome by default:
chrome-use open <url>drives the browser you’re already using instead of launching a separate one. - Token-efficient structured interface: agents receive an accessibility-tree snapshot plus
@eNreferences; each page is ~200–400 tokens, with no screenshots as input and no raw HTML stuffing. Screenshots are output, not input. - Extension relay transport: one-click store extension + native messaging, with no debug port and no “Allow remote debugging?” popup.
- CDP-native stealth: anti-detection is handled through Chrome/CDP overrides rather than JS patches; when connected to real Chrome, there are zero patches, and the full patch set is applied only with
--launch. - Humanize: human-like cursor trajectories + adaptive anti-bot handling.
- Multi-agent isolation: concurrent agents share one real Chrome through per-session tab groups without interfering with each other.
- Silent operation: runs in the background and never steals your foreground tab.
chrome-use is part of the *-use family: iphone-use drives your real iPhone, while chrome-use drives your real Chrome. The project is open source under Apache-2.0.
Anyone building agent automation deserves this. Go give it a star on GitHub so more fellow Agent builders can discover it: github.com/leeguooooo/chrome-use.
Built by leeguooooo. Field notes on AI agents, reverse engineering, and Cloudflare Workers are at blog.misonote.com. Follow @leeguooooo on X.

微信
支付宝
Comments
Replies are public immediately and may be moderated for policy violations.