Connecting
Real Chrome (Extension)
When a task needs the exact window the user is looking at right now—their real, already-logged-in session, not a fresh blank browser—use extension connect. It takes over the user's real Chrome: zero confirmations, zero tokens, no headless fingerprint. It is the highest anti-detection tier of any connection method.
The link has just four stops: the chrome-use CLI → a per-session daemon → the relay Chrome launches
for the extension → the ab-connect extension in the browser. The extension drives pages over
Chrome's own debugging protocol, so no remote-debugging port is opened. What each stop speaks and where the
state lives is in How It Works.
One-time install
Extension connect only needs to be set up once. First register the native-messaging host, then install the chrome-use extension.
# 1. Register the native-messaging host
$ chrome-use extension install
2. Install the chrome-use extension. The easiest way—and the one that stays stable across restarts—is a one-click Add to Chrome from the Chrome Web Store:
- Store link: chromewebstore.google.com/detail/chrome-use
chrome://extensions → turn on Developer mode → Load unpacked →
pick extensions/ab-connect. Note: a load-unpacked extension may be disabled after Chrome restarts,
so prefer the store build for unattended scenarios.
Auto-connect: open takes over
Once the extension is installed, a plain chrome-use open <url> automatically connects through
the extension relay. auto_connect_cdp prefers the live relay over a bare
--remote-debugging-port, so Chrome 136+'s "Allow remote debugging?" authorization prompt
never appears. chrome-use extension connect is the explicit form of the same path.
# With the extension installed, open takes over the real Chrome via the relay
$ chrome-use open "https://example.com"
# The explicit form of the same path
$ chrome-use extension connect
--launch—see below.
Multiple Chrome profiles: see which one, then pick it
The relay binds to the extension worker of the profile currently talking to the native host. If a site comes back showing logged out, confirm you took over the right profile before concluding the login was lost.
# List every connected profile (shows email if identity permission is granted, else a stable id, with the default flagged)
$ chrome-use browsers
# Pin "this session" to a specific profile — sticky per session, so different agents don't interfere
$ chrome-use --browser "me@example.com" snapshot
# Check which profile you're currently driving
$ chrome-use extension status
$ chrome-use doctor
--browser <id|email> pins this session to a profile: the session's daemon
binds on first connect, each session can pick a different profile, so concurrent agents don't
fight over one. Logged out on the wrong profile ≠ login lost—run browsers first, then re-run with
the correct --browser.
--launch vs --profile auto
--launch opens an isolated blank test profile—no cookies, no logins, no extensions
(so the extension relay path is off). Its window is labeled chrome-use (<session>) in Chrome's
profile menu, so anyone watching the desktop can tell at a glance which session the window belongs to.
If a launched session needs more:
Drop --launch and use --profile auto instead (reuse the user's real Chrome profile),
or set AGENT_BROWSER_PROFILE=auto once to make every later call default to it.
--launch --args "--load-extension=<dir>".
If "Allow remote debugging?" really does pop up
Don't keep retrying—each retry pops it again. At that point there are only two possibilities:
-
You're on an old version. The relay-preference logic that avoids this prompt shipped many
versions ago; if you still hit it, your
chrome-useis too old—upgrade and retry:
$ curl -fsSL https://raw.githubusercontent.com/leeguooooo/chrome-use/main/install.sh | sh
# If which shows multiple installs, an old npm/pnpm copy may be shadowing the new one
$ which -a chrome-use
$ npm rm -g chrome-use # or pnpm rm -g chrome-use, so the install.sh version wins
- The extension / relay isn't up. Have the user install the store extension (the one-click link above); once installed the relay stays online and this prompt never comes back.
Relay drops: the CLI self-heals
If a command suddenly reports "couldn't reach your Chrome" / "relay … failed"—usually the MV3 service worker got suspended, or two agents are sharing one relay—the CLI now self-heals: it waits for the worker's keepalive to bring the relay back (about 25 seconds) and retries once, so most drops you never even notice. If a command does surface the error:
- Just re-run the command—by then the relay has usually reconnected.
- Still failing:
chrome-use status(check) →chrome-use extension connect(re-attach) → retry. The CLI registers the native host automatically, and opens the store page if the extension was never installed—you don't have to runextension installby hand. - Never have the user quit/restart Chrome with
--remote-debugging-portto recover a dropped relay—that loses all their tabs and completely breaks the extension path. chrome-use reconnectis a friendly alias forextension connect—it rebinds the session to the running Chrome with no reinstall needed.- Browser totally unrecoverable? Don't sit waiting on a screenshot—fall back to
non-visual verification:
get text/eval, or read the deployed page withcurl/WebFetch. Confirm a change is correct via DOM/HTML or the live URL, not a failure. Save screenshots for the visual checks you actually need to report to the user.
--session has its own
tab group and drives only its own tabs. Give each agent a distinct --session and run them in parallel
instead of one at a time.
OAuth / SSO redirects just work now
A login handoff (GitHub/Google OAuth, SSO) navigates the tab across processes, which used to
orphan the old session and make the next read fail with "stale sessionId". The relay now re-attaches the
opener automatically across that cross-process navigation and briefly retries the read while the new
process stabilizes, so snapshot/screenshot/eval/get keep working
through the entire handoff, and "Sign in with Google" / OAuth popup login goes end-to-end.
Strict multi-agent isolation
Every connected --session gets its own colored Chrome tab group (named after the
session) and drives only its own tabs—multiple agents share one real browser without crossing wires, and the
user's own tabs are never grouped. CDP doesn't move the user's mouse/keyboard while driving pages, so it never
fights them for control.
--session /
AGENT_BROWSER_SESSION, chrome-use auto-derives a per-agent default—
cu-<repo>-<id>, where <id> is a short hash of a stable per-agent
terminal/agent-environment id (CMUX_SURFACE_ID, TERM_SESSION_ID,
ITERM_SESSION_ID, TMUX_PANE …). So two agents in the same repo get different tab
groups by default and no longer step on each other's active tab. In a bare shell with none of those env
vars set, it falls back to the shared default. Override anytime: pass --session <name>,
or set it to the same value to deliberately have multiple agents share one tab group.
(The AGENT_BROWSER_* prefix is inherited from the upstream project—see Lineage for the history.)
A session (over the relay) tracks and drives only the tabs it created itself. Popups opened by
your own actions—like the OAuth account picker that pops up when you click "Sign in with Google"—are
followed and can be driven as part of your session (switch over and drive that picker). But it does not
adopt the user's existing tabs, another agent's tabs, or unrelated popups (a login window the user opened is
the user's). Bottom line: tab list shows only your session's tabs; to drive a specific page,
navigate to it in one of your own tabs—don't expect an existing or popped-up tab to appear in the list.
No debugging banner on the user's pages
adopt), never to the user's own tabs—so Chrome's "chrome-use started debugging this browser" banner
never covers a page the user is using (it only shows on attached tabs, and the agent's are all background tabs).
No Chrome restart, fully seamless.
Read a tab the user already has open: adopt
Need to read a tab the user already has open? Use chrome-use adopt <url-substring|targetId>—it
finds that existing tab across tab groups (the user's own, or another session's) and drives it, without
opening a new tab. When nothing matches it errors and lists the tabs it can see. This is the explicit,
opt-in way to cross the isolation layer above (it tags the adopted tab into your session's tab group).
# Adopt the tab the user is looking at, then do a read-only extraction on it
$ chrome-use adopt "claude.ai/design"
$ chrome-use snapshot
$ chrome-use get text
Anti-detection tier ranking
This real, logged-in Chrome (extension connect) > a headed launched browser > headless (forbidden). A genuine human browser has no headless / automation tells at all, so prefer it for any anti-bot-sensitive task.
Silent by default
When driving the user's real Chrome, the agent works entirely in the background—new tabs open
unfocused, the agent never forces a tab to the front, and focus is emulated so background pages still render and
report visibilityState: 'visible'. You don't have to do anything; just don't expect the user's view to
follow you (only use an explicit bringToFront when you deliberately want to surface a tab).
Behavioral anti-bot: humanized input
--humanize off|fast|human (or AGENT_BROWSER_HUMANIZE) gives clicks, typing, and scrolling
a human cadence; defaults to off, and a per-navigation detector auto-escalates pages guarded by
Akamai/PerimeterX/DataDome to human. Trajectory parameters, cadence, and tuning are covered in
Stealth & Anti-detection.
Getting past Cloudflare: solve once, reuse
Passing a Cloudflare challenge once mints a cf_clearance cookie bound to your
IP + User-Agent; reuse the same egress IP and UA to skip the challenge until it expires, and
driving the user's real Chrome (relay) persists it natively. Before spending effort solving, run
chrome-use cf-status (aliases cf, clearance) as a preflight to avoid
re-solving a challenge you already passed. The full flow, the reissue verdict, and reading the
cookie are covered in Stealth & Anti-detection.
Related pages
--session, tab groups, per-agent defaults, and concurrency.
OAuth/SSO handoff, reusing a real logged-in session.
Extension connect vs other browser-automation approaches.
Self-checks for relay drops, the authorization prompt, and picking the wrong profile.