
1. WebMCP 到底是什么为什么 AI Agent 终于不用再“猜网页”了WebMCPWeb Model Context Protocol是一套正在 W3C 孵化的浏览器原生 API 标准由 Google 和 Microsoft 联合推动目标是让网页主动把自身功能以结构化工具Tools的形式暴露给 AI Agent 调用。简单说它把每个网页从“一堆需要被解析的 HTML”变成“一个可以被直接调用的工具箱”。适合谁前端开发者、做 Agent 应用的工程师、以及被 DOM 抓取折磨过的自动化测试同学。过去让 Agent 操作网页主流两条路一是 DOM 抓取靠选择器定位按钮和输入框二是视觉模型截图后让多模态模型“看着点”。前者极其脆弱网站改个 class 名整条链路就崩后者 token 消耗巨大一个复杂电商流程动辄烧掉几万 token还经常点错位置。我试过用纯 DOM 方案跑一个“搜索机票并填表”的任务成功率大概七成剩下三成失败基本都栽在动态渲染和 iframe 上。WebMCP 的思路完全不同不要让 AI 像盲人摸象一样解析 HTML而是让网站开发者主动声明“我这里有个搜索工具参数是出发地、目的地、日期”。Agent 拿到的是 JSON Schema 描述的结构化契约调用时传结构化参数网页内部 JS 函数直接执行。交互从“视觉猜测”回归到“结构化契约”这才是准确率能从 70% 跳到 98% 的根本原因。它和 MCP 的关系需要说清楚很多人会混淆。MCPModel Context Protocol由 Anthropic 推出主要跑在后端连接 AI 模型与数据库、本地文件、服务器端工具。WebMCP 侧重前端是浏览器原生 API连接 Agent 与网页内的 JavaScript 逻辑。两者互为补充MCP 管后端资源WebMCP 管浏览器里的网页能力共同构成 AI 工具集成的全栈协议。你可以理解为 MCP 是“服务器侧的工具总线”WebMCP 是“浏览器侧的工具总线”。核心架构是三位一体。网页负责通过新 API 注册工具比如“搜索机票”“添加到购物车”浏览器作为信任层Mediator管理权限、显示用户确认弹窗、转发请求AI Agent 发现网页上的可用工具发送结构化 JSON 参数进行调用。整个链路里浏览器是中间人任何敏感操作都要经过它这也是安全性的根基。目前 WebMCP 已在 Chrome 146 Canary 版本作为早期预览开放规范仍在草案阶段。但 Google 和 Microsoft 联手意味着它很可能成为未来 Web 的基石标准。下面我会给出可复制的接入配置片段和本地验证步骤帮你在浏览器侧跑通一次 Agent 原生交互。2. 接入前的准备TaoToken 作为模型侧入口的配置WebMCP 解决的是“浏览器侧工具暴露”但 Agent 本身需要一个能调用工具的模型。这里我用 TaoToken 作为模型侧的统一入口它兼容 OpenAI 风格的接口配置简单适合在本地验证阶段快速跑通。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。先说清楚为什么需要这一步。WebMCP 的验证链路是Agent模型→ 浏览器中介 → 网页工具。模型需要能理解工具列表并生成结构化调用参数这要求模型支持 function calling / tool use。TaoToken 的接口兼容这套协议你可以在本地用 curl 或 SDK 直接调。第一步拿到 API Key。访问 https://taotoken.net/api-keys 登录后创建一个新的 Key复制保存。注意 Key 只在创建时显示一次丢了就重新建。这一步不要截图发群里Key 泄露等于账号被白嫖。第二步确认你要用的模型 ID。不同模型对 tool use 的支持程度不一样验证 WebMCP 建议选支持 function calling 的模型。你可以在模型对话页面 https://taotoken.net/models 先试一下模型是否能正常返回工具调用格式。如果只是纯文本对话那跑 WebMCP 会卡在参数生成环节。第三步配置本地环境变量。我习惯用环境变量管理 Key避免硬编码进代码export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用 Python可以这样初始化客户端import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL] ) resp client.chat.completions.create( model你的模型ID, messages[{role: user, content: 你好}] ) print(resp.choices[0].message.content)跑通这一步说明模型侧入口没问题。接下来才是 WebMCP 的浏览器侧配置。很多人卡在“模型能对话但不会调工具”原因通常是模型 ID 选错或请求里没带 tools 参数。验证时务必在请求体里加上 tools 字段否则模型不知道有工具可用。如果你要做长期编码或 Agent 开发可以考虑 Coding Plan它在调用额度和并发上更适合持续跑任务入口在 https://taotoken.net/coding-plan 。本地验证阶段用按量计费就够了别一上来就上套餐。3. 可复制的 WebMCP 接入配置片段这一节给出两种接入方式的完整配置声明式 API 和命令式 API。你可以直接复制到本地 HTML 文件里跑。3.1 声明式 API零代码让表单变成 Agent 工具声明式 API 针对标准 HTML 表单你只需要在标签上加几个特殊属性浏览器就会自动把它转成 AI 可调用的工具。适合现有表单快速接入不用写 JS。!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleWebMCP 声明式示例/title /head body h1机票搜索/h1 form >// 检查浏览器是否支持 WebMCP if (modelContext in navigator) { navigator.modelContext.registerTool({ name: calculate_mortgage, description: 根据贷款总额、年利率和年限计算房贷月供, inputSchema: { type: object, properties: { principal: { type: number, description: 贷款总额单位元 }, annualRate: { type: number, description: 年利率如 0.049 }, years: { type: number, description: 贷款年限 } }, required: [principal, annualRate, years] }, execute: async (params) { const { principal, annualRate, years } params; const monthlyRate annualRate / 12; const months years * 12; const monthlyPayment (principal * monthlyRate * Math.pow(1 monthlyRate, months)) / (Math.pow(1 monthlyRate, months) - 1); return { monthlyPayment: Math.round(monthlyPayment * 100) / 100 }; } }); } else { console.warn(当前浏览器不支持 WebMCP请使用 Chrome 146 Canary 及以上版本); }这段代码注册了一个calculate_mortgage工具Agent 调用时传principal、annualRate、years三个参数execute 函数返回月供。注意 inputSchema 用的是标准 JSON Schemarequired 数组声明必填字段。3.3 与模型侧对接的完整配置浏览器侧注册好工具后Agent 需要拿到工具列表并生成调用。下面是一个 Node.js 侧的配置片段把 WebMCP 工具列表转成 OpenAI 兼容的 tools 格式// webmcp-bridge.js const tools [ { type: function, function: { name: calculate_mortgage, description: 根据贷款总额、年利率和年限计算房贷月供, parameters: { type: object, properties: { principal: { type: number, description: 贷款总额单位元 }, annualRate: { type: number, description: 年利率如 0.049 }, years: { type: number, description: 贷款年限 } }, required: [principal, annualRate, years] } } } ]; async function callModel(userMessage) { const resp await fetch(https://taotoken.net/api/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${process.env.TAOTOKEN_API_KEY} }, body: JSON.stringify({ model: 你的模型ID, messages: [{ role: user, content: userMessage }], tools: tools, tool_choice: auto }) }); return resp.json(); }这段配置的关键是tools数组和tool_choice: auto。模型收到后会判断是否需要调用工具需要就返回 tool_calls 字段里面是工具名和参数。你拿到参数后转发给浏览器侧的 execute 函数即可。4. 本地验证跑通一次 Agent 原生交互配置写完了现在验证。我按步骤拆开你跟着做。4.1 启动本地服务把上面的 HTML 文件保存为webmcp-demo.html用本地服务器打开直接 file:// 协议部分 API 不可用python3 -m http.server 8080然后浏览器访问http://localhost:8080/webmcp-demo.html。注意必须用 Chrome 146 Canary 或更高版本稳定版还没开放这个 API。4.2 检查工具是否注册成功打开 DevTools Console输入navigator.modelContext.getTools().then(console.log)如果返回数组里有你注册的工具说明浏览器侧 OK。如果返回 undefined 或报错检查浏览器版本和 API 名称早期预览版可能用navigator.modelContext之外的名字。4.3 发起一次模型调用用 curl 测试模型侧是否能正确生成工具调用curl -X POST https://taotoken.net/api/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: 你的模型ID, messages: [{role: user, content: 帮我算一下贷款100万年利率4.9%30年的月供}], tools: [{ type: function, function: { name: calculate_mortgage, description: 根据贷款总额、年利率和年限计算房贷月供, parameters: { type: object, properties: { principal: {type: number}, annualRate: {type: number}, years: {type: number} }, required: [principal, annualRate, years] } } }], tool_choice: auto }预期返回里应该有tool_calls字段参数大致是{principal: 1000000, annualRate: 0.049, years: 30}。如果模型直接返回文本而没有 tool_calls说明模型不支持或 tools 格式不对。4.4 把参数转发给浏览器执行拿到 tool_calls 后在浏览器 Console 里手动执行验证navigator.modelContext.callTool(calculate_mortgage, { principal: 1000000, annualRate: 0.049, years: 30 }).then(console.log)预期输出{ monthlyPayment: 5307.27 }左右。这个数字你可以用房贷计算器核对。跑通这一步整条链路就通了模型生成参数 → 浏览器中介 → 网页 JS 执行 → 返回结果。4.5 完整链路串起来实际生产里你需要一个中间层把模型返回的 tool_calls 转发给浏览器。可以用 WebSocket 或 postMessage 实现。核心逻辑是模型返回 tool_calls → 中间层解析出工具名和参数 → 通过 postMessage 发给网页 → 网页调用 navigator.modelContext.callTool → 结果回传 → 再发给模型生成最终回复。这个中间层不复杂但要注意权限确认。如果工具注册时带了data-webmcp-confirmtrue浏览器会弹窗让用户确认中间层要处理这个异步流程不能直接假设调用成功。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节列真实会遇到的报错和排查路径。401 Unauthorized最常见。检查TAOTOKEN_API_KEY环境变量是否设置正确Key 有没有多余空格。用echo $TAOTOKEN_API_KEY确认。如果 Key 刚创建等几秒再试有时有同步延迟。另外确认请求头是Authorization: Bearer sk-xxx不是Bearer: sk-xxx。local proxy failed这个报错通常出现在本地开发环境配了代理但代理没启动。检查你的 HTTP_PROXY / HTTPS_PROXY 环境变量如果不需要代理就 unset 掉。注意这里说的是本地开发工具的代理配置不是网络层面的东西排查时看你的 shell 配置和 IDE 设置。reading choices这个报错说明你拿到的响应体里没有 choices 字段通常是 API 返回了错误但代码没检查状态码。修复方式是先判断resp.status非 200 就打印完整响应体const resp await fetch(url, options); if (!resp.ok) { const err await resp.text(); console.error(API 错误:, resp.status, err); return; } const data await resp.json(); console.log(data.choices[0].message);OAuth 相关报错如果你用 Claude Code 或类似工具接入可能会遇到 OAuth token 过期。这类工具通常有自己的认证流程检查配置文件里的 token 是否有效。如果是 Codex 的 auth.json确认文件路径和格式正确Base URL 指向 https://taotoken.net/api Key 和 Model ID 三件套齐全。工具调用返回空参数模型返回了 tool_calls 但 arguments 是空字符串。这通常是模型不支持 function calling 或 prompt 里没给足够上下文。换一个支持 tool use 的模型 ID或者在 system message 里明确说明“你可以调用以下工具”。浏览器报 modelContext is undefined浏览器版本不够。WebMCP 目前在 Chrome 146 Canary 预览稳定版没有。检查chrome://version如果是稳定版就下载 Canary。另外确认页面是通过 http://localhost 或 https 打开的file:// 协议下部分 API 不可用。CORS 报错本地 HTML 直接调 https://taotoken.net/api 会跨域。开发阶段用本地服务器代理或者在后端转发请求。生产环境应该由你的后端调模型 API前端只负责 WebMCP 工具注册和调用。排查顺序建议先确认模型侧能通curl 测试再确认浏览器侧工具注册成功Console 检查最后串链路。哪一步断了就修哪一步不要跳步。6. 从验证到落地把 WebMCP 接进你的 Agent 工作流跑通本地验证后下一步是把它接进真实工作流。这里给几个实用建议。第一工具描述要写清楚。模型能不能正确选工具很大程度取决于 description 的质量。不要写“搜索功能”要写“根据出发地、目的地和日期搜索可用航班返回航班列表”。参数描述也要具体比如“日期格式 YYYY-MM-DD”。第二敏感操作必须加确认。付款、删除、提交订单这类工具注册时带上data-webmcp-confirmtrue让浏览器弹窗拦截。Human-in-the-loop 是 WebMCP 安全模型的核心不要为了自动化绕过它。第三工具粒度要合理。不要把整个页面做成一个大工具也不要每个按钮都注册成工具。按业务动作划分比如“搜索”“加入购物车”“结算”三个工具而不是“点击搜索按钮”“点击加购按钮”。第四做好降级。WebMCP 还在草案阶段不是所有浏览器都支持。你的代码要检测navigator.modelContext是否存在不存在就回退到传统方案或提示用户升级浏览器。第五模型侧选对工具。长期跑 Agent 任务建议用 Coding Plan额度和并发更稳入口在 https://taotoken.net/coding-plan 。验证阶段用按量计费即可。模型对话调试在 https://taotoken.net/models 接入文档在 https://taotoken.net/doc API Key 管理在 https://taotoken.net/api-keys 。最后说一个我踩过的坑早期预览版 API 名称可能变navigator.modelContext在不同 Canary 版本里有过调整。如果你的代码突然报 undefined先去官方文档确认当前版本的 API 名称不要死磕旧代码。规范还在演进保持关注比一次写对更重要。