Stealth browser automation & web scraping for Node.js. CDP-first, undetected Chrome that bypasses Cloudflare Turnstile, pierces closed Shadow DOM, with a coherent fingerprint. TypeScript.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add browser-scraper -- npx -y @eurafaeldecarvalho/browser-scraper{
"mcpServers": {
"browser-scraper": {
"command": "npx",
"args": ["-y", "@eurafaeldecarvalho/browser-scraper"]
}
}
}Resumen de MCP Servers
# Browser Scraper: the stealth browser for web scraping and AI agents
**Undetected Chrome for Node.js that reads and operates the sites that block bots. Use it as a library, a CLI or an MCP server for Claude, Cursor and Codex. It turns any page, including closed Shadow DOM and cross-origin iframes, into clean Markdown, structured data or an accessibility snapshot an agent can click through. Local, free, MIT, bring-your-own-LLM.**
[](https://www.npmjs.com/package/@eurafaeldecarvalho/browser-scraper)
[](https://github.com/eurafaeldecarvalho/browser-scraper/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@eurafaeldecarvalho/browser-scraper)
[](https://nodejs.org)
[](./LICENSE)
```ts
import { scrape } from "@eurafaeldecarvalho/browser-scraper";
const page = await scrape({ url: "https://example.com", formats: ["markdown", "metadata"] });
console.log(page.tier); // "http" | "browser" | "stealth": the cheapest tier that worked
console.log(page.markdown); // clean, LLM-ready Markdown of the main content
```
```bash
# Give Claude Code a browser that gets through Cloudflare:
claude mcp add browser-scraper -- npx -y @eurafaeldecarvalho/browser-scraper mcp
```
`@eurafaeldecarvalho/browser-scraper` drives real Chrome over the raw DevTools Protocol (CDP). It never sends `Runtime.enable`, one of the most widely fingerprinted automation signals, and every layer of the browser's identity tells the same story. On top of that stealth core it adds the pieces AI workloads need: Markdown and metadata extraction, an accessibility snapshot with clickable refs, a one-call `scrape()` that escalates from plain HTTP to a stealth browser only when it has to, an MCP server, and optional LLM extraction with any model.
**Why this one:**
- **Gets through where headless browsers get blocked.** There is no `Runtime.enable` leak, the persona (UA, Client Hints, WebGL, timezone, locale) is coherent, and mouse and keyboard input are human-like. `solveTurnstile()` handles Cloudflare's checkbox.
- **Sees everything.** `find()`, `markdown()` and `snapshot()` all reach into **closed** shadow roots and **cross-origin iframes**, which Playwright's snapshot and Readability-style extractors miss.
- **Built for agents.** The MCP server and CLI work with no extra install. Credentials are typed through `{{SECRET}}` placeholders so the model never sees them, an allow-list restricts domains, and page content is fenced as untrusted data.
- **LLM only where it pays.** `generateExtractor()` has the model write CSS selectors **once**. After that `run()` extracts with no LLM, and `runOrHeal()` regenerates the selectors when the site changes.
- **Local and free.** No cloud, no API key, no per-page billing. You bring the proxy and, optionally, the model (OpenAI, Anthropic, Google, Ollama… through the Vercel AI SDK, or your own function).
## Passes the bot detectors people actually use
With the right setup — a clean residential/mobile IP, plus a real GPU (EC2 `g4dn`/`g5`) for render-hash targets — `browser-scraper` is built to clear the fingerprint suites and anti-bot stacks that block headless automation:
| Detection / fingerprint suite | | Anti-bot / WAF vendor | |
| --- | :---: | --- | :---: |
| `bot.sannysoft.com` — 0 failures | ✅ | Cloudflare (Turnstile) | ✅ |
| CreepJS — 0% headless, 0% stealth | ✅ | DataDome | ✅ |
| `bot-detector.rebrowser.net` | ✅ | Kasada | ✅ |
| Pixelscan | ✅ | Akamai Bot Manager | ✅ |
| IPHey | ✅ | PerimeterX / HUMAN | ✅ |
| Browserscan | ✅ | Imperva (Incapsula) | ✅ |
| Incolumitas | ✅ | Shape / F5 | ✅ |
| Fingerprint.com | ✅ | AWS WAF Bot Control | ✅ |
> **A ✅ means the fingerprint + behavior layer passes — it is not a guaranteed bypass.** Against hard targets your **IP reputation is the ceiling**: a datacenter ASN loses before the JavaScript runs, so route through a residential/mobile proxy (see [The production stack](#the-production-stack)). `browser-scraper` is **not** a CAPTCHA solver — for reCAPTCHA v2 / hCaptcha / Arkose (FunCaptcha) image challenges, pair it with a solver service. It *does* keep reCAPTCHA **v3** scores high via human-like input and warmed profiles.
> Numbers were taken on a desktop Chrome. On a GPU-less Lambda running **chrome-headless-shell** (`@sparticuz/chromium`) the surfaces differ — re-run the suites against your *actual* production binary and treat that as the source of truth (see [Cloud deployment](#cloud-deployment-lambda-vs-ec2-gpu)).
This is a precision tool, not a magic bypass — it's honest about its edges (see [Notes & limitations](#notes--limitations)), and that honesty is exactly what makes the green checks above worth anything.
---
## Contents
- [Install](#install)
- [Quickstart](#quickstart)
- [For AI agents & LLMs](#for-ai-agents--llms) — Markdown, `scrape()`, snapshot + refs, MCP server, CLI, LLM extraction
- [The tour](#the-tour) — what it does, by example
- [Pierce closed Shadow DOM + cross-origin iframes](#pierce-closed-shadow-dom-and-cross-origin-iframes-with-one-find)
- [Wait for the right moment](#wait-for-the-right-moment)
- [Interact like a human](#interact-like-a-human)
- [Control the network](#control-the-network)
- [Coherent browser fingerprint](#coherent-browser-fingerprint-user-agent-client-hints-webgl-timezone)
- [Persistent profiles & warming](#persistent-profiles--warming)
- [API reference](#api-reference)
- [Stealth, in depth](#stealth-in-depth)
- [WebGL / GPU on cloud hosts](#webgl--gpu-on-cloud-hosts)
- [The production stack](#the-production-stack) — proxy · VPS · solver
- [Cloud deployment (Lambda vs EC2-GPU)](#cloud-deployment-lambda-vs-ec2-gpu)
- [Identity & persistence](#identity--persistence)
- [WebRTC](#webrtc)
- [Alternatives — how it compares](#alternatives--how-it-compares)
- [FAQ](#faq)
- [Notes & limitations](#notes--limitations)
- [Support](#support)
---
## Install
```bash
npm install @eurafaeldecarvalho/browser-scraper
```
or:
```bash
pnpm add @eurafaeldecarvalho/browser-scraper
```
Requires Node.js ≥ 20 and Chrome/Chromium. Profile history seeding uses Node's built-in `node:sqlite` (Node ≥ 22.5) or the optional `better-sqlite3`; if neither is available it is simply skipped. The LLM helpers need `ai` (and `zod` if you use Zod schemas), and only if you import `/ai`.
Requires Node.js ≥ 20 and a local Chrome/Chromium (it's found automatically, or point at one with `chromePath`). For AWS Lambda, also install the optional `@sparticuz/chromium` — see [Cloud deployment](#cloud-deployment-lambda-vs-ec2-gpu).
## Quickstart
```ts
import { Browser } from "@eurafaeldecarvalho/browser-scraper";
const browser = new Browser();
try {
const tab = await browser.newTab();
await tab.goto({ url: "https://example.com" });
const heading = await tab.find({ selector: "h1" });
console.log(await heading?.text());
await tab.screenshot({ path: "example.png" });
} finally {
await browser.close();
}
```
That's the whole shape of the library: a `Browser`, a `Tab`, and `Element`s you find and act on. Everything below is detail on top of these three.
---
## For AI agents & LLMs
### Clean Markdown, metadata and links
```ts
const tab = await browser.newTab();
await tab.goto({ url: "https://shop.example.com/product/42" });
const { markdown, title, links, wordCount } = await tab.markdown({
mainContent: true, // drop nav/header/footer/cookie banners (default)
query: "price shipping", // optional: keep only the relevant blocks (BM25), saves tokens
links: "inline", // "inline" | "reference" | "none"
includeIframes: false, // true = also inline iframe documents, cross-origin included
});
const meta = await tab.metadata();
// { title, description, canonical, lang, image, openGraph, twitter, jsonLd: [...] }
// JSON-LD often already has the price, rating and availability: check it before you prompt.
```
`markdown()` reads Chrome's own DOM tree over CDP (`DOM.getDocument` with `pierce`). **No script is injected into the page**, and the content of **closed shadow roots** is included in reading order, with slots composed. For HTML you already have, `htmlToMarkdown(html)` and `extractMetadata(html)` do the same without a browser.
### `scrape()`: one call, cheapest tier first
```ts
import { Browser, scrape } from "@eurafaeldecarvalho/browser-scraper";
const browser = new Browser({ proxy: process.env.PROXY }); // reuse it across URLs
const page = await scrape({
url,
browser,
formats: ["markdown", "metadata", "links", "html", "screenshot"],
strategy: "auto", // http → browser → stealth (or pin one tier)
http: { curlImpersonate: "curl_chrome131" }, // optional: real Chrome TLS for the http tier
});
page.tier; // which tier produced the result
page.attempts; // [{ tier: "http", ok: false, reason: "needs JavaScript (empty app shell)", ms: 4 }, …]
```
| Tier | What runs | Used when |
|---|---|---|
| `http` | One request, no Chrome (Node fetch, or curl-impersonate for a genuine Chrome JA3/JA4) | Static pages, APIs |
| `browser` | The stealth Chrome | The HTTP response was blocked (403/429/503), a challenge, or an empty JS app shell |
| `stealth` | The same tab plus a behavioral warm-up and an interactive Turnstile solve | The browser still sees a challenge page |
A challenge page is **never** returned as content: if every tier is blocked, `scrape()` throws a `ScrapeError` that carries the `attempts`.
### Accessibility snapshot + refs (what agents click on)
```ts
console.log(await tab.snapshot());
// - main
// - heading "Sign in" [level=1]
// - textbox "Email" [ref=e3]
// - button "Continue"Lo que la gente pregunta sobre browser-scraper
¿Qué es eurafaeldecarvalho/browser-scraper?
+
eurafaeldecarvalho/browser-scraper es mcp servers para el ecosistema de Claude AI. Stealth browser automation & web scraping for Node.js. CDP-first, undetected Chrome that bypasses Cloudflare Turnstile, pierces closed Shadow DOM, with a coherent fingerprint. TypeScript. Tiene 10 estrellas en GitHub y su última actualización registrada es del 2026-10-18.
¿Cómo se instala browser-scraper?
+
Puedes instalar browser-scraper clonando el repositorio (https://github.com/eurafaeldecarvalho/browser-scraper) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar eurafaeldecarvalho/browser-scraper?
+
Nuestro agente de seguridad ha analizado eurafaeldecarvalho/browser-scraper y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene eurafaeldecarvalho/browser-scraper?
+
eurafaeldecarvalho/browser-scraper es mantenido por eurafaeldecarvalho. La última actividad registrada en GitHub es del 2026-10-18, con 0 issues abiertos.
¿Hay alternativas a browser-scraper?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega browser-scraper en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/eurafaeldecarvalho-browser-scraper)<a href="https://claudewave.com/repo/eurafaeldecarvalho-browser-scraper"><img src="https://claudewave.com/api/badge/eurafaeldecarvalho-browser-scraper" alt="Featured on ClaudeWave: eurafaeldecarvalho/browser-scraper" width="320" height="64" /></a>Más MCP Servers
Reverse engineer anything with agents, from app behavior down to native binaries.
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ A Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev