How do you design tool descriptions so an LLM chooses and uses them correctly?

5 minintermediatemcptoolsprompt-engineeringdesign

Quick Answer

Write tool descriptions the way you'd document a function for another engineer who has no other context — because that's effectively the model's situation. Be specific about what the tool does, when to use it (and when not to), what each parameter means including units/formats, and what the return value looks like. Avoid vague verbs ("process," "handle") and avoid overlapping tools that do nearly the same thing, which causes the model to pick the wrong one. Include example values in parameter descriptions for anything with a non-obvious format (dates, IDs, enums). This matters more than most people expect: the description and schema are the entire interface the model has to reason about the tool — there's no source code, no comments, no documentation site it can consult.

Detailed Answer

A tool's description isn't documentation for a human reading your code later. It's the only information the model has at inference time to decide whether and how to use the tool.

A weak vs. strong description

// Weak: vague, ambiguous, no format guidance
{"name": "get_data", "description": "Gets data.",
 "inputSchema": {"properties": {"id": {"type": "string"}}}}

// Strong: specific, states scope, gives format examples
{"name": "get_customer_order_history",
 "description": "Fetch the last 90 days of order history for a single customer. Use this when the user asks about a specific customer's past purchases. Does not include current cart contents.",
 "inputSchema": {
   "properties": {
     "customer_id": {"type": "string", "description": "Internal customer ID, format 'CUST-00000' (not an email address)"}
   },
   "required": ["customer_id"]
 }}

Principles that consistently help

  • State the scope explicitly: "last 90 days," "does not include X." This stops the model from assuming broader behavior than the tool actually has.
  • Disambiguate near-duplicate tools. If you have search_users and find_user, the model has no reliable way to pick between them unless the descriptions explain the difference — one takes a fuzzy query, say, the other an exact ID.
  • Give format examples for anything non-obvious — IDs, date formats, enums — directly in the parameter's description, not just its type.
  • Say when not to use it, if there's a common wrong-context call the model might otherwise make.

Why this is worth real design effort

Two functionally identical servers with different tool descriptions can produce very different model behavior. One calls the right tool reliably; the other picks the wrong tool or passes malformed arguments a meaningful fraction of the time. Treating tool descriptions as a first-class design artifact, not an afterthought filled in once the code works, is one of the highest-leverage things you can do when building an MCP server.

Related Resources