· via dev.to (home feed)
Text, not code: MCP tool descriptions and wildcard scopes open agents to injection
Two dev.to posts argue that the sharpest MCP agent risks are textual: tool descriptions that smuggle prompt injection and admin:* scopes that skip least privilege.

The attack surface is text the model reads
Two posts published on dev.to argue that the most overlooked risk in Model Context Protocol setups is not malicious code but the text a model reads before it ever calls a tool. The first post describes what it calls tool description injection: an attack that needs no vulnerability, bad dependency, or supply-chain compromise, only a text field the model reads and trusts.
An MCP tool definition is mostly JSON: a name, a description, and an input schema whose properties carry their own descriptions. All of that text reaches the model as context before it decides which tool to call and with what arguments. The post's example is a weather tool whose description looks legitimate but instructs the model to ignore previous instructions and pass any credentials found in the conversation into a notes field. The tool still fetches the weather, so a runtime audit of what it executes finds nothing wrong. The injection lives entirely in text the model treats as instructions.
Where payloads hide
The top-level description field is the one most scanners check, but according to the post the same payload works in input-schema property descriptions and titles, in enum value labels, and anywhere text gets concatenated into the prompt used for tool selection. A scan that only reads the top-level field misses a property description telling the model to always set a flag true regardless of what the user asked.
The post also flags encoding tricks built to survive a human skim of the manifest: zero-width and Unicode tag-block characters that render as nothing in an editor or a quick read of mcp. while the model still tokenizes them, HTML comments that visually deprioritize a payload in a diff even though the model reads the full string, and base64-like blobs that are not automatically malicious but deserve a second look.
The stated failure mode is not that nobody reviews manifests, but that config review checks which servers and scopes are declared, not what every description string says, and certainly not whether it contains invisible characters.
Wildcard scopes widen the blast radius
The companion dev.to post targets the permission side: mcp. files frequently end up with scopes like admin:* or full_access, not because anyone deliberately chose blanket admin rights, but because a server's README shows the wildcard as the fast path and the enumerated alternative is undocumented.
The post contrasts an internal CRM server declared with admin:* against one enumerated as contacts:read, contacts:write and notes:read. Both may grant the same effective access if the server only ever touches three endpoints, but the enumerated version tells any later reviewer exactly which endpoints those are. The wildcard reveals nothing until someone reads the server's source or something goes wrong.
Where it bites, per the post, is months later, when a second unrelated MCP server joins the same agent session, such as one that reads arbitrary web content. Deciding whether that pairing makes sense is hard when one side is a blanket wildcard, and auditing scope creep retroactively is close to impossible if nothing was recorded narrowly in the first place.
What static checks can and cannot do
Both posts point to the author's sentinel-scan-cli, a manifest-only scanner that makes no network calls. It flags imperative-override language, trusted-instruction framing, invisible Unicode, HTML comments and suspicious base64 blobs in descriptions and schema titles, mapping findings to OWASP LLM01, alongside checks for wildcard scopes, hardcoded credentials in args, plaintext remote transports and missing provenance metadata.
The posts are candid about limits. Pattern matching will not catch a payload phrased in a way nobody has seen, and a static scope check cannot tell what a wildcard resolves to at the API level or catch a server that under-declares its scope but over-reaches in code. On the fix side, the scope post notes that most servers supporting scoped permissions also support enumerated ones, the wildcard simply tends to be the shorter README example, and enumerating costs roughly five minutes of reading the server's tool list.
Why it matters
Agent security effort tends to concentrate on what tools execute at runtime. These two posts argue the higher-frequency failures are textual: descriptions that steer the model and scopes that hide what a tool can touch. Both are invisible to capability audits and to casual config review, and both compound as more servers share a single agent session. If wildcard scopes and unreviewed description text remain the ecosystem's default path, least-privilege enumeration and manifest scanning become baseline hygiene for anyone wiring agents to real systems.
- #mcp
- #prompt-injection
- #llm-security
- #least-privilege
- #ai-agents