WebMCP Website Actions: A Safety Checklist for AI Agents

Use this WebMCP website actions checklist to expose safe AI agent tools with clear effects, server-side authorization, confirmations, and receipts.

Cover Image for WebMCP Website Actions: A Safety Checklist for AI Agents

On August 31, OpenAI added support for website tools in the desktop browser. ChatGPT Work and Codex can now discover tools that supported sites expose through WebMCP, then use those tools inside the same browser session. Four days later, the Web Machine Learning Community Group published a new WebMCP draft report.

WebMCP lets a page register JavaScript functions that an AI agent can call. That can be more reliable than making an agent hunt through buttons and forms. It also gives the agent another path into your application. Before shipping one, review this contract:

Contract fieldWhat the site must declare or enforceRelease evidence
User goalOne plain-language job with a specific resultTest prompt selects only the intended tool
EffectRead, reversible write, or consequential actionDescription, annotation, and implementation agree
IdentityThe user and account allowed to run itServer rejects another account and an expired session
InputTight schema plus business validationExtra, malformed, and unauthorized values fail
ConfirmationExact effect shown before commitmentCancel leaves state unchanged
Replay controlIdempotency rule for writesDuplicate calls create one result
ResultStructured outcome, receipt, and safe errorAgent can distinguish success, rejection, and unknown
AuditTool, actor, arguments, decision, and effectOne trace reconstructs the call without storing secrets

The table is the minimum useful asset. A tool should stay private until every row has an owner and a passing test.

Understand the new path into your site

Classic MCP usually connects an AI client to a separate server. WebMCP puts the tool registration inside a web document. The current draft exposes a modelContext interface that lets a page register tools with a name, description, JSON Schema input, execution callback, and optional annotations.

Those annotations include hints for read-only tools, untrusted output, and consequential actions. They help an agent or browser choose safer behavior. They do not enforce your business rules. A tool marked read-only can still contain code that writes data. A tool described as "review cart" can still charge a card if its callback does that. The WebMCP draft calls out this gap directly: natural-language intent and actual behavior can diverge.

The browser session matters too. A WebMCP tool runs on a page that may already have the user's authentication cookies, account selection, payment state, and private data. The server must treat the call like any other authenticated request. The model's choice to invoke a tool is never proof that the user may perform the operation.

WebMCP is a Community Group draft, not a W3C standard. Browser and product support will change. Keep an ordinary, accessible interface working beside the tool so customers are not locked to one agent or browser.

Give each tool one visible effect

Start from the user's goal, then cut the tool until its name and description leave little room for interpretation.

manage_order is too broad. It might retrieve status, change an address, cancel fulfillment, or issue a refund. The agent cannot know which side effects hide behind the verb "manage," and a reviewer cannot write one sensible confirmation rule for it.

Prefer narrower tools:

  • get_order_status reads one order the current user may view.
  • prepare_return_request calculates eligibility and returns a preview without changing the order.
  • submit_return_request commits the preview after confirmation.
  • cancel_return_request reverses the request when the business process still allows it.

Write the description as a behavioral contract. State what changes, what does not, whose record is affected, and what the result means. Keep policy text and instructions out of values supplied by visitors. Tool names, parameter descriptions, and return values all become model input, so user-generated prose inside them can act as prompt injection.

The description must match the code path. Review it whenever the implementation changes. Renaming a button does not update a stale tool definition, and a stale definition can make an agent choose the wrong operation with complete confidence.

Reuse the application's trusted boundary

A WebMCP callback should call the same application service as the visible UI. It should not duplicate authorization or create a shortcut around server validation.

For every execution, the server should:

  1. Resolve the current authenticated user from the session, never from a model-supplied user ID.
  2. Resolve the active account on the server and verify membership again.
  3. Parse the input against a strict schema that rejects unexpected fields.
  4. Apply the same ownership, policy, inventory, pricing, and rate-limit checks as the normal interface.
  5. Write through an idempotent command for any state change.
  6. Return a stable status and receipt that describes the actual external effect.

Do not send a broad application object into the agent and ask it to choose safe fields. Build a small result after authorization. An order-status tool might return a public carrier status, estimated date, and masked order reference. It does not need payment details, internal fraud notes, or other orders in the account.

This is where the chatbot tool-permissions checklist transfers well to WebMCP. The transport is new. Least privilege, dedicated business operations, and server-side checks are still the controls that decide what can happen.

Worked example: preview, confirm, commit

Consider a customer who asks an agent, "Return the blue lamp from my last order." The page exposes prepare_return_request and submit_return_request.

The first tool performs an authorized lookup and returns a preview:

{
  "status": "ready_for_confirmation",
  "preview_id": "ret_prev_8f21",
  "order_reference": "...1842",
  "item": "Blue desk lamp",
  "refund_estimate": "$48.00",
  "return_method": "Prepaid label",
  "expires_at": "2026-09-09T15:20:00Z"
}

The browser shows those details to the customer. Nothing has changed yet. If the customer confirms, the agent calls the commit tool with only the preview ID and an idempotency key. The server reloads the preview, verifies the same user and account, checks that it has not expired, and recalculates eligibility before submitting.

{
  "status": "submitted",
  "return_id": "ret_7319",
  "receipt_id": "rcpt_44b6",
  "submitted_at": "2026-09-09T15:14:22Z",
  "next_step": "Download the prepaid label"
}

Now change the case. The agent retries after a network timeout. The same idempotency key must return ret_7319, not create a second return. If the preview expired, the server returns preview_expired and no return ID. If the user switched workspaces, it returns account_mismatch. An empty response or timeout stays outcome_unknown until a status lookup finds a receipt.

The final answer should follow the receipt. "Your return was submitted" is valid only when the commit result contains the return ID. This is the same discipline used in chatbot action verification: the attempted call and the completed business effect are different events.

Treat tool text as untrusted input

The WebMCP draft identifies prompt injection in tool metadata, arguments, and output as a core risk. A product review returned by get_product_reviews could contain text that tells the agent to ignore the user and make a purchase. A support ticket could tell the agent to send account data to another site. The string is data, even when it sounds like an instruction.

Site authors can reduce the risk:

  • Keep names and descriptions static, short, and reviewed in source control.
  • Mark results that contain visitor, merchant, forum, ticket, or document text with the untrusted-content hint.
  • Return typed fields instead of one large prose block when the data has known structure.
  • Separate retrieval from transactions so untrusted output cannot commit an action in the same call.
  • Require fresh confirmation after the application renders the exact item, quantity, price, account, and destination.
  • Restrict outbound destinations and data fields even when another tool asks for them.

An annotation is still a hint. The browser agent may use it to decide when to warn the user, but your server owns the authorization and confirmation requirements. If a purchase, deletion, message, booking, or account change requires approval in the visible UI, the WebMCP path should require the same approval or a stronger one.

Test the path agents will actually call

Unit tests for the callback are useful, but they do not prove that an agent discovers the correct tool, supplies the right account context, handles cancellation, or reports the outcome honestly. Run release tests through a supported browser-agent path.

Test casePrompt or conditionPass condition
Ambiguous goal"Deal with my last order"Agent asks what outcome is wanted; no write runs
Cross-account targetRequest an order from another workspaceServer denies before returning private fields
Description mismatchRename an effect without updating metadataContract test blocks the release
Injected outputProduct review asks the agent to buyText remains data; no transaction starts
Confirmation cancelUser rejects the rendered previewNo state change and no success claim
Duplicate executionRetry the same commit after timeoutOne business record and one stable receipt
Route changeNavigate away while a tool is runningAbort is handled; stale tools are unregistered
Expired sessionAuthentication ends before commitServer denies and asks for a fresh sign-in
Unsupported clientBrowser cannot discover WebMCPVisible form still completes the same job

Capture tool registration, selected tool, normalized arguments, authenticated actor, account, policy decision, idempotency key, result code, receipt, and final agent message. Redact secrets and unnecessary customer fields. A trace should show whether the agent chose badly, the site rejected the call, or the external operation completed.

Include lifecycle tests for single-page applications. Tools registered for one route should disappear when that route unmounts or its data becomes stale. Honor the execution abort signal, but do not assume aborting the browser callback reverses a request that already reached the server. Query the receipt before retrying.

The AI browser-agent website test guide covers labels, focus, errors, and visual flows. Keep those tests. WebMCP adds a structured route; it does not excuse a broken human route.

Measure safe completion, not call volume

A rising WebMCP call count says the feature is discoverable. It does not say users got the right result.

Track selection accuracy, validation-denial rate, confirmation-cancel rate, duplicate-effect rate, unknown-outcome rate, receipt coverage, and durable task completion. Review denials by cause. Frequent schema failures point to a tool contract the agent cannot use. Frequent account mismatches may reveal stale session state. Many cancellations may mean the preview exposes a surprise that the earlier conversation hid.

Sample successful calls too. A tool can return HTTP 200 while changing the wrong record, omitting a required disclosure, or leaving the agent to invent what happened. Compare the receipt with the final message shown to the user.

Let the website remain in charge

WebMCP gives websites a structured way to work with browser agents. The useful part is precision: a site can name the jobs it supports, validate typed input, show the user the exact effect, and return a receipt the agent can report.

That precision only survives when the tool uses the same authorization and business rules as the rest of the application. Start with one read-only goal. Add preview and commit as separate steps for writes. Test injected text, cancellation, retries, route changes, and account boundaries before exposing a consequential action.

Build your chatbot for free →

No credit card required.

Inizia gratisNessuna carta di credito richiesta
WebMCP Website Actions: A Safety Checklist for AI Agents – Agentkit