Observed since 20 Oct, 22:22 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Production-grade, human-mimicking browser automation framework for autonomous agents. Survives modern anti-bot systems.
Playwright gets detected. This is much harder to detect.
This is an anti-bot-evasion tool. Read the Acceptable Use Policy before use — you are responsible for using it lawfully and within the target site's Terms of Service.
This software is for lawful, authorized automation and testing only; you are responsible for compliance with applicable laws, target Terms of Service, and robots.txt directives.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND; the authors accept no liability for misuse. See LICENSE.
A production-grade stealth browser automation library for Python, built on Playwright. It survives modern anti-bot systems (Cloudflare, LinkedIn, Amazon, etc.) by looking convincingly human at every layer — TLS, navigator, WebGL/Canvas, behavior, recovery.
When to use it — you are building an autonomous agent, scraper, or operator tool that needs to pass bot detection in headless mode on protected sites.
When NOT to use it — you only need to scrape public, unprotected pages (use
httpx + selectolax or playwright directly). You need a real uTLS stack at the
wire level (use curl_cffi). You need CAPTCHA solving (this project intentionally
stops at detection + intervention; see Limitations below).
pip install agentic-stealth-browser
playwright install --with-deps chromium
from core import AgentBrowser
async with AgentBrowser(session_name="demo") as browser:
await browser.launch(headless=True)
await browser.safe_goto("https://bot.sannysoft.com")
# passes WebGL, Canvas, AudioContext, WebRTC, and TLS fingerprint checks
Sites don't just check your User-Agent anymore. They check everything:
| Attack Surface | Vanilla Playwright | This library |
|---|---|---|
| TLS handshake (client hello / JA3/JA4-ish) | Standard Python TLS — instantly identifiable | Region-spoofed TLS profile (process-level, not custom uTLS) |
Navigator APIs (navigator.webdriver, plugins, languages) | Leaks automation flags everywhere | Every property patched before first paint |
| WebGL / Canvas fingerprint | Headless GPU renders differently | Consistent buffers across sessions |
| Human behavior | Robotic clicks, instant typing | Bézier mouse curves, variable speed, fatigue simulation |
| Auto-recovery | None — blocks = failure | CAPTCHA detection → proxy rotation → retry chain |
| Account warming | Nothing | 14-day graduated ramp-up per account |
Result: passes bot.sannysoft.com, pixelscan.net, and CreepJS with zero flags in
headless mode as of the latest 4-hourly canary run (detection canaries run every 4 hours
via docs/canary.md).
This library is opinionated and has real limits. Operators should know them up front:
curl_cffi-grade wire-level
impersonation. Attach mode (CDP) degrades further: the host browser's TLS is whatever
the user already has.BasePlugin that calls your provider and
drops the cookie back into the session.RUN_E2E_ANTI_BLOCK=1) is
flaky by nature and skipped on PRs.Set AGENTIC_MAX_REQUESTS_PER_SESSION=<n> to cap navigations per session (safe_goto returns False once exceeded).
# Health check + stealth fingerprint test
stealth-browser health --preset linkedin_2026 --region us
# Start the operator dashboard
agentic-stealth-browser dashboard
from core import AgentBrowser
async with AgentBrowser(
session_name="my-session",
region="japan",
headless=True
) as browser:
await browser.launch()
await browser.safe_goto("https://example.com")
# TLS-spoofed, no webdriver leak, human-like interaction ready
{
"mcpServers": {
"stealth-browser": {
"command": "python",
"args": ["-m", "production.mcp_server"]
}
}
}
Then: stealth_launch → stealth_navigate → stealth_scrape → stealth_close.
Instead of launching a new Chromium, you can attach to a Chrome you already
have running with --remote-debugging-port=9222:
# Attach mode: use a fresh instance (async-with auto-launches a new browser first).
browser = AgentBrowser(session_name="attached")
await browser.attach_over_cdp(
"http://127.0.0.1:9222", # or the Windows host IP from WSL
new_context=True, # don't disturb the user's tabs
)
await browser.safe_goto("https://bot.sannysoft.com")
# safe actions + MCP scrape now operational on attached; close() leaves external browser running.
await browser.close()
See docs/ATTACH_OVER_CDP.md for the WSL→Windows
walkthrough, the MCP stealth_attach_over_cdp tool, and the stealth
degradation matrix (init-script stealth still applies; TLS/JA3 does not).
git clone https://github.com/shanewas/agentic-stealth-browser.git
cd agentic-stealth-browser
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
playwright install chromium
pytest tests/ -q
The dev extras pull in pytest, pytest-asyncio, ruff, and the test fixture
deps. The full suite takes ~2 minutes on a warm cache; the default run skips
live E2E (RUN_E2E_ANTI_BLOCK=1 to enable).
| Feature | What It Does |
|---|---|
| TLS Fingerprinting | Region client-hello profiles (JA3/JA4 surface); attach mode degrades (process-level) |
| Human Behavior | Mouse wobble, typing mistakes, fatigue, distraction |
| Auto Recovery | Block detection → proxy/session rotation → retry |
| Account Warming | 14-day gradual ramp-up for new accounts |
| Workflow Orchestrator | Queue, schedule, domain concurrency, retries, persistence |
| Python SDK | StealthClient — async API without MCP |
| Security Governance | Input validation, session isolation, policy engine, approval gates |
| Adaptive Stealth | Per-domain behavior profiles with FeedbackStore telemetry |
| Plugin System | Lifecycle hooks via BasePlugin |
| Operator Dashboard | Live DevTools, CAPTCHA intervention, workflow recording |
| Feature Flags | Runtime capability discovery per browser backend |
| Performance Profiling | Timing decorators + perf_benchmark.py |
advanced_stealth.py; one
API mismatch no longer aborts every patch queued after itattach_mode skips
navigator.platform / WebGL vendor-renderer / screen-DPR overrides that would
otherwise contradict a real attached browser's OS/GPUonicecandidate rebind (no
prototype-global leak); the addEventListener('icecandidate') variant is
now filtered tooPolicyEngine + ApprovalGate wired into
the dispatch path, fail-open by default (opt-in enforcement via
STEALTH_MCP_POLICY env)isError surfacing — failed MCP tool calls now raise
AdapterToolError instead of reporting silent success; playwright-mcp
pinned to 0.0.78 with the corrected tool schemaSee CHANGELOG.md for the full release history.
close(); bad
context/stealth installs roll back cleanly; human/scraper/recovery
initialized for attachstatus — added --headless and --session flags for headless
operator checks against a named sessionSee CHANGELOG.md for the full release history.
StealthClient async API without MCPAdditional references: CHANGELOG.md · Workflow Library · Migration Guide
├── core/ AgentBrowser, connection pool, session checkpoints
├── stealth/ TLS, scripts, Firefox adapter, caching
├── behavior/ Human simulation, personas, adaptive tuning
├── recovery/ Anti-block orchestrator
├── workflows/ Recorder, player, schema, library
├── production/ MCP server, SDK, orchestrator, security, profiler
├── plugins/ Plugin system with template
├── scripts/ Migration, evaluation, benchmarking
├── docs/ Attach-over-CDP, canary, plans, analysis
├── examples/ Runnable recipes (Cloudflare, LinkedIn, Amazon)
└── tests/ Contract + integration tests (live E2E opt-in)
MIT. See LICENSE and CHANGELOG.md.
pypistats · 79 observations shown. Missing days are unknown. Source category: overall: without mirrors.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-20 – 2026-10-20 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-19 – 2026-10-19 | 5 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-18 – 2026-10-18 | 5 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-17 – 2026-10-17 | 11 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-16 – 2026-10-16 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-15 – 2026-10-15 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-14 – 2026-10-14 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-13 – 2026-10-13 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-12 – 2026-10-12 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-11 – 2026-10-11 | 22 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-10 – 2026-10-10 | 20 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-09 – 2026-10-09 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-08 – 2026-10-08 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-07 – 2026-10-07 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-06 – 2026-10-06 | 11 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-05 – 2026-10-05 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-04 – 2026-10-04 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-02 – 2026-10-02 | 12 | 2026-10-21T11:12:13.0886943Z |
| 2026-10-01 – 2026-10-01 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-30 – 2026-09-30 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-28 – 2026-09-28 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-27 – 2026-09-27 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-26 – 2026-09-26 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-25 – 2026-09-25 | 26 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-23 – 2026-09-23 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-22 – 2026-09-22 | 5 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-21 – 2026-09-21 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-20 – 2026-09-20 | 24 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-19 – 2026-09-19 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-18 – 2026-09-18 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-17 – 2026-09-17 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-16 – 2026-09-16 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-15 – 2026-09-15 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-14 – 2026-09-14 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-13 – 2026-09-13 | 24 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-12 – 2026-09-12 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-11 – 2026-09-11 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-10 – 2026-09-10 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-09 – 2026-09-09 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-08 – 2026-09-08 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-07 – 2026-09-07 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-06 – 2026-09-06 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-02 – 2026-09-02 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-09-01 – 2026-09-01 | 5 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-31 – 2026-08-31 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-29 – 2026-08-29 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-28 – 2026-08-28 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-27 – 2026-08-27 | 30 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-26 – 2026-08-26 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-24 – 2026-08-24 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-23 – 2026-08-23 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-22 – 2026-08-22 | 27 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-19 – 2026-08-19 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-18 – 2026-08-18 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-17 – 2026-08-17 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-16 – 2026-08-16 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-15 – 2026-08-15 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-14 – 2026-08-14 | 4 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-13 – 2026-08-13 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-12 – 2026-08-12 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-11 – 2026-08-11 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-10 – 2026-08-10 | 1 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-09 – 2026-08-09 | 8 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-08 – 2026-08-08 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-06 – 2026-08-06 | 9 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-05 – 2026-08-05 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-04 – 2026-08-04 | 8 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-03 – 2026-08-03 | 6 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-02 – 2026-08-02 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-08-01 – 2026-08-01 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-31 – 2026-07-31 | 3 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-30 – 2026-07-30 | 5 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-29 – 2026-07-29 | 2 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-28 – 2026-07-28 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-27 – 2026-07-27 | 7 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-26 – 2026-07-26 | 20 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-25 – 2026-07-25 | 15 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-24 – 2026-07-24 | 16 | 2026-10-21T11:12:13.0886943Z |
| 2026-07-23 – 2026-07-23 | 9 | 2026-10-21T11:12:13.0886943Z |
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 3.0.0 | 18 Jul 2026 | 11 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 22:22 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:28a3bf98aef4eecf0756d8d2e3f6f29c9aa08023c7009a403155c43219bef671