WebMCP inspector
Check whether a website supports WebMCP, see the tools it exposes to AI agents, grade them against agent-tool best practice, and export them as MCP, Anthropic, or OpenAI tool definitions.
What WebMCP is
WebMCP is a draft browser API from the W3C Web Machine Learning Community Group (editors from Google and Microsoft) that lets a web page expose its own functionality as tools an AI agent can call — a search, an add-to-cart, a booking form — with a name, a natural-language description, and a JSON Schema for the inputs. Instead of an agent guessing its way through your UI with screenshots and clicks, the page says what it can do and how to ask.
It borrows its vocabulary from the Model Context Protocol (MCP) — tools, input schemas, annotations like readOnlyHint — but runs inside the browser, in the user's session, under the page's origin and Permissions Policy. There is no server to host: the page registers tools with document.modelContext, and the user's agent (in the browser or an extension) discovers them.
Two ways a page exposes tools
Declarative: annotate an HTML <form> with toolname and tooldescription. The browser synthesizes the input schema from the form's controls (each control's name becomes a parameter; toolparamdescription describes it). Adding toolautosubmit lets the agent submit without the user pressing the button. This is the part of the spec still being written — the inspector follows the published declarative-API explainer.
Imperative: call document.modelContext.registerTool({ name, description, inputSchema, annotations, execute }) from JavaScript. Registration returns a promise, can be scoped to other origins with exposedTo, and can be unregistered by aborting a signal — which is how a page keeps only the tools relevant to its current state registered.
await document.modelContext.registerTool({
name: "search_products",
description: "Search this store's catalog by keyword and return up to 20 matching products with prices and availability. Read-only; it never changes the cart.",
inputSchema: {
type: "object",
properties: {
query: { type: "string", maxLength: 200, description: "Keywords, e.g. \"trail running shoes size 10\"" },
limit: { type: "integer", minimum: 1, maximum: 20, default: 8 },
},
required: ["query"],
additionalProperties: false,
},
annotations: { readOnlyHint: true },
async execute({ query, limit }) {
const response = await fetch(`/search/suggest.json?q=${encodeURIComponent(query)}&resources[type]=product&resources[limit]=${limit}`);
return response.json();
},
}, { signal: pageController.signal });What the inspector checks
The page HTML scan fetches the page without cookies and parses annotated forms into tools, reporting declaration problems (a form missing tooldescription, a name outside the spec's character rules, an action that doesn't resolve). It also looks for registration signals — references to document.modelContext and registerTool( — so you know when tools exist but only appear after JavaScript runs.
The live scan opens the page in a fresh, isolated browser, waits for registration to settle, and reads each tool's name, description, input schema, and annotations through the standard getTools() API. Nothing is invoked; the scan is read-only, cookie-free, and stops after ten seconds. When the HTML references modelContext but declares no forms, the inspector runs the live scan for you.
The quality report then grades every tool the way agent frameworks and eval suites judge them: names, descriptions, schemas, annotations, and the page's overall tool budget. Each finding links to why it matters and how to fix it, and the whole tool list can be exported as MCP, Anthropic, or OpenAI tool definitions.
How the quality grade works
Every tool starts at 100. Blocking problems (a name the browser rejects, a missing description, two names that collide) cost 15 points; should-fix problems (open schemas, undescribed parameters, agent-directed instructions in a description, auto-submit on a consequential form) cost 6; considerations (unbounded strings, missing annotations, a legacy API reference) cost 2. Per-tool deductions are averaged so a page with many decent tools isn't penalized for having many, then page-level issues are subtracted in full. 90 and up is an A; below 40 is an F.
The rules are the ones this playground enforces on its own WebMCP surface (documented in the project's WEBMCP.md and pinned by unit tests), aligned with the draft spec's security and privacy considerations and with Anthropic's guidance on writing tools for agents. They are opinions — well-tested ones — not spec conformance. A tool can register fine and still grade poorly; that's the point.
The agent's-eye view
Tool metadata isn't free. Every registered tool's name, description, and schema is sent to the model on every turn the agent takes on your page. The report totals those characters and estimates tokens so you can see what your page costs before the user has said a word — and flags when names and descriptions alone exceed a 2,500-character budget, the point where they start crowding out the user's request.
Near-duplicate descriptions and names that differ only in case are called out for the same reason: they don't break registration, they break selection. Selection errors are the failure mode you'll see most in evals, and they are the cheapest to fix.
Findings the inspector reports
incomplete-declaration— Form is missing toolname or tooldescriptionA declarative tool is a
<form>with bothtoolnameandtooldescription. With only one, the browser never registers it, so the form is invisible to agents while looking annotated to you.Fix: Add the missing attribute.
toolnameis the identifier the agent calls;tooldescriptionis the sentence it reads to decide whether to.invalid-name— Tool name is outside the spec's character rulesThe spec limits names to 1–128 characters of ASCII letters, digits,
_,-, and.. A space or unicode character makesregisterTool()reject the tool.Fix: Rename to lower_snake_case, for example
search_products, and keep it under 64 characters so it stays readable in an agent's tool list.tool-limit— More than 100 declarative tools on one pageThe inspector stops after 100 annotated forms. No agent selects well from a list that long, and every description is paid for on every turn.
Fix: Annotate the handful of forms an agent should actually drive on this page and leave the rest plain.
invalid-action— Form action can't be resolved safelyThe form's
actiondidn't resolve to a public HTTPS URL against the page. Agents submit the form as the user, so an unresolvable or non-HTTPS target is a dead end.Fix: Use an absolute HTTPS
actionon a public host, or omit it so the form posts back to the page.name-invalid— Name violates the spec patternBrowsers reject registration for names outside 1–128 characters of ASCII letters, digits,
_,-, and.; the tool silently never exists.Fix: Rename to a short lower_snake_case verb phrase.
name-style— Name isn't lower_snake_caseAgents see tools from many servers side by side.
searchProductsnext toadd_to_cartreads as two conventions, and long names get truncated in tool pickers.Fix: Use lower_snake_case under 64 characters: a verb, then the object (
search_products,get_order_status).name-generic— Name doesn't say what the tool doesSelection starts with the name.
submitoractionforces the agent to read every description before choosing, and it will still confuse tools on busy pages.Fix: Name the task: verb plus object. If two tools share a verb, add the noun that separates them.
name-collision— Two names differ only in case or separatorssearch-productsandsearch_productsare distinct to the browser but identical to a model that normalizes tokens. Calls land on the wrong one.Fix: Merge them, or rename so the words differ.
description-missing— No descriptionThe description is the only thing an agent has to decide when to call a tool. The spec also rejects empty descriptions at registration.
Fix: Write one to three sentences: when to call it, when not to, and what happens when it runs.
description-short— Description is too short to select onUnder about 80 characters a description is usually a label (
Search products), not guidance. The agent can't tell it apart from a similar tool or know its side effects.Fix: State the task, the boundary (
only returns results; never changes the cart), and the state it depends on (needs a loaded product page).description-long— Description is over 500 charactersEvery tool's description rides along on every agent turn. Long ones crowd out the conversation and usually contain detail that belongs on individual parameters.
Fix: Cut to the selection-relevant sentences and move formats, units, and examples into parameter descriptions.
description-side-effects— Side-effect boundary isn't statedAgents decide whether to confirm with the user based on what a tool changes. A description that doesn't say leaves them guessing, and the spec's misrepresentation-of-intent section is about exactly this gap.
Fix: Say whether it only reads, or what it changes and whether that is reversible. Pair it with
readOnlyHintorconsequentialHint.description-instructions— Description contains instructions for the agentText like “always call this first” or “do not tell the user” is the tool-poisoning pattern the spec's security section warns about. Agent clients increasingly flag or refuse such tools.
Fix: Describe the tool; don't steer the agent. Leave sequencing to the agent and disclosure to the user.
description-duplicate— Two tools have near-identical descriptionsIf the model can't tell two tools apart from their descriptions, it picks one arbitrarily. That shows up as tool-selection errors in every eval.
Fix: Lead each description with what distinguishes it, or merge the tools behind one parameter.
schema-missing— No input schemaWithout a schema the agent invents parameters or passes none. For a no-argument tool an explicit empty object tells it that's intentional.
Fix: Provide a JSON Schema
inputSchema; for no input use{ "type": "object", "properties": {} }.schema-open— Object schema accepts unknown propertiesModels hallucinate parameters. An open object silently accepts them, so the tool runs with a misspelled or invented argument instead of failing fast.
Fix: Set
additionalProperties: falseon every object, including nested ones.schema-undescribed— Parameters without descriptionsThe parameter description is where format, units, and examples live. Without it the agent guesses whether
dateis ISO-8601 orMarch 3, and whetherquantitymay be zero.Fix: Give every property a description; add
enum,format,minimum, or an example where it removes a guess.schema-unbounded— Unbounded strings or arraysThe spec lists input length limits as a mitigation for prompt injection and resource abuse. An unbounded string is also where an agent pastes a whole page by mistake.
Fix: Add
maxLengthto strings,maxItemsto arrays, or replace free text with anenum.schema-sensitive— Sensitive data would flow through the agentCard numbers, passwords, and government IDs in an input schema route personal data through the model and its logs. The spec calls this privacy leakage through over-parameterization.
Fix: Collect sensitive fields in the page's own UI and have the tool reference the resulting state (
use the saved payment method) instead.annotations-missing— No annotations registeredreadOnlyHint,consequentialHint, anduntrustedContentHintare how a tool tells the agent when to confirm with the user and when to distrust output. Without them every tool is treated the same.Fix: Add an
annotationsobject at registration:readOnlyHint: trueon pure reads,consequentialHint: trueon purchases and deletions,untrustedContentHint: truewhen the result contains user-generated text.annotations-contradiction— readOnlyHint contradicts a mutating nameAn agent that trusts
readOnlyHintskips confirmation. On a tool nameddelete_…oradd_…that removes the safety net the hint exists to provide.Fix: Set
readOnlyHint: false(or omit it) and considerconsequentialHint: true.autosubmit-consequential— Auto-submit on a consequential formtoolautosubmitlets the agent submit without the user pressing the button. On a POST, a checkout, or a delete, that removes the one confirmation the declarative model is built around.Fix: Remove
toolautosubmitfrom forms that change state; keep it for searches and filters.tool-count— Many tools registered at onceSelection accuracy falls as the list grows, and every description is paid for on every turn. Pages rarely need more than a handful of tools active at the same time.
Fix: Register per page or per state and unregister with an
AbortSignalwhen the UI changes. Keep a small always-on core (orientation, navigation) and add contextual tools.description-budget— Descriptions exceed the per-page budgetNames and descriptions together are the context every tool call costs the agent, on every turn. Past about 2,500 characters they start crowding out the user's own request.
Fix: Trim descriptions, move detail into parameters, and register fewer tools at once.
legacy-api— Page references navigator.modelContextThe spec moved the entry point from
navigator.modelContexttodocument.modelContextin May 2026 (each document gets its own context, which fixed lifecycle and permissions-policy questions). Older code paths stop registering in browsers that only ship the new location.Fix: Feature-detect
document.modelContextfirst and fall back tonavigator.modelContextwhile both exist in the wild.
WebMCP inspector FAQ
How do I check whether a website supports WebMCP?
Paste the page URL into the inspector. The HTML scan reports declarative form tools immediately; if the page registers tools from JavaScript, the live scan opens it in an isolated browser and lists what document.modelContext.getTools() returns. A page with neither annotated forms nor modelContext references doesn't support WebMCP yet.
Why does the HTML scan find no tools when I know the page registers some?
Imperative tools only exist after JavaScript runs, often after a storefront script loads from a CDN. The HTML scan never executes the page. Run the live scan — the inspector does this automatically when the HTML references modelContext but declares no forms.
Is the live scan safe to run on a production site?
Yes. It opens the page in a fresh browser context with no cookies or storage, reads only tool metadata (never calls execute or submits a form), blocks requests to hosts the page doesn't already load scripts from, and stops after ten seconds. Nothing is stored server-side.
What is the difference between WebMCP and MCP?
MCP is a client–server protocol: an agent connects to a server you host and calls its tools over JSON-RPC. WebMCP is a browser API: the page itself registers tools, in the user's session, under the page's origin, and the user's agent calls them locally. They share vocabulary (tools, input schemas, annotations) but not transport, hosting, or trust model.
Which is better, declarative forms or registerTool()?
Declarative forms are the least code and keep the user pressing the submit button, which is the right default for anything consequential. registerTool() gives you structured results, annotations, per-state registration, and tools that aren't forms at all. Most real pages use both: forms for the obvious actions, imperative tools for reads and state.
What makes a good WebMCP tool description?
One to three sentences that say when to call the tool, when not to, and what happens — including whether it only reads or what it changes. Keep it under about 500 characters and put formats, units, and examples on the parameters instead. Never include instructions aimed at the agent (“always call this first”); that's the tool-poisoning pattern the spec warns about.
How many tools should a page register?
As few as the current page can act on — usually a small always-on core (orientation, navigation, cart read) plus contextual tools registered per template and unregistered with an AbortSignal when the UI changes. The inspector flags more than eight active at once as worth a look and more than sixteen as a problem.
Does my Shopify store already support WebMCP?
Yes — Shopify registers WebMCP tools on storefronts automatically, so there is nothing to add to a theme. Run the live scan on your storefront to see exactly which tools shoppers' agents get, how they are described, and how they grade; racing.shop is a live example. Anything a theme or app registers on top shows up in the same list, so check for duplicates of the platform's tools.
Can I use a site's WebMCP tools from my own agent?
The tool definitions, yes: export them as MCP, Anthropic, or OpenAI tool definitions from the report. Executing them still requires a browser session on the page, because WebMCP tools run in the page's JavaScript under the user's origin — that is the design, not a limitation of the inspector.
Does the inspector store the pages or tools it scans?
No. Each scan is performed on request and returned to your browser; the worker keeps no history. The ?url= parameter in the address bar is there so you can share a link that re-runs the scan.
WebMCP guides
- WebMCP vs MCP: what's the difference? — Same vocabulary, different transport, hosting, and trust model — and why most sites end up with both.
- Writing WebMCP tool descriptions agents select correctly — The description is the only thing an agent reads before choosing. Here's what belongs in it — and what must not.
- WebMCP spec changes and what to update in your code — What moved, what was removed, what was added, and the one-line code change each one asks of you.
Read the WebMCP draft specification · Browse UCP developer tools