技术原理核心
WebMCP协议的技术架构、核心组件与设计哲学
协议定位:从MCP到WebMCP
Anthropic MCP回顾
Model Context Protocol(MCP)由Anthropic于2024年11月推出,是一种基于JSON-RPC的协议标准,用于连接AI模型与外部工具和数据源。MCP采用服务器中心架构:
┌─────────────┐ JSON-RPC ┌─────────────┐
│ AI Client │ ◄────────────► │ MCP Server │
│ (Claude) │ stdio/HTTP │ (Backend) │
└─────────────┘ └─────────────┘
MCP服务器作为独立进程或托管服务运行,AI客户端通过stdio、HTTP with SSE等传输协议连接。这种架构适合后端集成场景——连接文件系统、数据库、API和企业服务。
WebMCP的架构创新
WebMCP的核心洞察是:网页本身就是一个活的、已认证的、有状态的运行时。用户在场、会话活跃、JavaScript已拥有应用暴露的所有能力。与其通过独立服务器路由,不如让页面直接向浏览器声明自己的工具。
graph TB
subgraph Browser
A[Web Page / Tab] --> B[navigator.modelContext]
B --> C[Tool Registry]
end
subgraph Agent
D[AI Agent] --> E[Tool Discovery]
E --> F[Tool Invocation]
end
F --> B
C --> G[Execute in Page Context]
G --> H[Return Structured Result]
H --> D
WebMCP使网页成为MCP服务器的客户端侧实现——工具在客户端脚本中执行而非后端。
核心API表面
navigator.modelContext接口
WebMCP扩展浏览器的Navigator接口,新增只读属性:
navigator.modelContext // ModelContext对象
访问限制:仅在安全上下文(HTTPS)中可用。
ModelContext接口方法
| 方法 | 描述 |
|---|---|
provideContext(options) | 原子性地注册一组工具,替换之前所有注册 |
clearContext() | 清除当前页面所有已注册工具 |
registerTool(tool) | 添加单个工具,不清除已有注册 |
unregisterTool(name) | 按名称移除特定工具 |
工具定义结构(ModelContextTool)
{
name: "searchProducts", // 必需,唯一标识符
description: "搜索产品目录...", // 自然语言描述
inputSchema: { // JSON Schema,可选
type: "object",
properties: {
query: { type: "string" },
category: { type: "string" },
maxPrice: { type: "number" }
},
required: ["query"]
},
execute: async (inputs, client) => { // 必需,执行回调
// 工具在页面JS上下文中执行,拥有完整会话访问权限
const results = await searchCatalog(inputs);
return { content: [{ type: "text", text: JSON.stringify(results) }] };
},
annotations: {
readOnlyHint: true // 建议:此工具不修改状态
}
}
人机交互确认机制
execute回调接收ModelContextClient对象作为第二个参数,提供requestUserInteraction(callback)方法:
execute: async (inputs, client) => {
await client.requestUserInteraction(async () => {
// 用户确认后执行此回调
await processCheckout(inputs.cartId);
});
return { content: [{ type: "text", text: "结账完成" }] };
}
这是敏感操作的主要人机确认关口。
两种集成路径
声明式API(Declarative API)
无需JavaScript,通过HTML属性注解现有表单:
<form
id="support-ticket-form"
toolname="createSupportTicket"
tooldescription="提交新的客户支持工单"
toolautosubmit="true"
>
<input
type="text"
name="issueTitle"
required
toolparamtitle="问题标题"
toolparamdescription="问题简要描述"
/>
<textarea
name="description"
toolparamtitle="详细描述"
toolparamdescription="问题的详细描述"
></textarea>
<select name="severity">
<option value="low">低</option>
<option value="high">高</option>
<option value="critical">紧急</option>
</select>
</form>
关键属性:
toolname(必需):工具标识符tooldescription(必需):工具功能描述toolautosubmit(可选):代理填充后自动提交toolparamtitle/toolparamdescription:字段注解
SubmitEvent.agentInvoked布尔标志区分人工提交和代理提交,便于服务端差异化处理。
命令式API(Imperative API)
适用于非表单操作、多步骤工作流、动态工具注册:
navigator.modelContext.registerTool({
name: "filterProducts",
description: "按品牌、评分和库存筛选产品",
inputSchema: {
type: "object",
properties: {
brands: { type: "array", items: { type: "string" } },
minRating: { type: "number", minimum: 0, maximum: 5 },
inStockOnly: { type: "boolean" }
}
},
execute: async ({ brands, minRating, inStockOnly }, client) => {
await applyProductFilters({ brands, minRating, inStockOnly });
const count = document.querySelectorAll('.product-card').length;
return {
content: [{
type: "text",
text: `筛选完成,共${count}个匹配产品`
}]
};
}
});
两种API的选择策略
| 场景 | 推荐方案 |
|---|---|
| 现有HTML表单,输入定义清晰 | 声明式 |
| 表单提交触发服务端操作 | 声明式 + toolautosubmit |
| 非表单操作(登出、导航、自定义触发) | 命令式 |
| 多步骤工作流,有中间状态 | 命令式 |
| 基于应用状态动态注册工具 | 命令式 |
| 最大兼容性,最小JS开销 | 声明式 |
设计哲学
为什么是浏览器原生而非后端代理
-
会话继承:工具在已认证的浏览器会话中执行,无需单独的凭证管理。
-
零部署成本:无需维护独立的MCP服务器,无需后端API包装层。
-
实时状态:页面本身就是有状态的运行时,工具可以访问最新的应用状态。
-
安全边界清晰:浏览器执行同源策略、权限策略,提供原生安全隔离。
与后端MCP的互补关系
WebMCP并非替代后端MCP,而是解决不同层面的问题:
| 协议 | 层面 | 适用场景 |
|---|---|---|
| MCP | 后端工具集成 | 直接API调用、企业服务集成、无用户在场场景 |
| WebMCP | 客户端浏览器工具暴露 | 浏览器代理交互、继承用户会话、前端业务逻辑 |
一个复杂的代理任务可能同时使用两种协议:通过MCP连接数据库,通过WebMCP操作第三方Web界面。