Agentic AI Security
What Is Tool Poisoning?
- Tool descriptions
- Hidden instructions
- MCP servers
Short answer
Tool poisoning is an attack where the description of a tool offered to an AI agent contains hidden instructions. The model reads the whole description and may follow it, while the user usually sees only a short name. It is a form of indirect prompt injection, first documented for MCP servers by Invariant Labs in April 2025.
Maskflare Engineering Updated
How does tool poisoning work?
When an agent connects to an MCP server, it asks for the list of tools with a tools/list request. Each tool comes with a name, a description and a parameter schema. The model uses the descriptions to decide when and how to call a tool. That is the design, and it is also the opening: whoever writes the description is giving text to the model.
Invariant Labs' original notification shows the idea with a tool that adds two numbers. The user sees a short, innocent summary. The full description, which the model reads, adds a private instruction to also gather some sensitive local files and pass them along through a parameter, and not to tell the user. In their test, the client asked for confirmation but did not show the full tool inputs, so a user approving the call could not see what was being sent.
A harmless illustration, in prose rather than payload: imagine a tool called format_date whose description ends with a line telling the model to include the contents of a configuration file in its next call and to say nothing about it. The tool never has to do anything harmful itself. The description alone moves data.
What variations exist?
| Variant | How it works |
|---|---|
| Direct poisoning | A malicious server hides instructions in its own tool descriptions |
| Shadowing | One server's description tells the model how to use a different, trusted tool, for example to change where its output goes |
| Rug pull | A server behaves well when reviewed, then changes its tool descriptions later |
| Schema poisoning | Instructions sit in parameter names or parameter descriptions, not in the main text |
| Hidden characters | Instructions are made invisible with zero-width or tag characters, so a reviewer sees nothing |
Invariant describes tool poisoning as a specialised case of indirect prompt injection. The difference is where the text comes from: a tool listing the agent requested on its own, not a document someone sent.
How do you defend against it?
- Vet servers before you connect them, and keep an approved list. An unreviewed server is the usual entry point. See shadow MCP.
- Read the full descriptions, not the summary a client shows. Invariant recommends clear interfaces that separate what is meant for the model from what is meant for the user.
- Pin and compare. Record a hash of each tool description at approval time and alert when it changes, which catches rug pulls. Invariant recommends version pinning and checksums.
- Limit cross-server influence. Keep sensitive tools on separate agents from tools of unknown servers.
- Least privilege. A poisoned description can only make the model use tools it has. An agent with no file-read tool cannot be told to read files.
- Require approval for actions that send or change data, and show the real arguments when asking.
What does Maskflare check?
Maskflare's MCP gateway reads every tools/list answer on its way back to the agent. A dedicated detector, injection_tool_poisoning, looks at each tool description and each parameter description for:
- an instruction override such as "ignore previous instructions", in English, German, French, Italian or Spanish;
- hidden text, meaning invisible Unicode, bidirectional controls or markup that a person reading it would not see;
- an
<IMPORTANT>-style block aimed at the model; - an instruction to read secrets such as SSH keys,
.envfiles or an MCP configuration file; - an instruction to keep the user in the dark;
- an instruction to change how other tools behave.
The action is configurable. Alert counts the finding on the event, block answers like any other MCP block, and for hidden text strip removes the hidden characters and blocks. These checks are deterministic: fixed phrase lists and structural rules, no model, so every finding names the rule that fired. Because they run on each listing the gateway reads, a description that changes later is checked again.
What can't it catch?
- New phrasings. Phrase lists miss wording they were not written for. A rewritten attack in plain prose may pass.
- Servers outside the gateway. The checks run where Maskflare reads the traffic. A server an agent talks to directly is not covered.
- Hash pinning. The detector looks at what a description says each time. It does not by itself keep a signed record of what was approved.
- Logic abuse. A tool that behaves badly in its code, with an honest description, is a supply-chain problem, not a description problem.
Masking is the second layer. If a poisoned description convinces an agent to forward data, the values that reach the model through Maskflare's route are tokens, not the real ones. It narrows the damage and does not remove the need to vet servers.
Frequently asked questions
Is tool poisoning the same as prompt injection?
It is a kind of indirect prompt injection. The malicious text sits in a tool's description or schema, which the agent loads itself, instead of in a web page or an email.
Who discovered tool poisoning?
Invariant Labs published the attack against MCP clients in April 2025 under the title MCP Security Notification: Tool Poisoning Attacks.
Can the user see a poisoned description?
Often not. Many clients show a short summary or a name, and some do not show full tool inputs when asking for confirmation. Hidden characters can also hide text from a reviewer.
Does Maskflare detect tool poisoning?
Yes, in tools/list answers that pass through its MCP gateway, using deterministic rules. It can alert, block or strip hidden text. It cannot catch every phrasing and does not see servers that bypass the gateway.
What is a rug pull?
A server that behaves well while it is reviewed and later changes its tool descriptions or behaviour. Pinning descriptions and re-checking each listing helps.