关于 webmcp
webmcp 是一项 Agent 技能,通过宿主内置浏览器和网页工具在 Web 应用中执行请求。它要求优先调用应用的 WebMCP 工具,而非使用界面自动化。
主要功能
- 01在内置浏览器中打开应用
- 02解析 URL 和应用别名
- 03发现并调用网页工具
- 04回读更改以确认结果
适用场景
- 01在 Web 应用中创建或编辑内容
- 02修改选中的单个项目
- 03确认网页工具更改已生效
MCP 相关
它指导 Agent 通过宿主桥接或 document.modelContext 调用当前页面的 WebMCP 工具,并禁止用界面自动化替代工具操作。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ builderio/ skills --skill webmcp安装后在 Claude Code 中输入/webmcp确认已加载。
附带文件agents/openai.yamlREADME.md
详细介绍
WebMCP
/webmcp <url-or-app> [request] 会在宿主内置的
浏览器中打开 Web 应用,并通过页面自身的工具完成请求。第一个
参数是 URL 或应用别名;其余部分是请求。
/webmcp slides make me a new deck about customer onboarding
两条规则
- 在宿主内置的浏览器中打开——绝不使用外部 Chrome 窗口、 普通标签页或浏览器扩展。
- 调用页面的工具。 对于工具能够完成的操作,绝不点击、输入、 拖动、截图或使用 DOM 自动化。UI 控件仅用于导航和目视检查。
这就是全部约定。以下内容要么是标准页面 API, 要么是针对某个违反上述规则的特定宿主提供的变通方法。如果你的宿主原生支持 WebMCP, 遵守这两条规则,让它自行处理即可。
快速路径
/webmcp <url-or-app>不带请求时仅打开页面:在可见的内置标签页中打开解析后的 URL,确认页面已打开,然后停止。在用户 提供操作之前,不要列出工具、检查架构、登录或开始应用操作。/webmcp <url-or-app> <request>是操作路径:打开页面,然后 直接使用工具。绝不要根据页面内容或先前对话推断额外工作。
如果用户提供了请求,页面打开后要继续操作。一项编辑大约需要三次页面调用: 读取屏幕、执行修改、回读结果。如果已经进行到第六次评估,却还没有写入任何内容, 那你是在探索,而不是执行。
打开页面
- 接受完整 URL 或主机名;如果缺少协议,则添加
https://, 并保留主机、路径、查询参数和哈希。绝不要自行在 beta 和 production 之间切换。 - Claude Code 和 Cowork:执行
preview_start { url },然后执行tabs_select将标签页置于前台。Codex:执行cua.createBrowserTab("iab", url, { visible: true }),然后执行tab.markDeliverable()。 - 工具注册期间保持窗格可见。隐藏的窗格会限制工具注册和页面内计时器:实测中,一个应用在置于前台时立即注册了全部 217 个工具,而隐藏 28 秒后只注册了 59 个。
登录
开始工具操作前,读取页面标题和首几行内容。标题以
"— Sign in" 结尾、出现 "Sign in with Google" 按钮,或显示 "You don't have access",都意味着页面尚无工具。保持标签页原样,并说:
Please sign in in the open browser, then reply "continue". 绝不要输入、复制、检查或索要密码、Cookie、令牌或验证码。登录后,应用可能会重定向并丢失深层链接状态(例如 ?slide=3);请重新读取屏幕,不要假设原目标仍显示在屏幕上。
调用页面工具
如果宿主有自己的 WebMCP 桥接,请使用它,并跳过此处的其他内容
(list-browser-session-webmcp-tools 配合 run-browser-session-webmcp-tool,或
list-host-webmcp-tools 配合 run-host-webmcp-tool):调用一次列表工具,
然后使用准确发现的名称、来源和参数调用运行工具。不要用通用的 tool-search、
其他应用的连接器、ask_app 或远程 API 替代当前标签页的页面工具。
否则,请在页面中执行求值。document.modelContext 是规范的页面 API,
适用于任何 WebMCP 网站;navigator.modelContext 已弃用。
const ctx = document.modelContext;
const tool = (await ctx.getTools()).find((t) => t.name === NAME);
const codex =
typeof ctx.codexExecuteTool === "function" ||
typeof ctx.codexGetTools === "function";
const raw = await ctx.executeTool(tool, codex ? ARGS : JSON.stringify(ARGS));
描述符不能在页面外调用;绝不要将其复制出来再由宿主调用、手工构造经过身份验证的 HTTP 请求,或在开发者控制台中输入内容。
按宿主划分的评估器
- Claude Code 和 Cowork:
javascript_tool在页面世界中运行,并支持顶层await。返回一个 JSON 字符串,并将其截取到约 8 KB;每次调用的工具时限接近 45 秒。每次评估批量执行两到四次有依赖关系的调用;不要在批次中进行导航。 - Codex: 每个会话先尝试一次
tab.capabilities.get("webmcp").fetchTools()。截至 2026-09,当前模型会返回does not support command "webmcp_list_tools"——这意味着本会话剩余时间内桥接不可用,而不是页面没有工具。然后使用 CDP:globalThis.__cdp ??= await tab.capabilities.get("cdp"),接着调用一次await globalThis.__cdp.documentation()(首次 CDP 调用若没有先调用它就会失败),然后调用cdp.send("Runtime.evaluate", { expression, awaitPromise: true, returnByValue: true }),并通过nodeRepl.write(...)输出response.result.value。每次评估只进行一次调用。Playwright 的隔离世界无法访问document.modelContext;请使用 CDP。 - 任何评估器输出都可能在开头附带无障碍树或其他观察结果。解析末尾明确返回的值;树只是上下文,不是工具结果。
值得了解的宿主问题
每个问题都曾导致一次真实的调试过程。它们都不是页面或应用故障——不要将其诊断为页面或应用故障。
- Codex CDP 会在约 3 秒后失效(“Timed out running CDP command”)。超时的评估器调用意味着结果未读到,并不代表写入失败:不要重新发起写入,下一次评估时读取结果。
- 尽管文档称
cua_repl内核会在调用间保持持久,Codex 仍会回收它,而且let/const句柄不会保留。实测于 2026-09-08:页面调用全部成功,之后内核重置,导致cdp is not defined、tab is not defined、Browser is not available: 2,而cua.getState()花了 5.4-6.6 秒才返回“Sky Computer Use native pipe startup failed”。请将句柄保存在globalThis上,并在每次评估开头重新解析;出现cdp is not defined或tab is not defined时,重新打开标签页并再次运行documentation()。不要尝试通过cua.getState()恢复——失败的正是这个调用。 - 仅限 Codex,且与上述重置问题不同:浏览器本身也可能失效。
Browser is not available: <name>或No browser is available表示应用内浏览器进程已退出,而不是你的句柄失效;没有任何调用可以让它恢复。实测于 2026-09-09(01a0869c):尽管应用中标签页看起来仍处于打开状态,cua.getTab、cua.createBrowserTab和cua.getBrowser({ url })均连续失败了 17 分钟——标签页可见并不能证明桥接仍在运行。第二次失败后就停止。告知用户需要重新打开应用内浏览器;或者,对于任何依赖服务端的操作,改用应用自身的 MCP 服务。这里代价高昂的错误是反复重试,而不是选错恢复调用。 - Claude Code 的
preview_start和navigate几乎每次在全新加载时都会报告“denied or failed”,即使页面已经加载。 请检查tabs_context或get_page_text,不要重试导航。
执行请求
- 对依赖状态的工作,读取一次屏幕,确认当前对象、其 ID 和所选内容。如果请求中已包含 ID,则跳过。
- 按名称选择工具。页面的工具列表和应用自身的 MCP
instructions就是索引——应先阅读,而不是猜测。如果屏幕读取结果已指出工具及其参数,直接调用即可;列出和描述工具是为了应对不熟悉的应用和未确定的参数,不是每次编辑前都要走的仪式。 - 使用准确的 ID,只调用一次最小化变更工具。对于文本,使用准确的所选内容进行一次字面替换;如果架构提供
expectedMatches: 1,则使用它。不要改动无关内容。 - 读回已更改的项目;或者,如果变更工具返回的哈希或 ID 中回显了新内容,则信任该结果;然后才能报告成功。写入后页面会自行重绘;如果读回已确认结果,就不要重新加载、截图或等待确认。
如果结果包含 nextRequiredAction,它会指出下一个工具;请按其指示操作。
你就是整个请求的模型。“生成演示文稿”“设计待办应用”“编写落地页”“起草表单”意味着由你创作内容,并通过应用自身的创建和更新工具保存。绝不要把创作交给应用内置 Agent;绝不要调用描述中要求暂停并等待用户在应用中回答的工具(那些回答应发送到应用内聊天,而不是发送给你);如果有具名工具能完成工作,就绝不要调用通用的 ask_app。如果确实存在未定的决策,请在你自己的聊天中询问,并说明默认方案后继续。
将“这个”“所选文本”、光标位置或单个具名字段视为聚焦编辑:读取一次屏幕、执行一次变更、进行一次针对性的读回。范围由文字决定,而非所选内容:“这段文本”指所选内容,而“这张幻灯片”“这个屏幕”或“这一节”指整个当前项目,即使恰好存在文本选区也是如此。
对于样式更改(深色模式、新调色板、“与其他项匹配”),你编辑的项目只是多个同类项目之一,而用户期望它与同类项保持一致。先读取共享样式并复用其取值;像调整相邻源文件的结构样式前会先查看一个真实的同类项一样,也要读取一个真实的同类项——颜色统计可以确定颜色和字体,但无法确定间距或元素顺序。只有在用户提出要求时,才引入文档中尚未使用的颜色或字体。
错误
- 仍在注册:在页面外稍等片刻后再调用。
- 页面显示就绪,但找不到工具:说明该工具确实不在此页面上。报告缺失前,先检查工具列表中是否有负责该操作的组合工具。
- 验证或契约消息会指出字段或取值;修正参数后重试一次。
Internal server error是服务器故障,不是参数问题。最多重试一次,然后报告工具、参数和任何请求 ID,并说明写入未成功。绝不要把失败的写入报告为已完成,也绝不要因为工具失败而改用 UI 自动化。- Pending:在下一次评估时读取结果。不要再次发送写入请求。
MCP 不可用
如果经过一轮发现和一次独立的评估器确认后,仍没有主机桥接或页面 API,则在执行任何会更改状态的 UI 操作前停止。说明页面是否声明支持 WebMCP,以及缺少哪项主机能力。绝不要从 /webmcp 回退到点击、输入、拖动或键盘自动化;只有用户明确要求针对这项操作使用 UI 自动化时,才可例外。工具列表调用失败、工具确认收到请求或任务已排队,都不能证明编辑已完成。
Agent-Native 专属补充
以上内容均为通用说明。本节是为 Agent-Native 应用提供的便捷功能,不适用于其他网站。
别名。 处理 URL 之前,会先通过此列表解析第一个独立词;显式 URL 和主机名保持不变。calendar、content、plan、slides、clips、brain、analytics、mail、dispatch、forms、design、assets、crm、macros -> <name>.agent-native.com;factory -> agent-native-factory.netlify.app。chat 已有意排除。
页面辅助工具。 Agent-Native 页面还会提供 window.__agentNativeWebMcp,这是对 document.modelContext 的封装,增加了就绪状态和部分注册表状态、工具筛选功能,以及可在求值结束后继续运行的调用。它是我们自己的功能,不属于 WebMCP——其他网站都没有,因此依赖它之前请先检查,并且绝不要因为它不存在就认定“此页面没有工具”。
const an = window.__agentNativeWebMcp;
await an.ready(); // { state, registered, total }
await an.tools("slide"); // [{ name, description, required, readOnly }]
await an.describe("update-slide");
await an.call("view-screen", {}, { waitMs: 2000 });
an.result(id); // for { state: "pending", id }
如果调用在 waitMs 时间内尚未完成,call 会返回 { state: "pending", id };该调用会继续在页面中运行。在 Codex 约 3 秒的 CDP 时间上限内,请传入 { waitMs: 2000 },这样读取操作和大多数写入操作都能在同一次求值中完成;默认情况下,无需为每次调用都配对执行一次 result() 读取。
如果它是 undefined,说明尚未开始注册——页面已退出登录、仍在加载,或运行的是较旧版本。请改用上文的 document.modelContext。
原生连接器。 如果宿主已将该应用配置为自己的 MCP 服务,且其中已提供相应工具,执行由服务端支持的操作时应优先使用这些工具:即使浏览器或宿主重置,该传输方式仍可继续使用。只有裸 url 且没有 Authorization 标头的条目不会注册任何工具——这表示缺少 agent-native connect <url>,而不是应用不支持 MCP。托管应用默认提供精简版连接器目录,页面本地工具也仅存在于页面中,因此此连接器是页面工具的补充,而非替代。