kakeklar.no WebMCP audit

audited Aug 28, 2026in 5s
63/ 100

2 tools registered. Strongest in WebMCP use, weakest in human experience.

WebMCP use80
Usefulness75
Human experience0
about:blank

No agent run recorded yet.

No steps recorded

Tools

/?gjester=12&alder=6
plan_birthday_party: warning

plan_birthday_party

Configure the Norwegian kids' birthday party (child's age, number of child guests, accompanying adults, venue, duration, main dish, bread split and per-allergy guest counts) and generate the age-aware shopping list. Use this whenever the user wants to set up or adjust the party and see what to buy.Takes an action on the site.
pagehttps://kakeklar.no/?gjester=12&alder=6
implementation
viaimperative
entry pointdocument
registered after730ms
executepresent
api surface
agerequired
guestsrequired
adultsoptional
typeoptional
durationoptional
mainDishoptional
breadRatiooptional
allergiesoptional
annotations
read onlyfalse
destructivenot declared
idempotentnot declared
open worldnot declared
untrusted contentnot declared
titlenot declared
2 findings
warningNaming quality
1.5 / 2
Tool naming makes selection harder than it needs to be: 1 name does not start with a verb (plan_birthday_party).
fix
{ name: "plan_birthday_party" /* short, unique, verb-based */ }
warningHuman parity
0 / 8
2 of 2 tools run through the JavaScript API with no visible counterpart, so the person co-browsing cannot see what the agent is offered. Declarative forms (or at least a title annotation) close the gap.
plan_birthday_party, get_shopping_list
fix
<!-- Give the tool a visible counterpart: a declarative form is one the person can see and use too. -->
<form toolname="plan_birthday_party" tooldescription="...">
  <!-- the same action, as UI -->
</form>
tool json
{
  "name": "plan_birthday_party",
  "description": "Configure the Norwegian kids' birthday party (child's age, number of child guests, accompanying adults, venue, duration, main dish, bread split and per-allergy guest counts) and generate the age-aware shopping list. Use this whenever the user wants to set up or adjust the party and see what to buy.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "age": {
        "type": "integer",
        "minimum": 1,
        "maximum": 14,
        "description": "The birthday child's age in years (barnets alder)."
      },
      "guests": {
        "type": "integer",
        "minimum": 1,
        "maximum": 40,
        "description": "Number of child guests attending (antall barn)."
      },
      "adults": {
        "type": "integer",
        "minimum": 0,
        "maximum": 20,
        "description": "Accompanying adults who stay and also eat (voksne). Defaults to the current value."
      },
      "type": {
        "type": "string",
        "enum": [
          "hjemme",
          "barnehage"
        ],
        "description": "Where the party is held: 'hjemme' (at home) or 'barnehage' (kindergarten). Defaults to the current value."
      },
      "duration": {
        "type": "integer",
        "minimum": 1,
        "maximum": 5,
        "description": "Party length in hours (varighet). Defaults to the current value."
      },
      "mainDish": {
        "type": "string",
        "enum": [
          "polser",
          "pizza"
        ],
        "description": "Main dish: 'polser' (hot dogs) or 'pizza'. Defaults to the current value."
      },
      "breadRatio": {
        "type": "integer",
        "minimum": 0,
        "maximum": 100,
        "description": "Percent of the bread that is soft potato lompe; the rest is hot-dog buns. Only relevant when mainDish is polser. Defaults to the current value."
      },
      "allergies": {
        "type": "object",
        "description": "Number of child guests with each dietary restriction. Omit a key when no guest has that restriction.",
        "properties": {
          "gluten": {
            "type": "integer",
            "minimum": 0,
            "description": "Child guests with gluten allergy."
          },
          "melk": {
            "type": "integer",
            "minimum": 0,
            "description": "Child guests with milk allergy."
          },
          "egg": {
            "type": "integer",
            "minimum": 0,
            "description": "Child guests with egg allergy."
          },
          "nott": {
            "type": "integer",
            "minimum": 0,
            "description": "Child guests with nut allergy."
          },
          "svin": {
            "type": "integer",
            "minimum": 0,
            "description": "Child guests who do not eat pork."
          }
        },
        "additionalProperties": false
      }
    },
    "required": [
      "age",
      "guests"
    ],
    "additionalProperties": false
  },
  "annotations": {
    "readOnlyHint": false
  }
}
Showing plan_birthday_party

Findings

WebMCP use

80 / 100 · weight 50
passTools registered
4 / 4
2 tools registered across 1 page.
failReal-browser eligible
0 / 8
The page's code registers these tools, but a real visitor's browser does not get them yet: WebMCP needs a native modelContext or a current origin trial token, and this page has neither.
passRegistration timing
4 / 4
Every measured tool registered within 730.2000000476837ms of navigation.
toolget_shopping_list
passCanonical entry point
4 / 4
All 2 tools register on the canonical document.modelContext entry point.
passSchema validity
5 / 5
All 2 tools declare a structurally valid object input schema.
passSchema quality
4 / 4
All 2 tool schemas describe their parameters and stay within Chrome's size guidance.
passStub detection
5 / 5
All 2 tools declare an execute handler.
passAnnotations present
4 / 4
All 2 tools declare a readOnlyHint, so an agent knows which calls change state.
passAnnotation mismatch
3 / 3
No tool claims to be read-only while its name says it writes (2 declared hints checked).
not applicableUntrusted content hint
0 / 2
No tool's contract suggests it returns text written by somebody other than the site, so there is nothing to flag as untrusted.
passRegistration errors
2 / 2
No tool registration threw during the capture.
warningToolchange coherence
1 / 2
2 tools were registered but the page never dispatched a toolchange event, so an agent subscribed to registry updates never learns they exist.
fix
document.modelContext.dispatchEvent(new Event("toolchange"));
not applicableInjection surface
0 / 3
The injection-surface model hop returned no usable result, so tool contracts were not reviewed for injection surface.

Usefulness

75 / 100 · weight 30
warningNaming quality
1.5 / 2
Tool naming makes selection harder than it needs to be: 1 name does not start with a verb (plan_birthday_party).
toolplan_birthday_party
fix
{ name: "plan_birthday_party" /* short, unique, verb-based */ }
not applicableDescription quality
0 / 6
The description-quality model hop returned no usable result, so descriptions were not rated.
not applicableTool selection
0 / 14
The tool-selection model hop returned no usable result.
not applicableCoverage vs. site type
0 / 8
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.

Human experience

0 / 100 · weight 20
warningHuman parity
0 / 8
2 of 2 tools run through the JavaScript API with no visible counterpart, so the person co-browsing cannot see what the agent is offered. Declarative forms (or at least a title annotation) close the gap.
toolplan_birthday_party
plan_birthday_party, get_shopping_list
fix
<!-- Give the tool a visible counterpart: a declarative form is one the person can see and use too. -->
<form toolname="plan_birthday_party" tooldescription="...">
  <!-- the same action, as UI -->
</form>
not applicablePage experience
0 / 12
The page-experience model hop returned no usable result, so the page was not graded.

Tool selection

The tool-selection model hop returned no usable result.
how this was captured
chrome
148.0.7778.96
capture shim
v1
spec snapshot
2026-08
mode
fast
pages
1
tools
2
run time
5s
finished
Aug 28, 2026