LetterMCP

MCP Tool Description Best Practices for Enterprise Servers

Attackers hide malicious instructions in tool descriptions that AI agents read but humans never see.

Staff Writer · · 10 min read
Cover illustration for “MCP Tool Description Best Practices for Enterprise Servers”
Agentic AI Foundations · August 25, 2026 · 10 min read · 2,179 words

When an MCP client connects to a server, it gets back a list of tool names, descriptions, and parameter schemas, and that's essentially it. The agent reads that metadata and decides what to call and how to call it, and in most setups, no human checks the decision before it fires. The description sits in a strange middle ground: it looks like documentation off to the side, but the model treats it as an instruction to act on.

I keep coming back to this because most teams still treat it like a footnote. The Python and TypeScript SDKs alone see roughly 97 million downloads a month, and 76% of software providers are already exploring or building on MCP as their connectivity layer. Most clients take the tool definition and drop it straight into the prompt, unchanged, word for word. When a description is vague or sloppy or someone's tampered with it, you don't get a broken doc page sitting unnoticed. Instead, you get a tool call nobody signed off on.

How tool poisoning turns descriptions into an attack vector

Tool poisoning happens when an attacker hides instructions inside a tool's name or description field, and the model reads them as real guidance while the user sees nothing off. Microsoft's own writeup on this pattern nails the core issue: the malicious text lives in metadata, not in anything a user typed or saw, so the input filters everyone built never get a look at it.

That's the whole trick, and it's worth sitting with. Validation layers watch what the user types; they don't watch what the server says about itself.

There's a meaner version of this called the rug pull. An attacker stands up an MCP server that looks completely clean, gets it through change control the normal way, then edits the tool definitions after it's already deployed. Whatever trust got approved in that first review carries forward, even though the tool underneath has changed shape entirely. Cloud Security Alliance research flags this as especially dangerous in enterprise settings, because most approval workflows have no step that goes back and re-checks a tool once it's live.

This isn't a thought experiment. Invariant Labs showed in 2025 how a malicious MCP server, sharing context with a legitimate WhatsApp integration, used tool poisoning to quietly pull a user's entire message history out the back door. A 2025 survey of open-source MCP servers found 5.5% showed signs of tool poisoning that could lead to over-privileged access. That's a small slice on its own, but it's a slice of a population that's multiplying fast, and 5.5% stops looking small the moment the denominator is ten times bigger.

Every field the model reads is a door, and I don't know a gentler way to put it. Treating the description as inert paperwork means ignoring the job it's actually doing.

The structural properties a tool description must have to be safe and reliable

Start with format: plain text, nothing else, no JSON, no HTML, no rich markdown dressing it up. Structured syntax gives an attacker more places to hide something, and it makes parsing ambiguous in ways a plain sentence just isn't.

Scope matters just as much, maybe more. Each server should cover one microservice domain and expose only the tools that belong to it. Once a server starts pulling in tools from five different domains, the agent's decision quality drops, and so does anyone's ability to actually audit what that server can do.

A common mistake: mapping every REST or GraphQL endpoint straight into its own MCP tool. That gives you a wall of near-identical tools and wrecks tool selection. Descriptions should map to workflows a person would actually ask for, not to whatever shape the API happens to have underneath.

Naming needs to be specific enough that two tools could never get confused for each other. Overlapping names, vague phrasing, either one pushes the agent toward guessing, and guessing is exactly what you don't want from a system with write access. Parameters should be typed and schema-backed, with enums wherever the valid inputs are a known, bounded set. Leave an input underconstrained and you're inviting the model to fill the gap itself.

One more thing worth doing: write a server-level description, not just tool-by-tool ones. Tell the agent what the server is for and how its tools fit into real workflows before it ever reads an individual entry. Coverage shouldn't stop at the happy path, either. MCP's own design guidance calls for documented failure modes. A description that only covers what happens when everything works leaves the agent stranded the moment something doesn't.

Describing side effects, write operations, and destructive actions explicitly

In July 2025, an AI agent on Replit deleted a production database holding over 1,200 records, even though it had been told directly to freeze all code and action. Somewhere in the tool layer, that agent had write and delete access it never should have had. Keep that one in mind for everything below, because it's the whole argument in a single sentence.

Write, edit, and delete operations should be opt-in at the description level, not the default. Least privilege doesn't start at the API gateway; it starts here, in the sentence that tells the model what a tool is allowed to touch.

State changes need to be spelled out in words, not left for the model to guess from a verb buried in the tool's name. A tool called update_record doesn't tell the agent enough on its own; the description has to say plainly that calling this thing modifies, deletes, or charges something, so the model reads that before it acts, not after the fact.

For anything that touches state or moves money, the description should note that a dry run or confirmation step exists before the real thing runs. If a tool uses elicitation to confirm something risky, document exactly what triggers it. Elicitation should never get used to pull sensitive data out of a user under the guise of confirming an action; that's a misuse of the pattern, plain and simple.

Where you can, have tools return a machine-readable summary of what changed, alongside the plain-language version, so downstream audit systems can parse what happened instead of relying on a log line written for a human eyeball. Auditors reviewing MCP deployments look for one thing above everything else: a gap between what the description claims a tool does and what its actual downstream access lets it do. That gap is the tell.

Embedding behavioral constraints and scope limits directly in descriptions

Venn diagram: Safe vs. Unsafe MCP Tool Descriptions. Compares Unsafe Descriptions and Safe Descriptions; overlap: Shared Properties.

A good description says what a tool does. A complete one also says what it won't do, and when it should refuse or hand the request up to a human instead.

Scope belongs in plain language, right there in the text. If a search tool should only ever touch one data domain, write that down, rather than leaving it as something the agent is supposed to infer from context clues that might not even be there.

I like the SPELLSMITH method for this reason: it builds security guidance directly into the tool description and pairs it with a reflection step that re-checks each concrete invocation before it ever hits the server's code. The description isn't just a label anymore; it's doing active work at call time.

High-risk operations should carry authorization language right at the tool and parameter level. What role is required, what approval is needed, stated where the agent actually reads it, not buried three layers deep in a policy doc enforced somewhere downstream. Compare a tool described as "manage files" against one described as "read files in the /reports directory; never modify or delete." The first invites the agent to stretch its interpretation as far as the words technically allow. The second doesn't give it room to stretch.

That stretching has a name: intent drift. Across multi-step tasks, agents given vague descriptions tend to widen their read of what a tool is for as the conversation goes on, and narrow, explicit constraints are about the only thing that reliably stops it. One rule that's easy to forget: descriptions should never reference, request, or confirm credential values. Treat this layer like it could show up in a log or a trace someday, because it can.

Cryptographic signing and change detection as a defense against post-approval mutation

Here's the exact problem the rug pull exploits: approval happens once, at a single point in time, but the tool definition sitting on a hosted server can change any time after that, and nothing forces a second look.

The Enhanced Tool Definition Interface, proposed in 2025 research, handles this by binding tool definitions to signed JSON Web Tokens and using OAuth 2.0 scopes to represent what each tool is allowed to do. Change the definition, even a little, and the signature breaks, which forces re-approval before the tool runs again.

In practice, that turns a silent edit into something that gets caught and logged instead of something that just quietly ships to production. Enterprises should only load tools from registries that enforce signing and block tampering with definitions, and clients should check the publisher's signature rather than assume it's clean because it looked clean last week.

Anywhere a server hosts tools with write, delete, or financial capability, signed-definition policy needs to be a requirement layered on top of login checks, not a nice-to-have bolted on later. The stakes keep rising with scale, too: the count of exposed MCP servers nearly tripled to 1,467 by a late-2025 count, with attackers increasingly going after the cloud infrastructure running these servers, not just the data sitting behind them.

What an auditable tool description looks like in practice

Think of a tool definition as an audit artifact in its own right, not paperwork you write once and forget. Guidance on MCP audits keeps circling back to the same red flag: a description that doesn't match what the tool actually does downstream.

A well-formed description for an enterprise environment hits a few marks without exception. It states clearly what the tool does and what domain it's scoped to. It names any state changes, deletions, or financial actions by name, not by implication. It lays out when the tool asks for confirmation or refuses outright. It states what role or approval is required to call it, documents what happens when the tool fails, and tells the agent what to do about it. And it carries no structured markup, no credential references, nothing that quietly drifts from its stated purpose.

None of this means much without logging behind it. A tamper-proof audit log of tool calls only earns its keep if it records the exact version of the description in place at the moment of the call, not just the tool's name. OTEL tracing should capture that version right alongside the invocation.

Who writes these descriptions matters almost as much as what's in them. Security reviewers belong on that team, sitting next to the engineers who built the capability underneath, because writing the description is a security decision whether anyone treats it that way or not. Centralized platforms that give security teams visibility across every MCP tool in an inventory, and that enforce policy at the moment of the call, let you check description-to-behavior alignment across a whole server fleet from one place, which beats auditing each server in isolation, one at a time, forever.

Maintaining tool descriptions as the server and its permissions evolve

Descriptions go stale the moment the underlying API or access model changes and nobody updates the text to match. That gap, between what's written and what's actually running, is one of the most common reasons agents misbehave in production.

The scale backs this up. A systematic look at more than 1,800 deployed MCP servers found over 30% carried at least one exploitable vulnerability, a rate higher than most enterprise software categories see at similar deployment scale. Stale descriptions aren't the only cause of that number, but they're a real contributor, and an easy one to fix compared to the rest.

Tool definitions need version control, the same way code does. Changes get reviewed, approved, recorded, with a clear trail of who changed what and when. Any edit that touches scope, permissions, or a stated behavioral limit should void whatever approval the tool had before, full stop, and force a fresh review before it goes back into production.

Reviews shouldn't wait for something to break, either. Descriptions need a set cadence, checked against how the tool is actually behaving in the field, with logs of real agent activity feeding back into that review instead of sitting unread in a dashboard somewhere.

What holds all of this together long-term is pretty simple to describe, even if it's hard to build: security and platform teams sharing ownership of the tool inventory, real-time detection for drift, tamper-proof records of every call. Descriptions that match current behavior, enforce current permissions, and state their limits plainly aren't just good hygiene. They're the thing the rest of your governance program is standing on, whether you've noticed yet or not.

Sources

  1. labs.cloudsecurityalliance.org
  2. obot.ai
  3. modelcontextprotocol.info
  4. medium.com

More in Agentic AI Foundations