ENเน„เธ—เธข
๐Ÿฅท stealth ยท ๐Ÿค– mcp ยท ๐Ÿ›  skill

Ultrastealth.

Maximum-stealth browser automation in Python โ€” plus an MCP server and a script-authoring skill that let your AI agent scrape even highly protected sites. Real Chrome with the default profile, native headful macOS mode, Xvfb on Linux, and rebrowser-playwright CDP-leak fixes.

Two tools, one decision

Pick by the target site. The craft-scraper skill generates a reusable script in whichever fits โ€” and uses the Ultrastealth MCP to figure out which.

๐Ÿฅท Ultrastealth โ€” this project

Headed real-Chrome automation with a persistent default-profile runner.

Use it for
  • Highly protected sites (Cloudflare, Imperva, DataDome)
  • JS-rendered SPAs with no usable API
  • Tasks needing clicks, forms, multi-step flows

โšก scrapling-js โ€” sibling

Pure-HTTP, no-browser fetching with TLS impersonation.

Use it for
  • JSON APIs & embedded JSON (__NEXT_DATA__)
  • Maximum speed & throughput (no browser)
  • Cloudflare Workers / edge deploys

Why it stays invisible

Detection is fought at the driver, the browser, and the page โ€” not just with a spoofed user-agent.

Driver-level patch

Renames rebrowser-playwright's four leaked identifiers (__pwInitScripts, UtilityScript, __playwright_builtins__, __playwright__binding__) at the driver source. Scores 6/6 on rebrowser's bot detector (0 fail; 4 probes correctly skipped as isolated-world-inaccessible by design).

Isolated-world evaluate

REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated runs page.evaluate off the main world โ†’ 0 positive detections on rebrowser's probe.

Headed, not headless

Launches real Chrome headfully on macOS and under Xvfb on Linux with a curated flag set โ€” no headless tells, automation flags stripped, navigator.webdriver:false.

Consistent, unmodified fingerprint

No injected canvas/WebGL/audio spoofing โ€” benchmarking showed the clean real-Chrome fingerprint already beats a spoofed one on every fingerprint site tested.

Network DevTools for agents

The MCP exposes Chrome-DevTools-style capture (browser_network_log/_detail/_response_body) โ€” perfect for discovering JSON APIs.

1Install the MCP server

Give your coding agent a stealth browser it can drive: navigate, click, type, screenshot, and capture network traffic โ€” all anti-detection.

Setup once

# Install ultrastealth + the MCP server, Chromium fallback, and driver patch
curl -fsSL https://raw.githubusercontent.com/anusoft/ultrastealth/main/install.sh | bash

# Re-run the browser install + patch after dependency upgrades
ultrastealth-install

By default Ultrastealth runs chrome+default-profile: real Google Chrome with your OS Chrome user-data root and --profile-directory=Default. On macOS this is native headful Chrome; on Linux headed mode needs an X server โ€” sudo apt install xvfb and run your agent under xvfb-run -a (or set DISPLAY). If Chrome is already open with the same profile, close it first or set ULTRASTEALTH_RUNNER=chrome+temp-profile / ULTRASTEALTH_USER_DATA_DIR=/path/to/profile. Prefer a repo clone? See the clone install below.

Then wire it into your tool

Claude Code
Codex
OpenCode
Cursor

One command

claude mcp add ultrastealth -- ultrastealth-mcp --transport stdio

or edit .mcp.json (project) / ~/.claude/settings.json (global)

{
  "mcpServers": {
    "ultrastealth": {
      "command": "ultrastealth-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}

Restart, then run /mcp to confirm the ultrastealth tools are listed.

Add to ~/.codex/config.toml

[mcp_servers.ultrastealth]
command = "ultrastealth-mcp"
args = ["--transport", "stdio"]

or, on recent Codex CLI

codex mcp add ultrastealth -- ultrastealth-mcp --transport stdio

Codex speaks stdio MCP โ€” keep --transport stdio.

Add to opencode.json (project) or ~/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ultrastealth": {
      "type": "local",
      "command": ["ultrastealth-mcp", "--transport", "stdio"],
      "enabled": true
    }
  }
}

Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project)

{
  "mcpServers": {
    "ultrastealth": {
      "command": "ultrastealth-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}

Enable it under Settings โ†’ MCP, then call its tools from chat.

Alternative: one shared HTTP server (always-on, multi-tool)

Run the server once and point every tool at a URL instead of spawning a process each:

ultrastealth-mcp --port 8090          # serves http://localhost:8090/mcp
  • Claude Code: claude mcp add --transport http ultrastealth http://localhost:8090/mcp
  • Cursor: { "mcpServers": { "ultrastealth": { "url": "http://localhost:8090/mcp" } } }
  • OpenCode: { "mcp": { "ultrastealth": { "type": "remote", "url": "http://localhost:8090/mcp", "enabled": true } } }
Alternative: clone install (no pipx)
git clone https://github.com/anusoft/ultrastealth.git
cd ultrastealth
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
rebrowser_playwright install chromium
python3 -m ultrastealth.patch_rebrowser

Then use "command": "python3", "args": ["-m","ultrastealth.mcp_server","--transport","stdio"] and set the tool's working directory (or MCP cwd) to the clone.

2Install the script-authoring skill

craft-scraper runs a one-time LLM authoring loop and emits a reusable, deterministic script that reruns forever with no LLM. It uses the MCP to inspect the site, then writes a scrapling-js script (fast, for APIs) or an Ultrastealth script (for protected/JS sites) โ€” automatically picking the right one.

One command โ€” installs into whatever agent you use

# the `skills` CLI (vercel-labs/skills) auto-detects your agent and
# installs to the right place โ€” Claude Code, Codex, Cursor, OpenCode + 70 more
npx skills add anusoft/ultrastealth --skill craft-scraper

Detects installed agents automatically; if it can't, it asks which to use. Run inside a project for project scope, or add -g for global (~/.claude/skills/ etc.). Bun users: bunx skills add โ€ฆ works the same.

Pick agents explicitly / non-interactive (CI)

npx skills add anusoft/ultrastealth --skill craft-scraper -g -y \
  -a claude-code -a codex -a cursor -a opencode

After installing, just ask โ€” or run /craft-scraper <task + url>. Manage with npx skills list / update / remove.

Manual install (no skills CLI)
git clone --depth 1 https://github.com/anusoft/ultrastealth.git /tmp/ultrastealth
mkdir -p ~/.claude/skills          # or your agent's skills dir
cp -r /tmp/ultrastealth/skills/craft-scraper ~/.claude/skills/

The skill is plain Markdown (skills/craft-scraper/SKILL.md + reference/), so it also drops in as any tool's native prompt/command/rule.

3What it looks like

Ask once. Get a script you can rerun forever.

You โ–ธ /craft-scraper download every product from shop.example.com/catalog

Agent โ–ธ browser_network_enable()            # MCP: stealth browser
        browser_navigate("โ€ฆ/catalog")
        browser_network_log(filter_type="xhr")
        โ†’ found JSON API  /api/products?page=N   โœ“ Path A (speed)
        โ†ณ writes  scrape_example.js  (scrapling-js, no browser at runtime)
        bun run scrape_example.js  โ†’ 1,284 products across 13 pages โœ“

# rerun anytime, no LLM:
bun run scrape_example.js --resume

No API and Cloudflare in the way? The agent falls back to Path B and emits an Ultrastealth headed Python script instead โ€” same skill, same command. For Cloudflare-Turnstile-gated sites it builds in a persistent browser profile + challenge-solving (and notes that those targets need a residential IP). See the worked example examples/egp-announcements.py in the repo.

Or use it as a library

import asyncio
from ultrastealth import UltrastealthFetcher

async def main():
    async with UltrastealthFetcher(headless=False) as us:   # macOS headful; Linux uses Xvfb
        html = await us.fetch_and_evaluate(
            url="https://bot.sannysoft.com/",
            js_expression="() => document.documentElement.outerHTML",
            wait_secs=3.0,
        )
        print(html[:500])

asyncio.run(main())