WebMCP 桥接器:让 agent 通过内置无头 Chromium,发现并调用网站按 W3C WebMCP 协议暴露的站点工具。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:T-Markus-Liang/dsh-webmcp
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
English | 中文
dsh-webmcp
dsh-webmcp 是 DeepSeek Harness 插件,让 agent 借助内置的无头 Chromium,发现并调用网站依照 W3C WebMCP 协议对外暴露的站点工具。
WebMCP 是 W3C Web Agents 社区组的标准化提案(github.com/webmachinelearning/webmcp)。2026-08,OpenAI 让 ChatGPT 桌面版内置浏览器支持站点工具并发起挑战赛,Google Chrome Labs 也开源了 webmcp-tools。本插件无需外部浏览器、也不用手工维护选择器,即可把这项能力带给 DeepSeek Harness 的 agent。
为什么:WebMCP 与传统自动化
| 方面 | 传统自动化 | WebMCP 站点工具 |
|---|---|---|
| 站点如何暴露动作 | 靠你维护的硬编码选择器与脚本 | 协议声明的工具面(navigator.modelContext、window.webmcp、form[data-webmcp-tool]) |
| 发现 | 逆向分析页面 | webmcp_discover 直接返回归一化工具清单 |
| 调用 | 重放点击与键盘输入 | webmcp_invoke 在页面内执行站点自身的真实工具函数 |
| 同意 | 站点对调用毫无话语权 | 协议要求站点侧确认 |
| 漂移 | 页面一改就崩 | 跟随站点自己声明的契约 |
安装
dsh plugin --profile web add github:T-Markus-Liang/dsh-webmcp
MCP 网关(stdio)
插件同时提供 bin/dsh-webmcp-serve.mjs,这是一个 stdio MCP 网关,把某网站对外暴露的 WebMCP 工具桥接给任意 MCP 客户端(Claude Code/Desktop、Codex 等)。指向一个 URL,站点工具即变成任何 MCP 客户端都能原生消费的本地 MCP server。
dsh-webmcp-serve <url> [--allow-private-hosts] [--manifest-ttl-ms N] [--no-cache]
客户端配置示例:
{ "mcpServers": { "my-site": { "command": "node", "args": ["/path/to/dsh-webmcp/bin/dsh-webmcp-serve.mjs", "https://example.com/app"] } } }
协议:换行分隔 JSON-RPC 2.0(MCP stdio),实现 initialize / ping / tools/list / tools/call。tools/list 来自页面 discover(双挂载 / Map / Promise / executeToolByName 全兼容);tools/call 复用同一 BrowserSession 管线。Manifest 磁盘缓存于 ~/.dsh-webmcp/manifests/(默认 TTL 300s;--no-cache 关闭)。诊断只走 stderr——stdout 是纯 MCP 通道。私网目标默认拒绝(与插件一致)。
网关还提供 HTTP 传输(Streamable-HTTP 风格):POST /mcp 承载请求/响应,GET /sse(Server-Sent Events)用于 server→client 通知(如 tools/list_changed)。启用:
dsh-webmcp-serve <url> --http --host 0.0.0.0 --port 9000 --token <secret>
POST /mcp 承载请求/响应 JSON-RPC;GET /sse 为事件流。Bearer 认证:请求头 Authorization: Bearer <secret>(缺失/错误 → 401)。多个 MCP 客户端可并发调用;tools/list_changed 广播给所有活跃 SSE 订阅者。streamable-http MCP 客户端配置:
{ "mcpServers": { "my-site": { "type": "http", "url": "http://host:9000/mcp",
"headers": { "Authorization": "Bearer <secret>" } } } }
站点侧接入套件
站点不必等浏览器到位即可向 agent 暴露动作。插件内置零依赖嵌入片段(sitekit/webmcp-register.js),站点作者只需一行 <script src> 引入,再通过 WebMCP.register(...) 即可声明一个工具。
<script src="https://cdn.example.com/webmcp-register.js"></script>
<script>
WebMCP.register({
name: 'search_products', // 必填、唯一
description: 'Search the catalog', // 人话可读、面向 agent
inputSchema: { type: 'object', properties: { q: { type: 'string' } }, required: ['q'] },
outputSchema: { type: 'object', properties: { count: { type: 'number' } } },
annotations: { readOnlyHint: true }, // MCP ToolAnnotations
execute: async (args) => ({ count: queryYourDb(args.q) }),
});
</script>
该片段被刻意设计得安全且诚实:
- 双挂载特性检测——同时探测
document.modelContext与navigator.modelContext。两处的挂载位置在 Chrome 各版本间漂移过,只测一个会静默失败(CloudNSite 的教训)。 - MCP 最坏假定注解归一——
destructiveHint默认true(openWorldHint同理),除非作者显式设为false,从而让 v1.1.0 宿主侧确认护栏总是拿到保守、可信的值。 - 零副作用 no-op——不支持 WebMCP 的浏览器直接返回
false,什么都不改。 window.webmcp回退——无 modelContext 时把工具 push 进桥接器也会探测的window.webmcp注册表;Chrome 151+ 的Promise<void>registerTool已被 await,幂等守卫避免重复注册。
Agent 就绪度审计
dsh-webmcp-serve --check <url> 对站点执行 discover + computeReadiness,输出报告:url、title、工具数、schema 完整度、注解覆盖率,以及 readOnly / destructive 计数(score = 100 × (0.6 × schema + 0.4 × annotations))。
dsh-webmcp-serve --check https://ai-sdk-webmcp.persona-chat.dev
退出码:score >= 60(agent 就绪)返回 0,低于 60 返回 1,discover 失败返回 2。
快速开始
该插件注册了 2 个 agent 工具。
# 发现页面暴露的站点工具(agent 工具调用示例,外层包装仅为示意)
agent:
tool: webmcp_discover
input:
url: https://example.com
# 携带参数调用某个已发现的站点工具(args 可选)
agent:
tool: webmcp_invoke
input:
url: https://example.com
tool: <name-from-discover>
args:
query: "展示最新文章"
两个工具均接受可选参数 refresh(boolean):强制重新导航。 调用结果可能携带 argsWarning 字段,提示你遗漏了该工具 inputSchema.required 中的必填参数。webmcp_invoke 还接受 confirm(boolean):破坏性工具确认闸——annotations.destructiveHint 为 true 时必须显式传 true(宿主侧强制,页面不可绕过)。
配置
所有配置项均可选,统一写在 cordis.patch.yml 的 config 块中。
| 选项 | 默认值 | 说明 |
|---|---|---|
headless |
true |
以无头模式运行 Chromium。 |
navigationTimeoutMs |
30000 |
页面导航超时时间(毫秒)。 |
invokeTimeoutMs |
20000 |
单次工具调用超时时间(毫秒)。 |
chromiumPath |
"" |
Chromium 可执行文件的显式路径;优先级高于自动解析。 |
allowPrivateHosts |
false |
为 false(默认)时拒绝指向回环/私有网络的 URL(localhost、127/8、10/8、172.16/12、192.168/16、169.254/16、::1、fc00::/7、.local、.internal)——防止被提示注入诱导扫描内网。本地开发夹具请显式设 true。 |
sessionTtlMs |
30000 |
若工具目标 URL 与近期导航完全一致(TTL 内),跳过重复导航直接复用当前页面;设为 0 表示每次都导航。单次调用可传 refresh: true 强制刷新。 |
maxResultChars |
12000 |
工具结果序列化后超过该字节数时截断为 { truncated, totalBytes, preview, hint } 信封——防止超大输出撑爆 agent 上下文。 |
maxSessions |
3 |
按源(origin)划分的浏览器会话池上限;超出按 LRU 驱逐(1-8)。 |
idleTtlMs |
30000 |
空闲会话(及其浏览器)超时自动关闭;0 表示禁用回收。 |
trace |
true |
调用追踪 JSONL 写入 ~/.dsh-webmcp/trace/(按日轮转,失败静默)。设 false 关闭。 |
自 v0.1.1 起,工具发现会同时探测规范的两个挂载点——navigator.modelContext 与 document.modelContext——外加 window.webmcp 和声明式 <form data-webmcp-tool> 元素。自 v0.2.1 起进一步兼容 polyfill/原生实现的存储形态(Map 工具表、返回 Promise 的 getTools()),并在注册项无内联函数时自动经挂载点自身的 executeToolByName 分发调用。自 v1.1.0 起,discover 还会额外探测 /.well-known/webmcp 与 /.well-known/mcp.json(surface 记为 well-known),且每个工具条目都携带其 MCP annotations。
TypeScript 类型契约
TypeScript 使用者:import type { DiscoverResult, InvokeResult, BridgeConfig } from 'dsh-webmcp/types' —— 桥接 API 通过 types/index.d.ts 获得完整类型(无需构建步骤)。
Chromium 解析顺序
选择 Chromium 可执行文件时,插件按以下顺序依次尝试:
config.chromiumPath- 环境变量
DSH_WEBMCP_CHROMIUM - Playwright
ms-playwright缓存扫描 channel: 'chrome'(系统 Chrome)
HTTP 状态与仪表盘
GET /webmcp/status
{
"plugin": "dsh-webmcp",
"version": "0.1.0",
"browser": { "launched": true },
"config": {}
}
GET /webmcp/dashboard 提供每 5 秒自刷新的 HTML 观测页:
配置摘要、池状态、聚合指标(调用数 / 成功率 / p50 / p95 / 均值)、最近 20 次调用、
manifest 漂移事件。/webmcp/status 同步内嵌 stats 摘要。追踪按日写入
~/.dsh-webmcp/trace/YYYY-MM-DD.jsonl(可用 DSH_WEBMCP_TRACE_DIR 覆盖)。
Manifest 漂移检测:同一 URL 再次 discover 时若工具集合变化,结果携带
_meta.drift = { added, removed }(按源内存基线),并写入 manifest-drift 追踪行。
就绪度端点:GET /webmcp/readiness 返回 Agent 就绪度视图——按源的 score、schema 完整度、注解覆盖率,
以及 readOnly / destructive 计数(score = 100 * (0.6 * schema + 0.4 * annotations))。同一仪表盘还提供
交互式 Tool tester(POST /webmcp/tester 表单):选择已发现的工具、填写参数、勾选 confirm 复选框,即可
读回调用结果 JSON(body: { url, tool, args, confirm })。这是对商用就绪度扫描器(web-mcp.net 收费 $49/月)的
免费开源对位答案。
范围说明:与 W3C 提案的关系
WebMCP 标准化进展迅速:Chrome 149 与 Edge 150 已通过 Origin Trial 上线实验支持, ChatGPT 桌面版原生支持站点工具,Brave(Leo AI)提供实验性集成。Firefox 与 Safari 目前仅提交了标准立场议题。
本插件可驱动本地任意 Chromium 家族二进制(见下方解析链),刻意不支持驱动 Firefox 或 Safari。
诚实定位:W3C 提案将“无头浏览”与“全自主代理”列为非目标——其愿景是在具备内建 agent 的浏览器中实现人机协作。本插件是一个务实的过渡期桥接器与站点调试工具: 让尚无内建 agent 的 Harness 立即触达已暴露 WebMCP 工具的站点。完整的人机协作 体验,仍应期待并使用你浏览器未来的原生实现。
安全
- 站点 JavaScript 只运行在隔离的一次性无头 profile 中,绝不复用用户任何登录态。
- 工具调用由用户通过 agent 显式发起,绝不在后台静默执行。
- WebMCP 协议本身就要求站点侧用户确认,ChatGPT 的站点工具正是如此。
- 内网防护——即便提示注入诱导 agent 指向内网,默认也会拒绝该目标。
错误码
每次调用失败都会携带 error 码(缺少必填参数时附带 argsWarning)。宿主侧错误码:
| code | 含义 |
|---|---|
bad-url |
URL 缺少 http(s):// 协议头 |
private-host-blocked |
目标为环回/内网/链路本地——或解析到这类地址(v0.2.2 DNS 反重绑定守卫) |
dns-failed |
域名解析失败 |
network |
连接被拒/重置/不可达 |
timeout |
导航或页面求值超出预算 |
navigate-failed |
其他导航失败 |
internal |
桥接器自身异常 |
confirm-required |
工具被标注 destructiveHint:true——需带 confirm:true 重新调用 |
页面侧错误码来自注入 agent:unknown-tool(页面无此工具)、not-callable(工具无可调用实现)、tool-threw(工具自身抛错,附消息与截断堆栈)。
路线图
此处为精简版;含验收标准的完整阶梯见 ROADMAP.zh.md。
| 版本 | 主题 | 状态 |
|---|---|---|
| v0.2.0 | 内网防护 + 会话复用 | ✅ 已发布 |
| v0.2.1 | polyfill/原生运行时兼容 + argsWarning + 结果预算 | ✅ 已发布 |
| v0.2.2 | page-agent 工程化 + DNS 防护 + 错误码矩阵 | ✅ 已发布 |
| v0.3.0 | stdio MCP server 网关模式 | ✅ 已发布 |
| v0.4.0 | 按源会话池:并发 + LRU 驱逐 + 空闲回收 | ✅ 已发布 |
| v0.5.0 | 可观测:JSONL 追踪 + 仪表盘 + manifest 漂移 | ✅ 已发布 |
| v1.1.0 | annotations 透传 + 破坏性护栏 + well-known 探测 | ✅ 已发布 |
| v1.2.0 | 推送(tools/list_changed)+ outputSchema 透传 + 仪表盘就绪度与测试器 | ✅ 已发布 |
| v1.3.0 | TS 契约 + 类型/运行时一致性审计 | ✅ 已发布 |
| v1.4.0 | 网关 HTTP/SSE 传输 + bearer 认证 + 多客户端 | ✅ 已发布 |
| 后续 | polyfill 自动注入、诊断包、dsh-browser 互通 | 探索中 |
License
MIT
链接
同类插件
Tencent/BrowserSkill#dsh-plugin-browserskill★ 8736
BrowserSkill 的 DeepSeek Harness 浏览器自动化桥接插件,通过原生浏览器工具控制可见的 Chrome 和 Edge Agent Window,支持可访问性与 VOM 页面观察、截图、隔离的多会话控制和 Web UI 实时观察浮层。
omdsh-dev/dsh-browser#packages/browser/bridge-browser★ 809
Chrome 侧边栏扩展,让 DSH 直接操控你的浏览器,无需视觉能力。
liustack/modsearch★ 659
纯文本 agent 的联网搜索桥:搜索网页与 X,返回结构化 JSON 证据(search/fetch/引用)。
DDDMUC/dsh-free-search★ 378
DSH 免费搜索插件:7 个引擎(DuckDuckGo/Bing/SearXNG 免费 + Exa/Perplexity/DeepSeek 付费)、自动回退、设置页 UI(API key 输入 + 官网链接)、web_fetch、引擎测试工具。
wqty123/dsh-browser★ 109
共享真实浏览器:用户可观看并随时接管的原生 Electron 窗口,agent 通过 CDP 驱动,内置 20 个 browser_* 工具(打开/快照/执行/填表/截图/下载/登录态);任务级会话隔离、登录态持久化、人机验证识别,纯 `dsh web` 无需桌面外壳即可自托管。
Tabbit-Browser/dsh-tabbit★ 107
让 DeepSeek Harness 能够控制 Tabbit 浏览器:安装即自动加载 tabbit-browser skill,检测国际版 Tabbit 与国内版 Tabbit Browser 正式版(>= 1.9.0),检查 tabbit-cli 常驻运行时,按平台诊断调用 CLI 所需的 DSH sandbox 模式,并在没有合格版本时通过后台任务下载与系统地区匹配的正式版安装包。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。