跳到主要内容

WebMCP — Service Worker 工具

本章讲 WebMCP 的进阶分支:让 agent 调用用户当前没打开的网站。核心是把工具搬进 Service Worker 后台执行,难点在路由(谁处理这次调用)和会话隔离(不同对话别串了购物车)。这是一份补充性 explainer,不是规范正文。

1. 要解决的问题

主 explainer 讲的是 agent 操作已打开的标签页。但有时 agent 需要一个用户没打开的站点:比如你在看地图找营地,想让 agent 后台帮你订营位,而不想它切走你的标签页(docs/service-workers.md:9-13)。

需要的是:agent 能发现一个能处理预订的 app,并在后台无 UI 地把请求发过去。Service Worker(本就为后台运行设计)是天然载体。

2. 一句话方案

网站把 Service Worker 注册成 WebMCP provider;工具调用在 worker 脚本里处理,不用开任何窗口。若某工具确实需要用户交互(如付款),worker 可以开一个浏览器窗口、用 postMessage 与之通信,把敏感步骤交还给用户(docs/service-workers.md:15-17)。

3. 注册与发现:从「用户先访问过」到「JIT 安装」

Service Worker 要先被安装才能提供工具。最朴素的方式是用户访问站点时 navigator.serviceWorker.register()(docs/service-workers.md:111)。但这要求用户先自己找到并访问该站,体验差。

更好的设想是 JIT(just-in-time)安装:借鉴实验性的 Payment Handler API 已引入的 app manifest serviceworker 字段(docs/service-workers.md:115-128),让浏览器直接 fetch worker 脚本并安装,无需用户先导航:

// docs/service-workers.md:118-128
{
"name": "Example App",
"start_url": "/",
"serviceworker": { "src": "service-worker.js", "scope": "/", "use_cache": false }
}

设想再加一个字段标明「本 app 支持 WebMCP(有工具)」,供发现机制(目录/搜索)索引(docs/service-workers.md:130-132)。发现层(Discovery Layer)目前是占位,具体机制 TBD,讨论见 Appendix A(docs/service-workers.md:258-275)。

4. 完整流程:从用户提示到后台执行

下面这张时序图来自 explainer(docs/service-workers.md:142-191),展示了含 JIT 安装的完整链路:

注意 worker 激活后才调 agent 对象的方法登记工具(docs/service-workers.md:136)。explainer 里用的是 worker 全局作用域上的 agent 对象,和主 explainer 同名。

(inferred)API 命名漂移提示: 本 explainer(2025-08-28 首发)用的是 self.agent.provideContext({tools:[...]})(docs/service-workers.md:223-238),而规范主体如今已是 document.modelContext.registerTool(...)(§01)。这两处接口名/形状不一致,几乎可以肯定是规范演进中的命名漂移——agent/provideContext 是较早的写法,主 API 后来改名成了 modelContext/registerTool。本章按 explainer 原文引用,但读者应知道 Service Worker 侧的最终接口大概率会向主 API 对齐。

5. 路由:谁来处理这次调用

页面工具是 1:1 的——一个页面、一个操作它的 agent(docs/service-workers.md:194-195)。Service Worker 打破了这个简单模型:worker 不属于任何窗口,而属于一个源(+ 可选 scope 路径),可能同时被多个 client agent 调用,调用还可能任意交错(docs/service-workers.md:196-197)。

explainer 列了三种架构(docs/service-workers.md:201-215):

架构谁处理调用复杂度
单 tab + 页面工具全部给当前活跃页面简单(1:1)
仅 Service Worker全部给 worker;可能多个 agent 连它
tab + Service Worker 并存有歧义:同名工具该给谁?复杂

第三种的歧义由 client agent 自己决定,可能很实现相关(docs/service-workers.md:211-213)。explainer 给的直觉例子:邮箱既有打开的 tab 又装了 PWA(带 worker),用户已经在 tab 里起草了给经理的邮件,这时说「把现状发给经理」,agent 可能「看到」草稿而选择走那个打开的 tab

一条硬规矩:一次工具调用永远只路由给一个 server,即便 client 连了多个登记了同名工具的 server(docs/service-workers.md:215)。工具也按 worker + 源 scope,防止某 app 抢注 searchadd-to-cart 这类通用名(docs/service-workers.md:138)。

6. 会话状态:用 sessionId 隔离不同对话

问题:用户开了两个对话——一个买生日礼物、一个买菜——都通过同一个购物站的同一个 worker 操作。调用都汇到同一个脚本上下文,worker 怎么知道往哪个购物车写?(docs/service-workers.md:217-219)

方案:给工具调用带一个 Session ID,作为参数传进 execute。这样回调同时拿到工具参数和带 sessionId 的 client info,据此缓存该会话独有的状态(docs/service-workers.md:219-221):

// docs/service-workers.md:223-238
self.agent.provideContext({
tools: [{
name: "add-to-cart",
description: "Add an item to the user's shopping cart.",
inputSchema: { /* ... */ },
async execute(params, clientInfo) {
const cart = carts.get(clientInfo.sessionId); // 按会话取购物车
cart.add(params.itemId);
}
}]
});

这里 execute(params, clientInfo) 比页面侧多了第二个参数 clientInfo——这是 Service Worker 场景为支持多会话特意加的。

7. 安全:Service Worker 把「致命三件套」凑齐了

explainer 直接引用 Simon Willison 的 Lethal Trifecta(致命三件套):私有数据 + 不可信内容 + 对外通信(docs/service-workers.md:250-252277-279)。Service Worker 工具很容易把三者凑齐:工具常为暴露用户数据而生(私有数据)、渲染用户提交内容的站会把恶意内容经工具喂给 agent(不可信内容)、能对外通信的 agent 可能泄露数据。

起步缓解(docs/service-workers.md:253-254):一旦 agent 会话访问了某 worker 的工具,就把该会话限制在那个 worker 的源/scope 内;并对会话剩余部分禁用 web 搜索等对外通信,以堵第三点(外泄)。多源工具协作是否能安全实现,explainer 明说「目前不清楚,欢迎社区输入」(docs/service-workers.md:255-256)。

8. 边界与局限

  • 整章是补充 explainer,不是规范。 index.bs 里没有 Service Worker 的规范算法。本章描述的是设计设想。
  • 接口名待对齐。 见 §4 的漂移提示:agent.provideContext 大概率会向 document.modelContext.registerTool 收敛。
  • 发现与 JIT 安装机制 TBD(docs/service-workers.md:132258-275)。

9. 代码地图

主题文件符号 / 锚点
问题与方案docs/service-workers.md:9-17The Problem / TL;DR
JIT 安装与 manifestdocs/service-workers.md:107-132serviceworker manifest 字段
完整时序docs/service-workers.md:142-191sequenceDiagram
路由三架构docs/service-workers.md:194-215Routing
会话隔离docs/service-workers.md:217-238sessionIdclientInfoprovideContext
安全(三件套)docs/service-workers.md:250-256Lethal Trifecta