DEV Community

Renato Marinho
Renato Marinho

Posted on

Stop writing MCP tool descriptions like a human is reading them

I've spent the last few years watching developers build incredible MCP servers, only to watch them fall apart in production because of something fundamentally stupid: bad instructions.

You build a sophisticated integration—maybe it connects to a legacy CRM or a complex billing API. You handle the auth, you manage the sandboxing via V8, you've got your TypeScript types perfectly mapped. Then, at the finish line, you write a tool description that sounds 'nice.' Something like: "This tool allows you to fetch user information from our database and will return the details as a string."

And then, when you drop it into Claude Desktop or Cursor, the agent starts hallucinating. It tries to pass user_id when you named the parameter userId. It forgets that the output is a string because you didn't explicitly state the return type in an actionable way. It gets lost in the 'fluff.'

The problem isn't your LLM. The problem is that you are writing for humans, but these tools are being consumed by agents. Agents don't need politeness; they need semantic density.

The Semantic Density Problem

When we talk about function calling in the MCP ecosystem, we aren't just talking about APIs. We are talking about a new kind of Instruction Set Architecture (ISA) where the 'instructions' are written in natural language but executed via high-precision logic.

In this context, every extra word in your tool description is essentially noise that increases the probability of a parsing error or a reasoning failure. If an agent has to navigate through three sentences of 'context' before it hits an imperative verb, you are wasting its context window and increasing its cognitive load. This is where semantic density comes in.

Semantic density is the ratio of actionable information to total text length. A high-density description uses imperative verbs and provides clear return types, minimizing linguistic noise that can distract an LLM during function calling.

I recently started using a specific tool to audit my own server definitions: the Tool Description Semantic Density Scorer. It doesn't just 'feel' like your descriptions are good; it actually measures their structural integrity.

Analyzing Verb Density and Actionable Commands

The first thing the scorer looks at is calculate_verb_encensity. This sounds academic, but in practice, it's about identifying whether your tool description is actually an instruction or just a paragraph of prose.

An effective MCP tool should be anchored by imperative, action-oriented verbs: retrieve, update, delete, fetch, calculate. If I see descriptions that use passive voice or descriptive fluff like "is designed to help you...", the density ratio drops. A high-density string, like "Retrieve the record and then update it," has a much higher concentration of actionable commands relative to its length (roughly 0.28 in our tests). This tells the agent exactly what the operation entails without the need for secondary reasoning.

The Silent Killer: Naming Uniformity

There is another way MCP tool calls fail that is almost impossible to catch during a standard unit test: naming inconsistency across parameter lists.

You might have one parameter as user_id (snake_case) and another as userAge (camelCase). To a human, it's trivial. To an LLM attempting to construct a valid JSON object for a function call, it’s a massive red flag that leads to downstream parsing failures in the integration layer.

The Scorer uses analyze_naming_uniformity to audit these parameter lists. It checks for casing consistency (e.g., camelCase vs. snake_case) and returns a uniformity score. If your tool definition has even one deviant parameter, it flags it. This is critical when you're building complex tools that rely on consistent patterns across multiple function calls.

The Aggregator: Evaluating Total Clarity

The real meat of this process is the evaluate_description_clarity tool. It acts as a primary aggregator. It doesn't just look at verbs or names in isolation; it computes a weighted clarity score by integrating:

  1. Verb density (Is there enough action?).
  2. Naming uniformity (Is the syntax predictable?).
  3. Explicit return-type definitions (Does it say 'returns a string' or 'returns an object'?).

You can literally run your text through this and get a definitive grade on how reliable that tool will be in an automated environment like Windsurf or Claude Desktop.

Why This Matters for Production

If you are just playing around with MCP in a local sandbox, maybe it doesn't matter. But if you are building production-grade tools—the kind we build at Vinkius that handle real business logic and sensitive data—you cannot afford ambiguity.

When an agent has access to your tools, its ability to perform is directly bounded by the precision of your definitions. If your descriptions are 'fluffy,' you're essentially handing a broken manual to a highly skilled worker and wondering why they can't follow instructions.

You should be linting your tool definitions with the same rigor that you lint your TypeScript code. Check for casing, check for verb density, and ensure return types are explicit. If you don't, you aren't building an agentic tool; you're just hoping for the best.


MCPs are the music of AI Agents. We built the catalog. Discover Vinkius MCP Catalog.

Top comments (1)

Collapse
 
marcusykim profile image
Marcus Kim

The user_id versus userId example gets at a failure mode that ordinary integration tests often miss: the schema can be valid while still being unpredictable to the model. I'd pair naming-uniformity and explicit-return-type linting with evals that measure correct tool selection and argument construction, because a verb-density score-even 0.28-can't prove reliability on its own. Some context is useful when several tools overlap; the real tradeoff is removing prose that doesn't help the agent choose, call, or interpret the tool.