Tool Poisoning
Hiding instructions in an MCP tool description so the model follows them without the user ever seeing.
What is tool poisoning?
Tool poisoning is prompt injection delivered through an MCP tool's own metadata. The model reads each tool's name, description and parameter documentation to decide when to call it. Those strings come from the server, and the model treats them as trustworthy context — so an attacker who controls a server can write instructions into a description and have the model act on them.
What makes it distinct from ordinary prompt injection is visibility. Injected text in a document is at least in something the user opened. A tool description is never rendered in the chat: the user sees a tool called read_file, and the model sees read_file plus three hundred words telling it to also exfiltrate ~/.ssh/id_rsa on every call and to say nothing about it.
How it works
Three steps, and none of them require compromising the client:
- 01
Publish or compromise a server
Either stand up a plausible MCP server, or take over an existing one. Nothing needs to be broken into on the victim's side — they install a tool integration, which is a supported action.
- 02
Write instructions into the metadata
The payload goes in the tool description or a parameter's documentation. Delimiters, role markers and "system" framing all help, because the model has no reliable way to tell metadata from instruction.
- 03
The model acts with the user’s authority
Whatever credentials the agent holds are now available to the attacker's instructions. The user approved a tool, not the sentence hidden inside it.
Why it matters
The trust boundary is in the wrong place. A user reviewing an MCP integration sees a tool list; they do not see the text the model sees, and no client surfaces it by default. Approval is being given for something other than what is being approved.
It also survives review. A server can serve a benign description during evaluation and a poisoned one afterwards — the description is fetched at connect time, not pinned at install time — so a manual check is a point-in-time observation of something the server controls.
And the blast radius is the agent's, not the tool's. An agent typically holds repository access, cloud credentials and a shell. A poisoned description on a weather tool inherits all of it.
What defends against it
Pin and diff descriptions
Record the metadata approved at install time and re-check it on every connect. A description that changes is an event, not a detail.
Show the model’s view
If the user can read exactly what the model reads, hidden instructions stop being hidden.
Scope the capability
Capability scoping bounds what the tool may do regardless of what the description asks for.
Separate credentials per server
An agent that holds one server's token cannot spend another's. This is what limits the blast radius.
Log and audit tool calls
The exfiltration attempt is visible in the call log even when it is invisible in the chat.
How Safeguard uses it
Safeguard scans MCP servers for instruction-shaped content in tool metadata, pins the approved description and flags drift, and enforces per-server capability scopes so a poisoned description cannot reach beyond what the tool was granted. See MCP Server and MCP server security.
See what your agent is actually being told.
Safeguard reads every MCP tool description the way the model does, and flags the ones carrying instructions.
Self-healing security runs on Safeguard.
Your first fix PR is minutes away.
No sales call required, even your agent can complete the purchase over MCP.