AI agents can drive web UIs, but asking them to infer buttons, labels, and form state from the DOM alone gets brittle fast — especially for operational workflows with evidence review, drafts, and confirmed writes.
WebMCP gives pages a structured tool surface (navigator.modelContext) so agents discover named actions with schemas instead of click-guessing. Google Antigravity is how I used parallel subagents to plan, implement, test, and document the demo without degrading the human UX.
This post walks through a small operations desk demo: a normal triage UI for humans, plus five WebMCP tools with an explicit confirmation gate for status changes.
Sample code is in a public GitHub Gist (linked below). The full sprint workspace repo is private.
The problem
Support and ops desks usually mix:
- read-only lookups (case queue, evidence),
- draft suggestions (next steps),
- durable writes (status changes).
Agents mimicking mouse clicks struggle when labels are ambiguous, state spans panels, or irreversible actions need human approval. WebMCP lets the page declare capabilities as tools while keeping the human UI first-class.
Demo at a glance
Human UI: case queue, evidence, draft box, pending update, confirm button.
| Tool | Purpose | Destructive? |
|---|---|---|
list_cases |
Queue snapshot | No |
get_case_status |
One case summary | No |
draft_next_step |
Suggested triage steps | No |
prepare_status_update |
Stage a status change + token | Pending |
confirm_status_update |
Apply staged change | Yes (requires token) |
Writes require a confirmation token from prepare_status_update. Agents can prepare; humans (or an explicit confirm call) must approve.
Origin isolation matters
WebMCP requires an origin-isolated document. Use COOP/COEP headers — plain python -m http.server is not enough.
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "credentialless")
self.send_header("Permissions-Policy", "tools=*")
Enable chrome://flags/#enable-webmcp-testing and relaunch Chrome 149+.
Registering tools
On Chrome 149, tools register on navigator.modelContext (not document.modelContext):
const mc = navigator.modelContext;
mc.registerTool({
name: "list_cases",
description: "List support cases in the operations desk",
inputSchema: { type: "object", properties: {} },
execute: async () => JSON.stringify(cases, null, 2),
});
Full sample (HTML + server + run script):
Antigravity workflow
Built with parallel subagents:
- Planner — sprint requirements → one ops-desk journey
- Implementation — UI + WebMCP tools + confirm gate
- Verification — automated CDP test of the full tool chain
- Docs — article, gists, proof screenshots
Topic alignment: Dynamic Subagents & Shared Agent Harness.
Run it locally
Download the gist files, then:
python3 webmcp-origin-isolated-server.py
# open http://127.0.0.1:8765/ in Chrome (WebMCP flag enabled)
Check DevTools → Application → WebMCP for registered tools.
What I validated
Automated tests confirm:
- origin isolation is
true, - five tools register,
-
prepare_status_update+confirm_status_updatemove CASE-101 toinvestigating.
Limitations
- Local dev uses a Chrome flag; production origins need the WebMCP Origin Trial.
- WebMCP needs a visible tab — not headless-only.
- Demo state is in-memory; production would persist server-side.
Tags
#AgenticArchitect #GoogleAntigravity
Timothy Olaleke — Google Developer Expert (Google Cloud)


Top comments (0)