Zendriver MCP
Provides a real, headed Google Chrome browser controlled over the Chrome DevTools Protocol, with tools for navigation, element interaction, forms, tabs, cookies and storage, network and console inspection, emulation, screenshots, tracing, and browser automation.
Enables running Lighthouse audits against pages through the browser, exposing a tool for page audit tasks.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Zendriver MCP
A Model Context Protocol server that gives an AI agent a real, headed Chrome, driven over the Chrome DevTools Protocol through zendriver, and built so the page it is looking at cannot tell an agent is there.
98 browser tools behind a small fixed tool list: navigation, elements, forms, tabs, cookies and storage, network logs and mocking, emulation, accessibility, tracing, Lighthouse, screencasts and more.
Hard to detect by design. Helper scripts and element ids live in an isolated JavaScript world, nothing is written into the DOM, and clicks and keys are trusted input events.
Built for the current MCP spec. It serves 2026-07-28 and the 2025 handshake versions from one server. Every tool returns structured results, carries annotations, and fails with an error code and a recovery hint.
Contents
Related MCP server: puppeteer-real-browser-mcp-server
Quick start
Requirements: Python 3.10+, Google Chrome or Chromium, and a display. On a headless Linux
host, run Xvfb (Xvfb :99 & and DISPLAY=:99). The server never runs Chrome headless; see
why.
Claude Code
claude mcp add browser -- uvx --from git+https://github.com/coffeegrind123/zendriver-mcp-next zendriver-mcpAny MCP client (stdio):
{
"mcpServers": {
"browser": {
"command": "uvx",
"args": ["--from", "git+https://github.com/coffeegrind123/zendriver-mcp-next", "zendriver-mcp"],
"env": { "DISPLAY": ":99" }
}
}
}From a checkout
git clone https://github.com/coffeegrind123/zendriver-mcp-next
cd zendriver-mcp-next
uv sync
uv run zendriver-mcp # stdio
uv run zendriver-mcp --help # transports, tokens, optionsHow an agent uses it
The server sends the model short instructions when it connects. The core loop is:
start_browser → navigate(url) → get_interaction_tree → click / type_text / press_key
→ get_text_content or screenshot → stop_browsernavigatewaits for the page to settle. It waits fordocument.readyStateto reach complete, then for the network to go idle, and reports which of the two happened.Elements are addressed by CSS selector, or by the numeric id that
get_interaction_treeassigns. Ids stay valid while the element exists. A stale id fails with codestale_idinstead of hitting the wrong element.Tabs. Every page tool takes an optional
tab="tab_2", which acts on that tab for one call without switching to it. Tabs the page opens itself (popups,target=_blank) are picked up automatically.Everything else is one search away.
search_tools("block requests")finds the tool, andcall_toolruns it.batchruns a known sequence in one call. A later step can read an earlier result as"$N.field", or as"${N.field}"inside a longer string.jobsruns a slow tool in the background (Lighthouse, heap snapshots, video export) and records its progress.
Every result has structured content plus a text summary. Every failure is an isError result
shaped like this:
{ "error": "Something covers #buy at (640, 412): <div#cookie-banner>.",
"code": "element_obscured",
"hint": "Close the overlay on top (a cookie banner, a modal) or scroll so the element is unobstructed. force=true clicks at that point anyway." }Tools
The default tools/list has 19 entries: the core loop below, plus search_tools,
describe_tool, call_tool, batch and jobs. The core tools are tagged
anthropic/alwaysLoad so that Claude Code's tool search never defers them. Set
ZENDRIVER_MCP_SURFACE=full to list all 103 directly.
Core (always listed) | Reached through |
| tabs and history · element queries · shadow DOM · forms · human-like mouse and typing · per-page and whole-browser cookies · local storage · network and console logs · request blocking, extra headers, mocking and failure injection · proxy · user agent, locale, timezone, geolocation · device, CPU and network emulation · permissions · accessibility tree · tracing and heap snapshots · Lighthouse · screencast to MP4 · Cloudflare challenge handling · security audit |
The full list, with each tool's effect, parameters and summary, is in docs/tools.md. That file is generated from the code.
Resources. Files that tools write are served back as resources, so a remote client can fetch them:
browser://artifacts/{name}: screenshots, traces, heap snapshots, videos, cookie exports;browser://tabs;browser://tabs/{tab}/info,/consoleand/network.
{tab} and {name} support completion. On 2026-07-28 clients, opening or closing a tab
publishes resources/list_changed to subscriptions/listen streams.
Prompts. read_page, fill_form_task and audit_page.
What a page can and cannot see
Pages detect automation by looking for side effects. Each row below is a side effect that
other CDP tools leave behind and this server avoids. Each claim is checked by the live test
in tests/test_live.py, which records events from a listener inside the page itself.
Signal a page can check | Common CDP tooling | This server |
|
|
|
Marker attributes in the DOM ( | Written onto every element | None; ids live in an isolated world |
Helper code in the page's JS world (wrapped | Runs in the main world | Runs in an isolated world the page cannot reach |
Injected highlight elements and CSS rules | zendriver's | Never called |
| Common | Refused: every launch is headed |
| Historically observable | Measured not observable on Chrome 157 with the classic stack-getter probe |
The remaining exposure is documented, not hidden:
execute_jsruns in the page's own world by design. Prefer the dedicated tools.select_optionsets a native<select>by script, so itschangeevent is untrusted. For a trusted change, focus the select and usepress_key.start_browser(low_memory=true)adds container-friendly flags such as--disable-gpu, which produce detectable software WebGL. Use it only where Chrome cannot start without it.
Configuration
All settings are optional environment variables.
Variable | Default | Effect |
|
|
|
| – | Restricts which tools exist: |
| – | Comma-separated tool groups to keep (the group names are in docs/tools.md). |
| – | Exact tool names to keep or remove. |
| off | Starts Chrome on the first call that needs it, and replaces a browser that died. |
|
| Per-call time budget, in seconds. A hung CDP call returns an error rather than hanging the session. |
| budget − reserve | Time allowed for Chrome to start. |
| – | Extra directories, besides |
| off | Skips the X display pre-flight check before launching. |
|
| Where HTTP tokens are stored. |
|
| Where the bundled extensions are kept (uBlock Origin Lite and I Still Don't Care About Cookies, downloaded on first launch). Falls back to the temp dir when the cache cannot be written; a launch never fails over an extension. |
ZENDRIVER_MCP_GATEWAY=1 and ZENDRIVER_MCP_PROFILE=gateway are still accepted, and mean
SURFACE=catalog.
Running over HTTP
stdio gives each client its own browser. To let several clients share one long-lived browser, use Streamable HTTP:
zendriver-mcp --create-token laptop # prints the token once; only its hash is stored
zendriver-mcp --transport streamable-http --host 127.0.0.1 --port 8931
claude mcp add --transport http browser http://127.0.0.1:8931/mcp \
--header "Authorization: Bearer zmcp_..."Tokens. Bearer tokens are compared in constant time and stored as SHA-256 hashes with mode 0600. Each token's name becomes the caller identity, so one client cannot see or drive another client's tabs.
Without tokens. The server runs unauthenticated on loopback only. It refuses to bind any other address.
Host and Origin checks protect against DNS rebinding. Add LAN names with
--allowed-host.Rate limit. 600 requests per minute per token by default (
--rate-limit), answered with429andRetry-After.
Protocol support
Spec revision | Supported | Notes |
2026-07-28 | yes | Stateless, |
2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05 | yes | Initialize handshake; |
Features used:
tool annotations and titles;
outputSchemawithstructuredContent;isErrorresults with codes;resources, resource templates and completions;
prompts;
progress notifications, and cancellation that stops child processes;
resources/list_changed;server instructions, kept under Claude Code's 4,096-character limit.
The jobs tool gives every client, whatever it supports, a way to poll long-running work.
Architecture
MCP client ──stdio / Streamable HTTP──► MCPServer (SDK 2.3)
│ auth middleware: token → caller (HTTP only)
▼
┌──────────── catalog.py ────────────┐
│ core tools · search · call · batch │
│ jobs · resources · prompts │
└──────────────┬─────────────────────┘
▼
tools/*.py ── ToolBase._register: annotations, budget,
tab handle, Result → structured + text,
exception → {error, code, hint}
▼
dom.py: isolated world, element ids, trusted input, CDP geometry
session.py: browser, tabs and owners, logs, Fetch (proxy auth + interception)
▼
zendriver ──CDP──► headed ChromeDevelopment
uv sync --dev
uv run ruff check . && uv run ruff format --check .
uv run mypy src
uv run pytest # unit, contract and protocol tests
DISPLAY=:99 ZENDRIVER_MCP_LIVE=1 uv run pytest tests/test_live.py # real Chrome
uv run python scripts/gen_tool_docs.py # regenerate docs/tools.mdThe test suite enforces the conventions every tool must follow:
every tool has a title, annotations, an output schema and described parameters;
no tool returns an error as a success string;
no selector is interpolated into page JavaScript;
the default surface stays under a size budget;
the instructions name only tools that exist and stay under the size limit.
CI runs all of this, plus the live test under Xvfb.
Acknowledgements
Built on zendriver and the MCP Python SDK. The tool set started from Zendriver-MCP by Shubham Choulkar; the MCP layer, element access, error model, HTTP security and test suite were rewritten for this project.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Give AI agents a real cloud Chrome: open sessions, navigate, read pages, click, type and screenshot.
Let your AI agent operate any website through a real, logged-in browser session.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI agents to directly control your real Chrome browser with full context including login sessions, cookies, and open tabs. It provides tools for page scanning, JavaScript execution, CDP control, screenshots, and physical mouse/keyboard input for authentic browser automation.20244MIT
- AlicenseNot gradedqualityDmaintenanceProvides AI assistants with powerful, detection-resistant browser automation capabilities, allowing them to control a real web browser to navigate, extract content, and perform tasks while avoiding bot detection.19 npmMIT
- AlicenseAqualityCmaintenanceEnables AI agents to fully control a browser for web automation, including navigation, clicking, typing, scrolling, screenshots, and DOM inspection, with session persistence and anti-bot bypass.4043 npmMIT
- AlicenseBqualityCmaintenanceEnables AI agents to perform low-latency web automation with a persistent headed Chrome/Chromium instance, including navigation, DOM interaction, content extraction, screenshots, tab management, and batch/code execution via 18 MCP tools.20MIT