agent-browser-stealth
Stealth-first fork of agent-browser for production browser automation under anti-bot pressure.
This README focuses on stealth architecture and principles. For full command coverage inherited from upstream, use:
- upstream docs: https://github.com/vercel-labs/agent-browser
- local help:
agent-browser --help
What This Fork Optimizes
- Stealth is always on (legacy
launch.stealthis accepted but ignored). - Fingerprint surfaces are patched at multiple layers (launch args, CDP overrides, init scripts).
- Behavioral signals are humanized (typing cadence, cursor path, pacing, retry backoff).
- Region signals are auto-aligned (locale/timezone/Accept-Language) to reduce mismatch risk.
- Verification/captcha handling is policy-driven (
--risk-mode off|warn|block).
FAQ: agent-browser vs agent-browser-stealth
People often ask this: "What's the anti-detection approach compared to agent-browser-stealth on npm?"
agent-browser-stealthon npm is the package name for this fork.- The CLI keeps upstream-compatible command names (
agent-browseris still the main executable, withagent-browser-stealthas an alias). - The practical difference vs upstream
agent-browseris not one single "stealth switch"; it is a defense-in-depth stack designed for anti-bot pressure.
The core idea is layered hardening across the full automation lifecycle:
- Connection-aware policy: choose the best available stealth capability by mode (local launch/CDP/cloud provider).
- Fingerprint hardening: patch launch args, CDP metadata, and init-script surfaces before page code runs.
- Behavioral humanization: non-uniform typing/mouse/wait patterns instead of perfectly mechanical actions.
- Region coherence: auto-align locale/timezone/language signals to target geography.
- Risk-aware control loop: detect verification/captcha signals and handle them with explicit
risk-modepolicy.
Goal: reduce detection probability and improve stability in production automation. Non-goal: "guaranteed bypass" on every target.
Quick Start
Install
npm install -g agent-browser-stealth
agent-browser install
Minimal Usage
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser click @e2
Default: Auto Group Agent Tabs (CDP + Plugin)
agent-browser open https://example.com
# In CDP mode, tabs are grouped when the tab-group extension is installed
# Override group title
agent-browser --tab-group "My Agent Group" open https://example.com
- CDP (
--cdp/--auto-connect) keeps working unchanged. - If the extension is installed and handshake succeeds, agent tabs are grouped by session:
- session=
default:Agent Browser Stealth - other sessions:
Agent Browser Stealth • <session>
- session=
- If the extension is missing/unavailable, commands continue normally with silent no-op (no warning/error unless
AGENT_BROWSER_DEBUG=1). - Env overrides:
AGENT_BROWSER_TAB_GROUPfor base titleAGENT_BROWSER_TAB_GROUP_PLUGIN_IDfor expected extension ID
Install once in Chrome: load unpacked extension from extensions/tab-group-cdp/ (extension name: agent-browser-stealth).
Extension Capabilities (agent-browser-stealth)
- Session window isolation: tabs are kept in their session window when possible.
- Configurable isolation controls: side panel can toggle
strictWindowIsolationand cross-window activation guard. - Session-aware grouping: deterministic group color, default session expanded, non-default sessions collapsed.
- Download archive routing: downloads from managed tabs are routed to
agent-browser-stealth/<session>/.... - Domain allowlist fallback: when allowlist is configured for a session, extension can force-block out-of-policy tabs to
about:blank. - Risk hints (debug only): suspicious host/TLD hints are returned via handshake and printed only when
AGENT_BROWSER_DEBUG=1. - Side panel console: view session/tab/group mapping, focus a session, keep only one session, clean empty groups, edit session allowlist, and toggle auto-clean.
Stealth Architecture
flowchart TD
A["Command Input"] --> B["Stealth Policy Resolver"]
B --> C["Connection Mode Detection"]
C --> D["Launch Layer: Chromium Args"]
C --> E["CDP Layer: UA + Metadata Override"]
C --> F["Context Layer: Init Script Patches"]
D --> G["Behavior Layer: Humanized Interaction"]
E --> G
F --> G
G --> H["Risk Layer: Verification Detection and Handling"]
H --> I["Response with warnings and riskSignals"]
Policy by Connection Mode
| Mode | Stealth Capabilities | Notes |
|---|---|---|
| Local Chromium launch | Chromium launch args + CDP UA override + context init scripts | Most complete stack |
| Existing browser via CDP | CDP UA override + context init scripts | No local Chromium arg injection |
| Cloud provider (browserbase/browseruse) | Context init scripts | Remote browser runtime controls launch layer |
| Kernel provider | Context init scripts + provider-managed stealth | Provider-side stealth may also apply |
Principle 1: Always-On Stealth with Explicit Boundaries
- Stealth defaults to enabled and does not depend on a runtime toggle.
- Project policy forbids:
--profile/AGENT_BROWSER_PROFILE--channel/AGENT_BROWSER_CHANNEL
- Default CLI policy auto-attaches an existing browser: try CDP
localhost:9333first, then auto-discovery unless explicit connection options are provided.
Principle 2: Multi-Layer Fingerprint Hardening
2.1 Launch Layer (Local Chromium)
Injected Chromium args:
--disable-blink-features=AutomationControlled--use-gl=angle--use-angle=default
If no custom UA is set, the runtime UA is normalized to remove HeadlessChrome tokens.
2.2 CDP Layer (Browser/Page Targets)
- Uses
Emulation.setUserAgentOverrideto align:userAgentacceptLanguageuserAgentMetadatabrands and versions
- Applies overrides for existing/new targets, including worker-relevant contexts.
- Forces opaque white background (
Emulation.setDefaultBackgroundColorOverride) to avoid headless transparency fingerprints.
2.3 Context Init-Script Layer (Patch Inventory)
The init script patch set is injected before page scripts and currently includes:
navigator.webdriverremoval (including prototype-level cleanup).- CSS webdriver heuristic neutralization (
CSS.supports('border-end-end-radius: initial')probe). window.chrome.runtimebootstrap for missing runtime surfaces.- Locale/language normalization (
navigator.language,navigator.languages). - Realistic
navigator.pluginsandnavigator.mimeTypes. navigator.permissions.querynormalization for notifications.- WebGL vendor/renderer masking when SwiftShader indicators are present.
cdc_property cleanup on document/documentElement.- Window/screen dimension normalization (
outerWidth/outerHeight/screenX/screenY). - Screen availability patching (
availWidth/availHeight). - Hardware concurrency stabilization.
- Notification permission consistency.
- Active text color heuristic patching.
navigator.connectionnormalization.- Worker network signal normalization (
downlinkMax). prefers-color-schemelight-mode heuristic neutralization.navigator.shareexposure.navigator.contactsexposure.contentIndexexposure.navigator.pdfViewerEnablednormalization.- Media devices surface normalization.
navigator.userAgentcleanup (stripHeadlessChrome).navigator.userAgentDatabrand cleanup.performance.memorystabilization.- Default background color patching at script level.
Principle 3: Behavioral Humanization
- Navigation pacing jitter before
goto(short randomized delay). - Typing jitter for
type --delayandkeyboard type --delay:- per-character randomized delay around the requested base delay (about ±40%).
- Click path humanization:
- cursor moves on a Bezier-like curve before click.
- Wait supports random ranges (
wait min-max) for non-uniform timing.
Principle 4: Region Signal Alignment
Before navigation, the runtime derives region hints from target URL TLD and aligns:
- locale
- timezone
Accept-Language
Examples of built-in mappings include tw, jp, kr, sg, de, fr, uk, in, au.
Manual overrides are supported:
AGENT_BROWSER_LOCALEAGENT_BROWSER_TIMEZONE(orTZ)
Principle 5: Verification-Aware Risk Control
When a navigation lands on verification/captcha pages, structured risk signals are generated from URL/title/page-text evidence.
riskSignals include:
codesource(urlortitle)evidenceconfidence
Risk Mode
warn(default): wait for auto-clear, then retry with randomized backoff and return warnings +riskSignals.block: fail fast once verification/captcha interstitial is detected.off: skip detection/retry path.
agent-browser --risk-mode warn open https://example.com
agent-browser --risk-mode block open https://example.com
AGENT_BROWSER_RISK_MODE=off agent-browser open https://example.com
flowchart TD
A["Navigate"] --> B["Collect URL/Title/Text Signals"]
B --> C{"risk-mode"}
C -->|off| D["Return Success"]
C -->|block| E["Return Error with First Signal"]
C -->|warn| F["Wait for auto-clear, then retry up to 2 times"]
F --> G{"Signals Cleared"}
G -->|yes| H["Return Success + recovery warning + riskSignals"]
G -->|no| I["Return Success + warning + riskSignals"]
Operational Recommendations
- Prefer
--headedfor high-friction targets. - Reuse session state with one stable
--session-namefor continuity (when omitted, it defaults to--session). - Keep locale/timezone consistent with target market.
- Use
--risk-mode blockin strict pipelines that require explicit operator intervention on verification pages. - For
cookies set, use either--url <url>, or--domain <domain> --path <path>together. - If
--url,--domain, and--pathare all omitted, the cookie is scoped from the current page URL.
Validation Scripts
Run public detector checks after stealth changes:
node scripts/check-sannysoft-webdriver.js --binary ./cli/target/release/agent-browser
node scripts/check-creepjs-headless.js --binary ./cli/target/release/agent-browser
Doctor Diagnostics
Use doctor to quickly diagnose local CDP and tab-group plugin readiness:
agent-browser doctor
agent-browser --json doctor
doctor checks:
- CDP probe status (preferred
:9333plus common ports) - DevToolsActivePort discovery from local Chrome profiles
- Tab-group extension handshake (when currently attached in CDP mode)
Upstream Compatibility
This fork intentionally keeps command workflows close to upstream while concentrating custom behavior in stealth, policy, and anti-detection handling.
License
Apache-2.0