ContractKit

BROWSER LAB / OBSERVED BEHAVIOR

A callback receipt is not validation.

Local schema outcomes and native browser calls answer different questions. ContractKit keeps both results visible so one cannot stand in for the other.

Reviewed 15 October 2026 · Independent developer notes

The result we observed

On 15 October 2026, we launched an isolated Chrome for Testing 156.0.8078.4 instance on macOS. The default instance did not expose document.modelContext. An instance started with --enable-features=WebMCP exposed registration, discovery and invocation. This is a dated laboratory observation, not a statement that every Chrome installation enables the feature.

Our temporary tool declared an integer count, minimum one, required, with additional properties forbidden. Its callback returned a JSON string recording the supplied input. The browser reached that callback for all four object inputs below.

InputLocal schema resultNative observation
{"count":2}AcceptCallback entered
{"count":0}Reject: minimumCallback entered
{"count":"2"}Reject: typeCallback entered
{"extra":true}Reject: required / extra fieldCallback entered

A stringified object produced a TypeError before the callback. Aborting the registration removed the tool from discovery. In a separate delayed callback case, unregistering during execution did not stop that call from returning. Download the raw dated probe record.

Try the receipt check

  1. Run the local comparison first. Read any candidate failures before looking at native behavior.
  2. In a suitable development browser, follow Chrome’s WebMCP setup instructions. The documented local testing flag is chrome://flags/#enable-webmcp-testing; restarting may be required.
  3. Return to the workbench. Native testing becomes available only when the current register, discover and execute methods are actually exposed.
  4. Select “Run native receipt check.” Compare each schema outcome with whether the callback was entered. The temporary registration is removed afterward.

You do not need an AI account, API key or language model for this check. The test registers a uniquely named tool containing the candidate input schema and a fixed local echo callback. It does not execute your pasted code or call your backend. Its annotations describe that receipt handler, not the business action your real tool may perform.

What to do with a disagreement

If a locally rejected input reaches the callback, enforce validation at your own execution boundary before changing state. Keep authorization separate: a syntactically valid account identifier does not establish that the caller may access that account. Return an understandable failure and verify that no partial operation occurred.

If registration or execution fails before a callback, record the browser build, enabled feature, page context and error. A missing API is a distinct outcome from a rejected schema. The ordinary local workbench remains usable in browsers without native support.

What still needs a separate test

The workbench does not discover another website’s tools, cross origin boundaries, inspect a live user session or observe an AI selecting among tools. It also does not measure navigation, frame delegation, permission prompts, tool-description quality or backend effects. Use your own staging application and current browser tooling for those tests. Chrome’s tool-design guidance provides the broader context.

Bring the question back to a concrete case.

Open ContractKit ↗