👆 点击上方「迷斯特的小宇宙」,加「星标」不错过精彩内容
WebMCP Nexus 把“网页能力暴露给 Agent”这件事做成了前端工程流程:函数、类型、构建、运行时生命周期和本地 MCP 客户端连接,被放进同一条链路里。
最近看了 Alibaba 开源的 [WebMCP Nexus](https://github.com/alibaba/webmcp-nexus)。它的目标是让一个 React / TypeScript Web 应用,把自己的业务能力暴露成 MCP 客户端可调用的工具。
这件事听起来像“给网页加 API”,但从实现上看,它更像前端版本的 Agent 接入规范:业务函数仍然按原来的方式写,构建阶段从 TypeScript 类型和 JSDoc 里抽取契约,运行时再把这些函数注册到 navigator.modelContext,最后通过 local relay 让 Claude Desktop、Cursor、VS Code 这类本地 MCP 客户端调用浏览器里的能力。
一起来看下这个工具解决哪些工程问题。

图 1:WebMCP Nexus 官方 Demo 截图
Demo 里能看到右侧的 WebMCP 工具调试面板:页面当前暴露了全局工具和页面 / 组件级工具。这张图比纯概念图更能说明它的定位——让页面能力变成可发现、可调用、可调试的工具集合。
它解决什么问题
Web 应用过去对 AI Agent 并不友好。
人类能看懂按钮、表格、弹窗和路由状态,Agent 通常只能从 DOM、截图、无障碍树或脚本里猜页面意图。浏览器自动化能点按钮,但它不天然知道“搜索任务”“修改状态”“读取项目统计”这些业务动作的边界,也不知道哪些动作只读、哪些动作会产生副作用。
WebMCP 这类方向要解决的就是这层接口问题:网页不只呈现 UI,也主动暴露一组结构化能力。Agent 不再只能“看页面再点页面”,还可以发现页面声明的工具、读取参数 schema,然后按业务语义调用。
WebMCP Nexus 的切入点是前端工程化。它没有要求你为每个工具手写一份 schema,也没有要求把业务函数包进一层新的 defineTool。它把已有函数变成工具,大致依赖三件事:
TypeScript 函数签名提供参数结构;
JSDoc 提供工具描述和字段说明;
构建插件把这些信息转成 MCP 工具需要的 JSON Schema。
这样做的好处很明确:前端团队的事实源仍然是代码和类型,而不是另一份容易过期的配置文件。
功能拆解
WebMCP Nexus 仓库是一个 pnpm workspace,主要由四类模块组成。
| 模块 | 作用 |
|---|
webmcp-nexus-sdk | 运行时 SDK,提供 registerGlobalTools 和 useWebMcpTools |
webmcp-nexus-core | 构建时核心,负责 TypeScript 类型抽取和 JSON Schema 生成 |
vite-plugin-webmcp-nexus | Vite 插件,在构建阶段调用 core 做代码转换 |
webpack-plugin-webmcp-nexus | Webpack 插件,对 Webpack 项目做同样的转换 |
skill/SKILL.md | 给 Claude Code、Cursor 等 Coding Agent 使用的接入规则文档 |
它的 API 很少。README 里反复强调的也是这点:运行时只需要两个入口。
全局工具在应用启动时注册:
import { registerGlobalTools } from 'webmcp-nexus-sdk';
import * as queries from './tools/queries';
import * as navigation from './tools/navigation';
registerGlobalTools(queries, navigation);
页面或组件级工具在 React 生命周期里注册:
import { useWebMcpTools } from 'webmcp-nexus-sdk';
export default function TasksPage() {
const { createTask, updateTask, deleteTask } = useTodoStore();
useWebMcpTools({ createTask, updateTask, deleteTask });
return /* ... */;
}
这里最值得看的是作用域设计。
• 全局工具适合查询、统计、导航这类长期存在的能力;
• 路由工具适合某个页面独有的动作;
• 组件工具适合弹窗、面板、表单这类局部交互。
这个设计解决了一个真实问题:Agent 的工具列表不能无限膨胀,也不能在错误的页面调用错误的动作。组件卸载后相关工具应该消失,路由切换后旧页面的写操作也不应该继续暴露。
工作原理
先看整体链路。

图 2:WebMCP Nexus 工作方式
WebMCP Nexus 的核心链路可以分成四层:业务函数层、构建生成层、运行时注册层、连接调用层。
1. 业务函数层
开发者写的仍然是普通 TypeScript 函数。比较理想的函数形态是:单一对象参数、明确字段类型、函数和字段都有 JSDoc。
/**
* 根据关键词搜索任务。
* @readonly
*/
export async function searchTasks(params: {
/** 关键词,匹配标题与描述 */
query?: string;
/** 返回数量上限 */
limit?: number;
}) {
// 原来的业务逻辑
}
@readonly 也很关键。它不是给 TypeScript 用的,而是给宿主 Agent 判断调用风险用的。查询、搜索、列表这类工具可以标只读;新建、修改、删除这类工具不应该标只读。
这也是前端团队接入 Agent 工具时必须建立的习惯:工具不只是函数名和参数,工具还包含权限语义。
2. 构建生成层
构建插件做的事情在源码里比较清楚。
webmcp-nexus-core 的 transformCode 会先快速检查代码里是否出现 registerGlobalTools 或 useWebMcpTools。如果没有,就不处理这个文件。
如果有,它会调用 extractToolsFromFile,从注册调用位置向上追踪工具函数定义。它支持两类常见写法:
• { fn1, fn2 } 这种对象字面量注册;
• import * as api from './module' 这种 namespace import,再解析模块里的具名导出函数。
抽取完成后,schema-generator 会生成类似这样的注入代码:
searchTasks.__webmcpSchema = {
description: '根据关键词搜索任务。',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: '关键词,匹配标题与描述' },
limit: { type: 'number', description: '返回数量上限' }
}
},
readOnly: true
};
这段元数据会被插入到第一次注册调用之前。运行时 SDK 不再解析 TypeScript,它只读函数对象上的 __webmcpSchema。
这个分工合理:类型抽取放在构建阶段,运行时只做注册和调用,避免在浏览器里引入复杂的类型分析成本。
3. 运行时注册层
registerGlobalTools 和 useWebMcpTools 都会先确保 navigator.modelContext 可用。如果浏览器没有原生能力,就尝试加载 @mcp-b/webmcp-polyfill。
全局注册的流程很直白:遍历传入的工具 map,跳过非函数,跳过没有 __webmcpSchema 的函数,然后把工具注册到内部 registry 和 navigator.modelContext。
组件级注册复杂一些。useWebMcpTools 会:
• 用 useRef 保存最新函数,避免闭包里的旧实现被调用;
• 用工具名集合作为 useEffect 依赖,工具集合变化时重新注册;
• 在 Vite HMR 更新后触发 schema 重新注册;
• 在组件卸载时注销对应 scope 的工具。
这块实现说明作者确实考虑了前端运行时的实际形态。工具不是一份静态清单,而是随着路由、组件、HMR 和页面状态变化的。
4. 连接调用层
Web 应用注册工具后,本地 Agent 还需要一条路连到浏览器。
README 推荐使用 @mcp-b/webmcp-local-relay。它在本机以 stdio MCP server 的方式被 Claude Desktop、Cursor、VS Code 等客户端拉起,同时在本机开一个 WebSocket 端点。页面加载 relay 的 embed.js 后,会注入隐藏 iframe,把 navigator.modelContext 上的工具同步给本地 MCP 客户端。
MCP 客户端配置大概是这样:
{
"mcpServers": {
"webmcp-local-relay": {
"command": "npx",
"args": ["-y", "@mcp-b/webmcp-local-relay@latest"]
}
}
}
链路跑通后,Agent 可以看到页面暴露的工具。例如 demo 里有 listTasks、searchTasks、setTaskStatus 这类工具。用户对 Agent 说“把所有 todo 状态的任务按截止日期升序展示,然后把第一条标记为已完成”,Agent 可以按业务语义调用工具,而不是靠猜 UI 坐标。
一条函数的旅程
把上面的原理压缩成一条线,就是下面这张图。

图 3:一条函数如何变成工具
这里有两个实现选择很值得注意。
第一,schema 来自 TypeScript 类型,而不是手写配置。
这降低了双源维护成本。前端最怕的是函数参数已经改了,schema 还停在旧版本。WebMCP Nexus 把类型签名作为单一事实源,JSDoc 负责补充自然语言描述,两者一起生成工具契约。
第二,工具注册跟 React 生命周期绑定。
很多 MCP server 的工具列表是静态的。但浏览器页面不一样。页面有路由,有弹窗,有当前选中的任务,有某个组件是否挂载。一个“删除当前任务”的工具只有在任务详情页打开时才合理存在。WebMCP Nexus 把这个问题放进 useWebMcpTools,比只做全局工具更接近真实前端应用。
使用方法
如果你想在一个 Vite + React 项目里试一下,最小路径大概是四步。
1. 安装包
pnpm add webmcp-nexus-sdk
pnpm add -D vite-plugin-webmcp-nexus
Webpack 项目则把开发依赖换成:
pnpm add -D webpack-plugin-webmcp-nexus
2. 配构建插件
Vite 示例:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { vitePluginWebMcp } from 'vite-plugin-webmcp-nexus';
export default defineConfig({
plugins: [
react(),
vitePluginWebMcp({ include: ['src/**/*.ts', 'src/**/*.tsx'] }),
],
});
Webpack 示例:
// webpack.config.ts
import { WebMcpPlugin } from 'webpack-plugin-webmcp-nexus';
import type { Configuration } from 'webpack';
const config: Configuration = {
// ...常规配置
plugins: [new WebMcpPlugin({ include: ['src'] })],
};
export default config;
3. 写工具函数
工具函数建议遵守几个约束:
• 参数使用单一对象,不要用多个位置参数;
• 参数字段尽量用明确类型,不要用 any / unknown;
• 查询类工具加 @readonly;
• 字段说明写在 JSDoc 里,方便生成更可读的 schema;
• 泛型、条件类型、复杂映射类型先别放进工具边界。
示例:
/**
* 按条件搜索任务。
* @readonly
*/
export async function searchTasks(params: {
/** 关键词,匹配标题与描述 */
query?: string;
/** 状态过滤 */
status?: 'todo' | 'in_progress' | 'done';
/** 返回数量上限 */
limit?: number;
}) {
return taskStore.search(params);
}
4. 注册工具
全局工具放入口文件:
import { registerGlobalTools } from 'webmcp-nexus-sdk';
import * as taskQueries from './tools/taskQueries';
registerGlobalTools(taskQueries);
页面/组件工具放在对应组件里:
import { useWebMcpTools } from 'webmcp-nexus-sdk';
function TaskDetailPanel({ taskId }: { taskId: string }) {
const updateTitle = async (params: { title: string }) => {
return taskStore.updateTitle(taskId, params.title);
};
useWebMcpTools({ updateTitle });
return /* ... */;
}
最后配置本地 MCP 客户端的 relay,启动 Web 应用,Agent 就能发现浏览器页面里的工具。
创新在哪里

图 4:WebMCP Nexus 的创新点
我觉得 WebMCP Nexus 的创新点不在“注册工具”本身。注册工具这件事并不新,MCP server、浏览器自动化、页面脚本都能做一部分。
它更有价值的地方在四个工程选择。
类型是事实源
前端项目的契约本来就在 TypeScript 类型里。让开发者再写一遍 JSON Schema,会引入重复劳动,也会引入漂移风险。
WebMCP Nexus 用 ts-morph 从函数签名和 JSDoc 里反推 schema,这个方向对前端团队很自然。业务代码怎么演进,工具契约就跟着构建流程更新。
函数不被框架绑架
很多工具框架要求你用自己的 API 包一层:defineTool(...)、createAction(...)、z.object(...)。这在新项目里可以接受,但在已有业务里改造成本不低。
WebMCP Nexus 的设计是“函数保持原样,注册点负责发现”。这对存量前端应用更友好。业务函数不需要因为给 Agent 用就改掉调用方式,原有 UI、store、service 仍然可以照常使用。
生命周期进入工具系统
前端能力不是静态 API。一个组件存在时暴露某个能力,组件消失时能力就应该消失。这个约束如果交给开发者手写,很容易出现幽灵工具:页面已经离开,Agent 还能看到旧工具。
useWebMcpTools 把注册和卸载绑到 React 生命周期,是这套方案里很前端的一点。
Skill 把接入交给 Coding Agent
仓库里的 skill/SKILL.md 不是装饰。它把“如何把现有函数改造成 WebMCP 工具”写成了 Coding Agent 可以执行的规范:哪些是 MUST,哪些是 SHOULD,哪些只是风格建议。
这件事很现实。WebMCP 这种接入工作,最耗时的不是写 SDK 调用,而是把一堆已有业务函数改成可抽取、可描述、可安全调用的形态。Skill 文档等于把这套改造规则交给 Claude Code、Cursor 或其他 Agent,让它们按约束做机械改造。
这会让 WebMCP Nexus 的采用路径更短:团队先把工具函数规范写成 Skill,再让 Coding Agent 帮忙改造存量函数。
边界和风险
WebMCP Nexus 还处在早期阶段,README 也标了 early access。学习它时不能只看“几分钟接入”的部分,还要看边界。
第一,TypeScript 类型支持不是完整编译器语义。
基础类型、字面量联合、可选字段、三层以内嵌套对象都比较稳。但泛型、映射类型、条件类型、很深的嵌套对象、复杂对象数组,都不适合直接放进工具参数。工具边界应该显式、扁平、可描述,不要把内部类型系统的复杂性暴露给 Agent。
第二,本地 relay 改变了信任边界。
一旦浏览器里的工具能被本地 MCP 客户端调用,写操作就必须更谨慎。deleteTask、updateUser、submitOrder 这类工具不能只靠函数名区分风险。前端仍然要走权限、确认、审计和服务端校验,不能因为调用方变成 Agent 就绕过业务安全。
第三,SDK 的容错策略偏保守。
源码里很多浏览器 API 异常会被 catch 掉,避免影响页面运行。这对用户体验是好事,但对工程排障意味着你需要调试面板、日志或测试来确认工具是否真的注册成功。demo 里的右侧调试面板就很有必要。
第四,WebMCP 标准本身还在演进。
这类工具的长期价值取决于浏览器原生能力、polyfill、local relay 和 MCP 客户端支持的共同成熟。现在适合做内部工具、工程验证和可控场景接入,不适合直接假设它已经成为所有 Web 应用的默认能力层。
适合谁用
我会把 WebMCP Nexus 放在三个场景里看。
第一,后台管理系统和业务工作台。
这类系统本来就有大量结构化动作:搜索、筛选、改状态、生成报表、创建工单。Agent 如果只靠 UI 自动化,效率和稳定性都一般。把这些动作暴露成工具,收益比较直接。
第二,内部研发平台。
比如发布平台、监控面板、测试平台、数据看板。这里的用户多是工程师,能接受早期技术栈,也更需要 Agent 代办重复操作。
第三,复杂前端应用的 Agent 化改造。
如果一个应用已经有清晰的 service/store/action 层,WebMCP Nexus 可以把这些能力逐步暴露出去。先做只读查询,再做低风险写操作,最后才考虑高风险动作。
我不建议一上来把所有函数都注册成工具。更稳的路线是:
先暴露只读工具,例如 search、list、get、stats;
再暴露可撤销或低风险写操作,例如 update filter、set draft;
最后处理高风险操作,并配合确认弹窗、权限检查和审计日志。
WebMCP Nexus 的价值,是把浏览器里的业务动作从“只能被人点”变成“可以被 Agent 按契约调用”。这件事如果继续成熟,前端应用会从界面层,慢慢长出一层 Agent 可操作的能力层。
迷斯特的小宇宙,客户端技术背景,大前端技术、AI前沿技术分享,偶尔写写生活日记。
如果这篇文章对你有启发,点个「在看」或转发给朋友,是对我最大的支持 🙏