Ships the humanize feature: human-like cursor trajectories (Bézier + easing + press dwell), variable typing cadence, an adaptive per-navigation anti-bot detector that auto-escalates guarded pages to Human, and `--humanize` / AGENT_BROWSER_HUMANIZE control. Default Off → unchanged for ordinary sites.
agent-browser-stealth
English · 简体中文
Stealth fork of agent-browser — connects to your real Chrome, shares your login sessions, and is undetectable by anti-bot systems.
For basic usage, commands, and API reference, see the upstream documentation.
Give your AI agent the browser you already live in
No fresh Chrome. No re-login. No "are you a robot?" walls.
agent-browser-stealth points any agent — Claude Code, Cursor, Codex, your own scripts — at the Chrome you're already signed into everything on. It clicks in your window, so you watch it work and grab the wheel the moment it hits a 2FA prompt or captcha. And because it's literally your real browser (over a one-click extension, native messaging — no debug port), sites read it as 100% human: CreepJS scores it 0% bot.
Why not just use…
- Playwright / Puppeteer / browser-use? They boot an empty browser — so you redo every login, fight every captcha, and still get flagged as automation. We use the session you already have.
- Claude's Chrome extension? Great, but it only drives Claude. This drives any agent or CLI.
- A raw
--remote-debugging-port(web-access, etc.)? Chrome 136+ pops "Allow remote debugging?" on every connect. This never does — one-click Store extension, native messaging.
Full feature comparison (the receipts)
| Claude in Chrome | web-access / raw CDP port | Playwright · Puppeteer · browser-use | agent-browser-stealth | |
|---|---|---|---|---|
| Works with any agent / CLI (not one app) | ❌ Claude only | ✅ | ✅ | ✅ |
| Drives your real, logged-in Chrome | ✅ | ✅ | ❌ fresh empty profile | ✅ |
| No "Allow remote debugging?" popup | ✅ | ❌ every connect | — (own browser) | ✅ native messaging |
| Real-browser fingerprint (CreepJS ~0%)¹ | ✅ | ✅ | ❌ automation markers / headless | ✅ verified 0% |
No Runtime.enable CDP leak (rebrowser)² |
— | ❌ leaks | ❌ leaks | ✅ off by default |
| Many agents on one real Chrome, isolated tab groups³ | ❌ single app | ⚠️ shared tabs, no isolation | ❌ separate browsers | ✅ |
| Permissions footprint | 16 incl. <all_urls> |
full CDP | full control | 7, no <all_urls> |
¹ All three real-Chrome tools score ~0% on CreepJS (it's a real browser); we've measured ours. ² rebrowser's runtimeEnableLeak — verified clean on our relay path; Claude in Chrome not independently tested (—). ³ web-access can run parallel sub-agents on one browser, but without per-session isolation; each --session here gets its own colored, command-isolated tab group. See Anti-detection for the measured numbers.
Why this fork?
agent-browser launches a fresh browser with an empty profile. You need to log in again, and websites can detect it's automated.
agent-browser-stealth connects to your existing Chrome. Your cookies, sessions, and browser fingerprint are all real — because it IS your real browser.
| agent-browser | agent-browser-stealth | |
|---|---|---|
| Browser | Launches new Chrome | Connects to your Chrome |
| Login state | Empty, need to re-login | Your existing sessions |
| Fingerprint | Automation markers present | Your real fingerprint |
| User collaboration | Separate window | Same window, take over anytime |
| CAPTCHA | Agent stuck | You solve it, agent continues |
How it works
Your agent-browser CLI talks to a tiny browser extension over Chrome
native messaging — a local inter-process channel, no network socket, no
token, no remote server. The extension uses chrome.debugger to drive the tabs
you target in your own, already-logged-in Chrome, then hands results back to
the CLI. Everything stays on your machine.
Each --session gets its own colored Chrome tab group, so multiple agents
can share one real browser concurrently without stepping on each other — or your
own tabs.
Why the extension (not a raw debug port)
Other local tools drive Chrome over a raw --remote-debugging-port (CDP). Since
Chrome 136, every such connection pops a blocking "Allow remote debugging?"
consent dialog — and the port has to be enabled up front. Our extension uses
native messaging instead: install once, then zero per-use confirmation.
| agent-browser-stealth (this extension) | web-access (raw CDP port) | Claude in Chrome (chrome.debugger) | |
|---|---|---|---|
| Connect method | native messaging — no port, no token | --remote-debugging-port |
chrome.debugger |
| "Allow remote debugging?" popup | never ✅ | every connection 🔴 | no |
| Uses your real login | yes | yes | yes |
Runtime.enable (CDP) leak¹ |
off by default → clean ✅ | domain enabled | n/a |
| CreepJS stealth score² | 0% stealth · 0% headless ✅ | real Chrome | real Chrome |
| Per-session tab groups / concurrent agents | yes ✅ | no | no |
| Built for the agent-browser CLI | yes | a separate proxy | a single-app assistant |
¹ Verified against rebrowser-bot-detector: our relay reports
runtimeEnableLeak: 🟢 No leakandnavigatorWebdriver: 🟢. ² Verified against CreepJS on the connected real-Chrome path — see Anti-detection.The consent dialog isn't hypothetical: a raw-port tool pops it on every attach (Chrome 136+ security). The extension path never does.
Install
curl -fsSL https://raw.githubusercontent.com/leeguooooo/agent-browser-stealth/main/install.sh | sh
Downloads the prebuilt binary for your platform from the latest GitHub Release and installs agent-browser (+ the abs alias). No npm, no tokens.
Other ways to install
- Pin a version:
AGENT_BROWSER_VERSION=v0.27.0-fork.12 curl -fsSL https://raw.githubusercontent.com/leeguooooo/agent-browser-stealth/main/install.sh | sh - Custom location:
AGENT_BROWSER_BIN_DIR=$HOME/bin curl -fsSL … | sh - Windows: download
agent-browser-win32-x64.tar.gzfrom the Releases page and putagent-browser.exeon your PATH. - npm (legacy):
npm install -g agent-browser-stealth— still published, but GitHub Releases is the primary channel now.
Install the AI agent skills
The repo ships SKILL.md files for Claude Code, Cursor, etc. Pull them into the current project with skills.sh:
npx skills add leeguooooo/agent-browser-stealth
This drops skills/agent-browser (and the specialized skill-data/{core,electron,slack,dogfood,agentcore,vercel-sandbox}) into your project so your AI agent gets the right usage patterns and pre-approved bash permissions for agent-browser, agent-browser-stealth, and abs.
Command names
agent-browser, agent-browser-stealth, and abs are the same binary —
abs is just a short alias. There is no separate "stealth executable"; stealth
is a runtime behavior (see Anti-detection below), applied
automatically based on whether you attach to your real Chrome or --launch a
fresh one.
Setup: connect to your Chrome
Recommended — the browser extension (one click, no popups). Install the agent-browser-stealth extension from the Chrome Web Store, then register the local bridge once:
agent-browser extension install # register the native-messaging host (one-time)
agent-browser open https://x.com/home
agent-browser open then drives your real, logged-in Chrome over native
messaging — no debug port, no token, and no "Allow remote debugging?" dialog,
ever. The extension auto-updates and survives Chrome restarts, so it stays
connected with zero per-use confirmation (ideal for unattended/agent use).
Alternative — raw remote-debugging port (pops a consent dialog)
Without the extension, agent-browser attaches over the Chrome DevTools Protocol,
which Chrome only exposes when launched with a remote-debugging port (a
startup flag — the chrome://inspect toggle alone is not enough):
# macOS
open -a "Google Chrome" --args --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
# Windows: add --remote-debugging-port=9222 to your Chrome shortcut's target
Then agent-browser open <url> auto-discovers the port. On first attach,
Chrome 136+ shows an "Allow remote debugging?" dialog — click Allow once (it
persists for that Chrome session). The extension above avoids this entirely.
No setup / don't want to touch your real Chrome? Use
agent-browser --launch open <url> to spawn a fresh isolated stealth browser
(full anti-detection patches applied; see below). This always works without any
port setup and is what CI uses automatically.
Usage
# Connect to your Chrome and navigate
agent-browser open https://example.com
# Everything works through your logged-in browser
agent-browser click "Post"
agent-browser fill "Title" "Hello World"
agent-browser screenshot ./page.png
The agent operates in your Chrome — you'll see tabs opening, pages loading, clicks happening in real time. You can take over at any point (e.g. solve a CAPTCHA), then let the agent continue.
Standalone mode (--launch)
Spawn a separate browser instead of attaching to your running Chrome:
# Throwaway: fresh, EMPTY profile — no cookies, no login (good for CI/testing)
agent-browser --launch open https://example.com
# Keep your login: launch with your real Chrome profile (cookies/sessions intact)
agent-browser --launch --profile auto open https://x.com/home
# or name it explicitly: --profile Default / --profile "Profile 1"
⚠️ Plain
--launch(no--profile) uses a temporary empty profile — you will NOT be logged into anything. For logged-in sites use--profile auto(picks the Chrome profile you used most recently) or--profile <name>. agent-browser prints a warning when you--launchwithout a profile.
In CI environments, standalone mode is used automatically.
Anti-detection
When connected to your real Chrome, we inject zero JavaScript patches. Your browser's fingerprint is completely genuine. The guiding rule is native CDP/Chrome overrides over JS lies — a re-defined getter is itself detectable; a native override isn't.
navigator.webdriver = falseviaEmulation.setAutomationOverride(native, undetectable by CreepJS-style lie tests).Runtime.enableis left OFF by default. A liveRuntimedomain is a detectable CDP signal (the patchright/rebrowser "runtime leak") — even when attached to your real Chrome. We only enable it when you opt into console/error capture (see below).click,fill,eval, etc. work without it.
Test results (connected to real Chrome):
| Test site | Result |
|---|---|
| CreepJS | 0% stealth · 0% headless (no override traces at all) |
| bot.incolumitas.com | all checks OK — overflowTest, overrideTest, puppeteerExtraStealthUsed, worker consistency |
| bot.sannysoft.com | all green |
| BrowserScan | Webdriver · User-Agent · CDP all clean |
| Cloudflare Turnstile | passed |
0% stealth on CreepJS is the key number: because the connect path patches nothing, there is no override for a lie-detector to catch. (Dashboards that read navigator.languages order or IP geolocation may show a soft "navigator"/"location" flag — that tracks your real Chrome's language list and network, not an automation tell.)
When using --launch mode (standalone browser), a full suite of stealth patches is applied instead, and it still passes the suite above.
Verify it yourself
Don't take our word for it — point your connected Chrome at the toughest public detectors and compare:
- CreepJS — the most thorough fingerprint / lie detector
- bot.incolumitas.com — behavioral + fingerprint scoring with a public methodology
- BrowserScan — Webdriver / User-Agent / CDP / Navigator
- bot.sannysoft.com — the classic automation-marker checklist
- pixelscan.net · iphey.com — consistency & identity
We deliberately don't ship our own bot detector — the strongest, most honest benchmark is the market's best detectors run against your real browser.
Tuning knobs (environment variables)
| Variable | Default | Effect |
|---|---|---|
AGENT_BROWSER_CAPTURE_CONSOLE |
off | Enable Runtime domain so console / errors capture page output. Off keeps the stealthiest profile. |
AGENT_BROWSER_TIMEZONE |
unset | --launch only. An IANA id (e.g. Asia/Tokyo) sets the timezone natively (Intl + Date follow, no JS lie) to match a proxy; auto derives one from the locale. |
AGENT_BROWSER_BLOCK_WEBRTC |
auto | --launch only. Auto-forces WebRTC through the proxy when one is set (no real-IP leak). 1 hides the local IP without a proxy; 0 opts out. |
AGENT_BROWSER_HIDE_CANVAS |
off | --launch only. Adds session-stable canvas/audio fingerprint noise. Off by default (noise is itself a "lie"). |
AGENT_BROWSER_ADAPTIVE_REF |
on | When a saved @ref moves and the role/name re-query fails, relocate it by fingerprint similarity (high score + clear margin required, else it fails loudly). 0 disables. |
AGENT_BROWSER_CLICK_MODE |
(auto) | Click strategy. Default scrolls the target into view, dispatches a coordinate click, and falls back to a DOM .click() if a floating layer occludes the point. dom always uses .click() (best for autocomplete/menu items that close on blur); coord is strict coordinate-only (hard-fail on occlusion). |
Differences from upstream
Based on agent-browser v0.27.0. Changes:
- Auto-connect is default —
agent-browser open <url>connects to your Chrome instead of launching a new one - CDP-native stealth —
Emulation.setAutomationOverrideinstead of JS patches - Dual stealth mode — zero patches for real Chrome, full patches for
--launchmode --launch/--newflag — explicitly start a standalone browser- CI auto-detection — standalone mode when
CIenv var is set
All upstream features (commands, snapshots, screenshots, recordings, tabs, sessions, etc.) work the same. See the upstream repo for full documentation.
License
Apache-2.0 (same as upstream)


