All posts
Best practicesEngineeringEcosystem

Create an AI Agent Ready Website: A Practical Checklist

A concrete checklist and runnable WebMCP code to make your site AI agent ready — what works today, what breaks, and how to keep tools working in production.

Agent LayerOctober 13, 202610 min read

AI agent ready website is a fuzzy phrase. Here is the concrete version: expose machine-usable tools on your pages with WebMCP, keep your forms and content parsable, and verify agents can complete key flows. By the end, you’ll have a practical checklist, runnable code, and clarity on what works today and where support is still evolving.

TL;DR

  • Add WebMCP tools to pages that do things (search, add to cart, start checkout). Use feature detection and JSON Schema.
  • Keep forms and data machine-readable: labeled inputs, valid JSON-LD, predictable button names, no JS-only content for critical info.
  • Test with an agent that calls page tools today (e.g., ChatGPT desktop app) and track broader support on the ecosystem page.
  • Guard sensitive actions with in-page confirmation; never send secrets through tool inputs.
  • If you want drift detection, guardrails, analytics, and versioned configs, Agent Layer handles this without changing your backend.

What “AI agent ready” actually means

Agents need a stable interface to perform actions. Scraping DOM or clicking pixels is brittle. WebMCP gives your page a small, explicit tool surface an agent can discover and call using the user’s existing session. You can do this yourself with a few lines of JavaScript. No new backend is required.

Two truths to be clear about:

  • Ecosystem support is early. Some agents and browsers call tools today; others are behind flags or not yet. Track real status on the public WebMCP ecosystem support tracker.
  • There is no proven “SEO” effect from adding WebMCP. Think of it as an API for agents, not a ranking signal.

If you want a deeper primer on the standard itself, see WebMCP Explained: the native standard turning websites into AI APIs, and if you’re weighing protocols, see how WebMCP differs from MCP.

The checklist: make your site agent ready

1) Expose WebMCP tools on pages that do things

Start with your highest-value flows:

  • Product listing/search: search_products
  • Product page: add_to_cart
  • Cart: update_cart_item, apply_coupon
  • Checkout start: start_checkout (with explicit user confirmation in the page)
  • Account: update_profile, change_password (always confirm in-page)

Good tool descriptions state when to use the tool, preconditions, and side effects. Keep results small and JSON-serialisable.

Runnable example (add to cart and start checkout):

<script>
  // Feature-detect both current and older addresses
  const mc = document.modelContext ?? navigator.modelContext;

  if (mc) {
    // 1) Add a product to cart
    mc.registerTool({
      name: "add_to_cart",
      description: "Add a product variant to the user's cart. Use on product pages when a valid variant_id is known. Does not start checkout.",
      inputSchema: {
        type: "object",
        additionalProperties: false,
        required: ["variant_id", "quantity"],
        properties: {
          variant_id: { type: "string", description: "Internal variant identifier" },
          quantity: { type: "integer", minimum: 1, maximum: 20 }
        }
      },
      execute: async ({ variant_id, quantity }) => {
        // Example UI binding: submit hidden form or call your existing front-end action
        const res = await fetch(`/cart/add`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ variant_id, quantity })
        });
        if (!res.ok) {
          return { ok: false, error: `add_failed_${res.status}` };
        }
        const data = await res.json();
        // Keep results small; include cart count, not the whole cart
        return { ok: true, cart_count: data.cart_count };
      }
    });

    // 2) Start checkout (guarded by explicit user confirmation in page)
    mc.registerTool({
      name: "start_checkout",
      description: "Begin checkout for the current cart. Only call after the user has confirmed in-page. Opens checkout UI.",
      inputSchema: { type: "object", additionalProperties: false, properties: { confirm_token: { type: "string" } } },
      execute: async ({ confirm_token }) => {
        // Guardrail: require an explicit user click we set earlier
        const flag = window.__checkoutConfirmedAt && (Date.now() - window.__checkoutConfirmedAt < 30_000);
        if (!flag || confirm_token !== window.__lastCheckoutToken) {
          return { ok: false, error: "confirmation_required" };
        }
        // Trigger your normal checkout navigation
        window.location.href = "/checkout";
        return { ok: true, navigated: true };
      }
    });
  }

  // Minimal confirmation UI
  function confirmCheckout() {
    window.__lastCheckoutToken = Math.random().toString(36).slice(2);
    window.__checkoutConfirmedAt = Date.now();
    // Optional: visually indicate confirmation
    document.getElementById('confirmMsg').textContent = 'Checkout confirmed for 30s';
  }
</script>
<button onclick="confirmCheckout()">Proceed to checkout</button>
<div id="confirmMsg" aria-live="polite"></div>

Notes:

  • Sensitive actions (payment, account changes, deletion) should always require explicit user confirmation in the page.
  • Never pass secrets, API keys, or card details through tool parameters. Tools operate inside the user’s session; keep it that way.

For a step-by-step starter, see the WebMCP Tutorial: setup, tools, and deployment and the concise How to enable WebMCP on your website.

2) Make forms and actions machine-complete

Agents often need to fall back to filling a form the standard way, especially when a site lacks a tool for a niche action. Help them:

  • Label inputs with
  • Use type=email, type=tel, required, and aria-* where appropriate.
  • Give buttons consistent, unambiguous text or aria-labels (e.g., “Add to cart”, not “Do it”).
  • Avoid CAPTCHAs on core commerce flows. If unavoidable, provide an alternate path with tools.
  • Don’t hide essential content behind JS-only rendering with no server-rendered fallback.
  • Include valid JSON-LD for products, offers, and breadcrumbs.

If forms are central to your app, work through the WebMCP form coverage checklist.

3) Provide minimal discovery metadata

  • A sitemap and, if relevant, llms.txt to signal crawlable areas to agentic crawlers.
  • Stable, canonical URLs for product and account flows.
  • Avoid blocking legitimate agent crawlers in robots.txt if you want them to learn your structure.

4) Test with an agent that calls WebMCP tools today

Support is not universal. Based on verified data:

  • Agents that work today: ChatGPT desktop app and ChatGPT Work call page tools and are on by default (observed in production usage).
  • Behind a flag or early demos: Brave Leo (Nightly), Codex Chrome extension (with CDP), various frameworks like Vercel agent-browser and Stagehand work when they launch a Chrome that supports it.
  • Browsers: Chrome and Edge have origin trials; Brave has it behind a flag; Firefox and Safari are not shipping it.

See up-to-date details on the ecosystem support tracker. Build for what’s real now; keep your code feature-detected so you benefit as coverage expands.

5) Put guardrails where risk lives

  • Require in-page confirmation before tools that charge money, change account details, or delete data.
  • Constrain tool input with tight JSON Schemas (enums, min/max, formats).
  • Keep tool results compact: confirm what happened, return IDs and counts, not entire objects.
  • Log and monitor tool usage in your environment; be ready to rate-limit if abuse appears.

If you want built-in approvals and audit trails without writing plumbing, Agent Layer’s guardrails and analytics can sit over your tools with one script tag.

6) Observe, version, and fix drift

UIs change. Selectors move. Test tools against real intents routinely, and keep a rollback path when a change breaks a flow. Agent Layer provides:

  • Versioned configs per page template.
  • Health checks that detect selector drift and suggest new bindings.
  • Analytics of which agents called which tools and outcomes.
  • Test scenarios to assert “given this intent, the agent should call add_to_cart”.

You can run without these and maintain tools in your app code; the value is not having to reinvent observability and rollback.

Minimal search and cart example

Add a product search tool that returns a compact list, and a cart tool to update quantity. Keep descriptions explicit.

<script>
  const mc = document.modelContext ?? navigator.modelContext;
  if (mc) {
    mc.registerTool({
      name: "search_products",
      description: "Keyword product search. Use when the user asks to find items by text. Returns top matches with id and price.",
      inputSchema: {
        type: "object",
        additionalProperties: false,
        required: ["q"],
        properties: {
          q: { type: "string", minLength: 2 },
          limit: { type: "integer", minimum: 1, maximum: 10, default: 5 }
        }
      },
      execute: async ({ q, limit = 5 }) => {
        const res = await fetch(`/api/search?q=${encodeURIComponent(q)}&limit=${limit}`);
        if (!res.ok) return { ok: false, error: `search_failed_${res.status}` };
        const items = await res.json();
        // Return minimal fields
        return { ok: true, items: items.map(p => ({ id: p.id, title: p.title, price: p.price })) };
      }
    });

    mc.registerTool({
      name: "update_cart_item",
      description: "Change quantity for a cart line. Use only when line_id is known from prior cart view.",
      inputSchema: {
        type: "object",
        additionalProperties: false,
        required: ["line_id", "quantity"],
        properties: {
          line_id: { type: "string" },
          quantity: { type: "integer", minimum: 0, maximum: 20 }
        }
      },
      execute: async ({ line_id, quantity }) => {
        const res = await fetch(`/cart/update`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ line_id, quantity })
        });
        if (!res.ok) return { ok: false, error: `update_failed_${res.status}` };
        const data = await res.json();
        return { ok: true, cart_count: data.cart_count };
      }
    });
  }
</script>

How an agent uses WebMCP on your page

This sequence shows an agent discovering and calling tools within the user’s browser tab.

Agent discovers and calls WebMCP tools on a product page

What you can do without Agent Layer vs with it

You can ship WebMCP tools yourself. Agent Layer becomes useful when you want to keep them healthy in production.

Capability Without Agent Layer With Agent Layer
Register tools Hand-write JS in each template Define per-template once, publish as versioned configs
Drift detection Manual debugging when things break Health checks suggest new selectors
Guardrails Write your own confirmations and checks Built-in approvals for sensitive actions
Observability Add logs and dashboards Analytics of tool calls, agent identity, success/error, duration
Testing Build custom test harness Intent-based test scenarios
Rollback Ship new code One-click rollback to last working config

If you’re evaluating whether to build vs buy, read the practical WebMCP Tutorial: setup, tools, and deployment, then decide if you want the maintenance layer.

Common pitfalls

  • Missing feature detection: Only checking document.modelContext or only navigator.modelContext. Use both for now.
  • Vague tool descriptions: “Checkout” without preconditions leads to misuse. State when to call, preconditions, and side effects.
  • Over-sharing results: Returning full cart JSON on every call. Keep payloads small.
  • No guardrails on sensitive actions: Agents can start flows users didn’t confirm. Require in-page confirmation.
  • Unlabeled inputs and unnamed buttons: Agents stumble when semantics are unclear.
  • JS-only content for prices or availability: Agents and crawlers may miss it, breaking flows.
  • CAPTCHAs blocking key flows: Provide an alternative tool path or disable them where feasible.
  • Assuming universal support: Some popular agents ignore tools today. Test with one that doesn’t. Track ecosystem support.

What breaks in production

  • UI drift: DOM changes break hidden forms or selectors bound to tools. Health checks and versioning help you fix fast.
  • Silent failures: A tool returns a 200 but with an unexpected shape; your execute function returns ok: true. Validate responses.
  • Over-permissive schemas: Without min/max or enums, agents pass garbage. Tighten JSON Schema.
  • Race conditions: Rapid agent calls double-submit actions. Debounce or idempotency keys server-side.
  • Partial adoption: You added tools to product pages but not to the cart, so agents fall back to brittle scraping mid-flow.

A realistic adoption plan

  • Week 1: Add search_products and add_to_cart on product/search pages. Label forms and fix obvious a11y/name issues. Validate JSON-LD.
  • Week 2: Add update_cart_item and guarded start_checkout. Test with ChatGPT desktop app. Write two test intents.
  • Week 3: Instrument logs; tighten schemas; fix any drift. Decide if you want rollbacks and analytics via Agent Layer.

Where WebMCP works today

Summarised from verified data:

  • Agents: ChatGPT desktop app and ChatGPT Work call page tools today. Others like Brave Leo and Codex extension can work behind flags. Several agent frameworks (Vercel agent-browser, Stagehand) support it when launching a compatible Chrome.
  • Browsers: Chrome and Edge have origin trials, Brave behind a flag. Firefox and Safari do not support it.

This is evolving; confirm specifics on the ecosystem tracker.

Try it

Run the free agent-readiness audit at Agent Layer. You’ll get a score out of 100 across machine interface, semantic readability, funnel executability, and agent access, plus page-by-page tool suggestions. Then check live support status on the ecosystem page. When you’re ready to keep tools healthy in production, add the Agent Layer script to version, test, and observe your WebMCP tools without touching your backend.

Get started

Don't Be Invisible to Tomorrow's Buyers.

Make your platform executable for every AI assistant your customers already use. No engineering, no lock-in, no breakage.