Obscura The open-source headless browser for AI agents and web scraping. Lightweight, stealthy, and built in Rust. Native rendering is here. No Chromium required. Capture screenshots, screencast live pages, and export PDFs directly with Obscura. --- Obscura is a headless browser engine written in Rust, built for web scraping and AI agent automation. It runs real JavaScript via V8, supports the Chr
Tools
Tools
No tool list yet. Remote servers get one after the first health check.
The headless browser for AI agents and web scraping
Copy the stdio config for Cursor, Claude Desktop, Claude Code, or VS Code on this page. It uses the publisher's install, not a PlugMCP proxy.
Does Obscura need an API key?
No required environment variable is listed on this record.
What transport does Obscura use?
Obscura runs locally over stdio.
When was Obscura last checked?
Last checked 2026-11-10. Obscura The open-source headless browser for AI agents and web scraping. Lightweight, stealthy, and built in Rust. Native rendering is here. No Chromium required. Capture screenshots, screencast live pages, and export PDFs directly with Obscura. --- Obscura is a headless browser engine written in Rust, built for web scraping and AI agent automation. It runs real JavaScript via V8, supports the Chr
From the publisher
Documentation
Obscura is a headless browser engine written in Rust, built for web scraping and AI agent automation. It runs real JavaScript via V8, supports the Chrome DevTools Protocol, and acts as a drop-in replacement for headless Chrome with Puppeteer and Playwright.
Why Obscura over headless Chrome?
Metric
Obscura
Headless Chrome
Memory
30 MB
200+ MB
Binary size
~70 MiB
300+ MB
Anti-detect
Built-in
None
Page load
85 ms
~500 ms
Startup
Instant
~2s
Puppeteer
Yes
Yes
Playwright
Yes
Yes
Obscura Cloud
We are working on the hosted version, with managed infrastructure, residential proxies, and dedicated support. For people who want the engine without operating it themselves.
Key features
01. The headless browser for AI agents and web scraping
02. Obscura The open-source headless browser for AI agents and web scraping
# Direct manifest install (available once this change merges to main):
scoop install https://raw.githubusercontent.com/h4ckf0r0day/obscura/main/scoop/obscura.json
No Chrome, no Node.js, no dependencies. Release archives include both
obscura and obscura-worker: manual zip installs should keep both in
the same directory for the parallel scrape command; scoop handles
placement automatically (both binaries land in the app dir with shims
on PATH).
Archive suffix
Rendering
Stealth transport
none
Yes
No
-stealth
Yes
Yes
-no-render
No
No
-no-render-stealth
No
Yes
The scoop install pulls the default variant (rendering, no stealth). For
stealth on Windows, download the -stealth archive manually.
Linux release builds target Ubuntu 22.04 so the downloaded binary remains
usable on common LTS servers with glibc 2.35+.
Image on Docker Hub. Multi-stage build on distroless/cc:nonroot — no shell, no package manager, runs as uid 65532, ~57 MB compressed. A mounted --storage-dir must be writable by uid 65532. Publish to host loopback as above; -p 9222:9222 exposes the port on every interface.
Requires current stable Rust (rustup.rs). First build takes ~5 min (V8 compiles from source, cached after).
The stealth build also compiles BoringSSL and generates bindings, so it needs
CMake, Clang, and the libclang/LLVM development libraries. On Ubuntu/Debian:
The rendering build uses rustls. The rendering-and-stealth build uses
wreq/BoringSSL and therefore needs the additional build tools above.
Quick Start
Fetch a page
# Get the page title
obscura fetch https://example.com --eval "document.title"
# Extract all links
obscura fetch https://example.com --dump links
# Render JavaScript and dump HTML
obscura fetch https://news.ycombinator.com --dump html
# Write dump or eval output to a file
obscura fetch https://example.com --dump text --output page.txt
# Stream the raw response body verbatim (binary-safe; bypasses the JS/DOM layer).
# Use this for images, JSON, JS, CSS, or any non-HTML resource.
obscura fetch https://picsum.photos/200/300 --dump original > photo.jpg
# List every sub-resource URL the page would fetch (NDJSON; one record per asset)
obscura fetch https://example.com --dump assets
# Fetch through an HTTP or SOCKS proxy
obscura --proxy socks5://127.0.0.1:1080 fetch https://example.com --dump text
# Wait for dynamic content
obscura fetch https://example.com --wait-until networkidle0
# Bound navigation time for slow or broken pages
obscura fetch https://example.com --timeout 10
# Capture the settled page as PNG
obscura fetch https://example.com --screenshot page.png
# The screenshot flag also has a short form
obscura fetch https://example.com -s page.png
Testing against localhost / LAN dev servers
Obscura blocks fetches to private/internal IPs by default (SSRF protection).
To point it at a local dev server, pass --allow-private-network (or set
OBSCURA_ALLOW_PRIVATE_NETWORK=1):
obscura fetch http://127.0.0.1:3000 --allow-private-network --dump text
# Works on any subcommand, e.g. the CDP server for local Puppeteer/Playwright:
obscura serve --port 9222 --allow-private-network
Official release archives and the Docker image include the rendering engine.
It provides CSS layout and paint, viewport and full-page screenshots,
scroll-aware fixed and sticky geometry, activity-driven CDP screencasting, and
raster PDF export without starting Chromium.
The current implementation covers block, inline, flex, grid, table, float,
positioning, overflow, transform, text, image, SVG, canvas, background, border,
and animation paths. It remains an evolving independent
engine: long-tail CSS, some Web APIs, media playback, compositor effects, and
platform font rasterization may differ from Chromium. The existing
Puppeteer,
Playwright, and
MCP guides cover their capture APIs and limits.
Build with --features render,stealth, then enable stealth at runtime with the
global --stealth flag. The stealth build includes the complete rendering
engine; enabling stealth does not remove screenshot, screencast, PDF, CDP, or
MCP functionality.
read, close (stream a large response body in chunks)
Storage
getCookies, setCookies, deleteCookies
Input
dispatchMouseEvent, dispatchKeyEvent
LP
getMarkdown (DOM-to-Markdown conversion)
Fetch interception pauses matching main-document HTTP requests before transport. Fulfillment supplies the document body without contacting the server; continuation URL, method, body, and header overrides apply to that request only.
To download a large resource without one giant Network.getResponseBody blob, call Fetch.takeResponseBodyAsStream then read it in chunks with IO.read / IO.close. Response bodies over the cache limit (OBSCURA_NETWORK_BODY_BUFFER_BYTES, default 2 MiB) are not retained, so raise that limit when you intend to stream large downloads.
CLI Reference
Tuning V8
Obscura embeds V8 directly. Use --v8-flags to pass raw flags through to V8, same syntax as Chromium's --js-flags and Node's command-line flags. Most common use is raising the heap cap to fix JavaScript heap out of memory on JS-heavy pages:
Obscura caps the page's script-execution phase so one slow or hung page cannot stall a worker. The default budget is 30s; pages that finish sooner return immediately, so the cap only affects pages that keep running. A very heavy React/Vue/Angular SPA on a slow network can need more time to boot before it fires its data requests. Raise the budget with OBSCURA_SCRIPT_DEADLINE_MS (milliseconds), and pair it with a matching navigation timeout in your CDP client:
Modules that enhance an already-rendered page have a separate 3s per-module budget so one non-essential module cannot hold navigation open. Raise it for legitimate long-running modules such as a Vite HMR client:
An unmounted SPA shell already gives its app modules the full OBSCURA_SCRIPT_DEADLINE_MS budget. OBSCURA_FETCH_TIMEOUT_MS controls the module's network request, not its evaluation time. See Environment variables for the complete timeout model.
obscura serve
Start a CDP WebSocket server.
Flag
Default
Description
--port
9222
WebSocket port
--proxy
—
HTTP/SOCKS5 proxy URL
--stealth
off
Enable anti-detection + tracker blocking
--workers
1
Number of parallel worker processes
--worker-max-connections
off
Recycle a worker after N CDP connections (needs --workers > 1)
--worker-max-rss
off
Recycle a worker above this many MB resident (Linux)
--worker-max-age
off
Recycle a worker after this many seconds
--worker-drain-timeout
120
Seconds a replaced worker may finish its live connections before it is killed
--font-dir
—
Recursively load fonts once per worker (repeatable; render build)
--obey-robots
off
Respect robots.txt
With multiple workers, exited children are reaped and restarted. New connections
use ready workers only; if none are ready, the balancer returns HTTP 503. A crash
still closes that worker's existing sessions, which clients must reconnect.
The --worker-max-* options recycle workers gracefully: a replacement starts
first, new connections go only to it, and the old worker keeps serving the
connections it already has until they close (or the drain timeout passes), then
exits. Each recycle is logged with its reason.
Worker errors remain visible on stderr.
obscura fetch <URL>
Fetch and render a single page.
Flag
Default
Description
--dump
html
Output: html, text, links, markdown, assets (NDJSON of every sub-resource URL the page references), or original (raw response body)
--eval
—
JavaScript expression to evaluate
--wait-until
load
Wait: load, domcontentloaded, networkidle0. Network idle counts normal and stealth requests and requires a 500 ms quiet window within --timeout; an expired deadline is an error.
--timeout
30
Maximum navigation time in seconds
--wait
adaptive, up to 5
Post-load settling; an explicit value is a fixed delay in seconds
--selector
—
Wait for CSS selector
-s, --screenshot
—
Write a PNG screenshot (single URL; render-enabled build)
--stealth
off
Anti-detection mode
--output
—
Write dump or eval output to a file
--quiet
off
Suppress banner
--proxy
—
Inherited global HTTP/SOCKS5 proxy URL
obscura scrape <URL...>
Scrape multiple URLs in parallel with worker processes.
scrape and fetch --file ... --dump original keep at most --concurrency
jobs active, starting the next URL as soon as a slot becomes available. Results
remain in input order. URL input and completed results are still held in memory.
Flag
Default
Description
--concurrency
10
Parallel workers
--eval
—
JS expression per page
--format
json
Output: json or text
--quiet
off
Suppress scrape progress on stderr
--proxy
—
Inherited global HTTP/SOCKS5 proxy URL for all workers
MCP (Model Context Protocol)
Obscura ships an MCP server that exposes browser automation tools to AI agents (Claude Desktop, Cursor, etc.).
Start
stdio (default) — for Claude Desktop and MCP clients that launch a subprocess:
Navigate to a URL (url, optional waitUntil: load / domcontentloaded / networkidle0)
browser_snapshot
Return the current page URL, title, readable body text, and element references
browser_screenshot
Return the current page as an MCP PNG image (render-enabled build)
browser_pdf
Return the current page as an embedded PDF resource (render-enabled build)
browser_click
Click by current snapshot reference or CSS selector
browser_fill
Set an input value by reference or selector (triggers input + change)
browser_type
Append text to an input
browser_press_key
Dispatch a keyboard event (key, optional selector)
browser_select_option
Select an <option> by value or text
browser_evaluate
Evaluate a JavaScript expression and return the result
browser_wait_for
Wait for a CSS selector to appear (selector, optional timeout in seconds)
browser_network_requests
List network requests made by the current page
browser_console_messages
Return console messages logged by the page
browser_close
Close the page and reset browser state
The MCP server exposes still-image and PDF output. Use CDP when you need the
streaming Page.startScreencast protocol.
Integrations
Hermes agent plugin: run Hermes agent browser tasks on Obscura. The plugin spawns obscura serve per session (or connects to an already running server) and drives it over CDP, with optional --stealth.