MCP tool poisoning and rug pulls explained for app builders

What the two terms mean, how a lookalike email package became the textbook case, and six checks for the MCP servers your editor, agent or app can load.

Timothy Lindblom

Founder, Newly

Published Last updated

MCP tool poisoning hides instructions in a tool's description, which the AI model reads and the person approving the tool usually does not. A rug pull is the delayed version. The server or package behaves while you evaluate it, then changes after you approved it. postmark-mcp, a lookalike email package, is the textbook case of that delayed change.

What are MCP tool poisoning and a rug pull?

The Model Context Protocol (MCP) lets an AI agent call tools offered by a server: send an email, read a repository, query a database. Each tool arrives with a name, a description and a schema. The model reads all three to decide when and how to use the tool. Invariant Labs, writing on April 1, 2025, defined tool poisoning as malicious instructions embedded in tool descriptions that are invisible to users but visible to AI models. It defined the rug pull as a server changing a tool description after the client has already approved it.

Term or factWhat it meansSource and date
Tool poisoningHidden instructions in a tool's metadata that the model readsInvariant Labs, April 1, 2025
Rug pullA tool definition changes after the client approved itInvariant Labs, April 1, 2025
postmark-mcp15 clean versions, then 1.0.16 added a blind copy of every outgoing email; Snyk names 1.0.18 as the latest malicious versionPostmark and Snyk, September 25, 2025
Spec rule on trustClients must treat tool annotations as untrusted unless they come from trusted serversMCP 2026-07-28, checked October 24, 2026
OWASP listingMCP03:2025 Tool Poisoning, in a Top 10 that is still in betaOWASP, checked October 24, 2026
Timeline of an MCP rug pull: approval of a clean tool list, a later change to the description or package, then the model reads the new text and acts with the user's data.Day 1: you approveTool list looks cleanLater: it changesNew description or versionThe model reads itActs with your dataCheck here: pinned version or hash of the tool definitionAn approval given on Day 1 says nothing about what arrives later.

The consequence for you is about timing. A one-time review of a tool list tells you what the server said on that day. Whatever it says later reaches the model with the same trust.

What happened with postmark-mcp?

postmark-mcp was an npm package that presented itself as an MCP server for sending email through Postmark. Postmark stated on September 25, 2025 that it had not published its MCP server on npm and had no involvement in the package. The publisher released 15 versions without a problem. Version 1.0.16 then added a blind copy of every outgoing email to an address outside the sender's control.

Snyk's alert of the same date lists what such mail can hold: attachments, headers, secrets, tokens and customer data. It names 1.0.18 as the latest malicious version. Both vendors give the same advice: uninstall, review the logs, and rotate every credential the mail could have carried.

Two details matter for an app builder. First, the change sat in what the code did, so reading the tool's description would not have caught it. Second, the sign of trust was a growing version history, and an install that takes the newest release picks up the change without anyone deciding to.

How common is tool poisoning?

Two academic measurements give a sense of scale, with limits. The MCPTox benchmark built test cases on 45 real MCP servers and 353 tools and ran them against 20 AI agents. The highest attack success rate was 72.8%, and the paper reports that the best refusal rate, from one model, was under 3%. That measures how models react to poisoned descriptions in a lab. It does not measure how many servers in use are poisoned.

A second study, submitted on February 3, 2026, examined 10,240 real MCP servers. Most matched their descriptions. Roughly 13% showed substantial mismatches between what the description says and what the code does, such as undocumented privileged operations or hidden state changes. A mismatch can be a bug or sloppy documentation, so it does not prove malice. It does show that a description is a weak basis for trust.

What these numbers do not say

Neither study counts attacks against real users, and we found no primary source that does. Treat the figures as evidence that the weakness is real and that models follow tool text. They give no estimate of your odds.

What do the MCP spec and the big vendors say?

The 2026-07-28 tools page says clients must treat tool annotations as untrusted unless they come from trusted servers, and that there should always be a human with the ability to deny tool invocations. It also describes the listChanged capability, through which a server tells clients its tool list changed. On the page we read, nothing requires a client to ask for approval again after such a change. That gap is where a rug pull lives.

The vendors point the same way. OpenAI's documentation warns that MCP servers may update tool behavior unexpectedly, advises connecting to trusted and preferably official servers, and supports an allowed_tools setting to expose only the functions you need. Claude Code's security page says Anthropic reviews connectors against listing criteria but does not security-audit or manage any MCP server, and that a project's .mcp.json does not show every server a session can load, because other scopes, connectors and plugins can add servers.

The MCP security best practices add that a client with one-click local server setup must show the exact command before it runs, and should run servers with minimal privileges. The OWASP MCP Top 10 lists tool poisoning as MCP03:2025 and is still a beta project.

What should you check in your own setup?

MCP can reach your project through your editor or agent, your build machine, and any backend feature that lets your app's AI call tools. Because you can download the code from Newly or connect your own repository, the project also lives in whatever editor you open it with. Go through these in order.

1. List every server and who publishes it

Open each tool's MCP configuration, including .mcp.json in the repository, and write down every server. Include ones added by plugins or connectors. For each, find the vendor's own documentation and confirm the package name or URL matches. The postmark-mcp name looked right to anyone who did not check Postmark's site.

2. Pin what you run, and read upgrades

For a local server, set an exact version in the config and commit the lockfile. When a new version appears, read the changelog or diff before accepting it. Invariant's write-up recommends pinning server versions with a hash or checksum so the integrity of the tool description can be verified before it is used. For a remote server you cannot pin the code, so record a hash of the full tool definition and compare it each session if your client or a gateway supports that.

3. Expose few tools and keep a person in the loop

Allow only the tools you need. Anything that sends, writes, deletes or pays should require a person's approval each time. An email tool that can send without asking is exactly the tool a changed package wants.

4. Give each server a narrow token

A server only leaks what it can reach. Use a token limited to one job, and keep it out of your app. Anything in an EXPO_PUBLIC_ variable ends up in the bundle that anyone can download, per Expo's documentation. If a server ever handled a key you cannot account for, rotate it, as in our guide to rotating secrets after a breach.

5. Watch what the server touches

Postmark advised reviewing email logs. Do the equivalent for each server: sent mail with unexpected recipients, repository events you did not trigger, provider calls your app never made.

Which control catches which problem?

FailureWhat changesWhat catches itWhat misses it
Poisoned from day oneNothing; the text was hostile at first listingReading the descriptions, a small allow list, vendor-checked publisherPinning and hashing, which record the hostile text as trusted
Rug pull on a remote serverThe tool definition, after approvalHash of the full definition, re-approval on changePackage pinning, since the code runs on the server's side
Malicious package updateThe code in a new versionExact version, lockfile, reading the diff before upgradingReading descriptions alone, which can stay the same
Lookalike publisherThe name or URL you installedMatching the name to the vendor's own documentationAny check made after installing it

Where this stops

None of these controls prove a server is trustworthy. They shrink what a bad server can reach and make a change visible. If your deployment exposes an MCP endpoint on the internet, also read the MCP authorization checklist and the guide to exposed self-hosted AI endpoints.

Where do you stand?

Everything starts as unknown, because an unchecked item is unknown. Move an item to detected when you find the problem, and to confirmed only when you hold the evidence listed under it. The wider picture is in the 15-minute check for AI-built apps.

Your MCP check

  • Detected: You found the problem.
  • Unknown: Not checked yet, or the check could not tell.
  • Confirmed by owner evidence: You checked and kept the proof.
  1. 1. Every MCP server your editor, agent and backend can load is listed, with who publishes it.

    Evidence: a written list built from each tool's config, including servers added by plugins or connectors.

  2. 2. Each server's package name or URL matches the vendor's own documentation, not a lookalike.

    Evidence: the link to the vendor page that names the package or URL.

  3. 3. Local servers run an exact version from a committed lockfile, and upgrades are read before they are accepted.

    Evidence: the pinned version line and the lockfile entry.

  4. 4. Only the tools you need are exposed, and anything that sends, writes or deletes asks for a person's approval.

    Evidence: the allow list or the approval setting for each server.

  5. 5. Each server holds a token limited to its job, and no MCP token sits in an EXPO_PUBLIC_ variable or the app bundle.

    Evidence: the token scopes in the provider's dashboard and your .env files.

  6. 6. A changed tool description or a new package version gets read by a person before it is trusted again.

    Evidence: a hash record of the tool definitions or a dated note on the last review.

0 detected6 unknown0 confirmed by owner evidence

Your answers stay in this browser tab. Nothing is saved or sent.

Frequently asked questions

Is tool poisoning the same as prompt injection?

It is one route into it. Prompt injection means any text that steers the model against its owner. Tool poisoning is the case where that text sits in a tool's name, description or schema.

Was postmark-mcp a rug pull?

In the supply chain sense, yes. The package behaved for 15 versions, then 1.0.16 added a blind copy of every outgoing email. It was a malicious package update, so version pinning and review of upgrades address it. Reading descriptions would not.

Can a website scan find a poisoned MCP server?

No. Both red.run.cloud scans work from outside a live site. An MCP server list in your editor or in private configuration never answers a public request, so it stays unknown until you check it yourself. A scan can still show what your website exposes, such as a readable .env file or keys in shipped bundles.

I only build mobile apps with Newly. Does this apply to me?

Only if you add MCP somewhere. Newly builds a real React Native and Expo app, and you can download the code or connect your own repository. Open that project in an editor or agent with MCP servers installed, and the checklist above applies.

I installed a lookalike MCP package. What now?

Remove it from every environment, review the logs of whatever it touched, and rotate every credential it could read. Postmark gave the same three steps for its incident.

Sources

Checked on October 24, 2026. For related cases see supply chain attacks on AI and LLM tooling, and for the key-handling side leaked AI service API keys. The full index is on the security hub.

  1. MCP Security Notification: Tool Poisoning Attacks (April 1, 2025), Invariant Labs
  2. Information regarding the malicious postmark-mcp package, Postmark
  3. Malicious MCP Server Alert: postmark-mcp, Snyk
  4. MCP specification 2026-07-28: Tools, modelcontextprotocol.io
  5. MCP security best practices (2026-07-28), modelcontextprotocol.io
  6. MCPTox: A Benchmark for Tool Poisoning Attack on Real-World MCP Servers, arXiv 2508.14925
  7. Understanding and Measuring MCP Behavior under Misleading Tool Descriptions, arXiv 2602.03580
  8. OWASP MCP Top 10 (beta): MCP03 Tool Poisoning, OWASP Foundation
  9. Risks and safety for remote MCP servers, OpenAI developer docs
  10. Security: MCP security, Claude Code docs
  11. Environment variables in Expo, Expo docs

Continue Learning