Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MCP server (zendriver-mcp)

zendriver-mcp is a Model Context Protocol server that exposes zendriver-rs through 70 MCP tools (71 with the optional fingerprints feature), so any MCP-compatible client (Claude Desktop, Claude Code, custom agents) can drive a real, stealth-by-default Chrome browser.

Using Claude Code? The zendriver plugin installs this server plus scraping skills, commands, and a subagent in two commands — see the plugin chapter.

Install

cargo install zendriver-mcp

The default build enables interception, expect, cloudflare, imperva, datadome, monitor, fetcher, and tracker-blocking. The fingerprints and geo features are opt-in (add --features fingerprints,geo). For a lean build:

cargo install zendriver-mcp --no-default-features

Claude Desktop

{
  "mcpServers": {
    "zendriver": {
      "command": "zendriver-mcp"
    }
  }
}

HTTP mode

zendriver-mcp --http 127.0.0.1:8765

Bind localhost-only by default. It is the operator's responsibility to expose the endpoint via a reverse proxy + mTLS / network policy for remote access.

CLI flags

zendriver-mcp [OPTIONS]

OPTIONS:
    --http <ADDR>                  Run streamable HTTP transport on ADDR
                                   (e.g. 127.0.0.1:8765). Default: stdio.
    --stealth-profile <KIND>       Default stealth profile.
                                   [auto|native|spoof_macos|spoof_linux|spoof_windows]
                                   Default: auto
    --log <FILTER>                 Tracing log filter (EnvFilter syntax).
                                   Default: info
    -h, --help
    -V, --version

Tool surface

70 tools across these categories (71 with the optional fingerprints feature):

CategoryToolsCount
Lifecyclebrowser_open / _close / _status3
Navigationbrowser_goto / _back / _forward / _reload / _wait_for_idle / _wait_for_load / _bypass_insecure_warning7
Scroll / Windowbrowser_scroll / _get_window / _set_window3
Tabsbrowser_tab_list / _new / _switch / _close / _activate5
Findbrowser_find / _find_all2
Actionsbrowser_click / _hover / _type / _press / _key_sequence / _mouse / _set_value / _clear / _focus / _scroll_into_view / _upload11
Readsbrowser_element_state / _get_links / _search_resources3
Snapshots / Exportbrowser_html / _screenshot / _pdf / _save_mhtml4
Evalbrowser_evaluate / _evaluate_main2
Networkbrowser_request1
Cookiesbrowser_cookies_get / _set / _delete / _clear / _persist5
Storagebrowser_storage_get / _set / _delete / _clear4
Downloadsbrowser_download / _set_download_path2
Framesbrowser_frame_list / _frame_goto2
Stealthbrowser_set_stealth_profile / _set_user_agent2
Interception (gated)browser_intercept_add_rule / _remove_rule / _list_rules / _clear_rules4
Expect (gated)browser_expect_register / _await / _cancel3
Cloudflare (gated)browser_solve_turnstile1
Imperva (gated)browser_solve_imperva1
DataDome (gated)browser_solve_datadome1
Fetcher (gated)browser_install_chrome1
Monitor (gated)browser_monitor_start / _read / _stop3
Fingerprint (gated)browser_fingerprint_generate1

All find / action tools share a Selector arg — one-of css | xpath | text | text_exact | text_regex | role, with modifiers nth / visible_only / timeout_ms / frame_id. State-changing tools accept return_snapshot: bool for one-call action + observe. browser_pdf / _save_mhtml / _download return a binary-output shape ({ byte_len, saved_path? , base64? }): bytes go to save_path on the MCP host when given, else base64-inline (capped at 5 MiB). The default build enables interception / expect / cloudflare / imperva / datadome / monitor / fetcher / tracker-blocking; fingerprints and geo are opt-in.

Full JSON Schema for every tool's input + output is captured in crates/zendriver-mcp/tests/snapshots/ and changes there require an explicit cargo insta accept — the wire shape is reviewed.

browser_open options

browser_open accepts opt-in third-party tracker / fingerprinter blocking:

  • block_trackers: bool — enable blocking with the curated bundled list.
  • tracker_blocklist — one of { "url": "..." }, { "path": "..." }, or { "domains": ["..."] } to add custom hosts (implicitly enables blocking). Requires the default tracker-blocking feature.

The stealth-profile override accepts geo_country (ISO 3166-1 alpha-2, e.g. "DE") to derive a coherent locale + Accept-Language. The field is always present in the schema but only takes effect when the geo feature is enabled.

Stealth

Stealth is on by default (matching the zendriver library). Configure the default fingerprint via --stealth-profile at server start; switch live via browser_set_stealth_profile (takes effect on the next browser_open).

Troubleshooting

  • Logs go to stderr in stdio mode — stdout is reserved for MCP JSON-RPC. Use --log debug for verbose CDP-call logging.
  • Errors include _meta.suggested_next hints when applicable (e.g. ElementNotFound suggests reconnaissance via browser_html or a fresh browser_find_all snapshot).
  • HTTP smoke test binds 127.0.0.1:18765 by convention — if your environment has that port taken, set a different port via --http.
  • Real-Chrome integration tests are gated behind cargo feature integration-tests and #[ignore] markers: run via cargo test -p zendriver-mcp --features integration-tests -- --ignored.