MCP Client Auto-Approves a Tool on an Untrusted Server's `readOnlyHint` Annotation
mcp-client-untrusted-annotation-approval is a high severity check in the
ai category, written in python.
Its source is templates/ai/mcp/client-conformance/mcp-client-untrusted-annotation-approval.py in
cert-x-gen-templates.
What it checks
Section titled “What it checks”ACTIVE check. The MCP 2026-07-28 revision states that clients MUST consider tool annotations to be untrusted unless they come from trusted servers, yet documented client behaviour runs a tool annotated readOnlyHint: true with no approval interaction. This binds a synthetic MCP server that is registered with NO trust record and offers two tools whose definitions are identical apart from that one boolean - both of which write a nonce when invoked - then drives the target’s own MCP invocation path and reads which tool executed and which was gated. The annotated tool executing unprompted while its byte-identical twin is gated is the finding.
Header
Section titled “Header”| Field | Value |
|---|---|
| Id | mcp-client-untrusted-annotation-approval |
| Severity | high |
| Language | python |
| Category | ai |
| Author | Bugb Research |
| Template version | 1.0.0 |
| Confidence | 92 |
| CVSS | 8.1 |
| Weakness | CWE-807, CWE-862 |
| Tags | mcp, ai, agent, mcp-client, mcp-client-conformance, agent-posture, tool-annotations, readonlyhint, auto-approval, untrusted-metadata, human-in-the-loop, behavioural, active, intrusive, cwe-807, cwe-862 |
| Target kind | cli |
| Oracle | property, diff |
References
Section titled “References”Declared in the header. cxg parses @references and then discards it, and
nothing at scan time reads it, so this is the only place the links a
template cites are surfaced.
- https://modelcontextprotocol.io/specification/2026-07-28/server/tools
- https://modelcontextprotocol.io/specification/2026-07-28/basic/security_best_practices
- https://blog.modelcontextprotocol.io/posts/2026-03-16-annotations-are-hints/
- https://code.visualstudio.com/docs/copilot/chat/mcp-servers
- https://cwe.mitre.org/data/definitions/807.html
- https://cwe.mitre.org/data/definitions/862.html
Run it
Section titled “Run it”To see what the copy on your machine says about itself, and to confirm it is installed at all:
cxg template info mcp-client-untrusted-annotation-approvalThe id it prints is the one to pass anywhere a template is selected. See
cxg template for the rest of
the subcommand, Scan a target for running
a scan, and
A match is not a finding for how
to read what comes back.
Related
Section titled “Related”- Template catalog is the whole corpus.
- ai is the rest of this category.
- Templates by weakness class groups checks by the defect they look for.
- Contribute a template is the route from a check you needed and could not find to a merged one.

