内容
# 开源代码-webmcp
MCP 桥接器,连接 OpenCode 至 Chromium 的 WebMCP API。
将 Chromium 页面中注册的 WebMCP 工具暴露给任何 MCP 客户端(OpenCode、Claude Code 等)使用。
## 工作原理
```
OpenCode(MCP 客户端)
↕ MCP 标准输入输出协议
webmcp-bridge(MCP 服务器)
↕ Puppeteer + CDP
Chromium(启用 WebMCP)
↕ 注入脚本修改 document.modelContext
注册了 WebMCP 工具的网页
```
该桥接器启动 Chromium,并启用 `--enable-features=WebMCPTesting` 功能,导航到目标页面,通过 WebMCP API 发现工具,并使它们可被 MCP 客户端使用。
**注入脚本修改:** Chrome 150+ 版本存在一个 bug,`page.webmcp.invokeTool()` 返回 `{}` 而不是实际的工具结果。桥接器通过拦截 `registerTool` 来捕获 `execute` 函数,并替换 `executeTool` 以直接调用捕获的函数来解决这个问题。
## 前置条件
- Node.js 18+
- 支持 WebMCP 的 Chromium/Chrome(Chrome 150+)
- MCP 客户端(OpenCode、Claude Code 等)
## 安装
```bash
git clone <仓库地址> webmcp-bridge
cd webmcp-bridge
npm install
```
## 使用
### 独立使用
```bash
CHROME_PATH=/usr/bin/chromium \
WEBMCP_TARGET_URL="https://www.google.com" \
WEBMCP_HEADLESS=false \
node server.js
```
### OpenCode(opencode.json)
```json
{
"mcp": {
"webmcp-bridge": {
"command": ["node", "/path/to/webmcp-bridge/server.js"],
"enabled": true,
"type": "local",
"environment": {
"CHROME_PATH": "/usr/bin/chromium",
"WEBMCP_TARGET_URL": "about:blank",
"WEBMCP_HEADLESS": "false"
}
}
}
}
```
### 环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
| `CHROME_PATH` | `/usr/bin/chromium` | Chromium/Chrome 可执行文件路径 |
| `WEBMCP_TARGET_URL` | `https://www.google.com` | 初始导航页面 |
| `WEBMCP_HEADLESS` | `true` | 无头模式(`true`)或可见窗口(`false`) |
## 桥接器原生工具
这些工具始终可用,无论页面暴露哪些工具:
| 工具 | 描述 |
|---|---|
| `webmcp_navigate` | 导航 Chrome 到指定 URL 并刷新发现的 WebMCP 工具 |
| `webmcp_status` | 报告连接状态、当前 URL 和可用工具 |
| `webmcp_evaluate` | 在页面上下文中执行任意 JavaScript 代码 |
| `webmcp_invoke_tool` | 按名称调用任意 WebMCP 工具并传递参数 |
| `webmcp_register_test_tools` | 注册示例工具(`test_greet`、`test_calculator`、`test_fetch_title`)用于验证 |
## 架构
- **`server.js`** — 使用 `@modelcontextprotocol/sdk` 的单文件 MCP 服务器
- **Puppeteer** (`puppeteer-core`) — 通过 Chrome DevTools Protocol 驱动 Chromium
- **注入脚本修改** — `page.evaluateOnNewDocument` 注入脚本,拦截 `document.modelContext.registerTool` 和 `executeTool` 以捕获实际的 `execute` 函数
## 故障排除
- **"Failed to parse input arguments"** — 由 `document.modelContext.executeTool()` 在页面端失败引起。注入脚本修改通过直接调用捕获的执行器来解决这个问题。
- **"detached Frame"** — 页面已被导航离开或关闭。桥接器会自动通过创建新页面恢复。重新运行工具调用。
- **未发现工具** — 确保页面已调用 `document.modelContext.registerTool()` 注册工具定义。使用 `webmcp_evaluate` 手动调用 `document.modelContext.getTools()`。
- **测试工具中的 CORS 错误** — `test_fetch_title` 使用 `fetch()`,可能受到页面 CSP 的限制。在宽松的源地址上测试。
## 许可证
MIT