A useful MCP tool description explains the tool's purpose, when to choose it, what information it needs, and what the caller can expect back. Make the boundary between similar tools explicit. Put field-specific details beside the relevant inputs, and check the description against real requests before releasing it.

That is our recommended starting point for a tool interface. Clear wording can support better choices, but it does not guarantee correct behaviour or replace validation and access controls.

This guide uses an illustrative support-ticket service to show how to write and evaluate descriptions. The examples are proposed designs, not results from a customer deployment.

What role does the description play?

An MCP tool definition can describe its functionality alongside an input schema. The protocol also supports an optional output schema and behaviour annotations. Tools are designed to be discoverable and callable by models, although the host application decides how to present and control that interaction. See the MCP tools specification.

Our recommendation is to write the description as a short decision aid. Someone reading only the name, description, and inputs should be able to tell which requests the tool handles and where another capability is needed.

If the underlying scope is still unclear, first decide which API actions belong in your initial MCP integration. Editing the description cannot resolve a tool that combines several unrelated jobs.

Start with a pair of tools that could be confused

Imagine that your support service offers search_tickets and get_ticket. A first draft might describe them this way:

search_tickets: Get ticket information.

get_ticket: Retrieve support ticket details.

Both sound plausible for “What is happening with my delivery complaint?” The descriptions leave the important distinction unstated: one finds candidate tickets; the other retrieves a particular ticket whose identifier is already known.

For our example service, more useful descriptions would be:

search_tickets: Find support tickets in the connected account using a search phrase and optional status filter. Use when the ticket identifier is unknown. Returns matching ticket identifiers, subjects, statuses, and a next-page cursor when more matches exist. Does not create or update tickets. Use get_ticket to retrieve the full details of a known ticket.

get_ticket: Retrieve the subject, status, and customer-visible messages for one ticket in the connected account using its exact ticket identifier. Use when the identifier is already known from the user or a previous search result. Does not search across tickets or change their status.

These descriptions assume the service really has those behaviours and returns those fields. Adapt the wording to your implementation instead of copying a promise your API cannot keep.

Give each sentence a job

Our suggested description structure has four parts:

  1. Purpose: the specific operation and the object it acts on.
  2. Selection rule: the condition that makes this the appropriate tool.
  3. Result: the information returned, including a meaningful limitation.
  4. Boundary: a nearby action it does not perform, or a related tool to use next.

For get_ticket, “the identifier is already known” does real work. It distinguishes retrieval from search. “Does not change status” establishes a side-effect boundary. A paragraph about how innovative your support platform is would not help make either decision.

There is no word count in this recommendation. Keep the details that affect correct use, and remove sentences that repeat the name without adding meaning.

Explain inputs where the assistant supplies them

A good tool-level description still needs clear input definitions. In our ticket example, a field described only as “ID” leaves too much room for interpretation. We would describe ticket_id as:

The exact ticket identifier supplied by the user or returned by search_tickets. Preserve it unchanged; do not substitute a subject line or invent an identifier.

For the search cursor, we would use:

The opaque next-page cursor returned by an earlier search with the same filters. Omit it for the first page.

Those are proposed contracts for this example. Your implementation must define whether a cursor remains valid when filters change and how long it can be used.

JSON Schema's description and examples annotations provide explanatory information; they are not validation constraints. Its default annotation also does not, by itself, insert a missing value during validation. See the JSON Schema annotation reference.

Use the appropriate schema constraints and server checks for required fields and permitted values. For example, if your tool supports only open and closed as status filters, enforce that contract rather than relying on a sentence asking the assistant to comply.

Describe ambiguity honestly

Consider the request “Show me my latest ticket.” If your search tool has no documented sort order, its first result may not answer that question. Adding “returns the latest ticket” to the description would create a misleading interface.

For our example, the team has two reasonable options: support and document a suitable ordering, or describe the actual search behaviour and avoid claiming that the first match is the newest. The implementation decision comes before the wording.

The same review applies to “all,” “current,” and “complete.” If a search returns one page, say so. If a record excludes internal staff notes, say “customer-visible messages.” Specific boundaries help the assistant explain what it has retrieved.

This is also useful when reviewing tools generated from an OpenAPI description. A technically valid imported description can still leave the intended use unclear.

Keep permission checks in the service

“Only retrieves tickets in the connected account” should describe an enforced property of the service. Test it with an identifier belonging to another account. If the request succeeds when it should be denied, stronger prose will not fix the access problem.

Likewise, a tool that says it does not update records should not unexpectedly change a ticket's status as part of retrieval. Review the underlying operation with the team that maintains it.

The MCP specification says clients must consider tool annotations untrusted unless they come from a trusted server. Treat descriptive metadata as information for making decisions, and keep authorization and validation in the actual execution path. See the MCP tool definition requirements.

Evaluate the description against ordinary requests

Our suggested starting set for the ticket example includes requests with different expected choices:

Run the requests through each assistant client you plan to support. Record the selected tool, supplied arguments, result interpretation, and any clarification requested. Include repeated runs where variability matters. A single successful demonstration is a useful example, not a reliability measurement.

When a request fails, distinguish a wording problem from a missing capability, an invalid argument, or an API error. Change the relevant part and repeat the same evaluation set. Keep the examples as regression checks when tool descriptions evolve.

A reusable writing template

Use this as an editorial starting point, replacing every placeholder with verified behaviour:

[Verb] [specific object] within [scope]. Use when [selection condition]. Requires [essential prerequisite]. Returns [useful result and limits]. Does not [nearby action that could be confused with this one]. Use [related tool, if available] when [different condition].

Before publishing, read the description beside the most similar tool in your integration. If both appear equally suitable for the same request, make the distinction clearer or reconsider the tool boundaries.

The free Agent Readiness Audit proposes tools from your documentation, provides a readiness score, and gives a fixed setup price. Use that proposed scope as the starting point for reviewing the descriptions, inputs, and behaviour your customers will rely on.