MCP tool poisoning

The Model Context Protocol turned “give the agent a tool” into a one-line install, and in doing so it moved a large amount of trust to a place few people are watching: the tool description. An agent doesn’t read a server’s code. It reads the natural-language text the server hands over — the tool’s name, its description, its argument schema — and treats that text as instructions. That is the seam tool poisoning pries open. This is a field guide to the attack: what it is, the classes it comes in, what the public research actually measured, and the defenses that hold up. It is meant to be linked to, not to sell you anything.

What “tool poisoning” actually means

Tool poisoning is a form of indirect prompt injection aimed at MCP. Invariant Labs, who published the first public write-up in April 2025, defined it as an attack where “malicious instructions are embedded within MCP tool descriptions that are invisible to users but visible to AI models” (Invariant Labs, “MCP Security Notification: Tool Poisoning Attacks”). The gap it exploits is simple and structural: the model sees the complete tool description; the human usually sees a tidy one-line summary in a UI. Anything hidden in the space between those two views runs on the model’s authority without ever crossing your field of vision.

OWASP catalogs it as MCP03 — Tool Poisoning in its MCP Top 10, describing it as tampering “with the contract or schema definitions that govern agent-to-tool interactions” so that “legitimate agents behave incorrectly while passing superficial validation” (OWASP MCP Top 10, MCP03:2025). The important word there is contract. The attacker rarely needs a memory-corruption bug or a code exploit. They change the words the agent trusts, and the agent does the rest — with whatever credentials and reach you already gave it.

The Cloud Security Alliance frames the root cause precisely: a language model “cannot reliably distinguish the operational intent of a tool description from an embedded adversarial instruction” when both arrive as natural language, and a poisoned description loads into the agent’s context “in the same position — and with the same apparent authority — as system instructions” (CSA Research Note, “MCP Tool Poisoning”). There is no privilege escalation to catch, because there was never a privilege boundary between “documentation” and “command” to begin with.

The attack classes

“Tool poisoning” is an umbrella. Underneath it are a handful of distinct techniques, and defenses that stop one do not automatically stop the others.

1. Poisoned tool descriptions

The canonical case. A tool’s description carries hidden directives the model obeys. Invariant’s proof of concept used a benign-looking add tool whose description quietly instructed the Cursor agent to read ~/.cursor/mcp.json and ~/.ssh/id_rsa and smuggle their contents out through an unrelated parameter, all while presenting a plain arithmetic explanation as cover (Invariant Labs). Simon Willison’s write-up of the same disclosure names the underlying danger the lethal trifecta: the moment you mix “private data, untrusted instructions and exfiltration vectors” in one agent, a hidden instruction can turn access you granted for good reasons into a data leak (Simon Willison, “MCP has prompt injection security problems”).

2. Rug-pull updates

You review a tool, approve it, and trust it. Then the server changes the tool’s definition after approval. Willison’s summary is blunt: “MCP tools can mutate their own definitions after installation” (Simon Willison). It is the software supply-chain rug pull adapted to MCP — the thing you audited on Monday is not the thing that runs on Friday, and nothing in the base protocol forces you to notice. This is why the standing advice is to pin what you approved and detect drift, rather than trust a one-time review.

3. Cross-server shadowing

With several servers connected at once, a malicious one can plant instructions that hijack the agent’s behavior toward a different, trusted server’s tools — no one needs to call the poisoned tool for it to work. Invariant demonstrated an email-shadowing variant where a bogus tool silently redirected outgoing mail to an attacker’s address, overriding the user’s chosen recipient and never showing up “explicitly in the agent’s user-facing interaction log” (Invariant Labs). The blast radius of one bad server is the whole agent, not just that server’s own tools.

4. Schema poisoning

Instead of prose, the attacker corrupts the machine-readable schema — the argument definitions the agent and any validators rely on. OWASP describes the result as a “silent policy bypass: validation checks that match schema constraints may be bypassed because the schema itself is malicious” (OWASP MCP03:2025). If your guardrail trusts the tool’s own description of its arguments, a poisoned schema turns that guardrail into a rubber stamp.

5. Prompt injection via tool output

Even a tool you fully trust can hand back data containing instructions — a web page, an issue comment, an email body, a database row an attacker controls. The model reads the returned tokens with the same credulity it reads everything else. As Willison puts it, LLMs will trust “anything that can send them convincing sounding tokens.” The defensive principle, echoed by CSA, is to “treat tool-returned content as untrusted data” — output is not a command, no matter how authoritative it sounds (CSA).

What the data says

Two separate questions matter: how exposed is the MCP fleet, and how poisonable is it. The public research from 2025–2026 gives real numbers for both. Treat the exact figures as snapshots — methodologies and dates differ — but the direction is unambiguous.

Exposure. In an April 2026 internet scan, Censys found 12,520 reachable MCP services across 8,758 IP addresses, with 89.4% running a spec revision that supports OAuth 2.1 — while noting that MCP authorization is optional and, in practice, frequently just not switched on (Censys, “MCP Servers on the Internet”). Earlier, Trend Micro reported 492 MCP servers exposed to the public internet with no authentication or encryption, a count that had “nearly tripled to 1,467” in a follow-up (Practical DevSecOps, “MCP Security Statistics 2026”). Independent audits put the no-auth share of servers in the rough neighborhood of a quarter to two-fifths — a Zuplo report cited around 24–25% with no authentication at all, and an Astrix audit of 5,200+ servers found only 8.5% using OAuth while 53% leaned on static API keys or PATs (Practical DevSecOps).

Poisonability. An academic scan of 1,899 real-world MCP servers found roughly 5.5% exhibiting tool-poisoning characteristics (Practical DevSecOps, citing Hasan et al.). And in controlled testing, the attack works alarmingly well when nothing stops it: CSA reported laboratory testing across 45 MCP servers “recording attack success rates exceeding 60%,” with agents exfiltrating “private repository contents and message histories without user interaction” (CSA). Microsoft’s own checkpoint on the ecosystem notes that command injection and path traversal have been among the largest classes of MCP server vulnerabilities reported over the year — the kind of primitive that turns a poisoned instruction into real damage on the host (Microsoft, “The state of MCP security in 2026”).

The uncomfortable synthesis: a large, growing population of servers is reachable and under-authenticated, a measurable slice of them carry poisoned tools, and where a poison lands unguarded it succeeds most of the time. The attack is not theoretical scarcity meeting theoretical impact — both sides are populated.

Defenses that actually hold

No single control is sufficient; tool poisoning is a family, and you want overlapping mitigations. The good news is that the independent sources converge on the same short list.

  • Pin tool definitions, detect drift. Hash and pin each tool’s description and schema at the moment you approve it, then compare on every load. Invariant recommends clients “pin the version of the MCP server and its tools” using hashes or checksums; CSA says “hash and pin tool definitions at approval time.” This is the direct answer to rug pulls — the tool you audited is the only tool allowed to run.
  • Least privilege, at the argument level. Tool poisoning “redirects existing authorized access rather than circumventing access controls” (CSA). The narrower that access, the smaller the prize. A coarse allow/deny at the tool level is not enough — a single “send email” or “run query” tool is destructive or benign entirely depending on its arguments. Constraining the arguments, not just the tool name, is what shrinks the blast radius. We wrote separately on why tool-level allowlists fail and argument-level policy fixes it.
  • Human approval on sensitive calls. OWASP’s mitigations include “runtime enforcement requiring human approval for high-risk operations.” A hidden instruction can compose a request; it cannot, if you gate correctly, click approve for a call that reaches a person first. The value is highest exactly where poisoning pays off — exfiltration, spend, deletion, anything irreversible.
  • Never trust tool output as instructions. Treat everything a tool returns — and everything a tool describes — as untrusted data, not as trusted context. This is the discipline that blunts both output-borne injection and description poisoning.
  • Isolate and constrain the servers themselves. Microsoft recommends sandboxing local servers in containers with only the file-system and network access they need, and blocking outbound traffic by default (Microsoft). If a poisoned tool cannot reach the attacker’s endpoint, the exfiltration step fails even when the injection succeeds.
  • Audit tool loads and invocations. CSA calls for “structured logging of tool loads and invocations” and behavioral monitoring for anomalous actions. Because shadowing and rug pulls are designed to stay out of the user-facing log, the record that catches them has to live below the agent, not inside it.
  • Sign and version-control schemas. For schema poisoning specifically, OWASP recommends signing tool manifests, verifying signatures, and keeping schemas in immutable, reviewed registries — so a “silent policy bypass” via a tampered contract has nowhere to originate.

Where a control plane fits

Most of the defenses above share a property: they work best below the agent, at a chokepoint every tool call passes through, rather than being re-implemented inside each client. That is the honest case for a gateway or control plane, and it is worth stating plainly rather than dressing up. CSA lists “deploy an MCP gateway/proxy for description inspection” among its recommended mitigations for exactly this reason — a single point where you can pin definitions, enforce argument-level policy, hold a call for human approval, and write an audit record that the agent’s own UI can’t quietly skip.

Meandr is one such control plane. The mapping to the defenses above is direct: argument-level policy shrinks the reach a poisoned tool can exploit; human approvals gate the irreversible calls; and an immutable, queryable audit records what actually ran — who, what, and which rule decided. None of that removes your responsibility to vet servers, sandbox them, pin what you approve, and treat their output as untrusted — it concentrates the enforcement so you can apply it consistently instead of per-client. If you want the wider frame, see MCP security and MCP governance.

The one-paragraph version

Tool poisoning is prompt injection that arrives through the tool layer — hidden in a description, a schema, an update, another server, or a tool’s own output — and it works because an agent trusts natural language it cannot verify. The public data shows a large, under-authenticated MCP fleet, a real fraction of poisoned tools in the wild, and success rates above 60% where nothing intervenes. The defenses are known and boring: pin what you approved, grant the least access the job needs and constrain it at the argument level, put a human in front of anything irreversible, sandbox the servers, never treat tool output as a command, and log every call somewhere the agent can’t edit. Do those, and a poisoned description becomes a note the system ignores instead of an order it obeys.

Sources