Names, descriptions and schemas
By the end: Write a tool description and schema that a model can use correctly first time.
A tool declaration is a piece of prompt engineering that happens to be structured. The model chooses between tools by reading their names and descriptions, so those are not documentation — they are the decision procedure.
Name for the job, not the endpoint. `search_orders` tells a model when to reach for it; `orderQueryV2` does not. Describe when to use it and when not to, because most wrong tool calls are a model picking a near neighbour. If two tools are easy to confuse, say so in both descriptions.
{
"name": "search_orders",
"description": "Find orders for a customer when you do not have an order id. Search by email, or by name plus postcode. Returns at most 20 matches, newest first. If you already have an eight-digit order id, use get_order instead — it is exact and cheaper.",
"input_schema": {
"type": "object",
"properties": {
"email": { "type": "string", "description": "Customer email, exact match, case-insensitive." },
"name": { "type": "string", "description": "Full name. Must be given with postcode." },
"postcode": { "type": "string", "description": "Delivery postcode, spaces ignored." },
"since": { "type": "string", "description": "ISO 8601 date. Omit for all time." }
},
"required": []
}
}Describe every field, including the obvious ones, and say what format you want in words rather than hoping. Where an argument has a small set of valid values, enumerate them in the schema so the model cannot invent a fourth. Where a default is sensible, make the field optional and say what happens when it is omitted.

