1. WebMCP 到底是什么,为什么 AI Agent 终于不用再“猜网页”了
WebMCP(Web 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 的关系需要说清楚,很多人会混淆。MCP(Model 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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_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_KEY="sk-你的key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"如果你用 Python,可以这样初始化客户端:
import os from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.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 lang="zh-CN"> <head> <meta charset="UTF-8"> <title>WebMCP 声明式示例</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 Schema,required 数组声明必填字段。
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-confirm="true",浏览器会弹窗让用户确认,中间层要处理这个异步流程,不能直接假设调用成功。
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-confirm="true",让浏览器弹窗拦截。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 名称,不要死磕旧代码。规范还在演进,保持关注比一次写对更重要。