web-bridge

web-bridge

MCP server that lets AI editors execute JavaScript, read console output, and simulate clicks/input on static web pages. Supports multiple browser pages and can be deployed remotely via HTTP transport.

Category
访问服务器

README

web-bridge-mcp — Let AI editors operate any static web page

web-bridge-mcp is an MCP Server (single Node process, dual interfaces) that lets AI editors execute JavaScript, read the console, and simulate clicks / typing on any static web page that includes client.js. Great for cross-browser, multi-tab local debugging — and it can also be deployed to a public server.

   AI Editor             ┌───────────────────┐            Browser page
┌──────────────┐         │    MCP Server     │         ┌──────────────────┐
│  MCP Client  │         │  (Node, 1 process) │         │ <script src=     │
│              │ stdio or │ · Iface B: MCP    │WebSocket │  :3210/client.js">│
│  AI stops    │◄───────►│   (stdio / http)  │◄────────►│  client.js       │
│    here      │ Streamable│ · Iface A: WS    │ Iface A │  (eval execution/│
└──────────────┘ HTTP(remote)│ · HTTP /client.js│        │   console capture)│
                           └───────────────────┘        └──────────────────┘

The AI editor and the browser never talk directly: both connections terminate at the MCP Server (server.js, the relay). The AI manipulates pages indirectly through tool calls.

中文文档 (Chinese)

Quick Start (3 steps)

Whether local or on a public server, the flow is the same: ① start the relay server with node → ② configure its http/https URL in your editor → ③ embed the <script> tag into your static page.

Step 1: Start the MCP relay server

# npm package: web-bridge-mcp — runs directly via npx; if you cloned this repo, run npm install first

# Local use (listens on 127.0.0.1 only by default)
npx web-bridge-mcp --transport http        # in this repo: npm run serve

# Deploy to a public server (token is mandatory on the public internet;
# keep it running with systemd / pm2)
npx web-bridge-mcp --transport http --host 0.0.0.0 --port 3210 --token <secret>

Once started there are three endpoints (localhost:3210 for example):

Endpoint URL For
MCP endpoint http://127.0.0.1:3210/mcp Paste into your editor (step 2)
Page script http://127.0.0.1:3210/client.js Embed into your page (step 3)
Status page http://127.0.0.1:3210/ Open in a browser to see connected pages

CLI flags can also be set via environment variables PORT / HOST / TOKEN / TRANSPORT.

Step 2: Configure the relay server URL in your editor

ZCode / Claude Code (project .mcp.json, or claude mcp add), Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "web-bridge-mcp": {
      "type": "http",
      "url": "http://127.0.0.1:3210/mcp"
    }
  }
}

When deployed on a server (with token), replace the URL with the public one and add the auth header:

{
  "mcpServers": {
    "web-bridge-mcp": {
      "type": "http",
      "url": "https://your-domain.com/mcp",
      "headers": { "Authorization": "Bearer <secret>" }
    }
  }
}

Note 1: type refers to the MCP transport protocol (http = Streamable HTTP transport; stdio = process pipe, see below) — it is independent of the URL's own protocol. So even if the url is https://, type stays http: https is simply http over TLS, and there is no separate "https" transport type.

Note 2: Claude Desktop only supports the local stdio mode below.

Step 3: Embed the script into your static page

Any page, any port works (CORS is open):

<script src="http://127.0.0.1:3210/client.js"></script>

When deployed on a server, point the script at it (with token if enabled):

<script src="https://your-domain.com/client.js?token=<secret>"></script>

Verify

Tell the AI: "Use web-bridge-mcp's list_pages to see which pages are connected, then eval_js to click #btn and read the console". If it lists your page, all three steps are wired up.

Order doesn't matter: the page can be opened before the server — client.js auto-reconnects (1s→2s→5s→10s backoff) and attaches as soon as the server is up. Hub status page: http://127.0.0.1:3210/

Once embedded, the page shows a small draggable status bubble in the top-right corner (green = connected, yellow = connecting, red = disconnected), so you can always tell the page is bridged to the MCP server and whether the link is alive. Double-click the bubble to see exactly what the MCP server has done to the page — every operation with its natural-language note, success/failure and duration, grouped per page load.

Alternative: local stdio mode (the editor starts the server)

If you only use it locally and don't want to run step 1 manually, put the server path directly in your editor config: the editor spawns it as a child process, MCP runs over the process's stdin/stdout pipe (no URL needed), and the relay is up automatically; the process exits with the editor.

{
  "mcpServers": {
    "web-bridge-mcp": {
      "command": "npx",
      "args": ["-y", "web-bridge-mcp"],
      "env": { "PORT": "3210" }
    }
  }
}

(Same format for Cursor / Claude Desktop; if you cloned this repo, use "command": "node", "args": ["/path/to/web-bridge-mcp/server.js"] — see the template mcp.json.)

How to choose:

HTTP mode (3-step guide above) stdio mode
Who starts server.js You, manually; can live on a server The editor, on demand
Editor config Just a URL command + args
Best for Server deployment, multi-device / shared, remote access Local instant use; the only option for Claude Desktop

In both modes the browser side is identical (the <script> from step 3).

Admin Console & Groups (multi-project / shared)

To serve multiple projects at once, or hand each person/editor its own isolated entry point, start in group mode:

npx web-bridge-mcp --transport http --port 3210 --admin <admin-password>

# In this repo: npm run serve:groups (password defaults to 123456; override with the ADMIN_PASSWORD env var)

Open http://127.0.0.1:3210/admin, log in with the admin password, and you can:

  • Create groups: each group gets its own secret token plus two ready-to-copy snippets —
    • The editor-side MCP JSON (URL points to the group's own /g/<token>/mcp)
    • The page-side relay <script> tag (the group's own /g/<token>/client.js)
  • Human observation window (auto-refresh every 1.5s — the human and the AI see the same live view):
    • Connected pages (title / pageId / URL / connected-at)
    • Console stream of any page
    • AI call log — every action the AI performed via MCP in this group's pages (tool, code, duration, result), so you can audit exactly what the AI did

Groups are fully isolated: an editor connected to group A cannot see or touch group B's pages. Group data persists in data/groups.json (customize with --data <path>; the file contains tokens — never commit it; data/ is already gitignored).

Security & limits: a group token equals full control of that group (arbitrary JS in its pages) — treat it like a password. Generate the admin password with openssl rand -hex 32; always use TLS on the public internet; in group mode editors can only connect via HTTP URL (stdio unavailable).

MCP Tools

Tool Params Description
list_pages List connected pages (pageId, title, URL, connected-at)
eval_js code, optional pageId / timeoutMs / note Execute arbitrary JS in the page and return the serialized result; await supported; last expression is returned automatically, or use return in a statement block; $ / $$ (querySelector / querySelectorAll) provided
get_console optional pageId / limit Read the page's recent console output and uncaught errors
click selector, optional pageId / note Find element by CSS selector and click() (scrolls into view first)
type selector / text, optional pageId / note Focus, write text, dispatch input / change events (contenteditable compatible)
get_text optional selector (default body), pageId / note Read element innerText

pageId rule: it can be omitted when exactly one page is connected; with multiple pages and no pageId the tool returns an error plus the page list, and the AI retries with the right pageId.

note: a natural-language description of the operation, shown to the human on the page side (in the status-bubble operation log, above the executed code). The AI is instructed to always provide it; click/type/get_text fall back to a short label like click #btn when omitted.

Public Deployment Notes

  • HTTPS pages can only reach https/wss (mixed-content restriction). Use nginx / caddy as a reverse proxy for TLS termination; client.js auto-detects X-Forwarded-Proto / X-Forwarded-Host and generates the correct wss:// URL — no extra config needed. caddy example (auto certs):

    your-domain.com {
      reverse_proxy 127.0.0.1:3210
    }
    
  • With a token enabled, /mcp accepts three auth styles: Authorization: Bearer <secret> (recommended; put it in editor headers config), X-Web-Bridge-MCP-Token: <secret>, or the ?token= query parameter.

  • HTTP transport implements the official Streamable HTTP protocol (stateless): every request is handled independently while sharing the same hub, so multiple editors can connect at once.

  • For public deployments always: set --token, use TLS, and only open the ports you need in the firewall.

Security Notes

  • By default the server listens on 127.0.0.1 only. Any web page open on this machine (including third-party sites you browse) can try to connect to the local port — in default no-token mode they could receive AI-sent code and forge results.
  • On untrusted networks, or when exposing to LAN devices (--host 0.0.0.0), always enable --token: fetching client.js then requires ?token=<secret>, and the first WebSocket packet is verified too.

WebSocket Message Protocol (internal reference)

WS messages between the browser and the MCP Server are JSON text frames; refer to this when working on lib/hub.mjs / client.js:

Direction Message Fields Notes
page → server hello role:"page", pageId, url, title, ua, token? First packet after connect; disconnected if not received within 5s; duplicate pageId (duplicated tab) → new connection replaces the old
page → server page-info url, title Sent on connect, DOMContentLoaded/load/popstate/hashchange, and every 5s as a poll fallback (SPAs)
page → server console level, text, ts Wrapped console methods & uncaught errors, batched with 500ms throttle; server keeps a 500-entry ring buffer per page (kept after disconnect)
page → server eval-result reqId, ok, value?, error?, durationMs Late responses (already timed out) are ignored
server → page welcome pageId hello accepted
server → page eval reqId, code, timeoutMs Code to execute
server → page error error e.g. invalid token

eval conventions (client.js): code is first wrapped as an expression async () => ( code ), falling back to a statement block (with return) on SyntaxError; $ / $$ are predefined; timeouts are enforced server-side (default 30s, max 120s); results are safely serialized as string previews (Error→stack, DOM→outerHTML excerpt, circular refs marked, depth ≤ 6, ≤ 50k chars).

Development

  • Tests: npm test (Node e2e: spawns the server + fake pages + tool calls over both stdio and HTTP transports); npm run test:browser (Playwright real-browser e2e: Chromium loads test/test-page.html, verifies all 6 tools over a real WebSocket; run npx playwright install chromium first). The real-browser flow can also be verified manually with the test page.
  • Dependencies: ws (WebSocket), @modelcontextprotocol/sdk (MCP), zod (validation); dev dependency @playwright/test. Node ≥ 18.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选
mcp-server-qdrant

mcp-server-qdrant

这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。

官方
精选
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选