npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@devinwangd/cloak-browser-mcp

v0.1.1

Published

Model Context Protocol (MCP) server backed by CloakBrowser stealth Chromium. Drop-in replacement for @playwright/mcp with source-level fingerprint patches, humanized inputs, and persistent profiles. 80 tools across navigation, interaction, page state, net

Readme

cloak-browser-mcp

A Model Context Protocol (MCP) server backed by CloakHQ/CloakBrowser — a source-patched Chromium that passes Cloudflare Turnstile, reCAPTCHA v3, FingerprintJS, BrowserScan, and 30+ other bot detection services without runtime JS injection.

Drop-in replacement for @playwright/mcp with 80 tools: full Playwright-MCP parity plus a Cloak-exclusive stealth/profile/audit layer.

Works with Claude Code, Cursor, VS Code, Codex, Gemini CLI, Windsurf, or any MCP client.


Table of contents


Why CloakBrowser over vanilla Playwright?

| | @playwright/mcp | cloak-browser-mcp | |---|---|---| | Chromium | Stock | Source-patched (58 C++ patches) | | navigator.webdriver | true (leaks) | absent | | Cloudflare Turnstile | Fails | Auto-pass | | reCAPTCHA v3 score | ~0.1 | ~0.9 | | Humanized mouse / keyboard | None | Bézier curves, typo correction | | Persistent profiles | Manual | First-class CLI flag + management tools | | GeoIP-aware emulation | None | Auto timezone/locale from proxy exit IP | | Stealth audit / detection probe | None | Built-in cloak_stealth_audit + cloak_detection_test |

When you don't need stealth, @playwright/mcp is faster and lighter — use that. When the site has any bot detection (Cloudflare, DataDome, PerimeterX, FingerprintJS) — use this.


Quick start

1. Install once

The wrapper installs from npm; the CloakBrowser Chromium binary (~200 MB) downloads on first use into ~/.cloakbrowser/.

npm install -g @devinwangd/cloak-browser-mcp

Or run on demand without installing:

npx @devinwangd/cloak-browser-mcp --caps all

After install, the binary on PATH is cloak-browser-mcp (unscoped) — that's what you reference in MCP client configs below.

2. Wire into your MCP client

Claude Code (~/.claude.json or project .mcp.json)

{
  "mcpServers": {
    "cloak-browser": {
      "command": "cloak-browser-mcp",
      "args": ["--caps", "all"]
    }
  }
}

Cursor / VS Code (.cursor/mcp.json or .vscode/mcp.json)

{
  "servers": {
    "cloak-browser": {
      "command": "cloak-browser-mcp",
      "args": ["--caps", "all"]
    }
  }
}

Persistent profile + proxy + humanized inputs

{
  "mcpServers": {
    "cloak-browser": {
      "command": "cloak-browser-mcp",
      "args": [
        "--caps", "all",
        "--profile-dir", "/Users/me/.cloak-browser-mcp/profiles/work",
        "--proxy", "http://user:[email protected]:8080",
        "--timezone", "Europe/London",
        "--locale", "en-GB",
        "--geoip",
        "--humanize",
        "--viewport", "1920x1080",
        "--allowed-domains", "*.example.com,*.cloudflare.com"
      ]
    }
  }
}

3. Use it

In Claude Code:

"Open example.com, click the search box, search for 'hello', take a screenshot."

The agent will call browser_navigatebrowser_snapshotbrowser_clickbrowser_typebrowser_take_screenshot.


Capabilities (--caps)

| Cap | Tools | Use when | |---|---|---| | (always) | navigation, interaction, page state | Standard browsing | | network | request inspection, route mocking, offline simulation | Debugging APIs, testing failure modes | | storage | cookies, localStorage, sessionStorage, storage state export/import | Auth state persistence, session replay | | vision | pixel-coordinate mouse | Bypassing accessibility tree for canvas / SVG apps | | pdf | browser_pdf_save | Snapshotting pages as PDF | | testing | verify_* + generate_locator | Codegen for Playwright tests | | devtools | highlight, tracing, video, resume | Debugging agent decisions | | config | get_config, close, run_code_unsafe | Introspection + (with --enable-unsafe-eval) arbitrary JS | | humanize | cloak_humanize_set | Tuning humanized input parameters |

--caps all enables everything (except run_code_unsafe, which additionally requires --enable-unsafe-eval).


CloakBrowser-exclusive tools (always on)

| Tool | Purpose | |---|---| | cloak_set_fingerprint | Override canvas seed, GPU vendor/renderer, screen size, hardware concurrency, device memory, UA brand, platform, storage quota | | cloak_set_timezone | Live timezone via CDP (no relaunch) | | cloak_set_locale | Override navigator.language and Accept-Language | | cloak_set_geolocation | Set coords, or auto-resolve from proxy exit IP | | cloak_set_proxy | Switch proxy mid-session | | cloak_detection_test | Load a known probe (CreepJS, FingerprintJS, BrowserScan, SannySoft, Cloudflare Turnstile) and dump results | | cloak_stealth_audit | Programmatic check: navigator.webdriver, plugin count, WebGL vendor, languages, UA, chrome.runtime, canvas hash, $cdc_* CDP signals | | cloak_request_signal_inspect | Capture per-request TLS / header signals for a single URL | | cloak_persistent_profile_create / list / delete | Manage ~/.cloak-browser-mcp/profiles/ | | cloak_binary_info / cloak_binary_update | Inspect / refresh the CloakBrowser Chromium binary |


CLI flags

| Flag | Value | Default | Notes | |---|---|---|---| | --caps <csv> | all or any subset | (none) | Enables capability-gated tools | | --profile-dir <path> | Absolute path | (ephemeral) | Persistent user-data dir | | --headless / --headed | (boolean) | headed (visible) | Pass --headless for batch/CI runs. | | --proxy <url> | http(s)/socks5 with inline auth | none | | | --timezone <tz> | IANA tz | system | e.g. America/New_York | | --locale <bcp47> | BCP-47 | system | e.g. en-US | | --user-agent <ua> | string | (cloak default) | | | --viewport <WxH> | e.g. 1920x1080 | 1280×720 | | | --geoip | boolean | off | Auto resolve geolocation from proxy IP | | --humanize | boolean | off | Enable Bézier mouse + typo-correcting keyboard | | --fingerprint-seed <int> | int | random | Deterministic canvas/WebGL noise | | --allowed-domains <csv> | host patterns | (open) | Whitelist for browser_navigate | | --blocked-domains <csv> | host patterns | (none) | Blocklist for browser_navigate | | --enable-unsafe-eval | boolean | off | Required for browser_run_code_unsafe | | --upload-allow-dir <path> | path | (none) | Restrict file-upload source paths | | --download-dir <path> | path | (cwd) | Where downloaded files land | | --max-pages <n> | int | 20 | Concurrent tab cap | | --self-test | boolean | off | Print the tool list and exit |


Tool inventory

Tools are grouped by capability. The "always-on" sections are exposed regardless of --caps; capability-gated sections require the matching --caps entry.

Always-on

Navigation

| Tool | Required | Optional | Notes | |---|---|---|---| | browser_navigate | url | waitUntil, timeoutMs | Subject to --allowed-domains / --blocked-domains. Returns a fresh [eN] snapshot. | | browser_navigate_back | — | — | History back in the active tab. | | browser_tabs | action (list/new/switch/close) | index, id, url | Manage tabs by id (t1,…) or 0-based index. |

Interaction

| Tool | Required | Optional | Notes | |---|---|---|---| | browser_click | target | element, doubleClick, button, modifiers | target is a eN ref or a Playwright selector. | | browser_type | target, text | element, submit, slowly | slowly:true triggers per-character typing; combine with --humanize. | | browser_hover | target | element | | | browser_drag | startTarget, endTarget | startElement, endElement | | | browser_drop | target | paths, data | File paths via setInputFiles; arbitrary MIME data via synthetic DataTransfer. | | browser_select_option | target, values | element | | | browser_press_key | key | — | Page-level key press (e.g. Control+A, ArrowDown). | | browser_handle_dialog | accept | promptText | Responds to the most recently captured dialog. | | browser_file_upload | paths | — | Paths constrained by --upload-allow-dir if set. | | browser_fill_form | fields | — | Each field has target + value (+ optional kind). | | browser_scroll | — | target, direction, amount | Element-scoped or page-level. |

Page state

| Tool | Required | Optional | Notes | |---|---|---|---| | browser_snapshot | — | — | Accessibility tree with [eN] refs for interactable nodes. | | browser_take_screenshot | — | element, target, type, fullPage, quality, saveAs | Image is returned inline; optionally saved to disk. | | browser_console_messages | — | level, limit | Buffered console + pageerror. | | browser_wait_for | — | timeMs, text, textGone, selector, state, timeoutMs | | | browser_resize | width, height | — | | | browser_evaluate | function | element, target | Function source must be an arrow or function expression. |

CloakBrowser-exclusive

| Tool | Required | Optional | Notes | |---|---|---|---| | cloak_set_fingerprint | — | seed, gpuVendor, gpuRenderer, screenWidth, screenHeight, hardwareConcurrency, deviceMemoryGB, uaBrand, uaBrandVersion, platform, storageQuotaMB | Some flags only take effect on next launch — call browser_close then any tool to relaunch. | | cloak_set_timezone | timezone | — | Live via CDP. | | cloak_set_locale | locale | — | Sets navigator.language + Accept-Language header. | | cloak_set_geolocation | — | latitude, longitude, accuracy, fromProxyIp | fromProxyIp calls ipapi.co/json/ via current proxy. | | cloak_set_proxy | proxy | — | Recreates the context. | | cloak_detection_test | — | suite, customUrl | Suites: creepjs, fingerprintjs, browserscan, sannysoft, cloudflare-turnstile. | | cloak_stealth_audit | — | — | Programmatic audit. | | cloak_request_signal_inspect | url | — | Returns TLS details, response status, request headers, response headers. | | cloak_persistent_profile_create | name | — | Creates ~/.cloak-browser-mcp/profiles/<name>. | | cloak_persistent_profile_list | — | — | | | cloak_persistent_profile_delete | name, confirm=true | — | | | cloak_binary_info | — | — | | | cloak_binary_update | — | — | |

Capability-gated

--caps networkbrowser_network_requests, browser_network_request, browser_route, browser_route_list, browser_unroute, browser_network_state_set.

--caps storagebrowser_cookie_set/get/list/delete/clear, browser_localstorage_*, browser_sessionstorage_*, browser_storage_state, browser_set_storage_state.

--caps visionbrowser_mouse_click_xy, browser_mouse_move_xy, browser_mouse_drag_xy, browser_mouse_down, browser_mouse_up, browser_mouse_wheel.

--caps pdfbrowser_pdf_save.

--caps testingbrowser_verify_element_visible, browser_verify_text_visible, browser_verify_list_visible, browser_verify_value, browser_generate_locator.

--caps devtoolsbrowser_highlight, browser_hide_highlight, browser_start_tracing, browser_stop_tracing, browser_start_video, browser_stop_video, browser_video_chapter, browser_resume.

--caps configbrowser_get_config, browser_close, browser_run_code_unsafe (also needs --enable-unsafe-eval).

--caps humanizecloak_humanize_set.


Target syntax for interaction tools

The target argument accepts:

  • eN ref from a prior browser_snapshot — e.g. e7. Most reliable.
  • CSS selector — e.g. button.primary.
  • xpath=… — e.g. xpath=//button[contains(., "Submit")].
  • text=… — e.g. text=Sign in.
  • role=…[name="…"] — e.g. role=button[name="Submit"].

After any navigation or significant DOM mutation, call browser_snapshot again to refresh refs.


Example flows

1. Take a screenshot of a Cloudflare-protected page

You: Open https://example-cloudflare-protected.com, wait for the page to settle, take a full-page screenshot.

Agent calls:
  browser_navigate(url="https://...")
  browser_wait_for(textGone="Checking your browser")
  browser_take_screenshot(fullPage=true)

Vanilla @playwright/mcp fails the Turnstile check; cloak-browser-mcp passes it automatically because the stealth patches are below the JS layer.

2. Sign into a SaaS dashboard, persist auth, reopen later

Phase 1 — initial sign-in with a fresh profile:

// .mcp.json
{
  "mcpServers": {
    "cloak": {
      "command": "cloak-browser-mcp",
      "args": [
        "--caps", "all",
        "--profile-dir", "/Users/me/.cloak-browser-mcp/profiles/saas-prod",
        "--humanize"
      ]
    }
  }
}
You: Open https://saas.example.com, sign in as [email protected] / <password>, then confirm I'm on the dashboard.

Phase 2 — reopen later, all cookies still present:

You: Open https://saas.example.com — you should already be signed in from yesterday's session.

3. Probe how stealth is doing

You: Run a stealth audit and then load the SannySoft bot detection test.

Agent:
  cloak_stealth_audit()
  cloak_detection_test(suite="sannysoft")

You'll see all green if stealth is intact.

4. Switch geolocation/timezone mid-session via proxy

You: Switch to a UK proxy, align my timezone/locale/geo to match, then load a country-specific landing page.

Agent:
  cloak_set_proxy(proxy="http://uk-proxy.example.com:8080")
  cloak_set_timezone(timezone="Europe/London")
  cloak_set_locale(locale="en-GB")
  cloak_set_geolocation(fromProxyIp=true)
  browser_navigate(url="https://example.com/uk")

5. Mock an API response while testing a frontend

You: While loading example.com, return a fake 500 to /api/orders so I can verify the error state.

Agent:
  browser_route(pattern="**/api/orders", status=500, body='{"error":"simulated"}', contentType="application/json")
  browser_navigate(url="https://example.com")
  browser_take_screenshot()
  browser_unroute(pattern="**/api/orders")

6. Export storage state, replay in a fresh session

Agent:
  browser_storage_state(filename="/tmp/saas-state.json")
  # …later, in a new ephemeral session…
  browser_set_storage_state(filename="/tmp/saas-state.json")
  browser_navigate(url="https://saas.example.com")

7. Run a Playwright trace for human review

You: Trace this whole flow so I can replay it in Playwright Trace Viewer.

Agent:
  browser_start_tracing(filename="/tmp/trace.zip", screenshots=true, snapshots=true)
  # …agent runs the flow…
  browser_stop_tracing()

You: open /tmp/trace.zip in Playwright Trace Viewer (https://trace.playwright.dev)

Security model

Read this before deploying on any machine that has production credentials.

TL;DR

| Asset | Trust boundary | |---|---| | cloak-browser-mcp source (this repo) | MIT, public, audit by reading. | | cloakbrowser npm package | Trust the CloakHQ maintainers + npm registry. | | CloakBrowser Chromium binary | Downloaded on first use from cloakbrowser.dev. SHA-256 verified by upstream wrapper. The binary is closed-source by license. | | Your env vars / Keychain / shell history | The MCP server inherits your process env. Do not run with prod credentials in scope unless you trust the supply chain. |

Threats this package introduces

1. Supply-chain compromise

Three packages are pulled at install/run time: @modelcontextprotocol/sdk, playwright-core, and cloakbrowser + its downloaded Chromium binary. If CloakHQ's npm publish token or cloakbrowser.dev is compromised, an attacker could push a malicious binary that runs under your user account.

Mitigations:

  • Pin a known-good cloakbrowser version.
  • Set CLOAKBROWSER_BINARY_PATH to an audited binary.
  • Leave CLOAKBROWSER_SKIP_CHECKSUM at default (false).
  • Audit ~/.cloakbrowser/ and any --profile-dir you use.

2. Agent-driven browser navigation

By default browser_navigate accepts any URL. An LLM agent can be prompt-injected into navigating somewhere malicious.

Mitigations:

  • --allowed-domains <csv> (supports *.example.com).
  • --blocked-domains <csv> (checked first).
  • Use a dedicated ephemeral --profile-dir, not your real browser profile.
  • --max-pages <n> caps tab explosion.

3. Arbitrary JS execution

  • browser_evaluate — runs JS in the page sandbox. Cannot read your local filesystem. Always available.
  • browser_run_code_unsafe — runs JS in this Node.js server process. Can do anything Node can. Double-opt-in: needs --caps config AND --enable-unsafe-eval.

Mitigation: never combine --enable-unsafe-eval with a machine that has prod credentials in env vars.

4. File system reach

browser_file_upload and browser_drop can attach any file you have read access to. Use --upload-allow-dir <path> to restrict.

Write-side: browser_take_screenshot --saveAs, browser_pdf_save, browser_storage_state, browser_start_tracing write files at agent-chosen paths. If you don't want this, omit --caps pdf / storage / devtools.

5. Persistent profile leakage

A --profile-dir accumulates cookies/localStorage/IndexedDB. If synced to cloud storage, every site you've signed into via the agent becomes accessible to anyone with that sync token. Default path ~/.cloak-browser-mcp/profiles/<name> lives outside common cloud-sync roots.

6. Prompt-injection-driven exfil

A malicious page can prompt-inject the agent into navigating elsewhere with stolen state, or POST DOM secrets out. This is an LLM problem, not an MCP problem.

  • Use a separate session per task — browser_close between unrelated jobs.
  • Prefer ephemeral over persistent profiles for sensitive flows.
  • Review agent tool calls when the task touches anything authenticated.

7. Network egress

| Call | Destination | When | |---|---|---| | CloakBrowser binary download | cloakbrowser.dev (override via CLOAKBROWSER_DOWNLOAD_URL) | First use after install | | Browser traffic | Whatever the agent navigates to | Always | | cloak_set_geolocation --fromProxyIp | ipapi.co/json/ | Only when explicitly invoked |

The wrapper does not phone home and does not collect telemetry.

Recommended deployment profiles

"Tight" (sensitive machine — has prod credentials):

--caps network,storage,pdf
--profile-dir /Users/me/.cloak-browser-mcp/profiles/scoped
--allowed-domains *.target.com
--upload-allow-dir /tmp/cloak-uploads
--max-pages 5

No --enable-unsafe-eval. No vision cap (xy clicks bypass allow-listing).

"Open" (research / personal browsing):

--caps all
--humanize
--max-pages 20

"Untrusted" (you don't fully trust the upstream binary yet) — run inside a Docker container or a fresh macOS user account with no Keychain access and no .env files mounted.

Reporting vulnerabilities

If you find a security issue in cloak-browser-mcp (not in the upstream cloakbrowser package or its binary): open a private security advisory at https://github.com/devinwang/cloak-browser-mcp/security/advisories/new.

For issues in upstream CloakBrowser: https://github.com/CloakHQ/CloakBrowser/security/advisories/new.


Changelog

[0.1.1] - 2026-05-24

  • BREAKING (UX): default is now headed (visible browser) instead of headless. An interactive MCP server should let the user watch the agent work. Pass --headless explicitly for batch/CI usage. Smithery default flipped to match.

[0.1.0] - 2026-05-24

  • Initial release. ~62 MCP tools backed by CloakHQ/CloakBrowser, covering full Playwright-MCP parity plus a Cloak-exclusive stealth/profile/audit/binary-management layer.
  • CLI: --caps, --profile-dir, --headless/--headed, --proxy, --timezone, --locale, --user-agent, --viewport, --geoip, --humanize, --fingerprint-seed, --allowed-domains, --blocked-domains, --enable-unsafe-eval, --upload-allow-dir, --download-dir, --max-pages, --self-test.
  • Smithery YAML for one-click integration.
  • MIT-licensed wrapper; upstream CloakBrowser Chromium binary remains proprietary-free-redistribute-prohibited.

License

  • Wrapper code: MIT (this package).
  • CloakBrowser Chromium binary: proprietary, free to use, no redistribution. See https://github.com/CloakHQ/CloakBrowser/blob/main/BINARY-LICENSE.md.

Acknowledgments