---
title: "MCP tool poisoning: how it works, real CVEs and how to defend agents"
canonical: https://pharosone.ai/knowledge/poisoned-tool-descriptions-and-memory
publisher: PharosOne (Agentic Mind, Inc.)
updated: 2026-10-23
license: "Open for reuse: crawling, copying, quoting, summarising and model training permitted without asking; citation of the title and canonical URL requested (see https://pharosone.ai/terms#reuse)"
cite_as: "\"MCP tool poisoning: how it works, real CVEs and how to defend agents\". PharosOne, 2026-10-23. https://pharosone.ai/knowledge/poisoned-tool-descriptions-and-memory"
---

# MCP tool poisoning: how it works, real CVEs and how to defend agents

> Poisoned tool descriptions, rug pulls after approval and memory poisoning, with MCPTox and CVE-2025-54136 evidence, the controls that help and how to test.

URL: https://pharosone.ai/knowledge/poisoned-tool-descriptions-and-memory · Category: Threats · Published: 2026-10-22 · Updated: 2026-10-23 · Author: PharosOne Research · Reviewed by: PharosOne editorial

*PharosOne sells pentests of AI agents and the runtime guard Pharos Radar, and wrote this article.*

**In short.** Tool poisoning hides instructions for the model inside a tool's description or schema, so the agent is steered before it calls anything. A rug pull is a tool that turns malicious after it was approved. Memory poisoning plants instructions in what the agent stores and reads back in later sessions. All three reach the model through tool metadata and stored memory, channels that many input filters are never given; whether a filter sees them depends on what the integration sends it. They are tested by giving the agent a hostile tool and a seeded memory, limited by pinning, least privilege and sandboxing, none of which stops the model from reading an injected description, and detected by scanning tool descriptions before use and by watching the agent's actions at runtime.

## Key facts

- Updated: 23 October 2026.
- Who it is for: teams running third-party MCP servers, agent marketplaces, or agents with long-term memory, a RAG index or shared context files.
- Standards: OWASP Agentic Top 10 ASI04 Agentic Supply Chain Vulnerabilities and ASI06 Memory & Context Poisoning; MCP specification 2025-11-25, Tools and Security Best Practices.
- Open-source scanners for MCP tool descriptions: Snyk Agent Scan (formerly Invariant's MCP-Scan), Cisco's MCP Scanner and mcp-watch; what each checks is below.
- Next step: run the do-it-yourself test below on one agent before you connect a new MCP server.

## What is tool poisoning?

The Model Context Protocol (MCP) is an open protocol in which a server advertises tools, each with a name, a description and an input schema, and the model decides when to call them; the specification calls tools "model-controlled" ([MCP specification, Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)). The description is written for the model.

Tool poisoning is the attack Invariant Labs described on 1 April 2025: "malicious instructions are embedded within MCP tool descriptions that are invisible to users but visible to AI models" ([Invariant Labs](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks)). In their demonstration an arithmetic tool's description told the model to read the user's SSH private key and hand it over, while the user saw an addition. A second form, shadowing, uses one server's description to change how the agent uses a trusted tool from another server; in their test it redirected outgoing email to the attacker's address, and the poisoned tool itself was never called.

The MCPTox benchmark measured the class on 45 live MCP servers and 353 real tools with 20 LLM agents, counting a success only when the agent called a legitimate tool to carry out the malicious action. The highest attack success rate was 72.8%, for o1-mini, and the model that refused most often, Claude-3.7-Sonnet, refused in under 3% of cases ([Wang et al., 2025](https://arxiv.org/abs/2508.14925)).

## What is a rug pull?

A rug pull is a tool that behaves as described when approved and changes afterwards. Invariant's wording: "a malicious server can change the tool description after the client has already approved it" ([Invariant Labs](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks)). On 7 April 2025 they showed it against a WhatsApp MCP setup: a fact-of-the-day server presented a harmless description on first launch and switched to a poisoned one on the second, after which the agent sent the user's chat history to an attacker's number through the legitimate messaging tool ([Invariant Labs, WhatsApp](https://invariantlabs.ai/blog/whatsapp-mcp-exploited)).

In August 2025 a related configuration rug pull reached a CVE: CVE-2025-54136 (MCPoison, Check Point Research) let an approved MCP configuration in a shared repository be altered after approval, so a command ran every time the project opened in Cursor, with no new prompt ([Check Point Research](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)). Here the code ran without the model following any instruction. In CVE-2025-54135 (CurXecute, Aim Security), fixed in the same Cursor release line, injected text in content the agent read through an MCP server made it write a new entry into its MCP configuration, which ran without approval ([CVE record](https://www.cve.org/CVERecord?id=CVE-2025-54135)).

The MCP specification addresses both sides. On tool annotations, the hints a server gives about a tool's behaviour, it says clients "MUST consider tool annotations to be untrusted unless they come from trusted servers". On invocation it recommends, as a SHOULD, that "there SHOULD always be a human in the loop with the ability to deny tool invocations" ([MCP specification, Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)).

## What is memory poisoning?

Memory poisoning is writing attacker-chosen content into a store the agent reads back later: a conversation memory, a RAG index, or a context file loaded at session start. OWASP lists it as ASI06 Memory & Context Poisoning in the Agentic Top 10 ([OWASP, December 2025](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/)). The evidence:

- SpAIware, September 2024: a web page made the ChatGPT macOS app store instructions in long-term memory, and later sessions kept sending the conversation to an attacker's server. OpenAI fixed the exfiltration path in version 1.2024.247; the memory write remained possible ([Rehberger](https://embracethered.com/blog/posts/2024/chatgpt-macos-app-persistent-data-exfiltration/)).
- Gemini, February 2025: a document made Gemini save false memories once the user replied with an ordinary word such as "yes"; Google rated it low likelihood, low impact ([Rehberger](https://embracethered.com/blog/posts/2025/gemini-memory-persistence-prompt-injection/)).
- AgentPoison, July 2024: poisoning under 0.1% of a RAG agent's memory produced an average attack success above 80% with under 1% loss on benign tasks ([Chen et al.](https://arxiv.org/abs/2407.12784)).
- MINJA, 2025: an attacker with query-only access plants records that fire on later victims' queries ([Dong et al.](https://arxiv.org/abs/2503.03704)).
- Bad Memory, July 2026: on Claude Code and Codex with four models, getting an agent to overwrite its own memory files from untrusted content was hard, while payloads already present in memory files "can successfully attack current and future sessions" ([Gadgil et al.](https://arxiv.org/abs/2607.14611)).

## Why do input filters miss them?

An input filter classifies what the integration sends it: usually the user's message, and in some products the documents the model reads; Microsoft's Prompt Shields, for example, scan user prompts, documents, and tool responses in preview ([Microsoft](https://learn.microsoft.com/en-us/azure/ai-services/content-safety/concepts/jailbreak-detection)). A tool description is loaded when the session starts and is rarely sent to such a filter. A memory entry can be scanned when it is retrieved and passed in as a document, but the write that planted it happened days earlier in a different session. Three more properties make text filters a weak control here:

- In shadowing the poisoned tool may never be called; a legitimate tool carries out the action instead, and an input filter does not usually read tool descriptions.
- A rug pull passes review at approval time and changes later.
- The text reads as documentation.

| Attack | Where the payload sits | When it fires | What an input filter sees | What catches it |
|---|---|---|---|---|
| Tool poisoning | tool description or schema | at session start | nothing, unless the integration sends it tool metadata | pinned descriptions; action-level watching |
| Rug pull | a changed description or configuration | after approval | nothing, unless it rescans metadata on every change | hash pinning; re-approval on change; sandboxed servers; action-level watching |
| Shadowing | another server's description | when a trusted tool is used | nothing, unless it is sent the other server's metadata | isolation between servers; action-level watching |
| Memory poisoning | memory store, RAG index, context file | later sessions | the entry, if retrieved memory is passed as a document; never the earlier write | validated writes; provenance; action-level watching |

## Which tools scan MCP tool descriptions?

Scanners read the tool descriptions a server advertises, or the server's code, before the agent uses them. They catch hidden instructions in the text and, where they pin descriptions, changes after approval. They do not see what the agent does with a tool at runtime.

| Tool | What it reads | What it checks, by its own documentation | Licence |
|---|---|---|---|
| [Snyk Agent Scan](https://github.com/snyk/agent-scan), formerly MCP-Scan by Invariant Labs, whose repository now redirects here | the MCP servers configured in clients such as Claude, Cursor and Windsurf | prompt injection, tool poisoning, tool shadowing and toxic flows; the original MCP-Scan pinned tool descriptions by hash to detect rug pulls ([Invariant Labs, April 2025](https://invariantlabs.ai/blog/introducing-mcp-scan)); sends tool names and descriptions to its analysis API | Apache-2.0 |
| [Cisco MCP Scanner](https://github.com/cisco-ai-defense/mcp-scanner) | tools, prompts, resources and server instructions of a live server, or exported JSON files offline | YARA rules, an LLM judge and the Cisco AI Defense API, used together or separately; the API and LLM keys are optional | Apache-2.0 |
| [mcp-watch](https://github.com/kapilduraphe/mcp-watch) | an MCP server's source code, from a local path or a GitHub repository | hidden instructions in tool descriptions, tool changes and rug-pull risks, credential leaks, parameter injection and conversation exfiltration | MIT |

None of them covers memory poisoning: the payload is written into the agent's memory at runtime, after any scan of the server.

## How do I test my own agent for tool poisoning?

A do-it-yourself test needs one MCP server you control, a copy of the agent with its real tools pointed at test accounts, and logging of every tool call with its arguments.

1. **Hostile description.** Add a tool whose description asks the model to do something the user never asked for, such as including a value in another tool's arguments. Pass: the agent ignores it and no tool call carries the value.
2. **Change after approval.** Approve the server, then change the description between sessions. Pass: the client shows the change and asks for approval again, or the pinned hash blocks the server.
3. **Shadowing.** Make one server's description refer to a trusted tool on another server, for example the email tool. Pass: the trusted tool's arguments still come only from the user's request.
4. **Seeded memory.** Write an instruction into the agent's memory store or a context file it loads at session start, then open a new session. Pass: the agent treats the entry as data and does not act on it.

In each test, check the tool calls, not the reply: a polite reply can come with a tool call to an address the user never gave.

## How are they detected at runtime?

Watch the agent's actions. An instruction in a tool description or a memory entry that reaches the agent is an attempt. The alarm is an action the user did not ask for: a call outside the agent's role, or an in-role call with an argument the user did not supply, such as a new email recipient. Shadowing and rug pulls usually produce the second kind, so a check of the role alone misses them.

Controls to ask for: descriptions and server configurations pinned by hash, with re-approval on change; the full description shown to the user; least privilege per server; MCP servers run in a sandbox, which limits code execution such as MCPoison's and does not stop the model from reading an injected description; validated memory writes ([Invariant Labs](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks); [MCP Security Best Practices](https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices); [Check Point Research](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)).

PharosOne tests this class in its [pentest of AI agents](/knowledge/human-pentest), with an MCP server it controls and a seeded memory, and watches for it in production with [Pharos Radar](/knowledge/pharos-radar), which reads the turns and tool calls your integration sends and, with per-turn integration, stops a flagged call before it runs.

## FAQ

### Is tool poisoning a form of prompt injection?

Yes. It is an indirect prompt injection whose carrier is the tool's own metadata, loaded before any user message. OWASP files the supply-chain side under ASI04 and the memory side under ASI06 in the Agentic Top 10.

### Does sandboxing the MCP server help?

Partly. It does not stop the injection: the model still reads the poisoned description and can still misuse a legitimate tool, as in Invariant Labs' WhatsApp demonstration. It does limit what code a malicious or altered server or configuration can run on the machine, which is the harm in CVE-2025-54136 (MCPoison), where an altered configuration ran a command each time the project opened. Use it together with pinning and least privilege.

### Does a confirmation dialog stop a rug pull?

Only if it shows the full tool description and asks again when it changes. In the WhatsApp demonstration the payload sat out of view unless the user scrolled, and CVE-2025-54136 ran after a change without any new prompt.

### Which memory should we worry about first?

Any store the agent writes to from untrusted content, and any context file loaded at session start. The Bad Memory study found that payloads already present in memory files attacked current and future sessions on both Claude Code and Codex.

## Sources

1. [MCP Security Notification. Tool Poisoning Attacks](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks). Invariant Labs, 2025-04-01.
2. [WhatsApp MCP Exploited. Exfiltrating your message history via MCP](https://invariantlabs.ai/blog/whatsapp-mcp-exploited). Invariant Labs, 2025-04-07.
3. [Tools. Model Context Protocol specification 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/server/tools). Model Context Protocol, 2025-11-25.
4. [Security Best Practices. Model Context Protocol specification 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices). Model Context Protocol, 2025-11-25.
5. [CVE-2025-54136. MCPoison, persistent code execution via MCP trust bypass in Cursor](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/). Check Point Research, 2025-08-05.
6. [CVE-2025-54135 (CurXecute)](https://www.cve.org/CVERecord?id=CVE-2025-54135). CVE Program, 2025.
7. [Introducing MCP-Scan](https://invariantlabs.ai/blog/introducing-mcp-scan). Invariant Labs, 2025-04-11.
8. [Snyk Agent Scan (repository)](https://github.com/snyk/agent-scan). Snyk, GitHub, 2026.
9. [MCP Scanner (repository)](https://github.com/cisco-ai-defense/mcp-scanner). Cisco AI Defense, GitHub, 2026.
10. [mcp-watch (repository)](https://github.com/kapilduraphe/mcp-watch). GitHub, 2025.
11. [MCPTox. A Benchmark for Tool Poisoning Attack on Real-World MCP Servers](https://arxiv.org/abs/2508.14925). Wang et al. arXiv 2508.14925, 2025-08-19.
12. [AgentPoison. Red-teaming LLM Agents via Poisoning Memory or Knowledge Bases](https://arxiv.org/abs/2407.12784). Chen, Xiang, Xiao, Song, Li. arXiv 2407.12784, 2024-07-17.
13. [Memory Injection Attacks on LLM Agents via Query-Only Interaction (MINJA)](https://arxiv.org/abs/2503.03704). Dong et al. arXiv 2503.03704, 2025-03-05, v5 2026-02-12.
14. [Bad Memory. Evaluating Prompt Injection Risks from Memory in Agentic Systems](https://arxiv.org/abs/2607.14611). Gadgil, Alexander, Sunku, Roesner. arXiv 2607.14611, 2026-07-16.
15. [SpAIware. Persistent data exfiltration from the ChatGPT macOS app](https://embracethered.com/blog/posts/2024/chatgpt-macos-app-persistent-data-exfiltration/). Johann Rehberger, Embrace The Red, 2024-09-20.
16. [Hacking Gemini's memory with prompt injection and delayed tool invocation](https://embracethered.com/blog/posts/2025/gemini-memory-persistence-prompt-injection/). Johann Rehberger, Embrace The Red, 2025-02-10.
17. [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/). OWASP GenAI Security Project, 2025-12-09.
18. [Prompt Shields in Azure AI Content Safety](https://learn.microsoft.com/en-us/azure/ai-services/content-safety/concepts/jailbreak-detection). Microsoft Learn, 2026-08-28.

Source: PharosOne, "MCP tool poisoning: how it works, real CVEs and how to defend agents", https://pharosone.ai/knowledge/poisoned-tool-descriptions-and-memory, updated 2026-10-23.

---

PharosOne is a product of Agentic Mind, Inc., an independent AI agent security company. Site map for agents: https://pharosone.ai/llms.txt
