What is MCP tool poisoning?
It is indirect prompt injection placed in a tool’s metadata. Invariant Labs described the attack on 1 April 2025: a tool description carries instructions that are invisible to the user but visible to the model, and the model acts on them.
The mechanism comes from how MCP works. The client asks for the tool list (tools/list) and hands the name, description and schema of each tool to the model. The model treats that text as trusted context, although it comes from a third-party server. Our MCP security page covers this attack surface in detail. The logic matches classic prompt injection, except that the channel is the tool definition rather than the content of a document.
In the experiment Invariant described, a server offered an innocent-looking add tool. Its description told the model to read ~/.cursor/mcp.json and the SSH keys, then pass them as a parameter to the tool. The client tested was Cursor, and its confirmation dialog showed only a simplified version of the call, without the full arguments.
What is an MCP server “rug pull”?
A rug pull is a change of behaviour after approval. Invariant describes it this way: a malicious server modifies a tool description once the client has validated it, so a user who trusted the server is attacked later. The comparison they draw is with malicious updates on package registries.
On 7 April 2025 Invariant published a variant against whatsapp-mcp. A server first shows a harmless tool (a “fact of the day”), the user approves it, and on the next launch the description becomes poisoned. It tells the agent to send WhatsApp messages to a number controlled by the attacker, with the user’s conversations in the message body. The malicious server never even needs to be called: the description alone steers the agent.
The postmark-mcp case shows the same pattern on the supply chain side. According to BleepingComputer (25 September 2025), this unofficial npm package was clean up to version 1.0.15. Version 1.0.16 added a line that silently copied the publisher on every email sent, over roughly 1,500 downloads. That is not a poisoned description, but it is a server changing after it earned trust.
| Attack | Where the payload hides | When it acts | Source |
|---|---|---|---|
| Tool poisoning | A tool’s description or schema | From the first session | Invariant Labs, 1 April 2025 |
| Shadowing | A description that alters how another tool is used | When the targeted tool is called | Invariant Labs, 1 April 2025 |
| Rug pull | A description changed after approval | After the update | Invariant Labs, 7 April 2025 |
| Malicious package version | The server’s own code | After the package updates | BleepingComputer, 25 September 2025 |
What does the MCP specification say about this risk?
It asks clients not to trust servers blindly. The specification (18 June 2025 version) says clients must treat tool annotations as untrusted unless they come from a trusted server, and that there should always be a human able to deny a tool call.
It also recommends that clients show a tool’s inputs to the user before the call, to avoid malicious or accidental exfiltration, and that they log tool usage. On the server side it lists input validation, access controls and rate limiting. A server can also signal a change to its tool list with the notifications/tools/list_changed notification. Treat that signal as a security event to log and check.
How do you test for tool poisoning and rug pulls?
Test four things: what the user sees, what the model follows, what changes over time, and what leaves. Run every test against a test server you control and a development or staging environment, never against real data.
- Inventory. List the MCP servers wired to the agent, their version, their origin (publisher, repository, package) and the tools they expose. A server nobody can trace is already a finding.
- Fingerprint. Compute a hash of each tool’s name, description and schema, and store it. Invariant recommends pinning versions and verifying descriptions by hash before use.
- Compare over time. Re-run
tools/listat each session and after eachlist_changed. Any change in a description should block the tool until a human reviews it. - Display test. On a test server, put a long harmless marker in a description, with part of it hidden (line breaks, text at the end of the field). Check what the client shows: the full description, a truncated one, or only the name.
- Obedience test. In a test tool’s description, ask the model to add a canary token to a parameter. If the canary reaches the server, the model follows descriptions without any check.
- Shadowing test. Deploy two test servers: a legitimate one with a send tool, and another whose description tries to redirect recipients. Compare the recipient the user asked for with the one that actually receives the message.
- Rug pull test. Make the test server change its description between two sessions. Did the agent ask for approval again? Does a log record the change?
- Parameter test. Check whether the confirmation dialog shows the full arguments. In Invariant’s example, that is exactly what was missing.
Our method explains how we frame these tests, and nothing is kept without the client’s agreement.
Which defences should you put in place?
Pin, display, isolate, filter. Invariant’s recommendations line up with the specification:
- Pin server versions and tool descriptions, verified by hash.
- Display the full description and the arguments before any sensitive call, separating text meant for the user from text meant for the model.
- Isolate servers from each other: one server must not be able to influence how another server’s tools are used. Invariant talks about dataflow controls between servers.
- Limit the rights of each tool: an addition tool needs no file system or network access.
- Validate outputs and parameters on the server side, and keep a human in the loop for irreversible actions (see our article on human approval).
- Log the tool lists seen, the changes and the calls.
Invariant stresses one point: protecting descriptions is not enough, you also have to control the data going into and out of the model.
Which frameworks should a report cite?
Tool poisoning falls under LLM01 (prompt injection) and LLM03 (supply chain) in the OWASP Top 10 for LLM Applications 2025, and under LLM06 (excessive agency) when the tool holds overly broad rights. For agents, the OWASP Top 10 for Agentic Applications (published 9 December 2025) has an ASI04 entry on agentic supply chain vulnerabilities and an ASI02 entry on tool misuse and exploitation.
How does CleanIssue test this risk?
We treat tool poisoning and rug pulls as two cases of one control: the trust given to whatever describes a tool. In the Agent Red Team Express, we connect a test MCP server to the agent, on your development or staging environment, and measure what the client displays, what the model executes and what changes between two sessions. For several agents and several servers, the scope is quoted as a Custom Red Team. The deliverable follows the format of the sample report.
A free 30-minute first call is enough to list your MCP servers and decide whether this test makes sense for you.
Does your product ship an AI agent? CleanIssue tests what a stranger can make it do with the Agent Red Team Express (5 days, €1,900), or a custom red team for several agents and MCP servers. First step: a free 30-minute discovery call.
Related articles
Three adjacent analyses to keep exploring the same attack surface.
MCP Connected to a Database: What to Lock Down
An MCP server wired to your database inherits its account's rights. Risks, account hardening, server audit points and a step-by-step testing protocol.
Function Calling: The AI Agent Attack Surface
Function calling and AI agents: five families of tool attacks, safer tool design and a testing protocol to limit unauthorized actions.
Azure DevOps MCP: Hidden Instruction in a Pull Request
The Azure DevOps MCP server returns the raw pull request description, HTML comments included, to the agent. Mechanism, conditions, no fix as of July 21.
Sources
- Invariant Labs: MCP Security Notification, Tool Poisoning Attacks
- Invariant Labs: WhatsApp MCP Exploited
- MCP specification (18 June 2025): Tools
- BleepingComputer: unofficial Postmark MCP npm package stole emails
- Promptfoo: OWASP Top 10 for Agentic Applications (ASI01 to ASI10)
- OWASP: LLM01 Prompt Injection
Related services
If this topic maps to a real risk in your stack, these are the most relevant CleanIssue audits.