WEBMCP AUDIT REPORT

https://example.by/

scanned2026-10-21T08:47:23.298Z
rulepackrulepack-2026.10.1
scannerwebmcp-scanner/0.3.0
tools9
$ node scanner/bin/webmcp-scan.js https://example.by/
live Live

Visible to real users: tools are registered through the native, flag-free WebMCP API. Any capable agent visiting this page today can see and call them.

D
security grade from deterministic rules only
0critical
0high
4medium
0low
5info

Origin trial tokens

kindfeatureoriginexpirysubdomainorigin matchesstatus
meta WebMCP https://example.by:443 2026-11-17T00:00:00.000Z no no valid

Agent readiness: 16 of 18 checks pass

Can an AI agent find, open and understand this page? These checks read robots.txt, llms.txt, the sitemap, security.txt and the page's own metadata. They never affect the security grade; each one links to its fix and to the vendor document it rests on.

statuscheckevidencefinding
pass Page opens for a bot HTTP 200, "Services Hub — 100% Client-Side Tools & Apps"
pass robots.txt present 8 group(s), 1 sitemap line(s)
pass Page allowed for every crawler User-agent: * allows /
pass On-demand assistant fetchers allowed ChatGPT-User, Claude-User, Perplexity-User allowed
pass AI search crawlers allowed OAI-SearchBot, Claude-SearchBot, PerplexityBot, Googlebot, Bingbot, Applebot allowed
pass Training crawlers none blocked (vendor default)
pass AI usage policy stated explicit groups for Googlebot, Bingbot
pass Sitemap reachable urlset, 32 <loc> entries (via robots.txt)
pass Sitemap declared in robots.txt https://example.by/sitemap.xml
info llms.txt HTTP 404 site.llms-txt-missing
info security.txt (RFC 9116) HTTP 404 site.security-txt-missing
pass Indexable (no noindex) index, follow
pass <title> present "Services Hub — 100% Client-Side Tools & Apps"
pass Meta description present 212 chars
pass Canonical URL declared https://example.by/
pass Structured data (JSON-LD) WebSite
pass Open Graph preview Services Hub — 100% Client-Side Tools & Apps, image
pass Document language en

Coverage

techniquestatustimeevidence
Native, flag offcomplete5174 ms1 frame(s), 9 tool(s)
Native, flag forced oncomplete4945 ms1 frame(s), 9 tool(s)
Document-start capture hookcomplete4947 ms1 frame(s), 9 tool(s)

No explicit Permissions-Policy: tools=… directive was observed; the specification default is self.

Tools

nametitledescriptionoriginsourceannotationsschema props
list-tools List the tools and apps published on the Services Hub, with id, category, description, URL, tags, logo, tech stack, demo video (when there is one) and capabilit… https://example.by native 5
list-categories List the categories the Services Hub tools are grouped into, with how many tools sit in each. https://example.by native 0
get-tool Return the full record for one Services Hub tool: description, every domain it answers on, where the processing happens, accepted and produced formats, interfac… https://example.by native 1
search-tools Find Services Hub tools by keyword. Searches names, descriptions, categories, domains, file formats and the task phrasings each tool is indexed under. https://example.by native 1
recommend-tool Describe a task in plain language and get the Services Hub tools that fit it, best first, with the reason each one matched. Use this when you know what the user… https://example.by native 2
find-tool-for-file Given a filename, extension or MIME type, return the Services Hub tools that accept it, and the tools that produce it. https://example.by native 1
list-formats List every file format the Services Hub handles, mapping each input format to the tools that read it and each output format to the tools that write it. https://example.by native 0
open-tool Open one of the Services Hub tools in a new browser tab, by its name. This navigates the user, so only call it once they have chosen a tool. https://example.by native 1
set-theme Switch the Services Hub between the light and dark colour themes. https://example.by native 1

Findings

SECURITY 4

MEDIUM SECURITY LLM08 deterministic
missing-annotations

Mutating tool ships without readOnlyHint

Tool "list-formats" looks state-changing but declares no readOnlyHint. Agents use that flag to gate risky calls; without it they cannot tell this tool apart from a safe read.

tool list-formats · field annotations
{}
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check missing-annotations
How to fix

Set readOnlyHint explicitly on every tool: true for reads, false for anything that changes state.

annotations: { readOnlyHint: false }
full explanation of missing-annotations
MEDIUM SECURITY LLM08 deterministic
missing-annotations

Mutating tool ships without readOnlyHint

Tool "set-theme" looks state-changing but declares no readOnlyHint. Agents use that flag to gate risky calls; without it they cannot tell this tool apart from a safe read.

tool set-theme · field annotations
{}
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check missing-annotations
How to fix

Set readOnlyHint explicitly on every tool: true for reads, false for anything that changes state.

annotations: { readOnlyHint: false }
full explanation of missing-annotations
MEDIUM SECURITY LLM05 deterministic
schema-freeform-sink

Unvalidated free-form input on a sink-like parameter

Parameter "query" of tool "search-tools" accepts a free-form string with no enum/pattern/format. If it reaches a shell, filesystem, or outbound request, it is an injection/SSRF surface.

tool search-tools · field inputSchema.properties.query
{"type":"string","description":"Keyword to search for, e.g. \"pdf\", \"watermark
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check schema-freeform-sink
How to fix

Constrain the schema (enum, pattern, format, maxLength) and validate again inside execute(): a schema is documentation for the agent, not authorisation.

url: { type: "string", format: "uri", pattern: "^https://example\\.com/", maxLength: 2048 }
full explanation of schema-freeform-sink
MEDIUM SECURITY LLM05 deterministic
schema-freeform-sink

Unvalidated free-form input on a sink-like parameter

Parameter "file" of tool "find-tool-for-file" accepts a free-form string with no enum/pattern/format. If it reaches a shell, filesystem, or outbound request, it is an injection/SSRF surface.

tool find-tool-for-file · field inputSchema.properties.file
{"type":"string","description":"A filename, extension or MIME type, e.g. \"repor
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check schema-freeform-sink
How to fix

Constrain the schema (enum, pattern, format, maxLength) and validate again inside execute(): a schema is documentation for the agent, not authorisation.

url: { type: "string", format: "uri", pattern: "^https://example\\.com/", maxLength: 2048 }
full explanation of schema-freeform-sink

AGENT-UX 4

INFO AGENT-UX deterministic
agentux.freeform-string-args

Free-form string parameter on a tool that implies a bounded choice

Tool "list-tools" reads as choice/filter-like but parameter "category" has no enum/pattern/format/maxLength. A prior measurement round found enum-vs-free-text tool-call accuracy significantly different (p=0.0079); constrain the value set if the domain is bounded.

tool list-tools · field inputSchema.properties.category
{"type":"string","description":"Category filter, e.g. \"Converters\" or \"Games\
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check agentux.freeform-string-args
How to fix

Use an enum for a bounded domain; models call enum parameters more accurately than free text.

status: { type: "string", enum: ["open", "shipped", "delivered"] }
full explanation of agentux.freeform-string-args
INFO AGENT-UX deterministic
agentux.freeform-string-args

Free-form string parameter on a tool that implies a bounded choice

Tool "list-tools" reads as choice/filter-like but parameter "platform" has no enum/pattern/format/maxLength. A prior measurement round found enum-vs-free-text tool-call accuracy significantly different (p=0.0079); constrain the value set if the domain is bounded.

tool list-tools · field inputSchema.properties.platform
{"type":"string","description":"Platform filter, e.g. \"web\" or \"macOS\"."}
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check agentux.freeform-string-args
How to fix

Use an enum for a bounded domain; models call enum parameters more accurately than free text.

status: { type: "string", enum: ["open", "shipped", "delivered"] }
full explanation of agentux.freeform-string-args
INFO AGENT-UX deterministic
agentux.freeform-string-args

Free-form string parameter on a tool that implies a bounded choice

Tool "list-tools" reads as choice/filter-like but parameter "language" has no enum/pattern/format/maxLength. A prior measurement round found enum-vs-free-text tool-call accuracy significantly different (p=0.0079); constrain the value set if the domain is bounded.

tool list-tools · field inputSchema.properties.language
{"type":"string","description":"Interface language filter, e.g. \"en\" or \"ru\"
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check agentux.freeform-string-args
How to fix

Use an enum for a bounded domain; models call enum parameters more accurately than free text.

status: { type: "string", enum: ["open", "shipped", "delivered"] }
full explanation of agentux.freeform-string-args
INFO AGENT-UX deterministic
agentux.freeform-string-args

Free-form string parameter on a tool that implies a bounded choice

Tool "find-tool-for-file" reads as choice/filter-like but parameter "file" has no enum/pattern/format/maxLength. A prior measurement round found enum-vs-free-text tool-call accuracy significantly different (p=0.0079); constrain the value set if the domain is bounded.

tool find-tool-for-file · field inputSchema.properties.file
{"type":"string","description":"A filename, extension or MIME type, e.g. \"repor
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check agentux.freeform-string-args
How to fix

Use an enum for a bounded domain; models call enum parameters more accurately than free text.

status: { type: "string", enum: ["open", "shipped", "delivered"] }
full explanation of agentux.freeform-string-args

RECOMMENDED 1

INFO RECOMMENDED deterministic
schema.no-required

Schema has properties but no required list

Tool "list-tools"'s inputSchema declares properties but no `required` array. Opinion: most tools have at least one mandatory argument; an empty required list often just means the author never filled it in.

tool list-tools · field inputSchema.required
(absent)
$ mcpaudit-webmcp-scan --url 'https://example.by/' --check schema.no-required
How to fix

List the arguments the tool cannot run without.

required: ["query"]
full explanation of schema.no-required

READINESS 2

INFO READINESS deterministic
site.llms-txt-missing

No llms.txt

Optional but cheap: a short markdown index of what the site is and which pages matter, read by coding agents and assistants and audited by Chrome Lighthouse. Google Search ignores it (neither helps nor harms ranking).

How to fix

Add /llms.txt: an H1 with the site name, a one-line blockquote summary, then H2 sections of markdown links to the pages an agent should read. Google Search ignores the file (neither helps nor harms ranking); Chrome Lighthouse audits for it.

# Jane Doe

> Senior backend engineer (Go, Postgres), Berlin. CV, projects and contact.

## CV
- [Resume](https://example.com/cv.md): experience and skills

## Projects
- [Project A](https://example.com/projects/a.md): what it is and why it matters
full explanation of site.llms-txt-missing

Registering your own tools?

Start from a config the checks above already pass.

Build your own WebMCP config

Need a detailed audit?

On request we run a detailed MCP audit and prepare everything you need: findings, fixes and ready configs.

Order an audit

This is an automated, point-in-time report from three browser observations of the page: native without a forced flag, native with the experimental feature forced on, and a document-start registration capture. No tool or declarative form was executed, no account was used, and hidden or interaction-only states may not be represented. Agent-readiness checks fetch robots.txt, llms.txt, the sitemap, security.txt and the AI Catalog once each and never affect the grade. The grade, when shown, reflects deterministic checks only and is not a certification. Job edad6655b4ab4f0d. Rulepack rulepack-2026.10.1.