WebMCP: declare a site's agent tools, and gate the ones that spend money
Publish a WebMCP tool manifest so an agent calls named site tools instead of guessing at buttons, and validate that every tool has a real schema and every sensitive tool (pay, checkout, delete) requires a human confirmation before it runs.
Run this workflow
CI-verified, 2/2 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Site builders adding WebMCP tools as a progressive enhancement. CI validates the tool manifest: at least one tool, each with a name, an input schema (at least one field), and a declared return, and every tool marked sensitive carries requires_confirmation: true. No browser, no agent call. The live actuation is fenced.
Not for
- Expecting it to help today, WebMCP is a proposal in a Chrome 149 origin trial (co-authored by Google and Microsoft), not a ratified standard; other browsers have not shipped it and it only helps on sites that adopt it
- Headless, behind-the-scenes use, the tools run in JavaScript on a visible page, so a browser tab has to be open on the site
- Skipping the human on money or irreversible actions, confirmations reduce risk but an agent can still be misled; keep a person in the loop for anything that spends or cannot be undone
The Stack
Tested Against
github.com/webmachinelearning/webmcp (2026-07)node@20Side effects & data flow
- Network
- none, local only
- Writes
- ./webmcp.json
- Credentials
- none required
Prerequisites
- A site you control
- Chrome 149 origin trial + testing extension to actually run the tools
Steps
- 1
Declare the tools and validate the manifest
List the tools your site offers an agent, each with an input schema and a declared return, and mark the sensitive ones. CI checks every tool has a real schema and every sensitive tool requires a confirmation click, so a purchase or delete can never run unattended. Wiring the tools into the page and running them is fenced.
cat > webmcp.json <<'JSON' { "tools": [ { "name": "search_flights", "description": "Search available flights for a route and date", "sensitive": false, "input": { "origin": "string", "destination": "string", "date": "string" }, "returns": "a list of flight options with prices" }, { "name": "select_flight", "description": "Select a flight by id", "sensitive": false, "input": { "flight_id": "string" }, "returns": "the selected flight held for checkout" }, { "name": "checkout", "description": "Pay for the held flight", "sensitive": true, "requires_confirmation": true, "input": { "payment_token": "string" }, "returns": "an order confirmation number" } ] } JSON node -e ' const fs = require("fs"); const c = JSON.parse(fs.readFileSync("webmcp.json", "utf8")); function bad(m) { console.error("BAD: " + m); process.exit(1); } const tools = c.tools || []; if (tools.length < 1) bad("declare at least one tool"); const sensitive = []; for (const t of tools) { if (!t.name) bad("each tool needs a name"); if (!t.input || typeof t.input !== "object" || Object.keys(t.input).length < 1) bad("tool " + t.name + " needs an input schema with at least one field"); if (!t.returns || String(t.returns).length < 3) bad("tool " + t.name + " must declare what it returns"); if (t.sensitive === true) { if (t.requires_confirmation !== true) bad("sensitive tool " + t.name + " must set requires_confirmation: true (money or irreversible needs a human click)"); sensitive.push(t.name); } } console.log("webmcp OK: " + tools.length + " tool(s) declared with input+return schemas; " + sensitive.length + " sensitive tool(s) all require confirmation (" + sensitive.join(", ") + ")"); ' - 2
Wire the tools into the page (the actuation step, not checked by CI)
Register the tools with navigator.modelContext (or add toolname/tooldescription attributes to existing forms as a progressive enhancement), and test them in the Chrome 149 origin trial with the WebMCP extension. Keep a human in the loop on sensitive steps. The live actuation is fenced.
Eval, 2 fixtures
Last passed: verified todaymanifest-okcontainstimeout 30s · max $0Expected:
webmcp OK: 3 tool(s) declared with input+return schemas; 1 sensitive tool(s) all require confirmation (checkout)clean-exitexit_codetimeout 30s · max $0Expected:
0
Results
Agents fumble on the web because they imitate a human: read the screen, guess the field, click and hope. WebMCP flips that, the site declares what it can do (search, filter, checkout) as callable tools with clear inputs and outputs, and the agent calls them directly. The tools run visibly on the page, and sensitive steps can demand a confirmation click, so an agent cannot quietly complete a purchase.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- Wire GLM-5.2 into Hermes: valid route, 64k-context check, no key in config
- Voyager pattern: validate a procedural skill store before you trust a saved skill
- Hermes MoA: stack frontier models into one virtual model for hard turns
- promptfoo: make agent evals fail the build, not the user
- E2B: run model-written code in a sandbox, not on your box
- DSPy: program the pipeline, compile the prompts (stop hand-tuning)
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).