### Setup: Start Obscura server and install Playwright Source: https://docs.obscura.sh/guides/use-with-playwright Run the Obscura server on port 9222 and install Playwright via npm. ```bash obscura serve --port 9222 npm install playwright ``` -------------------------------- ### Quickstart: create browser, navigate, and interact Source: https://docs.obscura.sh/guides/use-as-a-rust-library Rust example showing how to create a Browser with stealth mode, open a page, navigate to example.com, print URL and HTML length, wait for an h1 element, and evaluate JavaScript to get the document title. Uses tokio main and anyhow for error handling. ```rust use obscura::Browser; use std::time::Duration; #[tokio::main] async fn main() -> anyhow::Result<()> { let browser = Browser::builder() .stealth(true) .build()?; let mut page = browser.new_page().await?; page.goto("https://example.com").await?; println!("URL: {}", page.url()); println!("HTML bytes: {}", page.content().len()); let el = page.wait_for_selector("h1", Duration::from_secs(5)).await?; println!("Heading: {}", el.text()); let title = page.evaluate("document.title"); println!("Title: {}", title); Ok(()) } ``` -------------------------------- ### Setup: Start Obscura server and install puppeteer-core Source: https://docs.obscura.sh/guides/use-with-puppeteer Run the Obscura server on port 9222 and install puppeteer-core. Use puppeteer-core, not puppeteer, because the puppeteer package bundles a Chrome download. ```bash obscura serve --port 9222 npm install puppeteer-core ``` -------------------------------- ### Install system-wide with cargo install Source: https://docs.obscura.sh/guides/build-from-source Installs the CLI system-wide using cargo install with the render feature. ```bash cargo install --path crates/obscura-cli --features render ``` -------------------------------- ### Install obscura via AUR Source: https://docs.obscura.sh/quickstart/installation Install the obscura-browser package from the AUR using yay. ```bash yay -S obscura-browser ``` -------------------------------- ### Login once, scrape many Source: https://docs.obscura.sh/guides/persist-cookies-and-storage Start a server with a dedicated storage directory, drive a login flow once, then stop the server. Subsequent runs start logged in. ```bash obscura serve --storage-dir ./session-1 ``` -------------------------------- ### Start CDP server and run viewer Source: https://docs.obscura.sh/guides/watch-agent-sessions-live Starts the CDP server on port 9222, then runs the viewer script. The viewer connects to the CDP endpoint and serves a live view at http://localhost:8080. ```bash obscura serve --port 9222 ``` ```bash node watch.mjs ``` -------------------------------- ### Install Playwright Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Installs the Playwright package. ```bash npm install playwright ``` -------------------------------- ### Start CDP server with verbose logging Source: https://docs.obscura.sh/contributing/testing-and-debugging Starts the CDP server on port 9222 with verbose logging. Useful for driving the CDP server manually. ```bash obscura serve --port 9222 --verbose ``` -------------------------------- ### Start Obscura server Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Starts the Obscura server on port 9222, which listens for WebSocket connections. ```bash obscura serve --port 9222 ``` -------------------------------- ### Install puppeteer-core Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Installs the puppeteer-core package, which is required for Puppeteer connections. ```bash npm install puppeteer-core ``` -------------------------------- ### Start MCP HTTP server with token and allowed origins Source: https://docs.obscura.sh/guides/run-in-production-at-scale Starts the MCP server over HTTP on a non-loopback interface; token and allowlist are required for non-loopback binds and browser clients. Defaults: binds to 127.0.0.1, denies browser origins. Use on an internal network even with auth. ```shell OBSCURA_MCP_TOKEN="$(openssl rand -hex 32)" \ OBSCURA_MCP_ALLOWED_ORIGINS="https://app.example.com" \ obscura mcp --http --host 0.0.0.0 --port 3000 ``` -------------------------------- ### Install obscura on macOS Intel Source: https://docs.obscura.sh/quickstart/installation Download and extract the official macOS Intel archive, then verify the installation. May require removing the quarantine attribute if Gatekeeper warns. ```bash curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-macos.tar.gz tar xzf obscura-x86_64-macos.tar.gz ./obscura --version ``` -------------------------------- ### Server: serve with --storage-dir Source: https://docs.obscura.sh/guides/persist-cookies-and-storage Start `obscura serve` with `--storage-dir` so all CDP sessions share the same directory. Use different paths for isolated profiles. ```bash obscura serve --storage-dir ./obscura-data ``` -------------------------------- ### Fetch a URL with obscura fetch Source: https://docs.obscura.sh/quickstart/your-first-fetch Fetches the URL and prints the rendered HTML. Requires the obscura CLI to be installed. ```bash obscura fetch https://example.com ``` -------------------------------- ### Install obscura on Linux ARM64 Source: https://docs.obscura.sh/quickstart/installation Download and extract the official Linux ARM64 archive, then verify the installation. Requires glibc 2.35+ (e.g., Ubuntu 22.04). ```bash curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-linux.tar.gz tar xzf obscura-aarch64-linux.tar.gz ./obscura --version ``` -------------------------------- ### Query documentation with ask parameter Source: https://docs.obscura.sh/llms.txt Use this HTTP GET request to query the documentation dynamically when the answer is not explicitly present on the current page. The question should be specific, self-contained, and written in natural language. The response contains a direct answer and relevant excerpts and sources. ```http GET https://docs.obscura.sh/readme.md?ask= ``` -------------------------------- ### Screencast with CDP: start, acknowledge frames, stop Source: https://docs.obscura.sh/guides/use-with-puppeteer Creates a CDP session, listens for Page.screencastFrame events, acknowledges each frame, starts screencast with JPEG quality 80, navigates and interacts, then stops and detaches. Frames are activity-driven page captures, not fixed-rate video. ```javascript const client = await page.createCDPSession(); client.on('Page.screencastFrame', async ({ data, sessionId }) => { const jpeg = Buffer.from(data, 'base64'); // Consume or forward `jpeg` here. await client.send('Page.screencastFrameAck', { sessionId }); }); await client.send('Page.startScreencast', { format: 'jpeg', quality: 80, maxWidth: 1280, maxHeight: 720, }); // ...navigate, scroll, and interact... await client.send('Page.stopScreencast'); await client.detach(); ``` -------------------------------- ### Install obscura on Linux x86_64 Source: https://docs.obscura.sh/quickstart/installation Download and extract the official Linux x86_64 archive, then verify the installation. Requires glibc 2.35+ (e.g., Ubuntu 22.04). ```bash curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz tar xzf obscura-x86_64-linux.tar.gz ./obscura --version ``` -------------------------------- ### Install obscura on macOS Apple Silicon Source: https://docs.obscura.sh/quickstart/installation Download and extract the official macOS Apple Silicon archive, then verify the installation. May require removing the quarantine attribute if Gatekeeper warns. ```bash curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-macos.tar.gz tar xzf obscura-aarch64-macos.tar.gz ./obscura --version ``` -------------------------------- ### Install stealth build dependencies on Ubuntu/Debian Source: https://docs.obscura.sh/guides/build-from-source Installs the additional dependencies required for the stealth feature on Ubuntu/Debian: build-essential, cmake, clang, libclang-dev, and llvm-dev. ```bash sudo apt-get install build-essential cmake clang libclang-dev llvm-dev ``` -------------------------------- ### CLI: fetch with --storage-dir Source: https://docs.obscura.sh/guides/persist-cookies-and-storage Run `obscura fetch` with `--storage-dir` to persist cookies and localStorage. The second invocation starts with the state left by the first. ```bash obscura fetch https://example.com --storage-dir ./obscura-data obscura fetch https://example.com --storage-dir ./obscura-data ``` -------------------------------- ### Enable and monitor systemd service Source: https://docs.obscura.sh/guides/run-in-production-at-scale Enables and starts the Obscura systemd service and follows its logs. Use after creating the service unit file. ```bash systemctl enable --now obscura journalctl -fu obscura ``` -------------------------------- ### Docker run with storage dir setup Source: https://docs.obscura.sh/guides/run-in-production-at-scale Prepares a writable storage directory for the non-root container user (uid 65532) and runs the Obscura container with a CDP token and stealth mode. The container runs as uid 65532; without a writable storage dir, the cookie jar silently fails to persist. ```bash sudo install -d -o 65532 -g 65532 /srv/obscura/data docker run -d \ --name obscura \ --restart unless-stopped \ -p 127.0.0.1:9222:9222 \ -e OBSCURA_CDP_TOKEN="$(openssl rand -hex 32)" \ -v /srv/obscura/data:/data \ h4ckf0r0day/obscura \ serve --host 0.0.0.0 --storage-dir /data --stealth ``` -------------------------------- ### Run MCP server over HTTP on port 3000 Source: https://docs.obscura.sh/guides/use-the-mcp-server Starts the MCP server over HTTP on port 3000. Binds to 127.0.0.1 by default. ```bash obscura mcp --http --port 3000 ``` -------------------------------- ### Smoke test obscura with fetch commands Source: https://docs.obscura.sh/quickstart/installation Smoke test: fetch a page title and take a screenshot. Expected output is "Example Domain" and a nonempty PNG at smoke.png. ```bash ./obscura fetch https://example.com --eval "document.title" ``` ```bash ./obscura fetch https://example.com --screenshot smoke.png ``` -------------------------------- ### Preload script with add_preload_script Source: https://docs.obscura.sh/guides/use-as-a-rust-library Runs a script before any of the page's own script tags, following the CDP Page.addScriptToEvaluateOnNewDocument contract. Must be called before goto to install hooks before the page bootstraps. ```rust let mut page = browser.new_page().await?; page.add_preload_script("window.__patched = true;"); page.goto("https://example.com").await?; ``` -------------------------------- ### Clone and build the Obscura CLI with rendering Source: https://docs.obscura.sh/guides/build-from-source Clones the repository and builds the release binary with the 'render' feature, enabling geometry, screenshots, screencasting, and PDF export. The binary is output to ./target/release/obscura. ```bash git clone https://github.com/h4ckf0r0day/obscura.git cd obscura cargo build --release -p obscura-cli --bins --features render ``` -------------------------------- ### Profile memory with heaptrack Source: https://docs.obscura.sh/contributing/testing-and-debugging Run the serve command under heaptrack to analyze memory allocations. ```bash heaptrack ./target/release/obscura serve ``` -------------------------------- ### Register MyDomain.doThing in the CDP dispatcher Source: https://docs.obscura.sh/contributing/adding-a-cdp-method-or-web-api File: crates/obscura-cdp/src/dispatch.rs. This match arm routes the 'MyDomain.doThing' method to the handler added in the previous step. ```rust "MyDomain.doThing" => domains::my_domain::do_thing(&req.params, ctx, &req.session_id).await, ``` -------------------------------- ### Run rendering regression suites with render-repros Source: https://docs.obscura.sh/contributing/testing-and-debugging Runs the deterministic fixtures and the representative real-site suite at both the top and bottom of pages. Set BASELINE_BIN or CHROMIUM_BIN when producing paired captures. Keep viewport, user agent, settle policy, scroll position, animation sample, and capture boundary identical. A pixel-distance score is a regression tripwire, not a verdict. ```bash RUN_ROOT="$(mktemp -d)" OBSCURA_BIN=./target/release/obscura render-repros/run.sh "$RUN_ROOT/fixtures" OBSCURA_BIN=./target/release/obscura render-repros/representative-suite/run.sh "$RUN_ROOT/top" OBSCURA_BIN=./target/release/obscura render-repros/representative-suite/run.sh "$RUN_ROOT/bottom" bottom ``` -------------------------------- ### Build using system OpenSSL on older systems Source: https://docs.obscura.sh/guides/build-from-source If the build fails on the vendored OpenSSL with an AVX-512 assembler error (common on older VPS hosts), this command uses the system OpenSSL instead. ```bash OPENSSL_NO_VENDOR=1 cargo build --release -p obscura-cli --bins --features render ``` -------------------------------- ### Run the built binary Source: https://docs.obscura.sh/guides/build-from-source Runs the built binary to check the version and to fetch a page and evaluate a JavaScript expression. ```bash ./target/release/obscura --version ./target/release/obscura fetch https://example.com --eval "document.title" ``` -------------------------------- ### Profile CPU with perf and flamegraph Source: https://docs.obscura.sh/contributing/testing-and-debugging Build with the render feature, record CPU samples at 99 Hz with call graphs, and generate a flamegraph from the perf output. ```bash cargo build --release --features render perf record -F 99 -g -- ./target/release/obscura fetch https://heavy-spa.example perf script | flamegraph.pl > flame.svg ``` -------------------------------- ### Evaluate JavaScript in the page Source: https://docs.obscura.sh/guides/use-with-playwright Use page.evaluate to get the document title and page.$$eval to extract data from elements. ```javascript const title = await page.evaluate(() => document.title); const items = await page.$$eval('.item', els => els.map(el => ({ text: el.textContent, href: el.querySelector('a')?.href, }))); ``` -------------------------------- ### Connect to Obscura with puppeteer-core Source: https://docs.obscura.sh/guides/use-with-puppeteer Connects to the Obscura server using the WebSocket endpoint ws://127.0.0.1:9222. Requires puppeteer-core installed. ```javascript const puppeteer = require('puppeteer-core'); const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://127.0.0.1:9222', }); ``` -------------------------------- ### Use HTTP proxy with --proxy flag Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Configure an HTTP proxy for fetch and serve commands using the --proxy flag with a URL. ```bash obscura fetch https://example.com --proxy http://proxy.example.com:8080 obscura serve --proxy http://proxy.example.com:8080 ``` -------------------------------- ### Navigate to pages with page.goto Source: https://docs.obscura.sh/guides/use-with-puppeteer Navigates to pages with different waitUntil options and timeout. Default waitUntil is domcontentloaded; other values: load, networkidle2, networkidle0. ```javascript const page = await browser.newPage(); await page.goto('https://example.com'); await page.goto('https://example.com', { waitUntil: 'load' }); await page.goto('https://example.com', { waitUntil: 'networkidle0', timeout: 60000 }); ``` -------------------------------- ### obscura mcp CLI options Source: https://docs.obscura.sh/reference/cli-reference Displays the command-line options for `obscura mcp` as shown in the documentation. Includes flags for HTTP transport (--http), host and port binding (--host, --port, default 127.0.0.1 and 3000), proxy (--proxy), user-agent override (--user-agent), stealth mode (--stealth), allow-private-network, and verbose logging. --host requires --http, and a non-loopback bind requires OBSCURA_MCP_TOKEN. ```plaintext --http HTTP transport instead of stdio --host HTTP bind host (default 127.0.0.1) --port HTTP port (default 3000) --proxy HTTP or SOCKS5 proxy --user-agent Override the User-Agent --stealth Consistent browser fingerprint + tracker blocking (global) --allow-private-network Permit loopback / RFC1918 / link-local -v, --verbose Enable info logging ``` -------------------------------- ### Read URLs from stdin with obscura scrape Source: https://docs.obscura.sh/reference/cli-reference Example of piping a list of URLs from a file into obscura scrape using '-' as the URL argument. Requires obscura-worker next to obscura in PATH. ```bash cat urls.txt | obscura scrape - --eval "document.title" --concurrency 20 ``` -------------------------------- ### Inspect Tokio tasks with tokio-console Source: https://docs.obscura.sh/contributing/testing-and-debugging Build with tokio_unstable and the render feature, then run the server and attach tokio-console in another shell. Requires the workspace tokio dependency to be built with the tracing feature; not enabled by default, add it in the relevant Cargo.toml before profiling. ```bash RUSTFLAGS="--cfg tokio_unstable" cargo build --release --features render ./target/release/obscura serve # in another shell tokio-console ``` -------------------------------- ### Test for MyDomain.doThing Source: https://docs.obscura.sh/contributing/adding-a-cdp-method-or-web-api File: crates/obscura-cdp/tests/cdp_my_domain.rs. Creates a CdpRequest with the method and params, dispatches it, and asserts no error and the response 'ok' is true. ```rust use obscura_cdp::dispatch::{dispatch, CdpContext}; use obscura_cdp::types::CdpRequest; use serde_json::json; #[tokio::test(flavor = "current_thread")] async fn my_domain_do_thing_returns_ok() { let mut ctx = CdpContext::new(); let resp = dispatch(&CdpRequest { id: 1, method: "MyDomain.doThing".into(), params: json!({ "name": "test" }), session_id: None, }, &mut ctx).await; assert!(resp.error.is_none()); assert_eq!(resp.result.unwrap()["ok"], true); } ``` -------------------------------- ### Multi-statement eval with IIFE Source: https://docs.obscura.sh/quickstart/your-first-fetch Wraps multiple statements in an IIFE to evaluate them as a single expression. A bare block starting with const or let returns null because V8 gives top-level declarations an empty completion value. ```bash obscura fetch https://example.com --eval "(function(){ const links = document.querySelectorAll('a'); return Array.from(links).map(a => a.href); })()" ``` -------------------------------- ### Active interception with enable_interception Source: https://docs.obscura.sh/guides/use-as-a-rust-library Enables interception of all JS fetch/XHR requests, returning a channel. Each request must be resolved via its resolver to pass, block, mock, or rewrite. The example blocks /ads requests and mocks /api/flags responses. ```rust use obscura::{Browser, InterceptResolution}; let mut page = browser.new_page().await?; let mut rx = page.enable_interception(); tokio::spawn(async move { while let Some(req) = rx.recv().await { let action = if req.url.contains("/ads") { InterceptResolution::Fail { reason: "blocked".into() } } else if req.url.ends_with("/api/flags") { InterceptResolution::Fulfill { status: 200, headers: Default::default(), body: r#"{"newDashboard":true}"#.into(), } } else { // Pass through, or rewrite by setting url/method/headers/body. InterceptResolution::Continue { url: None, method: None, headers: None, body: None } }; let _ = req.resolver.send(action); } }); page.goto("https://example.com").await?; page.settle(2000).await; ``` -------------------------------- ### CDP method handler for MyDomain.doThing Source: https://docs.obscura.sh/contributing/adding-a-cdp-method-or-web-api File: crates/obscura-cdp/src/domains/my_domain.rs. Handles the CDP method 'MyDomain.doThing' by extracting a 'name' string from params, returning a JSON response with 'ok' and 'name'. ```rust // crates/obscura-cdp/src/domains/my_domain.rs use serde_json::{json, Value}; use crate::dispatch::CdpContext; pub async fn do_thing( params: &Value, _ctx: &mut CdpContext, _session_id: &Option, ) -> Result { let name = params.get("name") .and_then(|v| v.as_str()) .ok_or("missing name")?; // do the work Ok(json!({ "ok": true, "name": name })) } ``` -------------------------------- ### List all --dump formats Source: https://docs.obscura.sh/quickstart/extract-data Shows the available `--dump` format options for the `obscura fetch` command: `html`, `text`, `markdown`, `links`, `assets`, `original`, and `cookies`. ```bash obscura fetch https://example.com --dump html obscura fetch https://example.com --dump text obscura fetch https://example.com --dump markdown obscura fetch https://example.com --dump links obscura fetch https://example.com --dump assets obscura fetch https://example.com --dump original obscura fetch https://example.com --dump cookies ``` -------------------------------- ### Connect with Playwright Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Connects to Obscura using Playwright's connectOverCDP, opens a page, navigates to example.com, and prints the title. ```javascript const { chromium } = require('playwright'); const browser = await chromium.connectOverCDP('ws://127.0.0.1:9222'); const context = browser.contexts()[0] || await browser.newContext(); const page = await context.newPage(); await page.goto('https://example.com'); console.log(await page.title()); await browser.close(); ``` -------------------------------- ### Use SOCKS5 proxy Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Configure a SOCKS5 proxy using the --proxy flag with a socks5:// URL. ```bash obscura fetch https://example.com --proxy socks5://proxy.example.com:1080 ``` -------------------------------- ### Connect with Puppeteer Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Connects to Obscura using puppeteer-core, opens a page, navigates to example.com, and prints the title. ```javascript const puppeteer = require('puppeteer-core'); const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://127.0.0.1:9222', }); const page = await browser.newPage(); await page.goto('https://example.com'); console.log(await page.title()); // "Example Domain" await browser.disconnect(); ``` -------------------------------- ### Configure MCP HTTP server with token and allowed origins Source: https://docs.obscura.sh/guides/use-the-mcp-server Configures bearer authentication and an origin allowlist for the HTTP transport. A non-loopback bind is refused without a token of at least 32 bytes. ```bash OBSCURA_MCP_TOKEN="$(openssl rand -hex 32)" \ OBSCURA_MCP_ALLOWED_ORIGINS="https://app.example.com" \ obscura mcp --http --host 0.0.0.0 ``` -------------------------------- ### Use HTTP proxy with authentication Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Specify an HTTP proxy with user credentials in the URL for authenticated access. ```bash obscura fetch https://example.com --proxy http://user:pass@proxy.example.com:8080 ``` -------------------------------- ### Run integration test suite Source: https://docs.obscura.sh/guides/build-from-source Runs the integration test suite using Python. ```bash python3 tests/test_all.py ``` -------------------------------- ### Build Obscura with stealth feature Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Build the CLI with the stealth feature using cargo. Include rendering with 'render,stealth' or omit it with '--no-default-features --features stealth'. ```bash cargo build --release -p obscura-cli --bins --features render,stealth ``` -------------------------------- ### Drive CDP server manually with wscat Source: https://docs.obscura.sh/contributing/testing-and-debugging Connects to the CDP server with wscat and sends manual CDP commands. Useful for reproducing what Puppeteer or Playwright is doing without their abstraction. ```bash wscat -c ws://127.0.0.1:9222 > {"id":1,"method":"Target.createTarget","params":{"url":"about:blank"}} > {"id":2,"method":"Target.attachToTarget","params":{"targetId":"...","flatten":true}} > {"id":3,"sessionId":"...-session","method":"Page.navigate","params":{"url":"https://example.com"}} > {"id":4,"sessionId":"...-session","method":"Runtime.evaluate","params":{"expression":"document.title"}} ``` -------------------------------- ### Pipe and redirect output Source: https://docs.obscura.sh/quickstart/extract-data Shows how to redirect the Markdown dump to a file and pipe the text dump to `wc -w` to count words, using `--quiet` to suppress extra output. ```bash obscura fetch https://example.com --dump markdown > example.md obscura fetch https://example.com --dump text --quiet | wc -w ``` -------------------------------- ### Navigate to URLs Source: https://docs.obscura.sh/guides/use-with-playwright Navigate to a URL with different waitUntil options. Default is domcontentloaded; other values are load and networkidle. ```javascript await page.goto('https://example.com'); await page.goto('https://example.com', { waitUntil: 'load' }); await page.goto('https://example.com', { waitUntil: 'networkidle' }); ``` -------------------------------- ### Combine stealth, proxy, and user-agent Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Combine --stealth, --proxy, and --user-agent flags in a single serve command for comprehensive configuration. ```bash obscura serve \ --stealth \ --proxy http://user:pass@proxy.example.com:8080 \ --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ..." ``` -------------------------------- ### Docker memory and CPU limits Source: https://docs.obscura.sh/guides/run-in-production-at-scale Runs a Docker container with memory and CPU limits. Use this to constrain resource usage per container. ```bash docker run --memory=4g --cpus=2 ... ``` -------------------------------- ### Build without rendering (with and without stealth) Source: https://docs.obscura.sh/guides/build-from-source Two commands to build without rendering features. The first excludes layout, screenshots, screencasting, and PDF export. The second keeps stealth while excluding those features. The stealth feature builds BoringSSL and generates Rust bindings, requiring additional dependencies. ```bash cargo build --release -p obscura-cli --bins --no-default-features ``` ```bash cargo build --release -p obscura-cli --bins --no-default-features --features stealth ``` -------------------------------- ### Convert page to markdown with obscura fetch Source: https://docs.obscura.sh/guides/markdown-extraction Converts the rendered page to markdown. Output is printed to stdout unless redirected. ```bash obscura fetch https://example.com --dump markdown ``` -------------------------------- ### Tune reliability limits with environment variables Source: https://docs.obscura.sh/guides/run-in-production-at-scale Sets explicit timeouts and budgets for navigation, script execution, module loading, CDP commands, and network requests. Defaults: navigation 30000ms, script phase 30000ms, module budget 3000ms, CDP command 60000ms, fetch 30000ms. CDP timeout 0 disables; keep above navigation. ```shell OBSCURA_NAV_TIMEOUT_MS=60000 \ OBSCURA_SCRIPT_DEADLINE_MS=45000 \ OBSCURA_MODULE_BUDGET_MS=10000 \ OBSCURA_CDP_COMMAND_TIMEOUT_MS=70000 \ OBSCURA_FETCH_TIMEOUT_MS=20000 \ obscura serve ``` -------------------------------- ### obscura fetch options Source: https://docs.obscura.sh/reference/cli-reference Options for the fetch subcommand, which loads a URL and prints content or an evaluated expression. Includes dump formats, selector, wait, timeout, wait-until, user-agent, proxy, stealth, eval, output, screenshot, quiet, and verbose. ```text --dump html | text | links | markdown | original | assets | cookies (default html) --selector Narrow output to a CSS selector --wait Fixed post-load delay; omitted uses adaptive settle (5s cap) --timeout Navigation timeout (default 30) --wait-until domcontentloaded | load | networkidle2 | networkidle0 (default load) --user-agent Override the User-Agent --proxy HTTP or SOCKS5 proxy --stealth Consistent browser fingerprint + tracker blocking (global) -e, --eval Evaluate JS, print the result as JSON -o, --output Write to a file instead of stdout -s, --screenshot Capture the settled page as PNG (single URL) -q, --quiet Suppress info logging -v, --verbose Enable verbose logging ``` -------------------------------- ### Run obscura via Docker Source: https://docs.obscura.sh/quickstart/installation Run the official Docker image, publishing port 9222 to host loopback only. The image runs as uid 65532 with no shell or package manager; a mounted --storage-dir must be writable by that uid. ```bash docker run -d --name obscura -p 127.0.0.1:9222:9222 h4ckf0r0day/obscura ``` -------------------------------- ### Dump assets Source: https://docs.obscura.sh/quickstart/extract-data Outputs every external resource (stylesheets, scripts, images, fonts, iframes) and URLs requested via `fetch()`/XHR, one JSON object per line. ```bash obscura fetch https://example.com --dump assets ``` -------------------------------- ### Run MCP server with stealth and proxy Source: https://docs.obscura.sh/guides/use-the-mcp-server Runs the MCP server with stealth mode and a proxy. ```bash obscura mcp --stealth --proxy http://proxy.example.com:8080 ``` -------------------------------- ### Configure Claude Desktop to use obscura MCP Source: https://docs.obscura.sh/guides/use-the-mcp-server Claude Desktop configuration to register the obscura MCP server. Edit the config file at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows), then restart Claude Desktop. ```json { "mcpServers": { "obscura": { "command": "/path/to/obscura", "args": ["mcp"] } } } ``` -------------------------------- ### Run tests with cargo nextest Source: https://docs.obscura.sh/guides/build-from-source Runs the test suite with cargo nextest in release mode with the render feature. Use cargo nextest, not cargo test, because runtime tests require process isolation. ```bash cargo nextest run --release --features render --no-fail-fast ``` -------------------------------- ### Multiple identities with separate storage dirs Source: https://docs.obscura.sh/guides/persist-cookies-and-storage Run separate `obscura serve` processes on different ports with different `--storage-dir` paths to maintain isolated profiles. ```bash obscura serve --port 9222 --storage-dir ./identity-a obscura serve --port 9223 --storage-dir ./identity-b ``` -------------------------------- ### Inspect cookies with jq Source: https://docs.obscura.sh/guides/persist-cookies-and-storage Use `jq` to inspect the cookie jar. The format is stable and includes fields like `same_site`, `expires`, `http_only`, and `secure`. ```bash jq '.[] | select(.domain == "example.com")' ./obscura-data/cookies.json ``` -------------------------------- ### Wait for SPA content with --wait-until load Source: https://docs.obscura.sh/guides/markdown-extraction Waits for client-side rendered content to load before converting to markdown, useful for SPAs. ```bash obscura fetch https://my-spa.example --wait-until load --dump markdown ``` -------------------------------- ### Smoke test crypto.subtle.digest Source: https://docs.obscura.sh/contributing/adding-a-cdp-method-or-web-api Builds the project and runs a command that calls crypto.subtle.digest with 'SHA-256' on the bytes of 'hi', then prints the hex digest. ```bash cargo build --release --features render ./target/release/obscura fetch https://example.com --eval " crypto.subtle.digest('SHA-256', new TextEncoder().encode('hi')) .then(buf => Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('')) " ``` -------------------------------- ### Pin browser profile and rotate profiles Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Use environment variables to pin a specific browser profile by index or rotate profiles randomly per browser context. ```bash OBSCURA_PROFILE=2 obscura serve # pin a specific profile by index OBSCURA_ROTATE_PROFILE=1 obscura serve # random profile per browser context ``` -------------------------------- ### obscura serve options Source: https://docs.obscura.sh/reference/cli-reference Options for the serve subcommand, which runs the CDP server. Puppeteer and Playwright connect over WebSocket. Default endpoint is ws://127.0.0.1:9222. ```text -p, --port CDP port (default 9222) --host Bind host (default 127.0.0.1) --proxy HTTP or SOCKS5 proxy --user-agent Override the User-Agent --stealth Consistent browser fingerprint + tracker blocking (global) --workers Worker processes (default 1) --font-dir Recursively load fonts once per worker (repeatable; render build) --allow-file-access Permit CDP clients to navigate to file:// URLs --storage-dir Persistent cookies and localStorage --allow-private-network Permit loopback / RFC1918 / link-local -q, --quiet Suppress info logging -v, --verbose Enable info logging ``` -------------------------------- ### Dump links Source: https://docs.obscura.sh/quickstart/extract-data Outputs every `` on the page, one per line. ```bash obscura fetch https://example.com --dump links ``` -------------------------------- ### Set custom User-Agent Source: https://docs.obscura.sh/guides/configure-stealth-and-proxies Override the default User-Agent string for fetch and serve commands using the --user-agent flag. ```bash obscura fetch https://example.com --user-agent "Mozilla/5.0 (...) ..." obscura serve --user-agent "Mozilla/5.0 (...) ..." ``` -------------------------------- ### Server listening output Source: https://docs.obscura.sh/quickstart/connect-puppeteer-or-playwright Output shown when the server is ready, indicating the WebSocket endpoint. ```text obscura listening on ws://127.0.0.1:9222 ```