{
  "markdown": "# stealth-agent-browser-mcp\n\nA Model Context Protocol (MCP) server that gives AI agents a **stealth-grade Chromium browser** with a **hybrid Accessibility-Object-Model + Set-of-Mark vision** interface. Built for Claude, works with any MCP-compatible host.\n\n- **Stealth first.** Uses [`rebrowser-playwright`](https://github.com/rebrowser/rebrowser-playwright) to patch the `Runtime.Enable` CDP leak that bypasses `playwright-extra`-class stealth plugins. Passes modern bot-detection suites (CreepJS, bot.sannysoft.com) where vanilla Playwright fails.\n- **Token-lean by default.** `browser_snapshot` returns [Playwright aria snapshot](https://playwright.dev/docs/aria-snapshots) YAML (~2–5 KB) instead of raw HTML (100KB+). Every interactive element carries a `[ref=eN]` id that actions consume directly — no selectors, no drift.\n- **Hybrid vision when it matters.** Ask for `mode: \"hybrid\"` and the server overlays numbered red boxes on the screenshot so the model can ground visually ([Set-of-Mark prompting, Yang et al.](https://arxiv.org/abs/2310.11441)). The ref ids on the image match the ids in the YAML. No parallel numbering scheme to go out of sync.\n- **Readability-based content extraction.** `browser_scroll_read` runs [Mozilla Readability](https://github.com/mozilla/readability) through JSDOM and returns clean Markdown — optionally delta-only, so re-reads cost nothing when nothing changed.\n- **Proxy-ready.** Per-session proxy auth, useful with residential pools.\n\n> **Authorized use only.** Stealth tooling has legitimate applications (accessibility auditing, your-own-account automation, QA against sites you own or have permission to test). Do not use this server to violate a site's terms of service or applicable law. See [SECURITY.md](./SECURITY.md).\n\n---\n\n## Install\n\n```bash\nnpm install -g stealth-agent-browser-mcp\n# Chromium binary is fetched automatically on first launch\nnpx playwright-core install chromium\n```\n\nOr run without install via `npx stealth-agent-browser-mcp`.\n\n## Quickstart (Claude Desktop / Claude Code / Cursor)\n\nAdd to your MCP config:\n\n```json\n{\n  \"mcpServers\": {\n    \"stealth-browser\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"stealth-agent-browser-mcp\"],\n      \"env\": {\n        \"SAB_HEADLESS\": \"true\",\n        \"SAB_STEALTH_LEVEL\": \"patched\"\n      }\n    }\n  }\n}\n```\n\nRestart the host. The agent will see the tools listed below.\n\n## Tools\n\n| Tool | Purpose |\n|---|---|\n| `browser_navigate` | Navigate a URL and return a snapshot. |\n| `browser_snapshot` | `aom` (YAML only, cheapest), `vision` (raw screenshot), or `hybrid` (YAML + Set-of-Mark screenshot). |\n| `browser_click` | Click an element by its `[ref=eN]`. |\n| `browser_type` | Type into an input/textarea by ref. |\n| `browser_select` | Choose options in a `<select>` by ref. |\n| `browser_scroll_read` | Scroll and return Readability Markdown (delta-only by default). |\n| `browser_wait_for` | Wait for text or a ref to become visible. |\n| `browser_tabs` | `list` / `new` / `close` / `switch`. |\n| `browser_eval` | Evaluate a JS expression in the page's MAIN world; JSON result. |\n| `browser_set_proxy` | Update single-proxy config (effective after `browser_restart`). |\n| `browser_set_proxy_pool` | Replace residential proxy pool at runtime (effective after `browser_restart`). |\n| `browser_solve_captcha` | Fallback captcha solver (CapSolver / 2Captcha). Detects Turnstile/hCaptcha/reCAPTCHA on the page. |\n| `browser_restart` | Close + re-open the active browser session with current config. |\n\nAll action tools are addressed by the **ref** emitted in the last AOM snapshot. Refs are Playwright's own `aria-ref=eN` ids — there is no parallel numbering scheme.\n\n## Configuration\n\nAll via environment variables:\n\n| Var | Default | Notes |\n|---|---|---|\n| `SAB_HEADLESS` | `true` | `false` for a visible window (debugging). |\n| `SAB_STEALTH_LEVEL` | `patched` | `off` \\| `patched` \\| `paranoid`. |\n| `SAB_PROXY_SERVER` | — | Single-proxy mode. e.g. `http://host:port` |\n| `SAB_PROXY_USERNAME` / `SAB_PROXY_PASSWORD` | — | |\n| `SAB_PROXY_POOL` | — | Residential pool. Comma-separated URLs (`http://u:p@host:port,...`) or a JSON array of `{server, username, password}`. |\n| `SAB_PROXY_ROTATION` | `per-restart` | `per-session` \\| `per-restart` \\| `static`. |\n| `SAB_PROXY_STICKY_TEMPLATE` | — | Username template for sticky-IP providers. `${sessionId}` interpolates. Example: `brd-customer-c1-zone-res-session-${sessionId}`. |\n| `SAB_HUMAN_MOUSE` | `true` | Bezier-path click with pre-click hesitation. Defeats Datadome trajectory analysis. |\n| `SAB_CAPTCHA_PROVIDER` | `none` | `capsolver` \\| `twocaptcha` \\| `none`. |\n| `SAB_CAPTCHA_API_KEY` | — | Provider API key. |\n| `SAB_USER_DATA_DIR` | — | Persistent profile directory (cookies build reputation). |\n| `SAB_DEFAULT_TIMEOUT_MS` | `15000` | Per-action timeout. |\n| `SAB_MAX_ANNOTATED` | `75` | Max labelled boxes in hybrid mode. |\n| `SAB_VIEWPORT_W` / `SAB_VIEWPORT_H` | `1366` / `768` | |\n| `SAB_LOCALE` | `en-US` | |\n| `SAB_TIMEZONE` | `America/New_York` | |\n| `LOG_LEVEL` | `info` | `debug`, `warn`, etc. Always writes to stderr. |\n\n## Architecture\n\n```\nsrc/\n├── index.ts         # Entry (stdio)\n├── server.ts        # MCP server + tool registration\n├── tools.ts         # Tool handlers\n├── browser.ts       # Stealth Chromium launcher (rebrowser-playwright)\n├── session.ts       # Per-connection browser/context/page state\n├── snapshot.ts      # AOM + Set-of-Mark pipeline\n├── annotate.ts      # SVG overlay compositing (sharp)\n├── reader.ts        # Readability → Markdown (pierces open shadow roots)\n├── fingerprint.ts   # Rotatable UA/viewport/timezone profiles\n├── proxy.ts         # Residential pool + rotation + sticky-session template\n├── human-mouse.ts   # Bezier-curve cursor paths (ghost-cursor math)\n├── captcha.ts       # CapSolver / 2Captcha REST adapters\n├── config.ts        # Zod-validated env config\n└── logger.ts        # pino → stderr (never stdout)\n```\n\nAll logs go to **stderr** — stdout is reserved for JSON-RPC. Never add `console.log`.\n\n## TLS / JA3 fingerprint — why there is no Node-layer spoofer here\n\nA common ask for scrapers is: *\"spoof the TLS ClientHello (JA3) to look like Chrome, via curl-impersonate or node-tls-client.\"*\n\n**That applies to Node-layer HTTP scrapers** (`fetch`, `got`, `axios`) where the TCP connection originates from Node's OpenSSL, which emits a ClientHello signature distinct from Chrome's BoringSSL — and Cloudflare / Akamai Bot Manager drop it at the network layer before a single byte of JavaScript runs.\n\n**This MCP does not have that architecture.** Every request exits through Chromium. Chromium's TLS stack *is* Chrome's TLS stack (literally the same BoringSSL build), so the ClientHello JA3 is Chrome's JA3 by construction. No JS-level rewriting is possible or necessary.\n\nThe one place TLS can still betray you is if you route through a proxy that terminates and re-initiates TLS (MITM). Residential proxy providers (Bright Data, DataImpulse, Oxylabs residential, SOAX) route at TCP — they do not MITM TLS — and the Chromium handshake reaches the origin unmodified. The products that *do* MITM TLS are managed scraping browsers (Bright Data's Scraping Browser, Oxylabs Web Unblocker), which ship their own headless Chrome and replace this MCP rather than layering on top of it.\n\n**Bottom line:** with `rebrowser-playwright` + residential pool (P1) + human mouse (P2), the TLS fingerprint, CDP runtime, DOM surface, and behavioral layer all match real Chrome. Captcha solving (P3) is a fallback for the 1–5% of sessions that still get flagged.\n\n## Benchmarks\n\n`npm run bench:stealth` launches the configured browser against public bot-detection test pages (bot.sannysoft.com, CreepJS, pixelscan, BrowserLeaks WebRTC) and reports pass/fail. These are the same harnesses used by the `rebrowser-patches` and Patchright projects — see [rebrowser-bot-detector](https://github.com/rebrowser/rebrowser-bot-detector) for the reference suite.\n\nTypical local-fixture test run (see `test/`):\n\n| Test | Result |\n|---|---|\n| AOM YAML contains refs for all interactive elements | ✓ |\n| `hybrid` mode returns PNG + YAML, refs match | ✓ |\n| `click`/`type` by ref produces expected DOM change | ✓ |\n| Readability extracts article to Markdown | ✓ |\n| Delta-only scroll returns `(no readable content change)` on repeat | ✓ |\n\n## Comparison\n\n|  | stealth-agent-browser-mcp | [playwright-mcp](https://github.com/microsoft/playwright-mcp) | [browser-use MCP](https://docs.browser-use.com/customize/integrations/mcp-server) | [computer use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool) |\n|---|---|---|---|---|\n| CDP-level stealth (Cloudflare/DataDome) | ✓ | ✗ | partial | ✗ |\n| Accessibility-tree snapshots | ✓ | ✓ | ✓ | ✗ |\n| Set-of-Mark vision (ref-labeled screenshot) | ✓ | ✗ | ✗ | pure vision |\n| Readability-based scroll-and-read | ✓ | ✗ | ✗ | ✗ |\n| Token-lean by default | ✓ | ✓ | ✗ | ✗ |\n| Bundled agent loop | ✗ (host's model drives) | ✗ | ✓ | ✗ |\n\n## Development\n\n```bash\nnpm install\nnpx playwright-core install chromium\nnpm run build\nnpm test\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md). All contributions under Apache-2.0.\n\n## License\n\n[Apache-2.0](./LICENSE)\n",
  "bytes": 9230,
  "sha": "558513efc2e50f0e6ec1869b6f3b31252e9c499ae58cf7cb8a7ff328ba50081b",
  "repo_slug": "ykshah1309/stealth-agent-browser-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ykshah1309_stealth_agent_brows_7e47993b/readme"
}