Back to Blog
DevelopmentAug 13, 202612 min read

97% of MCP Tool Descriptions Are Broken — How to Test Yours

NT

Nikhil Tiwari

MCP Playground

TL;DR

  • 97.1% of MCP tool descriptions carry at least one defect, across 856 tools on 103 servers (arXiv 2602.14878).
  • 56% never clearly state what the tool does. The description is the only thing the model reads before choosing.
  • Rewriting descriptions helps — by a median of 5.85 percentage points on task success, not the transformation the headline implies.
  • It also costs you. The same study measured a 67.46% increase in execution steps and a regression in 16.67% of cases.
  • You cannot catch a bad description with a normal MCP test. Every call returns 200 whether the model chose well or not.
  • The only way to measure it is to make a model choose between your tools and score whether it got there.

Your MCP server works. Every tool returns valid JSON, the schemas validate, the handshake succeeds. And the agent still picks the wrong tool.

When that happens, the instinct is to blame the model. The model is rarely the problem. The problem is usually the one artefact you wrote by hand and never tested: the tool description.

A model does not see your code. It sees a name, a description, and a JSON Schema. That is the entire basis on which it decides whether to call your tool.

The MCP specification is deliberately quiet on description quality — it defines the wire format, not the prose. That leaves the highest-impact field in your server completely unguarded.

In February 2026 a team from Queen's University and Huawei published an empirical study of MCP tool description quality across the public ecosystem. The numbers are worse than most people assume, and the fix is more complicated than the headline suggests.

This post covers what the study found, the six defect classes it identified, why naively expanding your descriptions can make things worse, and how to get a real measurement instead of a guess.

What the research actually found

The paper is Model Context Protocol (MCP) Tool Descriptions Are Smelly! by Mohammed Mehedi Hasan, Hao Li, Gopi Krishnan Rajbahadur, Bram Adams and Ahmed E. Hassan. First submitted 16 February 2026, revised 31 May.

They examined 856 tools spread across 103 MCP servers and assessed each description against a defect taxonomy borrowed from code-smell research.

The headline result:

Finding Figure
Descriptions with at least one smell 97.1%
Fail to clearly state their purpose 56%
Task success gain from augmented descriptions +5.85pp (median)
Partial goal completion gain +15.12%
Increase in execution steps +67.46%
Cases where performance regressed 16.67%

Read the bottom three rows again. That is the part almost every summary of this paper leaves out, and it changes what you should do about it.

The six ways an MCP tool description fails

Glama built a Tool Definition Quality Score on top of this research, scoring each tool 1–5 across six dimensions. They map cleanly onto the defect classes.

1. Purpose clarity

The description does not say what the tool does. This is the 56% case — the single most common defect in the ecosystem.

A description like Panel runner is a noun phrase. It names a component in your architecture, not an action a user wants.

2. Usage guidelines

89% of descriptions never say when you should or should not use the tool. This is what causes tool confusion on servers with overlapping capabilities.

If you ship search_docs and get_page, and neither says which to reach for first, the model guesses. Sometimes it guesses wrong.

3. Behavioural transparency

Does the tool mutate anything? Is it idempotent? Does it hit a rate limit? A model that does not know a call is destructive will treat it like a read.

4. Parameter semantics

The tool description is fine, but the parameter descriptions are empty. So the model knows to call get_issue and has no idea what format issueId takes.

This is the defect that produces JSON-RPC -32602 invalid params errors at runtime.

5. Conciseness

Longer is not better. Every character of every description sits in the context window on every single turn, for every tool you expose.

A 60-tool server with 400-word descriptions burns real budget before the user has typed anything. I wrote about this in how MCP tools silently eat your context window.

6. Contextual completeness

The description assumes knowledge the model does not have. Internal entity names, project-specific jargon, an ID scheme documented only in your wiki.

The uncomfortable part: fixing descriptions has a cost

Here is where most write-ups of this study go wrong. They quote 97%, quote the success gain, and conclude: write longer descriptions.

The paper does not support that conclusion. Augmenting descriptions raised execution steps by 67.46% — the agent did more work to get to the answer.

And in 16.67% of cases the augmented description made performance worse. One time in six, the rewrite was a regression.

The real finding

Description quality genuinely matters, and you cannot fix it by writing more. The study's own ablations found that compact variants preserved the reliability gain while cutting the token overhead. Specific beats long.

So the actionable version is not "expand everything". It is: say the right things, cut the rest, and measure whether it worked.

That last clause is the one people skip. A 1-in-6 regression rate means you cannot assume your rewrite helped.

Three real descriptions, rewritten

These patterns come from tools I have pointed evals at. The names are changed; the shapes are exactly what shows up in the wild.

Scenario 1: the noun phrase

Before
{
  "name": "panel_runner",
  "description": "Panel runner."
}

What goes wrong: the model has no verb to match against the user's request. Asked to "survey our target customers", it never connects that to panel_runner.

After
{
  "name": "run_research_panel",
  "description": "Run a customer research panel against a target
audience and return per-question response breakdowns. Use for
new survey questions. To re-read a panel that already ran, use
get_panel_results instead."
}

Lead with the verb the user would use. Then name the sibling tool it gets confused with.

Scenario 2: the overlapping pair

A docs server ships search and fetch_page. Both descriptions are accurate. Neither mentions the other.

The observable symptom: the agent calls search, gets a list of URLs, calls fetch_page on the first one, does not find the answer, and calls search again with a slightly different query.

It gets there eventually. It burns four calls doing what should take two. On a metered API, that is your bill.

The fix is one clause in each description: "Returns ranked page URLs and snippets — call fetch_page on a result to read the full page."

Scenario 3: the undocumented ID format

Before
{
  "name": "get_issue",
  "description": "Get an issue.",
  "inputSchema": {
    "type": "object",
    "properties": { "issueId": { "type": "string" } },
    "required": ["issueId"]
  }
}

The model has to invent an ID format. It tries "1234". Your server wants "PROJ-1234". You get a -32602 or an empty result.

Add one line to the parameter and the failure disappears: "issueId": { "type": "string", "description": "Issue key in PROJ-123 form, as returned by list_issues." }

That final clause — as returned by list_issues — tells the model where to get a valid value. It is the highest-leverage sentence you can write.

See how a model reads your tools

Connect any MCP server and watch a real model choose between your tools — no install, no sign-up.

Test any MCP server free →

Why your test suite cannot see this

This is the core of the problem. A description defect is invisible to every form of testing that calls tools directly.

Run your server through an inspector and every tool returns 200. Run your integration tests and they pass. Validate against the 2026-07-28 spec and you are conformant.

None of that touches the question that matters: given these descriptions, does a model pick the right tool?

The reason is structural. When you call a tool yourself, you have already made the choice the model has to make. You skipped the only step that can fail.

The failure mode this produces is the nastiest one in MCP: every call succeeds and the final answer is still wrong. Nothing in your logs is red.

The annotations problem nobody talks about

The MCP spec lets a server declare readOnlyHint, idempotentHint and destructiveHint on each tool. These are part of how a model reasons about safety, and the 2026-07-28 spec release leaned further into annotations as a risk vocabulary.

Most servers in the wild declare none of them. That is a description defect with real consequences, and it is one you can fix in an afternoon.

It matters more than it looks. When I built the eval engine behind MCP Evals, missing annotations forced a hard design decision.

A functional eval calls tools with arguments designed to succeed. That is the whole point of it. So pointing one at an unannotated delete_record would really delete a record.

The only safe posture is fail-closed: an unannotated tool gets treated as destructive and excluded from a default run.

What this costs you

If your server ships no annotations, every automated tool that respects safety has to skip your tools — and so does any cautious agent framework. Three booleans per tool buys you back that coverage.

Note that "unknown" and "destructive" are not the same situation, even though both get excluded. An unannotated tool may well be read-only. You just cannot prove it, and guessing is not good enough when the call is designed to work.

How to actually measure description quality

Given a 1-in-6 regression rate, you need a measurement, not an opinion. There are three practical levels.

Level 1: read them against the six dimensions

Cheap and genuinely useful. Score each tool 1–5 on purpose clarity, usage guidelines, behavioural transparency, parameter semantics, conciseness and contextual completeness.

Anything scoring 1 or 2 on purpose clarity is a certain problem. Fix those first.

Level 2: make a model choose, once

Connect your server to a real model, ask a question a user would actually ask, and watch which tool it reaches for. This is the fastest way to find a confused pair.

You can do this in a browser with any of the models on MCP Playground without writing a harness.

Level 3: run it as an eval suite

The difference between level 2 and level 3 is repeatability. An eval is a task plus a scored outcome, run the same way every time your descriptions change.

This is what the academic benchmarks measure at ecosystem scale. MCP-Atlas runs 1,000 human-authored tasks across 36 real servers and 220 tools, with a public leaderboard. MCP-Bench exposes 250 tools across 28 servers to test cross-server orchestration.

Those tell you how good a model is. You want the same method pointed at your server.

The signal to watch is not just pass or fail. It is how many calls the model needed.

A task that passes in two calls and later passes in five did not stay the same. Call count is your description-quality metric, and it moves before pass rate does.

That is why the eval engine I built fixes the call budget at generation time. If the budget moved per run, the comparison would be meaningless.

The checklist

  • Lead with a verb the user would use, not a noun from your architecture.
  • Say when not to use it and name the sibling tool instead. This is the 89% gap.
  • Describe every parameter, and say which tool produces valid values for it.
  • Declare your annotations. All three booleans, on every tool.
  • Cut anything the model does not need. Compact variants performed as well as long ones.
  • Re-measure after every rewrite. One in six makes things worse.
  • Track call count, not just pass rate. It degrades first.

Frequently asked questions

Does the 97% figure mean my server is probably broken?+
It means your descriptions almost certainly carry at least one defect from the taxonomy, which is not the same as being broken. Many defects are harmless in servers with few tools and no overlap. The risk rises sharply with tool count and with tools that do similar things.
Should I just make every description longer?+
No. The same study that found the 97% figure also measured a 67.46% increase in execution steps and a regression in 16.67% of cases after augmentation. Its ablations found compact variants held the reliability gain at lower token cost. Be specific rather than long.
Can an MCP inspector detect a bad tool description?+
Not really. An inspector calls tools directly, which means you have already made the choice the model would have to make. It can tell you a description field is empty, but it cannot tell you whether the wording leads a model to the right tool.
What is the single highest-leverage fix?+
Adding a clause to each ID-shaped parameter saying which tool returns valid values, for example "as returned by list_issues". It removes the guessing that produces most -32602 errors, and it costs one sentence.

Where this leaves you

The 97% number is real, peer-reviewed and worth taking seriously. The naive response to it is not.

Description quality is a measurable property of your server, it degrades quietly, and the only instrument that reads it is a model being made to choose. Call count tells you before pass rate does.

Score your tools against the six dimensions, declare your annotations, add the "as returned by" clause, then check that the rewrite actually helped.

Find out if an agent can use your server

Walk through a finished MCP eval run — tools detected, tasks written, a model made to complete each one.

See MCP Evals → Test a server free →

New to the protocol? Start with what the Model Context Protocol actually is, then how to test an MCP server step by step.

NT

Written by Nikhil Tiwari

15+ years in product development. AI enthusiast building developer tools that make complex technologies accessible to everyone.

Build, compare & ship MCP agents — free

Connect any MCP server, run evals on it, compare 60+ models side-by-side, deploy hosted servers, and save reusable agents you can export as an API — all in your browser.

✦ Free credits on sign-up · no credit card needed

Try for Free →
97% of MCP Tool Descriptions Are Broken — How to Test Yours