audited Sep 9, 2026in 13s
64/ 100100% of the applicable check weight evaluated

15 tools registered. Strongest in tool selection, weakest in trust.

Shared experience62
Tool selection100
Tool quality83
Trust0
https://chameleon-webmcp.ryan-970.workers.dev
Captured view of https://chameleon-webmcp.ryan-970.workers.dev

Tools

0 read, 0 write, 15 undeclared
Loading map
describe_current_state: fail

describe_current_state

Returns the board snapshot plus unfinished. Empty tables, kanban, and checklists need add_rows (or bind_data first). A form with fields but no minted tool needs create_form_tool. add_rows does not mint. Also: title, theme, widgets (id, type, title, position, config, fields, rowCount, sample rows), mintedTools, last 10 activity entries, stateVersion, and humanChangesSinceLastDescribe: every human create, rename, drag, edit, delete, undo, or sample-load command since your last call, newest first with undone state. Read it before reorganizing so you build on their changes rather than over them. Pass stateVersion as expectedStateVersion on your next static mutation; STALE_STATE means re-read.No behaviour hints declared. Agents should treat it as possibly state-changing.
pagehttps://chameleon-webmcp.ryan-970.workers.dev/
implementation
viaimperative
entry pointdocument
registered after297ms
executepresent
api surface
include_sample_rowsoptional
annotations
read onlynot declared
untrusted contentnot declared
titlenot declared
3 findings
warningSchema quality
weight 4
15 of 15 tool schemas are harder for an agent to use than they need to be: describe_current_state description is 697 characters, over Chrome's 500-character guidance.
describe_current_state: description is 697 characters, over Chrome's 500-character guidance; add_widget: 1 parameter has no description (title); bind_data: 1 parameter has no description (fields); add
fix
{
  name: "describe_current_state",
  inputSchema: {
    type: "object",
    properties: {
      query: { type: "string", description: "What to search for" }
    },
    required: ["query"]
  }
}
failAnnotations present
weight 5
3 of 3 read-shaped tools do not declare readOnlyHint: true, so an agent has to treat them as possible writes and ask before calling. (Declaring readOnlyHint: false earns nothing - it is the default.)
describe_current_state, read_widget_data, get_activity_log
fix
{
  name: "describe_current_state",
  // Declare readOnlyHint: true on tools that truly have no side effects -
  // that is the claim that lets an agent relax confirmation on reads.
  // (false is the default, so declaring it adds no information.)
  annotations: { readOnlyHint: true }
}
warningInjection surface
weight 3
7 of 15 tools carry instruction-shaped text in their own metadata: describe_current_state Description instructs agent how to behave.
describe_current_state: Description instructs agent how to behave; add_widget: Description instructs agent on tool preference and usage; add_rows: Description instructs agent on required actions and prohibitions; create_form_tool: Description instructs agent on required actions and prohibitions
fix
{
  name: "describe_current_state",
  // Metadata DESCRIBES the tool - it never addresses the agent reading it.
  // Rewrite any name, description, title, or schema field description that
  // instructs the agent (which tool to prefer, what to output, rules to
  // ignore) so it states what the tool does and what it returns instead.
  description: "Searches the catalog and returns matching items with prices."
}
tool json
{
  "name": "describe_current_state",
  "description": "Returns the board snapshot plus unfinished. Empty tables, kanban, and checklists need add_rows (or bind_data first). A form with fields but no minted tool needs create_form_tool. add_rows does not mint. Also: title, theme, widgets (id, type, title, position, config, fields, rowCount, sample rows), mintedTools, last 10 activity entries, stateVersion, and humanChangesSinceLastDescribe: every human create, rename, drag, edit, delete, undo, or sample-load command since your last call, newest first with undone state. Read it before reorganizing so you build on their changes rather than over them. Pass stateVersion as expectedStateVersion on your next static mutation; STALE_STATE means re-read.",
  "inputSchema": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
      "include_sample_rows": {
        "default": true,
        "description": "Set false to omit sample rows for a smaller response.",
        "type": "boolean"
      }
    },
    "additionalProperties": false
  },
  "annotations": {}
}
Showing describe_current_state

Findings

Shared experience

62 / 100 · weight 30
not applicableVisible effect
weight 6
Not invoked on this run: this audit did not call any tool. Scheduled re-audits only read the registry; a live audit from the report page calls the tools that declare readOnlyHint: true.
warningPage experience
weight 16
3 of 4 page-experience marks came back short: usable The page is mostly blank, with a warning about browser compatibility..
usable: weak; clarity: weak; obstruction: weak
warningHuman parity
weight 8
The page the person sees came back short of the agent surface (3 of 4 page-experience marks came back short: usable The page is mostly blank, with a warning about browser compatibi...), so the two are not sharing an equal experience.
fix
// Make the tool's effect visible on the page the person is looking at:
// update the same UI your existing human flow uses when your_tool_name runs,
// so the person co-browsing sees what the agent just did.
execute: async (args, { signal }) => {
  const result = await performAction(args, signal);
  renderResultInPage(result); // the human-visible half of the same action
  return result;
}

Tool selection

100 / 100 · weight 25
not applicableInvoke success rate
weight 6
Not invoked on this run: this audit did not call any tool. Scheduled re-audits only read the registry; a live audit from the report page calls the tools that declare readOnlyHint: true.
passTool selection
weight 12
An agent chose an existing, callable tool and built a schema-valid call for all 3 canonical intents, each matching the kind of tool its intent needs. Nothing was executed, so this verifies selection, not outcomes.
not applicableCoverage vs. site type
weight 7
This tool set does not place the site in a category with a known expected tool shape, so there is no coverage baseline to score it against.

Tool quality

83 / 100 · weight 25
passRegistration timing
weight 1
Every measured tool registered within 301ms of navigation.
toolset_theme
passCanonical entry point
weight 3
All 15 tools register on the canonical document.modelContext entry point.
passSchema validity
weight 4
All 15 declared input schemas are structurally valid object schemas.
warningSchema quality
weight 4
15 of 15 tool schemas are harder for an agent to use than they need to be: describe_current_state description is 697 characters, over Chrome's 500-character guidance.
tooldescribe_current_state
describe_current_state: description is 697 characters, over Chrome's 500-character guidance; add_widget: 1 parameter has no description (title); bind_data: 1 parameter has no description (fields); add
fix
{
  name: "describe_current_state",
  inputSchema: {
    type: "object",
    properties: {
      query: { type: "string", description: "What to search for" }
    },
    required: ["query"]
  }
}
warningNaming quality
weight 2
Tool naming makes selection harder than it needs to be: 2 names do not start with a verb (bind_data).
toolbind_data
fix
{ name: "bind_data" /* short, unique, verb-based */ }
passStub detection
weight 4
All 15 tools declare an execute handler.
passRegistration errors
weight 2
No tool registration threw during the capture.
passDescription quality
weight 5
All 15 rated tool descriptions say what the tool does, when to use it, and what it returns.

Trust

0 / 100 · weight 20
failAnnotations present
weight 5
3 of 3 read-shaped tools do not declare readOnlyHint: true, so an agent has to treat them as possible writes and ask before calling. (Declaring readOnlyHint: false earns nothing - it is the default.)
tooldescribe_current_state
describe_current_state, read_widget_data, get_activity_log
fix
{
  name: "describe_current_state",
  // Declare readOnlyHint: true on tools that truly have no side effects -
  // that is the claim that lets an agent relax confirmation on reads.
  // (false is the default, so declaring it adds no information.)
  annotations: { readOnlyHint: true }
}
not applicableAnnotation mismatch
weight 5
No tool declares a readOnlyHint, so there is no safety claim to contradict.
not applicableUntrusted content hint
weight 3
No tool's contract suggests it returns text written by somebody other than the site, so there is nothing to flag as untrusted.
not applicableHint vs. observed
weight 4
Not invoked on this run: this audit did not call any tool. Scheduled re-audits only read the registry; a live audit from the report page calls the tools that declare readOnlyHint: true.
warningInjection surface
weight 3
7 of 15 tools carry instruction-shaped text in their own metadata: describe_current_state Description instructs agent how to behave.
tooldescribe_current_state
describe_current_state: Description instructs agent how to behave; add_widget: Description instructs agent on tool preference and usage; add_rows: Description instructs agent on required actions and prohibitions; create_form_tool: Description instructs agent on required actions and prohibitions
fix
{
  name: "describe_current_state",
  // Metadata DESCRIBES the tool - it never addresses the agent reading it.
  // Rewrite any name, description, title, or schema field description that
  // instructs the agent (which tool to prefer, what to output, rules to
  // ignore) so it states what the tool does and what it returns instead.
  description: "Searches the catalog and returns matching items with prices."
}

Tool selection

100% across 3 intents
I want to describe current state on this site.ok
chosedescribe_current_stateexpected describe current statekind matched
arguments
{}
I want to add widget on this site.ok
choseadd_widgetexpected add widgetkind matched
arguments
{
  "type": "table",
  "title": "New Widget"
}
I want to bind data on this site.ok
chosebind_dataexpected bind datakind matched
arguments
{
  "widgetId": "w_x8Kd2q",
  "fields": [
    {
      "key": "field_name",
      "label": "Field Name",
      "type": "text"
    }
  ]
}
model: gemini-2.5-flash

Add the tools this site is missing

Our scanner reads your website and suggests the right WebMCP tools for it.
Reads the site's public pages; takes a few seconds.
The open source webmcp plugin teaches your coding agent to audit a site, implement tools on document.modelContext, and verify them in a real browser. npx @ora-ai/webmcp-verify runs the verification on its own. No signup, no hosted service.
how this was captured
observed via
capture shim (Chromium 151.0.7922.34)
chrome
151.0.7922.34
capture shim
v3
spec snapshot
2026-08-26
mode
fast
pages
1 - entry page only
tools
15
invoked
not invoked; a live audit calls them
run time
13s
finished
Sep 9, 2026
Checked the way in-browser agents discover tools: the top-level document's modelContext registry, read after the page settles.