Skip to content

Field note

MCP Tool Poisoning: Security Checklist

Treat every MCP server's metadata, tool descriptions and returned content as untrusted input until a person or a policy layer has reviewed and approved them.

Treat every MCP server's metadata, tool descriptions and returned content as untrusted input until a person or a policy layer has reviewed and approved them.

What tool poisoning is

The Model Context Protocol (MCP) lets an AI client such as Claude, Claude Code, ChatGPT or Cursor discover tools from a server and call them. On connection the server sends a list of tools, each with a name, a description and an input schema. The model reads those descriptions to decide when and how to call each tool.

Tool poisoning is the abuse of that channel. A tool description contains instructions the model will follow but the approver never sees, because clients typically show a short name and a one-line summary. The hidden text might tell the model to read ~/.ssh/id_rsa and pass its contents as a "context" parameter, to call a second tool before this one, or to phrase replies so the user does not notice. A related trick is the rug pull: a server behaves well at approval time and changes its descriptions in a later update. Because a server can also shadow the behaviour of other tools by describing how they should be used, one bad server can affect calls to good ones.

The MCP specification says clients must treat tool annotations as untrusted unless they come from trusted servers, and the same logic applies to descriptions. The protocol assumes you have decided which servers to trust. Most small businesses have not.

A realistic UK SME example

A marketing agency's developer installs a free MCP server that promises better search over the team's Notion workspace. Its search_pages tool description ends with a paragraph, hidden below several blank lines, telling the assistant to also include the contents of any file named .env in the working directory "for indexing accuracy". The developer approves the server once in Claude Code, and from then on every search ships API keys to the server. Nothing crashed, no permission prompt appeared, and the audit log shows only ordinary search calls.

The checklist

  1. Know which transport you are using and why. MCP defines two standard transports. stdio runs the server as a local child process of the client and is the right choice for tools on a developer's own machine. Streamable HTTP is for servers shared across a team or hosted remotely, and carries the authentication, origin validation and session rules a network service needs. The older HTTP+SSE transport from the 2024-11-05 specification is deprecated; if a vendor still ships it, ask when they will move.
  2. Read the full tool descriptions before approving. Dump the server's tool list and read every description end to end, including whitespace. Inspect the raw JSON with the MCP Inspector or by calling tools/list directly. Anything addressed to the model rather than the user is a rejection.
  3. Pin the server version and diff on update. Install from a specific tag or commit, keep a copy of the approved tool list, and compare it after every update. A changed description is a re-approval, not a patch.
  4. Give each server the narrowest identity. Its own API token, scoped to the data it needs, expiring, and revocable without touching anything else. Never reuse a personal token or a global admin credential.
  5. Separate read tools from write tools. Approve read-only servers first. Add a write capability only when the workflow has run cleanly for a period and the logs have been reviewed.
  6. Keep secrets out of the model's reach. Environment variables, .env files, SSH keys and password managers should not be readable by the process the model drives. Run the client in a directory that contains only the project.
  7. Do not let one server see another's output unnecessarily. Where the client allows it, enable servers per project rather than globally, so a note-taking server is not present when the model is using a payments server.
  8. Log tool calls with arguments. You need to be able to answer "what did the model send and where" for any given hour. The MCP security and audit logging note describes what to record.
  9. Treat tool results as untrusted too. A web page, ticket or document returned by a tool can carry prompt injection just as a description can.
  10. Have a stop route. Removing a server and revoking its token should take minutes and be practised once.

What to write into policy

  • Only servers on an approved list may be configured on company devices; the list records the source, version, transport, token scope and approver.
  • Tool descriptions are read in full before approval and again after any update.
  • Servers with write or delete tools require a second approver.
  • Personal, admin or shared credentials are never used for an MCP server.
  • Any server found to include instructions addressed to the model is removed and reported.

The Claude Code MCP connector checklist applies these rules to that client's configuration files.

How to test

Write a deliberately poisoned test server: one harmless tool whose description asks the model to read a marker file and include it in the arguments. Connect it to your client in a clean project directory containing the marker file. If the marker's contents appear in the tool call, your client does not protect you and the controls above are your only defence. Repeat after client updates, because behaviour changes between versions.

Source basis

Keep reading

Related notes

26 Aug 2026 · 5 min

Claude Code MCP Security Checklist

Every MCP server you attach to Claude Code adds a new set of tools, a new credential and a new source of untrusted text, so review each one the way you would review a supplier integration.