All posts
EngineeringBest practicesEcosystem

WebMCP for testing: how to verify your site works with agents

A practical guide to WebMCP for testing: add tools, verify discovery across agents, run flows safely, and keep them working in production.

Agent LayerOctober 4, 202612 min read

WebMCP for testing usually means one thing: you want to know if an agent can discover and call your site’s tools reliably. By the end of this guide you’ll have a minimal test harness, a known‑good agent to try, and a checklist to keep WebMCP working in production.

TL;DR

  • Start with feature detection: support both document.modelContext and navigator.modelContext. Log when you successfully register a tool.
  • Test in an agent that works today: ChatGPT desktop app and ChatGPT Work call page tools. Cross‑check agent and browser support on the public WebMCP ecosystem tracker.
  • Keep tools small and explicit: strong JSON Schema, short JSON results, and clear descriptions with preconditions and side effects.
  • Add a user confirmation in the execute function for sensitive actions (payments, account changes, deletions).
  • For ongoing testing and drift: use Agent Layer’s free audit, versioned configs, analytics, and health checks; write intent tests that assert which tool should fire.

First: what “testing WebMCP” really means

WebMCP exposes in‑page tools that agents can call instead of scraping your DOM. There’s no separate backend to stand up. Testing is about three things:

  1. Your page registers tools correctly and safely.
  2. Real agents can see and call them.
  3. Those calls still work after you ship UI changes.

You can do (1) and some of (2) without Agent Layer. For (3), you either build your own guardrails and drift monitoring, or you use a platform. We’ll show both paths and where Agent Layer helps.

If you’re new to the standard, see the overview in WebMCP Explained: The Native Standard Turning Websites into AI APIs and the practical setup in How to Enable WebMCP on Your Website: A Practical Guide.

Minimal, testable WebMCP setup

Start with two tools: a safe, read‑only tool and a guarded, write tool. Keep their business logic separate so you can unit test it without an agent.

// Feature detect both modern and older address
const mc: any = (document as any).modelContext ?? (navigator as any).modelContext;

// Pure logic (unit test this directly)
function getCartSummary(cart: { items: { id: string; qty: number; price: number }[] }) {
  const total = cart.items.reduce((s, i) => s + i.qty * i.price, 0);
  return { count: cart.items.length, total };
}

async function applyCouponToCart(cartId: string, code: string) {
  // Example only: do not include secrets here. Rely on the user's session.
  // Simulate a guarded mutation; in production, call your in‑page API/client.
  return { cartId, code, applied: code === "SAVE10", note: "Sample" };
}

if (mc && typeof mc.registerTool === "function") {
  mc.registerTool({
    name: "get_cart_summary",
    description: "Use to read the current cart summary. No side effects.",
    inputSchema: { type: "object", properties: {}, additionalProperties: false },
    execute: async () => {
      // Grab state from your app; here we mock from a global
      const cart = (window as any).__CART__ ?? { items: [] };
      return getCartSummary(cart);
    },
  });

  mc.registerTool({
    name: "apply_coupon",
    description:
      "Apply a coupon to the current cart. Preconditions: user has a cart. Side effect: updates pricing. Ask user to confirm the code before applying.",
    inputSchema: {
      type: "object",
      properties: { code: { type: "string", minLength: 3 } },
      required: ["code"],
      additionalProperties: false,
    },
    execute: async ({ code }: { code: string }) => {
      // Guardrail: explicit user confirmation for sensitive action
      const ok = window.confirm(`Apply coupon "${code}" to your cart?`);
      if (!ok) return { applied: false, reason: "user_cancelled" };
      const cartId = (window as any).__CART_ID__ ?? "guest";
      const result = await applyCouponToCart(cartId, code);
      return { applied: result.applied, code: result.code };
    },
  });

  console.info("WebMCP: tools registered");
} else {
  console.warn("WebMCP: modelContext not available in this environment");
}

Notes:

  • Tools run in the page, with the user’s session. Do not pass secrets, API keys, payment tokens, or card data through tool parameters.
  • Keep results small and JSON‑serialisable. Send back exactly what the agent needs to continue the workflow.

How to test discovery and calls across agents

The WebMCP ecosystem is uneven. Some agents and frameworks work today, others are behind flags or not announced. Check the live ecosystem tracker for the latest status; here’s the short version as of our own testing:

  • Works today: ChatGPT desktop app and ChatGPT Work (native “site tools” on by default). Vercel agent‑browser, Stagehand, and Browser Use work in a Chrome they launch.
  • Behind flags or early: Chrome and Edge origin trials; Brave Nightly; Puppeteer with a flag; Cloudflare Browser Run test pool.
  • No support or no signal: Claude for Chrome, Gemini in Chrome, Perplexity Comet; Safari opposed; Firefox neutral; various cloud browsers unclear.

A concrete test plan

  1. Local smoke test
  • Load your page. Open DevTools. You should see “WebMCP: tools registered.” If not, your feature detection failed or the page blocked your script.
  • Unit test the pure functions (e.g., getCartSummary) independently to catch logic bugs without an agent in the loop.
  1. Agent test that works today
  • Open the same page in the ChatGPT desktop app. Start a conversation and ask it to “use site tools to apply coupon SAVE10”. You should see the agent choose apply_coupon and return the JSON response. If it refuses or scrapes the page instead, verify the description and input schema are specific enough.
  1. Framework test in CI or local
  • Use Stagehand or Vercel agent‑browser in a launched Chrome to point at your URL and ask the same intent. These frameworks are listed as working today on the tracker.
  • For Chrome origin trial users, enroll your origin and repeat the test in a stock Chrome with the trial token.
  1. Regression checks
  • Change a selector or UI label related to your cart and re‑run. If a tool depends on that selector, this is where drift bites. Either maintain tests that simulate agent calls or use a platform with health checks.

The following sequence diagram shows a successful test call through an agent that supports page tools.

Agent calls a page tool which executes and returns a small JSON result

For more environment details and flags, see WebMCP in Chrome: what works today and how to build for it.

Writing testable tools: schemas, descriptions, results

Agents choose tools from your descriptions, then validate inputs with JSON Schema. Loose schemas or vague descriptions are the top cause of “the agent didn’t call my tool.”

  • Be explicit in descriptions: when to use it, preconditions, and side effects.
  • Strong schemas: set required fields, use minLength/minimum, and disallow additionalProperties.
  • Small results: return a minimal, stable JSON object that describes what happened. Avoid HTML or megabyte payloads.

Example of a too‑loose schema vs. a tight one:

Aspect Loose schema Tight schema
Input { type: “object” } { type: “object”, properties: { code: { type: “string”, minLength: 3 } }, required: [“code”], additionalProperties: false }
Description “Apply coupon” “Apply a coupon to the current cart. Preconditions: user has a cart. Side effect: updates pricing. Ask user to confirm the code before applying.”
Result Arbitrary object { applied: boolean, code: string }

If you need a reference set of tools for common pages, see Essential WebMCP Tools for AI‑Ready Websites.

Testing sensitive actions safely

Your execute function runs with the user’s session. For payments, account changes, or deletions, require an explicit on‑page confirmation before proceeding. The earlier example used window.confirm. In production UIs, render a lightweight modal and gate the action.

mc?.registerTool({
  name: "delete_account",
  description: "Dangerous. Deletes the signed‑in account. Always ask user to confirm.",
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
  execute: async () => {
    const ok = window.confirm("Are you sure you want to delete your account?");
    if (!ok) return { deleted: false, reason: "user_cancelled" };
    // Call your in‑page client; do not pass secrets in params
    // await client.deleteAccount()
    return { deleted: true };
  },
});

This isn’t just good hygiene. Some agents will refuse to call tools that look dangerous without a clear user consent step in the description and behavior.

For a broader security checklist, read Preventing Prompt Injection in Agentic Web Interfaces.

Verifying execution in production

You have two honest options:

  • Roll your own: add logging around execute, wire a feature flag to turn tools on per environment, and maintain a dashboard of calls, errors, and durations. Create synthetic intents in a test agent and alert on drift.
  • Use Agent Layer: add one script, define tools per template, publish versioned configs, and get health checks, analytics, and test scenarios built‑in.

Where Agent Layer helps in testing:

  • Health checks catch drift when a selector or UI changes and suggest the new selector.
  • Analytics show which agent called which tool, success or error, and duration.
  • Test scenarios let you write a user intent and the expected tool, then verify the pick.
  • Guardrails on sensitive actions are enforced consistently.
  • Versioned configs let you roll back a bad change fast.

Even if you don’t use the platform, you can still run the free agent‑readiness audit for a baseline of machine interface issues and suggested tools per page type.

End‑to‑end test recipe you can adopt today

  • Add two or three essential tools per key template (product page, cart, checkout start). If you’re not sure which, see WebMCP example: concrete uses that work today.
  • Ship to a staging origin behind basic auth.
  • Verify registration logs locally and on staging.
  • Use ChatGPT desktop app to load the staging URL and issue intents like “add this product to cart”, “apply coupon SAVE10”, “start checkout”. Confirm that tools, not DOM scraping, are used.
  • Repeat the same intents in Stagehand or Vercel agent‑browser as part of CI.
  • Add a weekly synthetic run. Record results and diffs.
  • When you change UI structure, re‑run tests. Fix any selector‑dependent logic or update tool bindings.

What WebMCP testing can’t tell you

  • It does not change your Google rankings. If you saw “WebMCP for testing SEO,” that’s a category error. For a clear view, read WebMCP for SEO: what helps, what doesn’t, and what to build.
  • It won’t make unsupported agents call tools. Some widely used extensions and browsers ignore WebMCP today. Track support on the ecosystem page and build fallbacks if needed.
  • It doesn’t replace accessibility or human UX testing. Good labels and semantic HTML help both humans and agents, but they are separate responsibilities.

Debugging when an agent doesn’t call your tool

Work through these steps in order:

  1. Feature detection
  • Confirm your code checks document.modelContext first, then navigator.modelContext, and registers without errors.
  1. Descriptions
  • Read them literally. If a tool says “apply a coupon” but not “ask user to confirm,” some agents will skip it for safety. If it lacks preconditions, the agent may try DOM actions first.
  1. JSON Schema
  • Tighten it. Add required fields, lengths, and additionalProperties: false. Agents rely on this to know they can form valid inputs.
  1. Result size and shape
  • Return minimal JSON. If you return a complex nested object or HTML, the agent may choke or ignore it.
  1. Session and state
  • Tools execute in the current page context. Ensure the required session state exists (e.g., a cart). If your app lazily loads state, make your tool read from the same source the UI uses.
  1. Agent support
  • Verify the specific agent actually reads page tools. As of now, ChatGPT desktop app does; Claude for Chrome does not. See the support tracker.
  1. Sensitive actions
  • Add an explicit confirm step. Without it, the agent may decline to call your tool.

Common pitfalls

  • Only using document.modelContext and forgetting navigator.modelContext. Lightpanda and some older builds look at the older address.
  • Vague tool descriptions. Agents pick tools by description first; ambiguity means no call.
  • Over‑permissive schemas. If everything is optional, the agent can’t be confident.
  • Returning HTML or huge payloads. Keep results compact JSON.
  • No user confirmation for dangerous actions. Expect refusal or unintended side effects.
  • Assuming WebMCP improves SEO. It doesn’t. It’s for agents executing actions.
  • Tight coupling to brittle selectors. If your execute relies on a CSS selector, you’ll face drift the next time a class name changes.
  • No observability. When a tool fails, you have no idea which agent called it or why.

What breaks in production

  • UI drift: class or DOM changes break logic inside execute. Health checks and suggested selector updates help; otherwise, maintain a test matrix per template.
  • Agent heterogeneity: different agents interpret descriptions differently. Test with at least two implementations.
  • Environment flags: origin trials and behind‑flag frameworks can silently disable tools in certain builds.
  • State timing: single‑page apps that hydrate slowly may register tools before state is ready. Either wait for state, or have execute defensively fetch what it needs.

WebMCP vs MCP in testing

MCP (Anthropic’s Model Context Protocol) runs server‑side over stdio/HTTP. WebMCP is in‑page, in the user’s browser session. For local testing of user‑initiated site actions, WebMCP is the right target. If you’re unsure about the difference, read What is the Difference Between MCP and WebMCP?.

When to bring in Agent Layer

If you only need a demo, hand‑rolled tools and a quick ChatGPT desktop test may be enough. If you need this working next quarter:

  • Run the free agent‑readiness audit for a baseline and page‑by‑page tool suggestions.
  • Use the platform to define tools per template, publish versioned configs, and roll back safely.
  • Let health checks catch drift, and use analytics to see which agents call what.
  • Write test scenarios to assert “for this intent, the agent should pick apply_coupon.”

Try it

Start by running the free agent‑readiness audit on your domain. Then validate agent and browser support for your stack on the ecosystem tracker. If you want a walkthrough of your site, book time with the founder; otherwise, the guides above will get you shipping.

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.