🔶 WebMCP:教会网站与 AI Agent 对话
英文标题:🔶 WebMCP: Teaching Your Website to Talk to AI Agents
WebMCP 提出让网站以结构化工具的形式向 AI Agent 声明自身能力,替代脆弱的 DOM 抓取、屏幕识别与模拟点击方式。该提案由 Google 与 Microsoft 在 W3C Web Machine Learning Community Group 共同推进,目前是社区组草案,并已作为 Chrome 149 起的 Origin Trial 提供测试。开发者可通过 `document.modelContext.registerTool()` 为现有页面功能注册带 JSON Schema 的工具,复用已登录页面中的 JavaScript、状态和会话。文章还展示了一个注册 13 个工具的 Career Copilot 演示,以及 ChatGPT 通过这些 WebMCP 工具完成职位搜索、匹配和人工审批前准备的案例。
139.8 KB
184.9 KB
157.9 KB
171.7 KB
559.9 KB
中文
想象一下:一个 AI Agent 要在餐厅网站上为你预订餐桌。如今,它的工作方式像一名极有耐心、却有点困惑的实习生。它加载页面,读取原始 HTML,试图弄清 40 个 <div> 元素中哪个是日期选择器,猜测绿色按钮可能表示“确认”,点击它,等待,然后重新读取整个屏幕,看看是否发生了什么。下周只要移动一下这个按钮,Agent 就坏了。改一个 CSS 类名,它也坏了。再在顶部加一个 Cookie 横幅,它就可能完全点错东西。
这就是如今几乎所有“Agent 使用网站”的方式:屏幕抓取,然后寄希望于一切顺利。这种自动化方式,相当于通过电话描述截图来操作电脑。
WebMCP 提出了一种合理得多的方式。与其让 Agent 盯着网站猜测它能做什么,不如让网站以一组清晰、结构化的工具,声明 自己能做什么,Agent 可以直接调用这些工具。“这里有一个 book_table 工具。它接收日期、时间和用餐人数。调用它。”无需读取像素,无需猜测。最棒的是:它已经可以在 Chrome 中通过试用功能运行,添加第一个工具大约只需 10 分钟。
让我把整件事展示给你。
核心转变:从抓取到声明
整个理念可以浓缩为一个对比。同一项任务,两个世界。
今天:Agent 进行抓取
- 读取整个 DOM
- 猜测哪个元素是日期字段
- 模拟输入和点击
- 再次读取整个页面以检查结果
- 布局变化时失效
WebMCP:网站进行声明
- 页面注册一个 book_table 工具
- Agent 读取工具的 Schema
- Agent 使用结构化参数调用它
- 工具运行你真实的 JS 并返回结果
- 经得住重新设计:工具就是契约
左侧的方式很脆弱,因为 Agent 每次都在逆向解析你的 UI。右侧的方式很稳定,因为你提供了一个真正的接口。只要工具的名称和 Schema 保持不变,底层布局可以自由变化。
如果你读过我此前关于 MCP:让 AI 接触世界的端口 的文章,这会让你感到熟悉——这正是应该的。MCP 为 AI 提供了一种在服务器上调用工具的标准方式。WebMCP 则将同样的理念带入浏览器:网页 本身 成为提供工具的地方,这些工具运行在你已打开的标签页中,使用你已经登录的会话。
它究竟是什么
WebMCP 是一项拟议中的 Web 标准,由 Google(Chrome)和 Microsoft(Edge)在 W3C Web Machine Learning Community Group 中共同开发。它为网页提供一个小型 JavaScript API,用于注册可供 AI Agent 发现和调用的工具。Google 在 Chrome 文档中直白地将其描述为一种“为 AI Agent 构建并暴露结构化工具”的方式:网站对自身功能进行标注,让 Agent“准确知道如何与其交互”。需要准确说明其成熟度:它目前是 Community Group 的_草案_,不是已完成的 W3C 标准,也尚未进入标准化轨道;这恰恰说明,现在正是学习它并参与塑造它的时机。
有三件事让这个概念变得清晰:
- 发现(Discovery)。 页面可通过一种标准方式声明“我提供这些工具”,例如
checkout或filter_results,让 Agent 能够列出它们。 - Schema。 每个工具都以 JSON Schema 声明输入和输出,因此 Agent 能准确知道该传递什么,大幅减少幻觉或误读的空间。
- 状态(State)。 对页面当前状态形成共同认知,使 Agent 知道自己实际上可以执行哪些操作。
当前进展
WebMCP 已真实可运行,但仍处于早期阶段。它从 Chrome 149 开始以 Chrome Origin Trial 形式提供,你也可以通过标志位 chrome://flags/#enable-webmcp-testing 在本地启用。该提案位于 github.com/webmachinelearning/webmcp,Angular 已经提供实验性支持,Chrome 也发布了演示站点(披萨制作、旅行搜索和餐厅预订)。Google 自己的表述是,它“仍在积极讨论中,并且可能发生变化”。因此,现在是“试用它并参与塑造它”的阶段,而不是“将其投入生产环境”的阶段——也正因如此,值得现在就开始学习。
一次调用实际如何流转
下面是从页面到 Agent 再返回的完整闭环。没有什么奇特的事情发生:页面注册工具,Agent 列出它们,选择其中一个,使用结构化参数调用它,而你自己的 JavaScript 在页面中完成工作。
页面 注册工具:你的 JS 声明 book_table、search 等。
→
Agent 发现工具:列出页面的工具及其 Schema。
→
Agent 携带参数调用:传入符合 Schema 的结构化 JSON。
→
页面 运行 execute():在已登录页面中运行你真实的 JS。
→
Agent 获得结果:在标签页中可见地获得结构化答案。
工具的 execute 函数运行在你的真实页面内,使用你现有的 JavaScript、状态和用户自己的已登录会话。它是在标签页中可见地发生,而不是在某个不可见的无头浏览器中进行,因此用户可以观察并信任它。
“运行在你已经登录的页面中”这一点非常重要。Agent 不是一个在某处使用窃取凭据单独登录的机器人,而是在你打开且已认证的标签页里调用函数,使用你现有的会话。网站仍然控制自己要暴露什么,用户也可以看见整个过程。
看一次调用如何发生
具体来说,当你要求浏览器内 Agent 在启用了 WebMCP 的网站上执行某项操作时,过程如下:你的请求、Agent 选择已声明的工具、工具运行、返回结果。
你 › 今晚 8 点帮我订一张 4 人桌
Agent › 在此页面上发现工具 book_table
Agent › 正在调用 book_table({ date: "today", time: "20:00", party: 4 })
页面 › 预订完成。晚上 8:00 的 4 人餐桌,确认编号 #A17。
这次交互中没有任何 DOM 猜测。Agent 使用带类型的参数调用了一个具名函数,页面则用自己的代码完成其余工作。这就是 Agent 操作你的网站,与 Agent 操作你网站照片之间的区别。
代码确实非常少
这是会让人想立刻试用的部分。注册工具只需一次调用。使用 Chrome 文档中当前的命令式 API,一个为待办事项网站添加“新增项目”工具的例子,大致如下:
注册 WebMCP 工具(命令式 API)
javascript
await document.modelContext.registerTool({
name: 'add_todo',
description: 'Add an item to the to-do list',
inputSchema: {
type: 'object',
properties: { text: { type: 'string' } },
required: ['text']
},
execute: async ({ text }) => {
addTodoToPage(text); // your own existing function
return Added to-do: ${text};
}
});
就是这样。你为工具提供名称、描述、输入 Schema,以及一个调用现有代码的 execute 函数。Agent 使用 getTools() 发现它;如果工具不再相关,你还可以通过 AbortController 将其撤回。此外还有一种声明式形式:你可以标注 HTML 表单,而不是编写 JS。
注意 execute 做了什么:它调用了 addTodoToPage,也就是网站中已经存在的函数。WebMCP 并不要求你重建任何东西。你只是在为网站已有的可执行动作套上一层轻量、已声明的接口,让 Agent 能干净地访问它们。这就是“10 分钟”这一说法成立的原因。
有一点准确性说明,因为 API 很年轻且仍在变化:当前入口是 document.modelContext,而早期草案使用的是 navigator.modelContext。这一变化很合理,因为工具真正属于一个文档,而不是整个浏览器。如果你看到旧教程中使用 navigator,原因就在这里。在变更逐步推出期间,一行 shim(const mc = document.modelContext || navigator.modelContext)即可兼容两者。预计还会有一些类似边缘细节发生变化;毕竟它仍是草案。
一个真实案例,从头走到尾
官方 WebMCP 演示都是“调用一个工具就完成”:点披萨、订餐桌。它们很有用,但低估了这一理念,因为 WebMCP 真正有趣的部分不是一次工具调用,而是 Agent 串联 工具来完成真正的工作,并在人类真正关心的环节设置把关。因此,我没有只做一个玩具示例,而是构建并部署了一个真实项目配合本文;本节会如实带你走一遍,因为它比任何抽象例子都更能说明整个模型。
Career Copilot 是一个实验性的 Agent 职业门户。你向它提供简历;它从实时企业招聘看板中读取真实职位描述,评估你的实际匹配度,指出技能差距,并准备一批你可以一键批准的申请。没有任何伪造:职位是真实的,匹配结果根据真实职位描述文本计算,并且未经你的明确确认,它不会提交任何申请。
Career Copilot:一个在线 WebMCP 职业门户
打开它,点击“See it work instantly”,然后观看一个 Agent 如何基于实时数据完成完整的求职任务:读取简历,从 GitLab、Stripe 和 Databricks 拉取真实职位空缺,阅读每一份职位描述,评估你的匹配度,呈现技能差距,并提出一批待你批准的申请。该页面注册了 13 个真实 WebMCP 工具。
该项目已部署并完成验证。启用 chrome://flags/#enable-webmcp-testing 后,页面会显示“WebMCP live, 13 tools registered”,这些工具也会出现在 DevTools 的 WebMCP 面板中。无需启用标志位也可以试用:一个按钮便能运行整个任务。不过它绝不会真正提交申请,而是准备好申请内容后停下来等待你操作。

工具直接来自页面。 Chrome 的 DevTools → Application → WebMCP 面板。页面注册的每一个工具都会按其真实名称和描述列出,包括 aggregate_openings、compare_jobs、draft_outreach、explain_match,这正是 Agent 将会发现的内容。

点击一个工具,查看其契约。 选择 parse_resume 会打开详情窗格:名称、完整描述、所在框架,以及直接指向页面自身源代码中 registerTools 的 Origin。没有抓取,没有猜测,工具 就是 接口。
这些是已部署演示中的真实截图。面板左侧是 Agent 看到的工具列表;右侧是其中一个工具的完整契约。这就是今天浏览器中“网站与 Agent 对话”的实际样子。
而且,真实 Agent 确实驱动了它
在面板中列出工具是一回事,让生产级 AI Agent 使用 它们才是真正的测试。ChatGPT 现在已支持 WebMCP,因此我让它访问在线演示,并用自然语言要求它读取示例前端开发者简历,找出技能差距与最佳职位匹配项,并在提交任何申请前停止。它通过页面已声明的工具完成了整个流程。

ChatGPT 正在使用这些工具。 它自己的执行轨迹将页面读取为 WebMCP live · 13 tools registered,点名了 parse_resume 工具,并以“Completed using the page's WebMCP tools.”结束。没有 DOM 抓取,它调用了已声明的工具。

它产出的结果。 它读取了用户资料,汇总了 75 个实时职位,评估了 24 份真实职位描述,按照真实百分比和实际技能差距排列匹配结果,随后停止:4 个已入围,0 个已申请。 人工把关机制如设计所期那样生效。
这是来自不同厂商的 Agent,使用与 DevTools 面板中所列完全相同的已声明工具。分数并不是从页面上抓取而来,而是 Agent 调用 match_profile 工具时计算得到的。这就是 WebMCP 端到端兑现的全部承诺:用自然语言描述任务,Agent 通过干净的接口操作网站,而不是猜测网站上的按钮含义。
工作流:Agent 实际做了什么
以下是真实任务的逐步流程。每一行都是页面暴露的一个 WebMCP 工具;Agent 会将它们串联起来。请注意其结构:先是执行阶段,然后是会在人类关键决策处停下来的重要操作阶段。
| 工具 | 作用 | 类型 |
|---|---|---|
parse_resume |
将任意简历读取为真实个人资料:技能、资历、关注领域 | 读取 |
aggregate_openings |
从 3 个真实公司招聘看板拉取实时职位 | 读取 |
match_profile |
获取每一份真实职位描述,并评估你的实际匹配度和技能差距 | 读取 |
find_gaps |
将技能差距汇总为学习信号:“学习 X 以解锁更多职位” | 读取 |
shortlist |
将匹配度最高的职位加入你的流程;可逆 | 操作 |
prepare_applications |
为每个职位定制摘要,准备供审阅 | 操作 |
submit_batch |
打开一个人工审批面板:审阅这批申请,取消勾选任意项目,然后再申请 | 把关 |
真实的 Agent 循环。前四个工具均为只读,Agent 可以自由收集信息并进行推理。随后,shortlist 和 prepare 会改变可逆状态。只有最后一个步骤——以你的名义申请——具有重要后果,而且未经你点击,它无法发生。
English / 原文
Picture an AI agent trying to book you a table on a restaurant’s website. Today, it works like a very patient, slightly confused intern. It loads the page, reads the raw HTML, tries to figure out which of the forty <div> elements is the date picker, guesses that the green button probably means “confirm,” clicks it, waits, and re-reads the whole screen to see if anything happened. Move that button next week and the agent breaks. Rename a CSS class and it breaks. Add a cookie banner on top and it clicks the wrong thing entirely.
This is how almost all “agents using websites” works right now: screen-scraping and hoping. It’s the automation equivalent of operating a computer by describing screenshots over the phone.
WebMCP proposes something much saner. Instead of the agent guessing what your site can do by staring at it, your site declares what it can do, as a set of clean, structured tools the agent can call directly. “Here’s a book_table tool. It takes a date, a time, and a party size. Call it.” No pixel-reading. No guessing. And the best part: it already runs in Chrome behind a trial, and adding your first tool takes about ten minutes.
Let me show you the whole thing.
The core shift: from scraping to declaring
The entire idea fits in one comparison. Same task, two worlds.
Today: the agent scrapes
1Read the entire DOM
2Guess which element is the date field
3Simulate typing and clicking
4Re-read the whole page to check
5Break when the layout changes
WebMCP: the site declares
1Page registers a book_table tool
2Agent reads the tool's schema
3Agent calls it with structured args
4Tool runs your real JS, returns a result
5Survives redesigns: the tool is the contract
The left column is brittle because the agent is reverse-engineering your UI every time. The right column is stable because you gave it a real interface. The layout can change freely underneath a tool whose name and schema stay the same.
If you’ve read my earlier post on MCP, the port that let AI touch the world, this will feel familiar, and it should. MCP gave AI a standard way to call tools on a server. WebMCP brings that same idea into the browser: the web page itself becomes a place that offers tools, running in the tab you already have open, with the session you’re already logged into.
What it actually is
WebMCP is a proposed web standard, developed jointly by Google (Chrome) and Microsoft (Edge) in the W3C Web Machine Learning Community Group, that gives a web page a small JavaScript API to register tools that an AI agent can discover and call. Google describes it plainly in the Chrome docs: a way to “build and expose structured tools for AI agents,” where the site annotates its own features so agents “know exactly how to interact” with them. To be precise about maturity, it’s a Community Group draft , not a finished W3C standard and not yet on the standards track, which is exactly why now is the moment to learn it and shape it.
Three things make it click into place:
- Discovery. A standard way for a page to say “I offer these tools,” like
checkoutorfilter_results, so an agent can list them. - Schemas. Each tool declares its inputs and outputs as JSON Schema, so the agent knows exactly what to pass and there’s far less room to hallucinate or misread.
- State. A shared understanding of what’s on the page right now, so the agent knows what it can actually act on.
Where it stands today
WebMCP is real and runnable, but early. It's available as a Chrome origin trial from Chrome 149 , and you can switch it on locally with the flag chrome://flags/#enable-webmcp-testing. The proposal lives at github.com/webmachinelearning/webmcp, Angular already has experimental support, and Chrome ships demo sites (a pizza maker, travel search, a restaurant booking). Google's own words: it's "under active discussion and subject to change." So this is a "try it and shape it" moment, not a "ship it to production" one, and that's exactly why it's worth learning now.
How a call actually flows
Here’s the whole loop, page to agent and back. Nothing exotic happens: the page registers tools, the agent lists them, picks one, calls it with structured arguments, and your own JavaScript does the work in the page.
pageRegister tools Your JS declares book_table, search, etc.
→
agentDiscover Lists the page's tools and their schemas
→
agentCall with args Structured JSON matching the schema
→
pageexecute() runs Your real JS, in the logged-in page
→
agentGets result A structured answer, visibly, in the tab
The tool's execute function runs inside your actual page, using your existing JavaScript, state, and the user's own logged-in session. It happens visibly in the tab, not in some invisible headless browser, so the user can watch it and trust it.
That “runs in the page you’re already logged into” detail is a big deal. The agent isn’t a separate bot logging in with stolen credentials somewhere. It’s calling a function in your open, authenticated tab, using the session you already have. The site keeps control of what it exposes, and the user can see it happen.
Watch one call happen
Concretely, when you ask an in-browser agent to do something on a WebMCP-enabled site, it looks like this: your request, the agent picking the declared tool, the tool running, the result.
you › book a table for 4 tonight at 8
agent › found tool book_table on this page
agent › calling book_table({ date: "today", time: "20:00", party: 4 })
page › Booked. Table for 4 at 8:00 PM, confirmation #A17.
No DOM guessing anywhere in that exchange. The agent called a named function with typed arguments, and the page did the rest with its own code. This is the difference between an agent operating your site and an agent operating a photograph of your site.
The code is genuinely tiny
This is the part that makes people want to try it. Registering a tool is one call. Using the current imperative API from the Chrome docs, a to-do site adding an “add item” tool looks essentially like this:
register a WebMCP tool (imperative API)
await document.modelContext.registerTool({
name: 'add_todo',
description: 'Add an item to the to-do list',
inputSchema: {
type: 'object',
properties: { text: { type: 'string' } },
required: ['text']
},
execute: async ({ text }) => {
addTodoToPage(text); // your own existing function
return `Added to-do: ${text}`;
}
});
That's the whole thing. You give the tool a name, a description, an input schema, and an execute function that calls code you already wrote. The agent discovers it with getTools(), and you can pull a tool back with an AbortController if it stops being relevant. There's also a declarative flavor where you annotate an HTML form instead of writing JS.
Notice what execute does: it calls addTodoToPage, a function that already exists on your site. WebMCP isn’t asking you to rebuild anything. You’re wrapping the actions your site can already do in a thin, declared interface so an agent can reach them cleanly. That’s why the ten-minutes claim is real.
One accuracy note, because the API is young and moving: the current entry point is document.modelContext, while earlier drafts used navigator.modelContext, the move makes sense because tools really belong to a document, not the whole browser. If you follow an older tutorial showing navigator, that’s why. A one-line shim (const mc = document.modelContext || navigator.modelContext) bridges both while the change rolls out. Expect a few more edges like this to shift; it’s a draft.
A real one, worked all the way through
The official WebMCP demos are all “call one tool and you’re done”, order a pizza, book a table. Useful, but they undersell the idea, because the interesting part of WebMCP isn’t one tool call. It’s an agent chaining tools to do real work, with a human gate on the part that matters. So instead of a toy, I built and deployed a real one to go with this post, and this section is the honest walk-through of it, because it teaches the whole model better than any abstract example.
Career Copilot is an experimental agentic career portal. You give it a resume; it reads real job descriptions from live company boards, scores your true fit, tells you your skill gaps, and prepares a batch of applications you approve in one click. Nothing is faked: the jobs are real, the matching is computed from real job-description text, and it applies nothing without your explicit OK.
Career Copilot, a live WebMCP career portal
Open it, tap "See it work instantly", and watch an agent run a full job-search mission over live data: read a resume, pull real openings from GitLab, Stripe and Databricks, read each job description, score your fit, surface your skill gaps, and propose a batch of applications for you to approve. It registers 13 real WebMCP tools on the page.
Deployed and validated. With chrome://flags/#enable-webmcp-testing on, the page reports "WebMCP live, 13 tools registered" and they show up in the DevTools WebMCP panel. No flag needed to try it: one button runs the whole mission anyway. It never really submits an application, it prepares them and stops for you.
And this isn’t a diagram of what should happen, here’s the actual browser proving it. Turn the flag on, open DevTools, and Chrome grows a WebMCP panel that lists every tool the page registered, each with the same name and description the agent sees. This is the whole pitch made visible: the website declares its tools, and the browser reads them straight off the page.

The tools, straight from the page. Chrome's DevTools → Application → WebMCP panel. Every tool the page registered is listed with its real name and description, aggregate_openings, compare_jobs, draft_outreach, explain_match, exactly what an agent would discover.

Click one, see its contract. Selecting parse_resume opens a Details pane: name, full description, the frame it lives in, and an Origin that points right back at registerTools in the page's own source. No scraping, no guessing, the tool is the interface.
Real screenshots from the deployed demo. The left of the panel is the tool list an agent sees; the right is one tool's full contract. This is what "the website talks to the agent" actually looks like in the browser today.
And a real agent actually drove it
Listing tools in a panel is one thing. Getting a production AI agent to use them is the real test. ChatGPT supports WebMCP now, so I pointed it at the live demo and asked it, in plain English, to read the sample frontend resume, find the best job matches with skill gaps, and stop before applying to anything. It did the whole thing through the page’s declared tools.

ChatGPT, using the tools. Its own trace reads the page as WebMCP live · 13 tools registered, names the parse_resume tool, and signs off with "Completed using the page's WebMCP tools." No DOM scraping, it called the declared tools.

The result it produced. It read the profile, aggregated 75 live roles, scored 24 real job descriptions, ranked the matches with honest percentages and real gaps, and stopped: 4 shortlisted, 0 applied. The human gate held, exactly as designed.
A different vendor's agent, using the same declared tools the DevTools panel lists. The scores aren't scraped from the page, they're computed by the match_profile tool when the agent calls it. That's the whole promise of WebMCP working end to end: describe the task in words, and the agent operates the site through a clean interface instead of guessing at its buttons.
The workflow: what the agent actually does
Here’s the real mission, step by step. Each row is a WebMCP tool the page exposes; the agent chains them. Notice the shape: a run phase, then a consequential act phase that stops for a human.
parse_resumeReads any resume into a real profile: skills, seniority, focus arearead
aggregate_openingsPulls live roles from three real company job boardsread
match_profileFetches each real job description and scores your true fit + gapsread
find_gapsAggregates the gaps into a learning signal: "learn X to unlock more roles"read
shortlistAdds the strongest fits to your pipeline. Reversibleact
prepare_applicationsTailors a summary per role, ready to reviewact
submit_batchOpens a human approval panel: review the set, uncheck any, then applygate
The real agent loop. The first four tools are read-only, the agent gathers and reasons freely. Then shortlist and prepare change reversible state. Only the last one, applying in your name, is consequential, and it cannot happen without you clicking approve. That split is the entire safety model of WebMCP, made concrete.
This grouping is worth internalizing, because it’s how you should design any WebMCP surface: separate what merely reads from what acts , and put the human gate only where it’s truly needed.
13 tools, three tiers. WebMCP lets a tool flag itself with hints like readOnlyHint, so the agent (and the browser) know which calls are safe to make freely and which need a human. Getting this taxonomy right is most of what makes an agentic surface trustworthy.
A real run, not a mockup
Here’s the actual tool-activity log from a validated run with a frontend engineer’s resume. Watch it read real descriptions and score honestly, no fake 99%s:
______tool activity · real run
→ toolparse_resume(…)
✓ resultSam Patel, Senior Frontend Engineer · 11 skills · frontend focus
→ toolaggregate_openings()
✓ result75 live roles from GitLab, Stripe, Databricks
→ toolmatch_profile()
✓ resultreading 24 real job descriptions…
✓ resultDesign Engineer, Presence @ GitLab: 80% , no gaps
✓ resultSenior Software Engineer, Fullstack @ Stripe: 57%, gaps: python
✓ resultAI Engineer @ GitLab: 54%, gaps: python, llm
→ toolfind_gaps()
✓ resulttop gaps across matches: python, testing, api
→ toolshortlist([4 roles])
→ toolprepare_applications([4])
⏸ gateawaiting your approval for 4 applications…
✓ resultapplied to 3 (you unchecked 1) ✓
·Mission complete.
A genuine run. The frontend resume's true best fit, a Design Engineer role at 80%, came from reading the real job description, not the title (the title never says "React"). The scores are honest and capped, the gaps are real, and the human approved 3 of 4 in the batch. Swap in a backend or data resume and the whole thing re-ranks to that person's real best matches. That's what a scraper fundamentally cannot do.
The one hard thing, and why the human gate is the right answer
Building this taught me the honest limit of “auto-apply”, and it’s worth stating plainly because it’s the real engineering lesson. Everything up to the apply button is easy to automate and genuinely useful: reading resumes, aggregating openings, matching, tailoring. The last mile , actually submitting into a company’s application system, is the hard part. Those systems (Workday, Greenhouse and friends) are deliberately not open APIs, they sit behind logins and bot-detection, and automating submission usually violates their terms.
This is exactly the gap WebMCP is meant to close. If a careers site exposed a submit_application tool the way this demo does, an agent could apply cleanly, in your own authenticated session, with your approval. Until sites do that, the correct design isn’t to fake the last mile, it’s to automate everything up to it and keep a human on the submit. That’s not a compromise. An agent that silently applies to jobs in your name is a liability; one that does all the work and asks before it acts as you is a superpower. WebMCP’s consent model is what makes that line enforceable.
The full source is a single self-contained HTML file, and I wrote up the deeper product thinking, the candidate and employer sides, the phased build, the honest limits, as a design note in the repo.
The trust model, because this is the scary part
The obvious worry: if a page can hand tools to an agent, can a malicious page trick the agent into doing something awful? The design takes this seriously, and it’s worth knowing the guards.
- It runs visibly, in the tab. No headless, background execution. A browsing context has to be open, so actions happen where the user can see them.
- Same-origin only. Tool registration is gated by a
toolsPermissions Policy that defaults toself, so a random cross-origin iframe can’t quietly register tools unless the top page explicitly allows it. - Sensitive actions can demand a human. For things like making a purchase, a tool can require an explicit user confirmation dialog before it proceeds. Human-in-the-loop is built into the pattern, not bolted on.
- Untrusted content is flagged. Tools carry annotation hints like
readOnlyHintanduntrustedContentHint, so the agent can treat a tool that returns third-party content with appropriate suspicion, which matters given everything we know about prompt injection.
None of this makes it magically safe, the standard is young and the security model is still being worked out, but the shape is right: visible, same-origin, consent-gated, and honest about untrusted data.
Honest pros and cons
Why it's exciting
Structured tool calls instead of brittle DOM scraping
Runs in the user's real, logged-in session, no separate bot auth
The site stays in control of what it exposes
Survives redesigns: the tool contract outlives the layout
Reuses code you already have, tiny to adopt
A real standard direction, not one vendor's lock-in
Why it's early
Experimental: origin trial only, subject to change
Chrome-first today; broad browser support isn't here yet
Needs site adoption to matter; agents can't call tools that don't exist
Discoverability gap: a client must visit a site to learn its tools
Security model still maturing (malicious tools, injection)
Complex sites may need real refactoring to expose clean tools
The cons are almost all "it's early," not "it's wrong." That's the profile of a promising standard in its incubation window: the idea is sound, the ecosystem hasn't caught up yet.
Where it fits: use cases
The pattern shines anywhere an agent needs to do something on a site, not just read it.
E-commerce
Expose search_products, add_to_cart, checkout. An agent shops your store through real tools, not by clicking around.
Booking & travel
Multi-city, multi-passenger trips or restaurant tables, where the form is complex and scraping is painful.
SaaS dashboards
Let an agent run the actions your app already has: create a ticket, filter a report, update a record.
Form filling
Declare the form's fields and a submit tool; the agent maps data in cleanly instead of guessing inputs.
Accessibility
A declared, semantic tool surface is a gift for assistive agents, clearer intent than raw markup.
Internal tools
Wrap your admin panel's actions as tools so an internal assistant can drive them safely and visibly.
The through-line: any site that has "things you can do," not just "things you can read," is a candidate. The richer your site's actions, the more WebMCP gives you.
Where this is headed
Now the fun part, because the ceiling here is high.
The obvious next step is standardization across browsers. Right now it’s a Chrome trial; the destination is a web standard every browser implements, the way fetch or the clipboard API are everywhere. When that lands, “does this site have an agent interface?” becomes as normal a question as “is this site mobile-friendly?”
That direction just got a real push: ChatGPT now supports WebMCP. Visit a WebMCP-enabled page and it can automatically use the tools the page declares to complete your task. That’s the interesting signal, it’s not just Google and Microsoft (who wrote the draft) anymore. When a second major AI vendor starts consuming page-declared tools, a proposal in its incubation window starts looking like a direction the ecosystem is actually moving in.
Then there’s the agentic web itself. Imagine sites shipping an agent interface alongside their visual one, on purpose, the way they ship a mobile layout today. Your site’s UI is for humans; its declared tools are for agents; both are first-class. A site that’s good at being operated by an agent gets used by more agents, which becomes a real reason to invest in the tool surface.
It gets more interesting when you combine WebMCP with remote MCP. WebMCP handles what lives in the browser (the page’s own actions, the user’s session), while remote MCP servers handle backend tools and data. An agent could fluidly use both: call a page’s add_to_cart tool via WebMCP, then hit a remote inventory MCP server for stock, stitching client and server tools into one task.
And further out: agent commerce. If a store exposes clean purchase tools and an agent can call them within the user’s authenticated, consenting session, you get a path to agents that actually complete transactions safely, with the human able to watch and confirm, rather than a scraper hammering a checkout flow. The same shape extends to booking, scheduling, support, anything transactional.
The big bet underneath all of it: the web was built for humans to read and click. The next version is built to also be operated by agents, cleanly and on the site’s own terms. WebMCP is one of the first serious attempts to make that a standard instead of a hack.
The takeaway, and go try it
Here’s the whole thing in a sentence: WebMCP lets your website hand an AI agent a clean set of tools instead of forcing it to reverse-engineer your buttons. That single shift, declare instead of scrape, makes agent interactions reliable, keeps the site in control, runs in the user’s real session, and survives your next redesign.
It’s early, it’s Chrome-first, and the standard will change. But the barrier to trying it is almost nothing: flip on chrome://flags/#enable-webmcp-testing, add a registerTool call wrapping a function your site already has, and watch an agent call it. Ten minutes, and you’ll understand the agentic web better than most people reading about it. Then go read the proposal, poke the demos, and file the rough edges you hit, because right now, while it’s still being shaped, your feedback actually moves it.
References
Written from scratch after reading the official documentation. These are the primary, verified sources. Nothing here is copied from them; the code shape follows the documented API.
- Chrome for Developers, WebMCP overview: https://developer.chrome.com/docs/ai/webmcp
- Chrome for Developers, WebMCP imperative API: https://developer.chrome.com/docs/ai/webmcp/imperative-api
- Chrome for Developers, WebMCP declarative API: https://developer.chrome.com/docs/ai/webmcp/declarative-api
- WebMCP specification (Draft Community Group Report): https://webmachinelearning.github.io/webmcp/
- WebMCP proposal, explainer, and source (W3C Web Machine Learning Community Group): https://github.com/webmachinelearning/webmcp
- Chrome Platform Status, WebMCP feature: https://chromestatus.com/feature/5117755740913664
- WebMCP demo sites (Google Chrome Labs): https://github.com/GoogleChromeLabs/webmcp-tools/tree/main/demos
- Patrick Brosset (Microsoft Edge), WebMCP updates and clarifications: https://patrickbrosset.com/articles/2026-02-23-webmcp-updates-clarifications-and-next-steps/
- OpenAI Developers, WebMCP support in the ChatGPT desktop browser (Aug 26, 2026): https://x.com/OpenAIDevs/status/2092344959248761263
- Model Context Protocol (MCP), for the underlying protocol: https://modelcontextprotocol.io
Background reading:MCP: The Port That Let AI Finally Touch the World for the protocol WebMCP builds on, and LLM security for why the trust model here matters.