{
  "markdown": "# obscura-mcp — ARCHIVED\n\n> **⚠️ Archived.** Upstream ships native MCP since [v0.1.4](https://github.com/h4ckf0r0day/obscura/releases/tag/v0.1.4) (`obscura mcp`). npm package deprecated.\n\n[![npm version](https://img.shields.io/npm/v/obscura-mcp)](https://www.npmjs.com/package/obscura-mcp)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\nAn MCP server adapter for [Obscura](https://github.com/h4ckf0r0day/obscura), a lightweight Rust headless browser for scraping and AI agent automation.\n\nExposes Obscura's native CDP capabilities through a clean MCP interface — no Chrome dependency, no heavyweight browser automation.\n\n## Installation\n\n```bash\nnpm install -g obscura-mcp\n```\n\nThe npm package itself is a small Node.js wrapper (~20 KB). The browser binary (~80 MB) is downloaded automatically on first use — no separate install step needed.\n\nThe binary is cached at `~/.obscura/bin/` and survives npm upgrades.\n\n**Pre-release builds** are published under the `dev` tag:\n\n```bash\nnpm install -g obscura-mcp@dev\n```\n\nTo use a custom binary path:\n\n```bash\nexport OBSCURA_PATH=/path/to/obscura\n```\n\n## Quick Start\n\n```bash\n# Install\nnpm install -g obscura-mcp\n\n# Verify\nobscura-mcp --version\n\n# Start MCP server (stdio — primary transport)\nobscura-mcp --transport stdio\n\n# Or with HTTP transport\nobscura-mcp --transport streamable-http\n```\n\nMost MCP clients (Claude Desktop, Cline, Continue) connect via `stdio`. The `streamable-http` transport is also supported for custom integrations.\n\n## Tools\n\nFour tools cover browsing, interacting, session persistence, and bulk scraping.\n\n### `browse_page` — one-shot page reading\n\nGet content from any page in a single call. Combine output format with optional JavaScript evaluation.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `url` | `string` | — | The URL to visit |\n| `format` | `\"text\"` \\| `\"markdown\"` \\| `\"html\"` \\| `\"links\"` \\| `\"cookies\"` \\| `\"axtree\"` \\| `\"layout\"` | `\"text\"` | Output format |\n| `eval` | `string` | — | JavaScript expression to evaluate (appended to output) |\n| `cookies` | `array` | — | Cookies to inject `[{name, value, domain?, path?, ...}]` |\n| `user_agent` | `string` | — | Override the browser user-agent string |\n| `headers` | `object` | — | Extra HTTP headers `{key: value, ...}` |\n| `stealth` | `boolean` | `true` | Accepted for compatibility; stealth is controlled by the Obscura server |\n\n**Examples:**\n\n```\nbrowse_page(url: \"https://example.com\")\nbrowse_page(url: \"https://example.com\", format: \"markdown\")\nbrowse_page(url: \"https://example.com\", format: \"axtree\")\nbrowse_page(url: \"https://example.com\", format: \"layout\")\nbrowse_page(url: \"https://example.com\", user_agent: \"TestBot/1.0\")\n```\n\n| `format` | What you get |\n|----------|-------------|\n| `\"text\"` | Plain text — stripped of HTML tags, scripts, styles |\n| `\"markdown\"` | Clean markdown — uses Obscura's native LP.getMarkdown CDP |\n| `\"html\"` | Raw HTML markup |\n| `\"links\"` | All href values — one per line |\n| `\"cookies\"` | Cookies with name, value, domain, path, expiry |\n| `\"axtree\"` | Accessibility tree — roles, names, values of all elements |\n| `\"layout\"` | Viewport metrics — dimensions, scroll offsets, device scale |\n\nWhen `eval` is provided, the JavaScript result is appended to the format output under a `--- eval ---` divider.\n\n---\n\n### `browse_interact` — one-shot page actions\n\nClick an element or type text into a page. For multi-step interactions (login → wait → extract), use `browse_session` instead.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `url` | `string` | — | The URL to visit |\n| `action` | `\"click\"` \\| `\"type\"` | — | Action to perform |\n| `selector` | `string` | — | CSS selector for the target element |\n| `text` | `string` | — | Text to type (required when `action` is `\"type\"`) |\n| `cookies` | `array` | — | Cookies to inject `[{name, value, ...}]` |\n| `stealth` | `boolean` | `true` | Accepted for compatibility; stealth is controlled by the Obscura server |\n\n**Examples:**\n\n```\nbrowse_interact(url: \"https://example.com\", action: \"click\", selector: \"a\")\nbrowse_interact(url: \"https://duckduckgo.com\", action: \"type\", selector: \"input[name=q]\", text: \"search query\")\n```\n\nBoth actions create a fresh page, perform the action, and close. The page context does not persist — for sequential interactions (type into a form, then click submit), use `browse_session` instead.\n\n---\n\n### `browse_session` — multi-step persistent sessions\n\nCreate a persistent browser session, interact with it across multiple calls, then close. Sessions auto-close after 5 minutes of inactivity. Multiple sessions can run simultaneously.\n\n| Parameter | Type | Required for | Description |\n|-----------|------|-------------|-------------|\n| `action` | `\"create\"` \\| `\"close\"` \\| `\"list\"` \\| `\"goto\"` \\| `\"wait\"` \\| `\"extract\"` \\| `\"click\"` \\| `\"type\"` | All | What to do |\n| `session_id` | `string` | All except `create`, `list` | Session ID from `create` |\n| `url` | `string` | `create`, `goto` | URL to navigate to |\n| `selector` | `string` | `wait`, `click`, `type` | CSS selector |\n| `expression` | `string` | `wait` (if no selector), `extract` | JavaScript expression |\n| `text` | `string` | `type` | Text to type |\n| `timeout` | `number` | `wait` (optional) | Max wait in ms (default 30000, max 120000) |\n| `user_agent` | `string` | `create`, `goto` | Override user-agent string for navigation |\n| `headers` | `object` | `create`, `goto` | Extra HTTP headers `{key: value, ...}` |\n| `clear_cookies` | `boolean` | `create` | Clear all browser cookies on session creation |\n\n**Session lifecycle:**\n\n| `action` | What it does | Returns |\n|----------|-------------|---------|\n| `create` | Opens a new browser tab. Optionally clears cookies. | Session ID |\n| `close` | Releases the tab and all its resources. Idempotent. | Confirmation |\n| `list` | Shows all active sessions with timestamps. | Session list |\n| `goto` | Navigates to a new URL. Page stays alive. | Confirmation |\n| `wait` | Polls until a CSS selector exists or a JS expression returns true. | Confirmation |\n| `extract` | Evaluates JavaScript and returns the result. | Eval result |\n| `click` | Clicks an element by CSS selector. | Coordinates |\n| `type` | Types text into an input field. | Confirmation |\n\n**Login flow example:**\n\n```\nbrowse_session(action: \"create\", url: \"https://example.com/login\")\n  → \"Created session: session_1\"\n\nbrowse_session(action: \"type\", session_id: \"session_1\", selector: \"#username\", text: \"user\")\nbrowse_session(action: \"type\", session_id: \"session_1\", selector: \"#password\", text: \"pass\")\nbrowse_session(action: \"click\", session_id: \"session_1\", selector: \"#login-btn\")\n\nbrowse_session(action: \"wait\", session_id: \"session_1\", selector: \".dashboard\", timeout: 10000)\nbrowse_session(action: \"extract\", session_id: \"session_1\", expression: \"document.title\")\n\nbrowse_session(action: \"close\", session_id: \"session_1\")\n```\n\n**Multi-article browsing example:**\n\n```\nbrowse_session(action: \"create\")\nbrowse_session(action: \"goto\", session_id: \"session_1\", url: \"https://en.wikipedia.org/wiki/JavaScript\")\nbrowse_session(action: \"extract\", session_id: \"session_1\", expression: \"document.title\")\nbrowse_session(action: \"goto\", session_id: \"session_1\", url: \"https://en.wikipedia.org/wiki/Python\")\nbrowse_session(action: \"extract\", session_id: \"session_1\", expression: \"document.title\")\nbrowse_session(action: \"close\", session_id: \"session_1\")\n```\n\n---\n\n### `browse_scrape` — parallel bulk scraping\n\nScrape multiple URLs simultaneously using isolated worker processes. Each URL gets its own headless browser worker — built on top of Obscura's native `scrape` command with `obscura-worker`.\n\n| Parameter | Type | Default | Max | Description |\n|-----------|------|---------|-----|-------------|\n| `urls` | `string[]` | — | 1000 | URLs to scrape in parallel |\n| `eval` | `string` | — | — | JavaScript expression to evaluate per page |\n| `concurrency` | `number` | `10` | `100` | Number of parallel worker processes |\n| `timeout` | `number` | `60` | `300` | Per-worker timeout in seconds |\n\n**Example:**\n\n```\nbrowse_scrape(urls: [\"https://news.ycombinator.com\", \"https://example.com\"], eval: \"document.title\", concurrency: 25)\n```\n\n**Output format (JSON):**\n\n```json\n{\n  \"total_urls\": 2,\n  \"concurrency\": 25,\n  \"total_time_ms\": 1250,\n  \"avg_time_ms\": 625.0,\n  \"results\": [\n    {\n      \"url\": \"https://news.ycombinator.com\",\n      \"title\": \"Hacker News\",\n      \"eval\": \"Hacker News\",\n      \"time_ms\": 612,\n      \"worker\": 0\n    },\n    {\n      \"url\": \"https://example.com\",\n      \"eval\": \"Example Domain\",\n      \"time_ms\": 638,\n      \"worker\": 1\n    }\n  ]\n}\n```\n\nOn errors (timeout, network failure, etc.), the per-URL result includes an `\"error\"` field instead of `\"eval\"`:\n\n```json\n{\n  \"url\": \"https://slow-site.com\",\n  \"error\": \"timeout\",\n  \"time_ms\": 60000\n}\n```\n\nThis is the tool that directly leverages Obscura's core advantage over headless Chrome: lightweight parallel scraping with built-in stealth. The ~30 MB per-worker memory footprint means 100 concurrent workers use less memory than a single Chrome instance.\n\n## Configuration\n\n### Claude Desktop / Cline / Continue / Any MCP client\n\n```json\n{\n  \"mcpServers\": {\n    \"obscura-mcp\": {\n      \"command\": \"obscura-mcp\",\n      \"args\": [\"--transport\", \"stdio\"]\n    }\n  }\n}\n```\n\n### VS Code (Cline extension)\n\n```json\n{\n  \"servers\": {\n    \"obscura-mcp\": {\n      \"command\": \"obscura-mcp\",\n      \"args\": [\"--transport\", \"stdio\"]\n    }\n  }\n}\n```\n\nAfter global npm install, `obscura-mcp` is on your PATH — no absolute paths needed.\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `OBSCURA_PATH` | — | Path to custom Obscura binary |\n| `OBSCURA_STEALTH` | — | Enable stealth mode (anti-detection) |\n| `OBSCURA_PROXY` | — | Proxy URL for all traffic |\n| `OBSCURA_USER_AGENT` | — | Default user-agent override |\n| `MCP_HTTP_HOST` | `127.0.0.1` | HTTP transport host |\n| `MCP_HTTP_PORT` | `3000` | HTTP transport port |\n| `MCP_TRANSPORT` | `stdio` | Transport mode: `stdio` or `streamable-http` |\n| `OBSCURA_STARTUP_TIMEOUT_MS` | `15000` | Milliseconds to wait for Obscura CDP to start |\n| `OBSCURA_NAVIGATION_WAIT_MS` | `3000` | Milliseconds to wait after page navigation |\n| `CDP_REQUEST_TIMEOUT_MS` | `10000` | Milliseconds to wait for CDP response |\n\n## Development\n\nBuilt with TypeScript, compiled to `dist/`, tested with Vitest.\n\n```bash\ngit clone https://github.com/Metadrama/obscura-mcp\ncd obscura-mcp\nnpm install\nnpm run build\nnpm test\n```\n\nAll 36 integration tests run against a real Obscura binary (auto-downloaded on first run). Tests use `StdioClientTransport` and cover every tool, format, and action.\n\n## Why Obscura?\n\n- **No Chrome** — pure Rust, no 200 MB browser bundle\n- **CDP-native** — exposes Chrome DevTools Protocol directly\n- **Anti-detection** — built-in stealth for scraping-resistant sites\n- **Tiny footprint** — ~15 MB binary, starts in milliseconds\n\n## License\n\nMIT\n",
  "bytes": 11062,
  "sha": "0d1254ceb36aeed4a19645af783626b18b51d77501b6f24c1ec5b35be88f15cc",
  "repo_slug": "metadrama/obscura-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_metadrama_obscura_mcp_3df4c5cb/readme"
}