news 2026/9/9 22:02:01

如何在 Puppeteer 中启用 WebMCP 并发现、执行页面注册的 MCP 工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何在 Puppeteer 中启用 WebMCP 并发现、执行页面注册的 MCP 工具

如何在 Puppeteer 中启用 WebMCP 并发现、执行页面注册的 MCP 工具

【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer

WebMCP 是一个实验性 API,允许网页注册工具,再由浏览器或外部 Agent(如 LLM)发现并调用。Puppeteer 提供了对应的实验性 API:page.webmcp属性,用于读取页面上已注册的工具列表、监听工具增减,以及直接执行工具并拿到返回结果。本文的任务是:在 Chrome 151+ 上通过 Puppeteer 启动带--enable-features=WebMCP标志的浏览器,完成「注册工具 → 发现工具 → 执行工具 → 读取结果」这条完整链路。

前提条件(来自 WebMCP 指南 与 Page API 的明确说明):

  • 浏览器必须是Chrome 151+,且需要支持 WebMCP CDP domain;
  • 启动时必须加--enable-features=WebMCP标志;
  • WebMCP 是实验性 API,接口可能变化。

启用 WebMCP:带标志启动浏览器

在 Puppeteer 中,WebMCP 支持通过page.webmcp属性访问,当浏览器支持该能力时,它会随页面导航自动初始化,无需手动调用构造函数:

import puppeteer from 'puppeteer'; const browser = await puppeteer.launch({ args: ['--enable-features=WebMCP'], }); const page = await browser.newPage(); // page.webmcp is now available console.log(page.webmcp);

如果启动时漏掉--enable-features=WebMCP标志,页面侧的document.modelContext工具注册不会生效,后续page.webmcp.tools()也将拿不到任何工具。

在页面中注册工具

Puppeteer 只负责「发现与执行」,工具本身需要在页面里注册。文档给出两种注册方式(见 WebMCP 指南)。

命令式注册(JavaScript)

通过page.evaluate在页面内调用document.modelContext.registerTool

await page.evaluate(async () => { await document.modelContext?.registerTool({ name: 'calculate_sum', description: 'Calculates the sum of two numbers', inputSchema: { type: 'object', properties: { a: {type: 'number'}, b: {type: 'number'}, }, required: ['a', 'b'], }, execute: ({a, b}) => { return a + b; }, }); });

registerTool还支持第二个参数传入AbortSignal:调用该 signal 的abort()后可以取消这个工具的注册,此时 Puppeteer 侧会收到toolsremoved事件(该行为在仓库测试 webmcp.test.ts 中有验证)。

声明式注册(HTML form)

WebMCP 支持将带特定属性的 HTML form 识别为工具:

await page.setContent(` <form toolname="search_products" tooldescription="Search for products in the catalog" > <input name="query" type="text" /> <button type="submit">Search</button> </form> `);

通过 form 注册的工具,可以拿到对应的表单元素句柄:

const tools = page.webmcp.tools(); const searchTool = tools.find(t => t.name === 'search_products'); const formHandle = await searchTool.formElement;

注意:form 必须带tooldescription属性。测试代码显示,缺少该属性的 form(如<form toolname="mytool"></form>)会触发pageissue事件,其genericIssueDetails.errorTypeFormModelContextMissingToolDescription

发现已注册的工具

page.webmcp.tools()返回当前页面注册的所有工具,每个WebMCPTool对象带有namedescriptioninputSchemaframe等属性(详见 WebMCPTool API):

const tools = page.webmcp.tools(); for (const tool of tools) { console.log(`Tool found: ${tool.name} - ${tool.description}`); }

如果工具是动态注册的,用事件监听代替轮询。page.webmcp是一个EventEmitter,事件包括toolsaddedtoolsremovedtoolinvokedtoolresponded(见 WebMCP API):

// Listen for new tools page.webmcp.on('toolsadded', event => { for (const tool of event.tools) { console.log(`New tool added: ${tool.name}`); } }); // Listen for removed tools page.webmcp.on('toolsremoved', event => { for (const tool of event.tools) { console.log(`Tool removed: ${tool.name}`); } });

toolsadded/toolsremoved事件的负载是一个tools数组(WebMCPToolsAddedEvent、WebMCPToolsRemovedEvent)。

一个需要注意的边界:工具注册归属于页面上下文。仓库测试 webmcp.test.ts 验证了——整页导航(再次page.goto到其他页面)会触发toolsremoved并使page.webmcp.tools()变回空列表;而同文档导航(如仅改 hash)不会清空已注册的工具。如果你的自动化流程中会频繁跳转,发现逻辑要按「每次导航后重新检查」来写。

执行工具并判断结果

对发现到的工具调用execute(input, options),第一个参数是匹配该工具inputSchema的输入对象,返回一个 Promise,resolve 为WebMCPToolCallResult(见 WebMCPTool.execute):

const tools = page.webmcp.tools(); const tool = tools.find(t => t.name === 'calculate_sum'); if (tool) { const result = await tool.execute({a: 5, b: 10}); if (result.status === 'Completed') { console.log('Result:', result.output); } else { console.error('Error:', result.errorText); } }

判断结果时主要看WebMCPToolCallResult的几个字段(见 WebMCPToolCallResult API):

  • status:调用状态,如CompletedCanceledError
  • outputstatusCompleted时的工具输出,其他状态下不存在;
  • errorText:错误文本;
  • exception:如果工具执行的 JavaScript 抛出异常,这里携带异常对象;
  • call:对应的WebMCPToolCall(含idinputtool),可用id把一次调用和它的响应关联起来。

仓库测试里有一条可直接参照的成功用例:注册一个execute: ({text}) => 'hello ' + text的工具后执行tool.execute({text: 'world'}),返回statusCompletedoutput'hello world',且errorTextexception均为 undefined。这就是本文场景的验证标准:execute的 Promise resolve 后,result.status === 'Completed'result.output与页面内execute函数的返回值一致,即整条链路跑通

取消执行中的工具

execute的第二个参数options.signal接收一个AbortSignal,用于取消进行中的执行(见 WebMCPToolExecuteOptions):

const controller = new AbortController(); // Cancel execution after 2 seconds setTimeout(() => { controller.abort(); }, 2000); const result = await tool.execute( {query: 'large data processing'}, {signal: controller.signal}, ); if (result.status === 'Canceled') { console.log('Tool execution was canceled.'); }

测试验证了取消后的结果形态:statusCanceledoutput不存在,errorText为空字符串。如果传入的 signal 在调用前就已经 abort,同样会得到Canceled结果。

观测工具的调用与响应

除了自己主动execute,还可以监听页面或浏览器主动发起的调用:

page.webmcp.on('toolinvoked', call => { console.log(`Tool ${call.tool.name} was invoked with input:`, call.input); }); page.webmcp.on('toolresponded', response => { console.log( `Tool ${response.call?.tool.name} responded with status: ${response.status}`, ); if (response.status === 'Completed') { console.log('Output:', response.output); } else if (response.status === 'Canceled') { console.log('Invocation was canceled'); } else { console.log('Error:', response.errorText); } });

toolinvoked事件的负载是 WebMCPToolCall,包含调用id、输入参数和被调用的工具对象;toolresponded的负载就是上文提到的WebMCPToolCallResultWebMCPTool对象本身也带toolinvoked事件,可以只监听某一个工具的调用。

限制与验证清单

  • 只支持 Chrome 151+ 的 CDP 模式,且必须显式传--enable-features=WebMCP;API 为实验性质,可能随版本变化(Page API 中webmcp属性标注为 Experimental)。
  • WebMCPWebMCPTool的构造函数均为内部实现,不应直接new或继承,统一通过page.webmcp获取。
  • 验证顺序可以按仓库测试的方式:page.goto一个页面 → 注册工具 → 等待toolsaddedpage.webmcp.tools()检查name/description/inputSchemaexecute后断言status === 'Completed'output值。完整用例可参考 test/src/cdp/webmcp.test.ts。
  • 更多细节见 docs/guides/webmcp.md 与 WebMCP API 文档。

【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 21:59:59

Revit二次开发入门:帮助文档、Lookup与外部加载工具全攻略

简介&#xff1a;Revit2018 API 开发学习资源包&#xff0c;面向利用 C#/.NET 扩展 Revit 功能的开发者与工程师。包内含官方帮助文档、Lookup 源码程序和 Addin-Manager 外部加载工具&#xff0c;覆盖 API 函数/类库说明、插件编写指导、模型数据实时查询与插件管理配置等环节…

作者头像 李华
网站建设 2026/9/9 21:59:37

月面坐标转换实战:MATLAB工具包解决经纬度与直角坐标互转

简介&#xff1a;CooRD MG 2.0是一款面向GIS与测绘领域的坐标转换工具&#xff0c;内置多国坐标系定义与常用转换算法&#xff0c;可帮助用户快速完成北京54、国家80、WGS84等基准面之间的坐标换算&#xff0c;适用于工程测量、地图制图以及多源空间数据融合前的坐标配准工作。…

作者头像 李华
网站建设 2026/9/9 21:59:15

内容社区互动数据聚合:MySQL聚合函数与索引优化实战

做内容社区的同学应该都有体会&#xff1a;产品上线初期&#xff0c;互动数据随便怎么查都很快&#xff0c;等用户量起来、帖子堆到几十万上百万之后&#xff0c;后台随便一个"今日热门榜"接口就能把数据库拖到报警。最近我在 PaperFlow 里做的就是这套东西——内容互…

作者头像 李华
网站建设 2026/9/9 21:58:54

大厂Java面试新趋势:从JVM基础到RAG应用的全景拆解

最近好几个读者私信我说&#xff0c;现在互联网大厂的Java面试题越来越看不懂了&#xff0c;上午还在问HashMap和线程池&#xff0c;下午面试官突然打开一个AI应用的项目页&#xff0c;问你RAG怎么做、向量数据库怎么选、LangChain4j和Spring Boot怎么集成。这种感觉我太熟悉了…

作者头像 李华
网站建设 2026/9/9 21:58:00

CAD文件创建时间能改吗?详解修改CAD时间属性的3种实用方法

做设计这行&#xff0c;相信不少朋友都遇到过这样的尴尬场景&#xff1a;甲方或审图方打开你发过去的CAD图纸&#xff0c;右键点开属性一看&#xff0c;发现文件的创建时间或修改时间不对劲&#xff0c;然后就开始追问“这图纸是不是最近改的”“怎么时间对不上”之类的问题。 …

作者头像 李华
网站建设 2026/9/9 21:57:55

西门子S7-1200点动控制仿真入门:TIA Portal零基础PLC实战

简介&#xff1a;面向零基础电工电子学习者的西门子S7-1200 PLC仿真入门包&#xff0c;围绕电动机点动控制&#xff0c;基于博途V15.1建立PLC与HMI联动仿真&#xff0c;无需实物即可模拟开关控制接触器、接触器控制电机的真实工况。压缩包共82个文件、约6.7MB&#xff0c;主要是…

作者头像 李华