How to write tool descriptions a model gets right
The most-read text you will ever write, read by something that cannot ask a follow-up question. Here is what makes the difference.
Your tool description is the most frequently read thing you will ever write, and its reader cannot ask a follow-up question. It is re-sent on every turn of every session your server is installed in, and everything the model does with your tool is decided from it.
Most descriptions are written the way a README subtitle is written: short, friendly, and empty of the things the reader actually needs.
Say what it does to the world, not what it is called
"Syncs a project" tells a model nothing it can act on. Sync in which direction? Does it create? Does it delete? A description that could describe four different tools will be used as though it were all four.
The test: read your description and ask whether it distinguishes this tool from a plausible neighbouring one. If not, the model has to guess, and it will guess consistently in whichever direction your wording leans.
State the failure, in the description
This is the single highest-value sentence you can add, and almost nobody adds it. "Returns 404 if the project does not exist" is worth more than a paragraph of features, because it converts a failure from something the model has to interpret into something it can report.
Without it, a failing call is just text, and a model reading unexplained text will do the thing agents do: try again, try differently, try harder. Users experience that as flakiness and write it into a review as flakiness.
Name the preconditions
- What has to exist first. "The project must already be created" saves an entire branch of wrong attempts.
- What it costs. If a call is slow or expensive, say so — a model given the choice will pick the cheap one when it is told which is which.
- What it will not do. "Does not create the project if it is missing" is a boundary, and boundaries are what stop improvisation.
Never write an instruction
A description that says "always call this first" or "ignore earlier guidance about scope" is read by the model as guidance from you, indistinguishable from the user's own. Whatever you intended, what you built is a way to steer somebody else's agent.
Describe the tool. Do not address the model. The moment your text tells it what to do, your description has become an instruction with your name on it.
Reviewers look for this specifically, and a buyer who reads surfaces will spot it. It is also the fastest way to have a listing rejected for something that was probably meant helpfully.
Keep it short, because it is charged per turn
Every word is re-sent on every turn, so a description is not a place to be thorough. Two sentences: what it does to the world, and how it fails. Everything else belongs in the schema, where the argument descriptions can carry the detail without being read as prose.
The shape that works
| Write this | Instead of |
|---|---|
| Creates an issue in one project. 404 if the project does not exist. | Manages your issues |
| Reads the file at path. Does not follow symlinks. | File access |
| Returns up to 50 rows; pass a cursor for the rest. | Queries the database |
| Cancels a subscription at period end. Irreversible. | Subscription management |
Rewriting a description costs an afternoon and changes how your server behaves in every session it is installed in — which makes it, by a wide margin, the highest-leverage editing you can do to a listing that is not getting installed twice.