Back to blog
MCPtool poisoningrug pullAI agents

MCP Tool Poisoning and Rug Pulls: How to Test Them

Published on 2026-11-046 min read
In short: MCP tool poisoning hides instructions inside a tool description: the model reads and follows them, the user never sees them. A rug pull adds time to the attack: the server changes the description after you approved it. To test for both, fingerprint every tool, compare the fingerprint at each session, and check what the client really displays before a call.

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.

AttackWhere the payload hidesWhen it actsSource
Tool poisoningA tool’s description or schemaFrom the first sessionInvariant Labs, 1 April 2025
ShadowingA description that alters how another tool is usedWhen the targeted tool is calledInvariant Labs, 1 April 2025
Rug pullA description changed after approvalAfter the updateInvariant Labs, 7 April 2025
Malicious package versionThe server’s own codeAfter the package updatesBleepingComputer, 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.

  1. 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.
  2. 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.
  3. Compare over time. Re-run tools/list at each session and after each list_changed. Any change in a description should block the tool until a human reviews it.
  4. 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.
  5. 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.
  6. 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.
  7. 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?
  8. 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.

Know what your agent can do before an attacker does.

A free 30-minute discovery call: you describe your agent, I tell you what I would test and what it costs. Five case studies are published.

Book a call