Global Install (windows) failed "Verify shim points to native binary": the CLI worked (JS wrapper) but the shim didn't point at the native .exe. Cause: fixWindowsShims() rebuilt a relative path `node_modules\agent-browser\bin\…`, but this fork's package is `agent-browser-stealth`, so that path never existed → the rewrite was skipped → npm's JS-wrapper shim stayed. Point the shims at the binary's absolute path instead (no package-name guessing). Also: npm frequently creates the .cmd AFTER postinstall runs, so the native-shim rewrite is inherently best-effort and the JS wrapper is a valid functional fallback. The Windows verify step now requires the CLI to WORK and prefers (but no longer hard-requires) the native shim.
agent-browser-stealth
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.
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
Attaching uses the Chrome DevTools Protocol, which Chrome only exposes when it is
launched with a remote-debugging port. This is a startup flag, not a setting
— the chrome://inspect toggle alone is not enough (it only enables target
discovery, not the CDP attach).
Recommended — fully quit Chrome, then relaunch with the port:
# 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 run agent-browser open <url> — it auto-discovers the port and attaches.
On first attach, Chrome 136+ shows an "Allow remote debugging?" dialog — click
Allow once (it persists for that Chrome session).
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)


