Zen
БесплатноНе проверенLets MCP clients control a live Zen/Firefox browser to navigate, click, fill forms, screenshot, and execute JavaScript through a persistent server and browser e
Описание
Lets MCP clients control a live Zen/Firefox browser to navigate, click, fill forms, screenshot, and execute JavaScript through a persistent server and browser extension.
README
A persistent MCP HTTP server paired with a Zen/Firefox browser extension that
lets any MCP client (Claude Code, Claude Desktop, ada-back, or anything else
that speaks MCP) remote-control your actual, already-running browser:
navigate, read, click, fill forms, screenshot, run JS.
The server runs as one long-lived process (mcp-zen, installed on $PATH)
rather than being spawned per-client. This matters because the browser
extension's WebSocket connection to it is completely decoupled from any
individual MCP client's session lifecycle — the extension connects once and
stays connected for as long as the server runs, regardless of how many
short-lived MCP sessions come and go on top of it (each mcpcall.mjs
invocation, each ada-back restart, etc.).
It combines two ideas from other projects:
- The tool surface of zen-mcp, which
talks to Zen over WebDriver BiDi. BiDi requires launching a dedicated
browser instance with
--remote-debugging-port, which doesn't work for a browser you're already using day-to-day. - The architecture of browser-control-mcp: MCP server ↔ localhost WebSocket (HMAC-signed) ↔ a WebExtension background script that performs the actions. This is what lets it attach to your main browser window instead of a separate automation-only instance.
Setup
1. Load the extension in Zen
- Build it:
npm install && npm run build(from this directory). - In Zen, open
about:debugging→ "This Firefox" → "Load Temporary Add-on..." → selectfirefox-extension/manifest.json. - The options page opens automatically. Copy the generated secret.
- Click Enable browser automation on the options page. This grants the
extension access to all sites (
<all_urls>), which every page-interaction tool (zen_click,zen_fill,zen_snapshot,zen_evaluate,zen_screenshot, ...) needs. It's a one-time grant, revocable any time fromabout:addons.
"Temporary" add-ons are unloaded when Zen restarts — you'll need to re-load
manifest.json(and re-copy the secret only if you regenerate it) each time, unless you package and install it permanently.
2. Configure the secret
cd mcp-server
cp .env.example .env
# edit .env, paste the secret from the options page as EXTENSION_SECRET
.env is gitignored — the secret never gets committed. server.ts loads it
at startup (mcp-server/.env, sibling of dist/); explicit env vars set by
whatever launches the process still take priority over the file. .env also
sets MCP_HTTP_PORT (default 8791) alongside EXTENSION_PORT (default
8765, the WebSocket port the extension connects to — a different port from
the one MCP clients talk to).
3. Install and run
bin/ is gitignored (it's a local PATH-install wrapper, not project source),
so create it once per checkout:
mkdir -p bin
cat > bin/mcp-zen <<'EOF'
#!/usr/bin/env bash
# Thin wrapper so `mcp-zen` can be installed on $PATH (e.g. symlinked into
# ~/.local/bin) while the actual project stays put wherever it's checked out.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
exec node "$SCRIPT_DIR/../mcp-server/dist/server.js" "$@"
EOF
chmod +x bin/mcp-zen
ln -sf "$(pwd)/bin/mcp-zen" ~/.local/bin/mcp-zen # once, so it's on $PATH
mcp-zen # runs in the foreground
It prints both listening addresses on startup and then blocks — run it under
your process supervisor of choice (systemd user service, nohup ... &,
whatever fits) for a real persistent deployment.
Point any MCP client at http://localhost:8791/mcp (Streamable HTTP), e.g.
Claude Desktop:
{
"mcpServers": {
"zen": { "url": "http://localhost:8791/mcp" }
}
}
For quick ad hoc testing without a full MCP client, use mcpcall.mjs:
node mcpcall.mjs zen_list_tabs '{}'
node mcpcall.mjs zen_navigate '{"tabId":12,"url":"https://example.com"}'
Each invocation opens its own short-lived MCP session — cheap, since it's independent of the extension's WebSocket connection.
Tools
| Tool | Notes |
|---|---|
zen_list_tabs |
|
zen_navigate |
|
zen_new_tab |
|
zen_close_tab |
|
zen_activate_tab |
Bring a tab to the foreground |
zen_snapshot |
Structured elements + selectors (filter: all/interactive/form) |
zen_screenshot |
Activates the tab first — see limitation below |
zen_get_page_text |
|
zen_get_form_fields |
|
zen_click |
Real CSS selector only -- see limitation below |
zen_click_text |
Click by visible text/aria-label instead of a selector |
zen_fill |
Native setter + input/change events, works with React/Vue/Angular |
zen_select_option |
|
zen_check |
|
zen_fill_form |
Batch of {selector, value, action} |
zen_scroll |
|
zen_press_key |
Synthetic keydown/keyup — see limitation below |
zen_evaluate |
Arbitrary JS in the page |
zen_wait |
No browser round trip |
zen_wait_for |
Polls in-page for text or a selector |
Every tab-scoped tool takes an optional tabId; omit it to target the
active tab of the current window.
Known limitations (vs. zen-mcp's BiDi approach)
- Screenshots only work on the visible/focused tab
(
captureVisibleTab), sozen_screenshotactivates the target tab first. BiDi can capture background tabs; a WebExtension can't. zen_press_keydispatches syntheticKeyboardEvents, not real OS-level key injection. Most JS listeners (keydownhandlers, framework key bindings) work fine; native browser behaviors triggered by a real keypress (e.g. Enter submitting a form via the browser's built-in behavior) may not fire — usezen_clickon the submit button instead when that matters.zen_click's selector goes straight to the page's owndocument.querySelector-- there's no jQuery/Playwright/BeautifulSoup selector engine underneath it, so:contains(),:has-text(),:-soup-contains()etc. all fail with "not a valid selector". Models reliably hallucinate these from training data on other automation tools;zen_snapshotalso falls back to a bare tag name (e.g."a") for elements with no id/name/aria-label, which is technically valid CSS but matches every such element on the page.zen_click_text(click by visible text/aria-label, no selector needed) exists specifically to route around both problems for the common "click the thing that says X" case.- The extension only allows commands listed in
firefox-extension/allowed-tools.yaml. There's no dynamic per-tool toggle UI or per-domain consent flow (deliberately, for simplicity) — edit that file and rebuild to change what's enabled.
Notes
typescriptis pinned to~5.7.3in everypackage.json. TypeScript 5.8+ has a regression (excessive/infinite type instantiation,TS2589, or an outright OOM crash ontsc) when compiling many chainedmcpServer.tool(...)calls against zod schemas with the currently published@modelcontextprotocol/sdk. Confirmed by bisecting: 5.7.3 and earlier compile clean, 5.8.3+ fails. Worth re-checking whether upstream fixes this before bumping.
Project layout
common/ shared TS message types (server <-> extension)
mcp-server/ persistent MCP HTTP server; hosts the WebSocket server the extension connects to
firefox-extension/ background script (WebSocket client) + options page
bin/mcp-zen PATH-installable entry point (symlink ~/.local/bin/mcp-zen -> this)
mcpcall.mjs one-off MCP tool call over HTTP, for ad hoc testing
License
MIT — see LICENSE.
Установка Zen
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/mikesmullin/mcp-zenFAQ
Zen MCP бесплатный?
Да, Zen MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Zen?
Нет, Zen работает без API-ключей и переменных окружения.
Zen — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Zen в Claude Desktop, Claude Code или Cursor?
Открой Zen на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Playwright
Browser automation, scraping, screenshots
автор: MicrosoftPuppeteer
Browser automation and web scraping.
автор: modelcontextprotocolopentabs-dev/opentabs
Plugin-based MCP server + Chrome extension that gives AI agents access to web applications through the user's authenticated browser session. 100+ plugins with a
автор: opentabs-devrobhunter/agentdeals
1,500+ developer infrastructure deals, free tiers, and startup programs across 54 categories. Search deals, compare vendors, plan stacks, and track pricing chan
автор: robhunterCompare Zen with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории browse
