Essential WebMCP Tools for AI‑Ready Websites
What “WebMCP tools” actually are, the core tool patterns most sites should expose, and working code you can paste to make agents use your site reliably.

If you searched for webmcp tools, here is the honest answer: WebMCP does not ship a built‑in catalog of tools. It’s a browser standard that lets your page define its own tools—small, typed functions agents can call instead of scraping your UI. By the end, you’ll know which tools to implement on your site, with working code and guardrails that hold up in production.
TL;DR
- WebMCP tools are site-defined: you register them on each page with a name, description, JSON Schema input, and an async execute.
- Start with intent-based tools, not UI replicas: search, get_item, add_to_cart, start_checkout, sign_in, book_appointment, submit_ticket.
- Use clear descriptions and schemas; require in-page confirmation for sensitive actions (payments, account changes, deletions).
- Feature-detect both addresses: document.modelContext and navigator.modelContext; some agents still read the older one.
- WebMCP support is early; it works today in some agents and frameworks. Track status at the public WebMCP support page and plan for drift and analytics with Agent Layer.
What a WebMCP “tool” is (and isn’t)
WebMCP is an in-page interface for AI agents. Your page registers tools—JSON-serialisable functions that run in the user’s current session. There’s no separate API key or backend for the agent; it calls the tool in the tab the user already has open.
- registerTool takes: name (snake_case), description, inputSchema (JSON Schema), and execute(params) => result.
- Tools should do one user-meaningful thing, return small JSON, and explain side effects in the description.
- WebMCP differs from Anthropic’s MCP (server-side). If you need a refresher, see the comparison in What is the Difference Between MCP and WebMCP?
Ecosystem reality: support is uneven. It works today in ChatGPT desktop “site tools” and ChatGPT Work, and across frameworks like Vercel agent-browser, Stagehand, and Browser Use. Chrome and Edge are running origin trials; Firefox and Safari don’t support it. See the hand-verified WebMCP ecosystem tracker for current status.
The essential tool patterns
There is no universal list, but common user intents map to predictable tools. Implement these first:
- Discovery and read:
- site_search
- get_product / get_article / get_doc
- list_variants or list_slots (for options/availability)
- Commerce and bookings:
- add_to_cart or add_to_basket
- start_checkout (must confirm in-page)
- apply_promo_code
- book_appointment (must confirm in-page)
- Account and support:
- sign_in and sign_out
- update_profile (must confirm in-page)
- submit_support_ticket
Name tools in snake_case. Keep inputs minimal but typed. Put preconditions and side effects in the description so agents can choose correctly.
Example 1: Product search tool (discovery)
This tool lets an agent search your catalog with filters. It returns a concise summary that the model can reason over without scraping your grid.
// Feature-detect WebMCP at both addresses
const mc = (typeof document !== 'undefined' && document.modelContext) ||
(typeof navigator !== 'undefined' && navigator.modelContext);
if (mc && typeof mc.registerTool === 'function') {
mc.registerTool({
name: 'site_search',
description: 'Search the product catalog by query and optional filters. Use to find products before adding to cart. Returns up to 10 concise results.',
inputSchema: {
type: 'object',
additionalProperties: false,
properties: {
query: { type: 'string', description: 'User search terms' },
category: { type: 'string' },
price_max: { type: 'number', minimum: 0 },
in_stock_only: { type: 'boolean' }
},
required: ['query']
},
execute: async ({ query, category, price_max, in_stock_only }) => {
// Use your site’s internal APIs/client state. Avoid secrets in params.
const url = new URL('/api/search', location.origin);
url.searchParams.set('q', query);
if (category) url.searchParams.set('cat', category);
if (price_max != null) url.searchParams.set('price_max', String(price_max));
if (in_stock_only) url.searchParams.set('in_stock', '1');
const res = await fetch(url.toString(), { credentials: 'same-origin' });
if (!res.ok) throw new Error('Search failed');
const data = await res.json();
// Return small, JSON-serialisable payloads agents can reason over
return {
count: Math.min(data.items.length, 10),
items: data.items.slice(0, 10).map((p) => ({
id: p.id,
name: p.name,
price: p.price,
currency: p.currency,
url: p.url,
in_stock: p.in_stock
}))
};
}
});
}
Why this shape works:
- The description tells the agent when to use it and what it returns.
- The schema is narrow. Agents can reliably fill it.
- The output is capped and regular—great for a language model.
Example 2: Add to cart with safe confirmation
Actions with money or account changes should not run silently from an agent. Require explicit user confirmation inside the page. The tool can open a confirmation UI and only proceed after the user approves.
const mc = (typeof document !== 'undefined' && document.modelContext) ||
(typeof navigator !== 'undefined' && navigator.modelContext);
function confirmAction(message) {
// Minimal, synchronous confirmation. Replace with your modal as needed.
return new Promise((resolve) => {
const ok = window.confirm(message);
resolve(ok);
});
}
if (mc && typeof mc.registerTool === 'function') {
mc.registerTool({
name: 'add_to_cart',
description: 'Add a specific product variant to the current cart. Requires user confirmation in-page before changing the cart.',
inputSchema: {
type: 'object',
additionalProperties: false,
properties: {
product_id: { type: 'string' },
variant_id: { type: 'string', description: 'Size/color SKU or option id' },
quantity: { type: 'integer', minimum: 1, default: 1 }
},
required: ['product_id', 'variant_id']
},
execute: async ({ product_id, variant_id, quantity = 1 }) => {
const ok = await confirmAction(`Add ${quantity} to cart?`);
if (!ok) return { status: 'cancelled' };
const res = await fetch('/api/cart/items', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'same-origin',
body: JSON.stringify({ product_id, variant_id, quantity })
});
if (!res.ok) throw new Error('Add to cart failed');
const { item_id, cart_count } = await res.json();
return { status: 'added', item_id, cart_count };
}
});
}
Notes:
- No secrets or tokens in tool params. Everything runs inside the user’s session.
- The description says “Requires user confirmation” so agents expect a prompt.
Example 3: Start checkout with an explicit consent gate
This tool demonstrates a stronger consent pattern. It refuses to proceed unless the user has completed a visible confirmation step in the DOM.
const mc = (typeof document !== 'undefined' && document.modelContext) ||
(typeof navigator !== 'undefined' && navigator.modelContext);
// Simple, explicit consent via a visible checkbox in your checkout UI
function userHasCheckoutConsent() {
const el = document.querySelector('[data-checkout-consent]');
return !!(el && el instanceof HTMLInputElement && el.checked);
}
if (mc && typeof mc.registerTool === 'function') {
mc.registerTool({
name: 'start_checkout',
description: 'Begin checkout for the current cart. Only runs after the user ticks the checkout consent box on the page. Do not pass payment details via this tool.',
inputSchema: { type: 'object', additionalProperties: false, properties: {} },
execute: async () => {
if (!userHasCheckoutConsent()) {
return { status: 'blocked', reason: 'missing_user_consent' };
}
const res = await fetch('/api/checkout/start', {
method: 'POST', credentials: 'same-origin'
});
if (!res.ok) throw new Error('Checkout start failed');
const { checkout_id, next_url } = await res.json();
// Navigate as a side effect; also return the state.
if (next_url) location.assign(next_url);
return { status: 'started', checkout_id };
}
});
}
This pattern is appropriate for payments, profile changes, cancellations, or deletions.
If you’re preparing a storefront end‑to‑end, see practical guidance in Preparing Your E‑Commerce Store for AI‑Driven Checkout.
Good tool descriptions win
Agents decide which tool to call by reading name + description + schema. Be explicit:
- When to use: “Use after the user picks a size and asks to buy.”
- Preconditions: “Requires an authenticated user.”
- Side effects: “Modifies the cart.”
- Limits: “Returns 10 items max.”
Avoid vague descriptions like “Handles checkout.” Models won’t choose them reliably.
Minimal sets by site type
For quick planning, here are practical starter sets. Adjust to your domain.
| Site type | Tools to implement first |
|---|---|
| E‑commerce | site_search, get_product, list_variants, add_to_cart, apply_promo_code, start_checkout |
| SaaS app | site_search_docs, get_doc, sign_in, update_profile, create_project, invite_user |
| Bookings | search_slots, list_slots, book_appointment, cancel_appointment |
| Support | site_search, get_article, submit_support_ticket, escalate_ticket |
For a broader discovery perspective, read The Rise of Agent Engine Optimization (AEO).
Flow: how an agent uses your tools
The sequence below shows an agent choosing and calling tools, with a user confirmation step before a side effect.
Testing and observability in practice
You can ship WebMCP without any vendor. But once agents start using your site, two problems appear:
- Drift: UI changes break your selectors or assumptions.
- Blind spots: You don’t know which agents call which tools, when they fail, or why.
Agent Layer is designed to remove this undifferentiated work:
- Define tools once per page template (product page, cart, search), publish as versioned configs, and roll back if needed.
- Health checks detect when a UI change breaks a tool and suggest the new selector.
- Guardrails for sensitive actions (payments, account changes) without hand-rolling prompts.
- Analytics log every tool call: which agent, success/error, and duration.
- Test scenarios: write a user intent and the tool you expect an agent to pick, then check it.
If you want a primer on the standard itself, see WebMCP Explained: The Native Standard Turning Websites into AI APIs.
What works today vs. what’s early
Based on hand-verified data in the ecosystem tracker:
- Agents that call page tools today: ChatGPT desktop app (native site tools), ChatGPT Work.
- Frameworks where it works today: Browser Use (hosted agents), Stagehand (TypeScript, launches a browser), Vercel agent-browser (default on in its launched Chrome).
- Behind flags or origin trials: Chrome and Edge (origin trials), Brave (Nightly), Puppeteer and Cloudflare Browser Run (flagged).
- No support or no signal yet: Claude for Chrome, Gemini in Chrome, Firefox, Safari, and several others.
Plan for graceful fallback. Your site should remain usable without tools—agents will still read the page. Tools are an optimization that makes outcomes reliable and fast.
Security and safety patterns
- Never pass secrets, API keys, payment tokens, or card data through tool params.
- Require explicit user confirmation for sensitive actions: payment, account changes, subscription changes, deletions.
- Keep return payloads small and non-sensitive. Return identifiers, not PII.
- Avoid tools that mash multiple irreversible steps into one. Prefer “start_checkout” over “place_order_now”.
- Describe authentication preconditions: “Requires logged-in user.”
For threat modeling and prompt safety in hybrid UI/agent flows, see Preventing Prompt Injection in Agentic Web Interfaces.
Common pitfalls
- Vague descriptions: If the model can’t tell when to use your tool, it won’t.
- Over-broad schemas: Optional everything leads to invalid calls. Keep schemas tight.
- No feature detection: Some agents still look at navigator.modelContext. Detect both.
- Silent side effects: Changing carts or profiles without an on-page confirmation will surprise users and can trigger abuse reports.
- Giant responses: Returning your entire catalog leads to timeouts and token bloat. Cap results and paginate via follow-up calls.
- Relying on DOM scraping anyway: If you expose tools but the core action still needs click automation, agents will be flaky. Move the side effect into execute.
- Ignoring support reality: Assuming “all agents” will call tools today. Check the ecosystem status and provide progressive enhancement.
- No drift plan: A refactor breaks a selector used inside execute. Without health checks and analytics, you’ll learn from angry users.
FAQ-level clarity
- Do I need a backend? No. Tools run in-page with the user’s session. You can still call your backend from execute.
- Is WebMCP the same as MCP? No. WebMCP is in-browser per page; MCP is server-side. Read the side-by-side in What is the Difference Between MCP and WebMCP?.
- Will this help SEO? WebMCP is for agents, not search rankings. For a grounded view, see WebMCP for SEO: what helps, what doesn’t, and what to build.
What breaks in production
- Selector drift: Internal DOM or data-attr changes inside execute break lookups. Health checks and suggested selectors save hours.
- Version mismatch: An old tool description that forgot to mention a consent requirement causes agents to call it incorrectly. Version your tool configs and roll back.
- Agent diversity: One agent reads tools, another scrapes. Keep your HTML semantic (labels, names, aria) so both paths work.
- Consent bypass attempts: Malicious scripts try to toggle hidden checkboxes. Verify visible, user-initiated state when checking consent.
- Rate spikes: A popular agent integration hammers site_search. Rate-limit in your API tier and keep tool responses small.
- Error opacity: Without analytics, a “failed” execute is a black box. Log error types and durations.
Try it
Add one tool to a high-intent page and ship it. Then run the free agent-readiness audit at the Agent Layer homepage. It scores your site and suggests tool candidates page by page, and the ecosystem tracker shows where WebMCP runs today. If you want drift detection, guardrails, tests, and analytics out of the box, Agent Layer plugs into your templates without rewriting your app.

