关于 add-webmcp
Add WebMCP 是一项开发技能,可从现有 Web 应用源代码出发,将 WebMCP 工具集成到应用中。它指导能力审查、实现和浏览器验证,同时保留应用现有的授权与确认边界。
主要功能
- 01扫描代码库以梳理应用能力
- 02依据现有验证器定义工具契约
- 03在浏览器应用中注册工具
- 04使用 Stagehand 验证发现和调用
- 05检查架构、注解和实际效果
适用场景
- 01将现有界面任务开放为 WebMCP 工具
- 02用无效输入测试工具行为
- 03验证变更仍受应用确认控件约束
MCP 相关
该技能为目标 Web 应用添加供浏览器 Agent 使用的一方 WebMCP 工具,并指导通过浏览器的 model context 注册工具及验证发现和调用。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ browserbase/ skills --skill add-webmcp安装后在 Claude Code 中输入/add-webmcp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreLICENSE.txtpackage.jsonpnpm-lock.yamlevals/evals.jsonreferences/implementation-and-validation.mdquality-rubric.mdscripts/scan-codebase.mjsvalidate-stagehand.mjstests/scan-codebase.test.mjsvalidator-safety.test.mjstests/fixtures/browserbase-owned-webmcp.e2e.jsoncatalog-gym.e2e.jsonsupport-gym.e2e.jsonwebmcp.consequential.jsonwebmcp.e2e.jsonwebmcp.init.jswebmcp.missing.jsontests/fixtures/sample-next/package.jsontests/fixtures/sample-next/app/page.tsxtests/fixtures/sample-next/app/api/catalog/route.tstests/fixtures/sample-next/app/checkout/page.tsx详细介绍
添加 WebMCP
将 Web 应用已实现的功能转化为由项目维护的一方 WebMCP 工具。修改目标代码库及其测试;不要引入托管代理或第三方运行时。
兼容性:捆绑的 Stagehand 验证器要求 Node.js 22.18 或更高版本。验证需要本地安装 Chrome/Chromium,或为可公开访问的预览提供 BROWSERBASE_API_KEY。
工作时请详细说明:逐步报告每个步骤的发现,而不只是提供最终报告。
如果用户要求根据一个在线 URL 生成独立的初始化脚本,请改用 webmcp-gen。此技能从源代码着手,将工具集成到应用中。
1. 确定应用边界
阅读目标代码库的说明、软件包清单、框架配置和当前 Git 状态。保留无关更改。
将 ADD_WEBMCP_SKILL_DIR 设置为包含此文件的目录,然后运行范围受限的扫描器:
node "$ADD_WEBMCP_SKILL_DIR/scripts/scan-codebase.mjs" "$TARGET_REPO"
将扫描结果视为线索,而不是结论。在单体代码库中,编辑前先确定实际的浏览器应用及其调用的服务端软件包。
2. 建立功能清单
从用户可见的入口开始,逐步追踪每个候选功能,包括客户端处理程序、验证架构、服务端边界、授权检查、副作用和返回状态。请检查:
- 路由和页面;
- 表单及其提交处理程序;
- 服务端操作、API 处理程序、RPC 过程和服务客户端;
- Zod、Valibot、Yup、Joi、JSON Schema 或同等验证器;
- 身份验证、授权、CSRF、幂等性、速率限制和审计钩子。
优先选择 search_catalog 或 save_draft 这类完整的用户任务,而不是机械地为每个端点创建一个工具。排除仅供内部或管理员使用的操作、绕过身份验证的操作、原始数据库访问、涉及机密的操作,以及界面未授予当前用户的功能。
为每个选定的工具记录其源文件、现有验证和授权边界、副作用、风险类别、确认行为以及安全的样例输入。详细清单和框架模式请参阅 references/implementation-and-validation.md。
3. 设计工具契约
- 使用稳定的动词-名词名称,并说明用户可见的效果、前置条件和重要的排除项。
- 根据应用现有的验证器或领域类型生成 JSON Schema。不要另行设计一个更宽松的契约。使用
additionalProperties: false关闭对象架构,并确保执行时的解析器也拒绝未知字段;如果发现架构已关闭,但运行时解析器仍允许未知字段,那么契约就没有真正关闭。 - 返回精简且可序列化为 JSON 的领域结果。不要返回 DOM 节点、凭据、Cookie、令牌或完整 HTML 文档。
- 调用与 UI 相同的客户端/服务边界,确保现有验证、授权、可观测性和业务规则仍然有效。
- 在处理器内部再次验证。Agent 提供的输入不可信。
- 切勿将请求原样回显为结果。应从应用自身的状态读取结果;如果状态是异步更新的(React 和大多数响应式存储不会在下一行代码执行时反映更改),则轮询直至状态稳定后再读取,并报告实际情况。回显会把静默无操作变成通过的测试。
审慎设置注解:
| 风险 | 工具设计 | 注解和确认行为 |
|---|---|---|
| 只读 | 不修改状态 | 注册 readOnlyHint: true;如果输出包含页面文本或用户控制的文本,则添加 untrustedContentHint: true |
| 可逆更改 | 草稿、偏好设置、购物车编辑 | 注册 readOnlyHint: false;保留身份验证和幂等性;仅使用可丢弃的状态进行测试 |
| 影响重大或不可逆 | 购买、发送、发布、删除、更改权限 | 尽可能将预览/准备与提交拆分;不要添加声明式的 toolautosubmit;最终操作必须由应用的实际确认控件触发 |
注册时使用当前 WebMCP 注解名称 readOnlyHint 和 untrustedContentHint。Stagehand v4 会将发现的注解规范化为 readOnly、untrustedContent,并在声明式表单中规范化为 autosubmit。这些只是提供给浏览器或 Agent 的提示,不是安全强制措施。应用必须负责强制执行权限、验证、确认、幂等性和重放保护。
4. 与应用集成
使用浏览器提供的运行时模型上下文:
const modelContext = navigator.modelContext || document.modelContext;
保留这两个访问器:当前 Chrome 将 document.modelContext 暴露为原生 ModelContext,而 navigator.modelContext 为 undefined,因此回退逻辑不可或缺,并非仅用于防御。该接口由浏览器提供,且存在于所有页面上,因此应用无需打包任何 polyfill。
在应用就绪后,从仅限客户端的根组件/提供器注册命令式工具。registerTool 会返回一个 promise,并按名称保证幂等——重新注册会替换之前的定义,而不会重复注册,且没有注销句柄——因此,无需拆除逻辑,重新挂载和热重载也安全。若现有表单已准确表示该任务,且保留可见的审核步骤很有价值,则使用声明式表单属性。
不要在工具执行器中重复实现服务端业务逻辑。不要为了让冒烟测试通过而放宽 CSRF、同源、身份验证或确认检查。切勿在浏览器代码中嵌入密钥。
5. 验证实现
运行目标项目的专项测试、类型检查和生产构建。然后创建一个小型 webmcp.e2e.json,列出所有预期工具。必须进行发现;是否调用由每个测试用例自行选择,并且必须使用合成数据或一次性数据。
安装一次验证器依赖项:
pnpm --dir "$ADD_WEBMCP_SKILL_DIR" install --frozen-lockfile
使用由 Stagehand 启动的本地浏览器验证 localhost:
node "$ADD_WEBMCP_SKILL_DIR/scripts/validate-stagehand.mjs" \
--url http://localhost:3000 \
--config "$TARGET_REPO/webmcp.e2e.json" \
--local
本地运行默认以有头模式进行,以便在验证时查看浏览器;在 CI 或无人值守运行时传入 --headless。
如果发现结果显示工具数为 0,请先检查主机,再怀疑代码:开发服务器通常只绑定到 localhost,因此 --url http://127.0.0.1:PORT 会找不到任何内容,而 http://localhost:PORT 则可以正常工作。这种失败现象与工具从未注册完全相同。
只有对于可公开访问的已部署预览,才使用 --browserbase。验证器使用 Stagehand v4 的真实 page.tools()、tool.invoke() 和 invocation.result() 调用路径。除非明确传入 --allow-consequential,否则它会拒绝可能产生重大后果的调用。
注入的 init 脚本可用于测试验证器本身,但不能证明目标应用提供了自己的工具。最终的应用验证必须在不使用 --init-script 的情况下运行。
6. 对工具进行对抗性验证,确认它们确实有效
步骤 5 可以证明每个工具都能被发现,且其执行器已运行。但这并不能证明工具完成了它声称的工作,通过配置检查也不能证明契约合理。请在步骤 5 通过后最后执行此步骤,并直接对实时页面进行测试,而不是将测试写入 webmcp.e2e.json——测试的目的就是探测作者未曾预料到的输入。
使用持久化浏览器会话操作页面,让测试在真实状态上逐步累积。browse CLI 是最轻量的选择——只需全局安装一次,会话便会在不同命令之间持续保留:
browse open http://localhost:3000 --session probe --local --headed
browse eval --session probe '(async()=>{const mc=document.modelContext;const t=(await mc.getTools()).find(x=>x.name==="my_tool");try{return "ACCEPTED "+JSON.stringify(await mc.executeTool(t,JSON.stringify({/* probe input */})));}catch(e){return "REJECTED";}})()'
browse screenshot --session probe --path /tmp/effect.png
否则,以下三点会耗费时间:browse open 默认使用无法访问 localhost 的云端浏览器,因此必须指定 --local;browse eval 只能可靠地接受单行脚本,因此每条命令只运行一个测试;executeTool 接受工具对象和作为 JSON 字符串的参数——传入普通对象会因 "Failed to parse input arguments" 而失败。
根据调用是被拒绝还是被接受来断言,不要依赖错误文本。WebMCP 层会将处理程序的消息替换为通用的调用失败字符串,因此调用方无法收到精确原因。
将发现的 tool.inputSchema 作为测试对象,而不是当作事实依据。对每个工具,测试以下内容:
- 架构封闭性。 调用时传入架构未声明的额外字段。遵循 §3 的工具会拒绝此调用。若调用被接受,则说明封闭契约只是装饰。
- 必填字段。 省略一个
required属性。调用必须失败;相比报错,返回携带 null 或不完整结果的Completed状态更糟,因为 Agent 会误以为调用成功。 - 类型和约束。 当架构要求
number时传入字符串;针对minimum/maximum传入超出范围的值;再传入不属于enum的值。若工具静默强制转换或原样回显,说明处理程序从未进行验证。 - 错误真实性。 确认本应失败的工具会报告非
Completed状态,而不是返回看似成功的内容。 - 注解真实性。 将每个工具的实际
annotations与步骤 3 中分配的风险进行比较。纯查询工具声明readOnly: false,或会产生变更的工具声明readOnly: true,都属于缺陷,即使发现流程通过也不例外。 - 干净拒绝。 完成上述格式错误的测试后,重新读取应用状态。被拒绝的调用不得留下任何痕迹;仅凭接受或拒绝结果无法发现的部分状态变更,也是缺陷。
- 后果性操作的限制。 绝不调用此类工具。确认工具声明了自身风险、不存在声明式
toolautosubmit,且应用自身的确认控件仍能阻止 Agent 直接触发操作。
接下来验证实际效果,而不是返回值。调用工具后,独立检查应用——对渲染状态使用 DOM 断言;若界面是画布或图表,则使用屏幕截图。处理程序返回 {saved: true},但实际毫无变化,这种情况能通过步骤 5,却会在此处失败。如果界面没有可读取的 DOM,就让工具从应用的真实存储中读取数据,以确保返回值源自真实状态,而非由执行器编造。
将所有差异都视为应用或工具契约中的缺陷,并在相应位置修复。不要为了通过此步骤而放宽架构、降低注解要求或删除测试。
7. 报告结果
列出已考虑的功能,并说明排除原因。对于每个已实现的工具,报告其契约、对应代码路径、风险/确认处理方式、Stagehand 的实际发现/调用结果,以及通过的第 6 步对抗性探测。说明未测试的环境或浏览器支持情况。
对于比较基准、质量审计或评分评估,请阅读 references/quality-rubric.md。报告数值评分前,先应用其中的资格门槛;不要让高诊断分数掩盖伪造行为、不安全的后果边界或缺少生产环境发现能力。