1. 浏览器里的 Agent 工具箱,到底缺了什么
WebMCP 是 W3C Web Machine Learning 社区组正在推进的草案,核心目标只有一个:让网页主动把可调用的能力暴露给浏览器里的 AI Agent。它定义了一个挂在navigator上的modelContext接口,网站通过声明式表单属性或命令式 JS 注册工具,Agent 侧则拿到一份结构化的工具清单,直接调用,而不是靠截屏猜按钮。
它适合谁?三类人最该关注:一是做 Chrome 扩展或浏览器侧 Agent 的开发者,二是企业内部 OA、CRM、工单系统的前端负责人,三是想把自家 SaaS 接入 AI 工作流的团队。这三类场景的共同点是:页面交互路径固定、认证已经跑在浏览器里、又不想为每个 Agent 单独写一套后端 API。
但真正动手时,卡点往往不在 WebMCP 本身,而在 Agent 的模型通道怎么配。浏览器侧 Agent 通常要同时对接多个模型供应商,每个供应商一套 Key、一套 base_url、一套鉴权头,散落在扩展的config.toml、环境变量和本地存储里,改一次配置要翻五个文件。这篇就围绕这个痛点,给出一份可复制的config.toml骨架,用 TaoToken 的统一 Key 和 API 通道把模型侧收敛成一处配置,再配合 WebMCP 的工具注册,跑通从配置到调用的最小闭环。
需要先说明一点:WebMCP 目前仍是社区组草案,Chrome 侧属于实验性能力,不同版本行为可能有差异。下面的配置骨架以「统一模型通道 + 浏览器侧工具调用」为主线,WebMCP 部分按当前公开的接口形态编写,你在自己环境里跑的时候以实际浏览器版本为准。
2. 前置准备:TaoToken 统一 Key 与通道
在写config.toml之前,先把模型侧的入口固定下来。TaoToken 的作用是把多家模型的调用收敛到一个 API 地址和一把 Key 上,浏览器侧 Agent 只需要认这一个通道,不用为每个模型维护独立的鉴权逻辑。
你需要做两件事。第一,在控制台创建一把 API Key,建议按用途分 Key,比如浏览器 Agent 单独一把,方便后续按 Key 统计和吊销。第二,确认接入地址,API 根地址是https://taotoken.net/api,模型对话、编码类请求都走这个前缀,具体路径按你调用的能力拼接。
创建 Key 的入口在控制台的 API Keys 页面,登录后新建即可,Key 只在创建时完整显示一次,记得当场保存到安全的地方。如果你还没注册,从官网进控制台就行。
注意:Key 不要硬编码进前端页面或提交到公开仓库。浏览器扩展场景建议放在扩展的本地配置或后台脚本里,页面脚本通过消息传递拿结果,避免 Key 暴露在页面上下文中。
接入文档里有各能力的完整路径和参数说明,配置前扫一眼能省不少试错时间。模型对话能力可以用来做 Agent 的推理主通道,编码类能力适合 Agent 需要生成或修改代码的场景,长期跑编码任务和 Agent 的可以看 Coding Plan 的额度方案。
3. 可复制的 config.toml 骨架
下面这份骨架把「模型通道」和「浏览器侧 Agent 运行参数」放在同一个文件里,方便扩展或本地 Agent 进程统一读取。字段名按常见 TOML 习惯命名,你可以按自己项目的解析逻辑调整。
# config.toml —— 浏览器侧 Agent 统一配置骨架 [provider] # 统一模型通道,所有模型请求走这里 base_url = "https://taotoken.net/api" api_key = "sk-你的TaoToken密钥" # 默认模型,按需替换为你实际调用的模型标识 default_model = "claude-sonnet" # 请求超时(秒) timeout = 60 # 失败重试次数 max_retries = 2 [provider.headers] # 统一鉴权头,TaoToken 兼容 OpenAI 风格的 Bearer 鉴权 Authorization = "Bearer ${api_key}" Content-Type = "application/json" [agent] # Agent 运行模式:browser 表示浏览器侧 mode = "browser" # 单轮最大工具调用次数,防止 Agent 陷入循环 max_tool_calls = 8 # 是否在调用敏感工具前要求用户确认 require_confirmation = true [webmcp] # 是否启用 WebMCP 工具发现 enabled = true # 工具注册来源:declarative 表示从 HTML 表单属性解析 # imperative 表示从 JS registerTool 注册 sources = ["declarative", "imperative"] # 允许 Agent 访问的域白名单,留空表示仅当前页同源 allowed_origins = [] [logging] level = "info" # 是否记录工具调用参数,调试期开,生产建议关 log_tool_args = false几个字段值得展开说。base_url固定指向 TaoToken 的 API 根地址,后面所有模型请求都在这个前缀下拼接,换模型不用换地址。api_key用占位符写法,实际加载时从环境变量或扩展存储注入,避免明文落盘。max_tool_calls是防呆字段,浏览器侧 Agent 一旦工具调用链失控,很容易连续触发页面操作,设个上限能兜住。require_confirmation对应 WebMCP 的敏感操作确认机制,支付、提交表单这类动作建议保持开启。
allowed_origins留空时,Agent 只能操作当前页面同源的工具,这是最保守也最安全的默认值。如果你确实需要跨标签页协作,再显式加白名单,并且清楚这会扩大攻击面。
4. 浏览器侧工具注册与调用验证
配置就位后,先验证模型通道通不通,再验证 WebMCP 工具能不能被 Agent 发现和调用。分两步走。
第一步,验证统一 Key 通道。用一条最小请求确认base_url和 Key 生效:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet", "messages": [{"role": "user", "content": "只回复 ok"}], "max_tokens": 16 }'返回体里能看到正常的choices结构,说明通道没问题。如果返回鉴权错误,先检查 Key 是否带上了Bearer前缀,以及有没有多余空格。
第二步,在页面里注册一个 WebMCP 工具,并让 Agent 调用它。命令式注册的写法大致如下:
// 页面脚本:注册一个可被 Agent 调用的工具 if (navigator.modelContext) { navigator.modelContext.registerTool({ name: "add-todo", description: "添加一个待办事项到当前列表", inputSchema: { type: "object", properties: { task: { type: "string", description: "待办内容" }, priority: { type: "number", minimum: 1, maximum: 5 } }, required: ["task"] }, async execute({ task, priority }) { const item = await addTodoToList(task, priority ?? 3); return { content: [{ type: "text", text: `已添加:${item.task}` }] }; } }); } else { console.warn("当前浏览器未启用 WebMCP,走降级路径"); }声明式写法更省事,直接在表单上加属性,浏览器会从字段自动推断参数 Schema:
<form action="/add-todo" method="POST" toolname="add-todo" tooldescription="添加一个待办事项到列表"> <input name="task" type="text" required> <input name="priority" type="number" min="1" max="5"> <button type="submit">添加</button> </form>验证动作:在 Agent 侧发起一句「帮我加一个明天交周报的待办」,观察 Agent 是否直接命中add-todo工具、execute是否被触发、返回值是否回到对话里。如果 Agent 没有发现工具,先确认navigator.modelContext是否存在,再确认工具注册发生在 Agent 扫描之前。工具注册是页面加载时执行的,Agent 扫描如果早于注册,就会拿到空列表。
5. 本篇常见错排查
报错一:navigator.modelContext is undefined。说明当前浏览器没启用 WebMCP。实验阶段需要在启动参数里开启对应特性,或者引入 Polyfill 做兼容。生产环境不要假设所有用户浏览器都支持,务必写降级分支,不支持时回退到传统 DOM 操作或直接提示用户。
报错二:模型请求 401。优先查 Key 是否正确注入。config.toml里写的是${api_key}占位符,如果你的加载逻辑没做变量替换,实际发出去的就是字面量。另外确认Authorization头是Bearer加 Key,中间一个空格,不要漏。
报错三:工具被 Agent 发现但调用失败。多半是inputSchema和execute解构的参数对不上。Schema 里声明了priority是 number,Agent 传了字符串,execute里又没做转换,就会在业务逻辑里炸掉。建议在execute入口做一次参数校验,类型不符直接返回isError: true和可读的错误文本,让 Agent 有机会自我修正。
报错四:Agent 反复调用同一个工具。这是工具返回值不够明确导致的。execute返回的文本要包含明确的结果状态,比如「已添加」或「失败:缺少 task 参数」,不要返回空字符串或模糊描述。Agent 拿不到明确信号就会重试,配合max_tool_calls上限能兜住,但根因还是返回值设计。
报错五:跨域工具不可见。WebMCP 继承同源策略,A 域注册的工具在 B 域页面里看不到,这是设计如此,不是 bug。需要跨标签页协作时,走浏览器消息传递,由各自页面的 Agent 分别调用本域工具,不要试图绕过同源限制。
6. 把配置收敛成一处,再谈 Agent 落地
浏览器侧 Agent 的复杂度,一半在工具发现,一半在模型通道。WebMCP 解决的是前者,让页面主动交出结构化能力;TaoToken 的统一 Key 和 API 通道解决的是后者,把多模型鉴权收敛成一个base_url加一把 Key。两者叠起来,config.toml里那几十行就是整个 Agent 的入口配置,改模型、换额度、调超时都在一处完成。
如果你正在做浏览器扩展或页面内 Agent,建议先把这份骨架跑通,再逐步加工具。工具从一两个高频动作开始,验证 Agent 的发现和调用链路稳定后,再扩到表单提交、支付确认这类敏感操作,并且保持require_confirmation开启。模型通道这边,Key 按用途分、按环境分,浏览器侧单独一把,出问题能快速定位和吊销。
接入文档里有各能力的路径和参数细节,配置过程中对着看能少踩坑。需要长期跑编码类 Agent 任务的,Coding Plan 的额度方案可以一并了解。工具注册和模型调用都跑通之后,你会发现浏览器侧 Agent 的最小闭环其实不复杂,难的是把配置和权限边界一开始就设计清楚。