Describe a tool once - its name, what it is for, and what it takes - and take the definition out in the shape Anthropic, OpenAI, Gemini or MCP expects. The checks on the left are the ones that decide whether the model uses the tool correctly, which is a different question from whether the JSON parses.
Formats5, from one definition
ChecksNaming, descriptions, enums
RunsEntirely in your browser
The tool
What the model reads before deciding to call it.
Parameters
Review
Nothing blocking - these are the habits that keep tool calls accurate.
This definition reads well.
The definition
Goes in the tools array of a Messages API request.
[
{
"name": "search_orders",
"description": "Search the customer's orders by status, date or product. Use it whenever the customer asks about an order they have already placed. Do not use it to create, cancel or modify an order.",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Free text to match against the product name or the order reference."
},
"status": {
"type": "string",
"description": "Restrict the search to orders in this state.",
"enum": [
"pending",
"shipped",
"delivered",
"cancelled"
]
},
"limit": {
"type": "integer",
"description": "How many orders to return, newest first. Defaults to ten on the server."
},
"customer_id": {
"type": "string",
"description": "The customer whose orders to search."
}
},
"required": [
"customer_id"
]
}
}
]
tool.anthropic.json
The description is the prompt
A model does not see your code; it sees the tool's name and description and decides from those. "Search orders" is a guess. "Search the customer's existing orders; do not use it to create or cancel one" is an instruction - and the negative half is what stops the wrong call.
Enums beat free text
A status parameter described as a string invites the model to invent one. The same parameter with four allowed values cannot be filled wrongly, and needs no validation on your side beyond the schema.
Why the envelope differs
The JSON Schema is identical everywhere; only the wrapper changes - input_schema for Anthropic, parameters for OpenAI and Gemini, inputSchema for MCP. Writing it four times by hand is how a tool ends up working with one provider and failing silently with the next.
Frequently asked questions
What is the difference between Anthropic, OpenAI and Gemini tool definitions?
The JSON Schema for the arguments is identical; only the envelope differs. Anthropic nests it under input_schema, OpenAI under parameters, Gemini under functionDeclarations, and MCP under inputSchema. That is the whole conversion, and it is where hand-written definitions usually break.
Why does my model call the wrong tool?
Almost always the description. A model chooses a tool by reading its name and description, so a vague one is a coin toss. Say what the tool does, when to use it, and explicitly when not to - that last clause prevents most wrong calls.
Should tool parameters use enums?
Wherever the set of valid values is closed, yes. A status described only as a string invites the model to invent one; the same parameter with four allowed values cannot be filled wrongly and needs no extra validation on your side.
What is the MCP tool format?
Model Context Protocol servers return tools from tools/list as objects with a name, a description and an inputSchema - the same JSON Schema, one more envelope. This page emits it alongside the provider formats.