After this, you'll be able to read an MCP tool schema and predict when the model will (and will not) call each tool, then write your own 3-tool schema for a domain you know.
Before you start
Complete Wire Your First MCP first; this lesson builds on having wired a real server so you can read its schema from the model's perspective rather than from a blank example.
The idea
You wire an MCP server, give Claude a task, and it calls the wrong tool. Not because the model is broken, but because the description said 'Gets file' and nothing else. The model reads tool descriptions the same way it reads everything: as text to interpret. A vague description produces a guessing agent.
Here is the before and after: Tool A: name is `file_reader`, description is 'Gets file', parameter is `path` (string). Tool B: name is `get_file_contents`, description is 'Returns the full text of a single file at an absolute path. Use this before editing a file. Do not use for directory listings.' Parameter is `path` (string, example: '/project/src/index.ts'). Tool B gets called correctly every time. Tool A gets guessed at.
The name should be a verb phrase: `get_file_contents`, not `file_reader`. The description needs three things: what it returns, when to call it, and one negative constraint. The parameter description needs a concrete example value, not just a type.
Token cost is real here. Every registered MCP tool loads its full schema into the system prompt on every call. Ten servers with 10 tools each means 100 descriptions loaded before you type a single word. Write tight descriptions. Every extra sentence has a per-call cost.
Try it (20 min)
Watch out for
Paste this into Claude:
Here is a tool schema from an open-source MCP server: [paste a JSON tool schema from a public MCP, or use this example: the filesystem MCP's read_file, write_file, and list_directory tools from github.com/anthropics/mcp-server-filesystem]. Read it and tell me: (1) When would the model call each tool? (2) What user request would cause it to pick the wrong tool? (3) What is ambiguous or missing in the descriptions? (4) How would you rewrite the weakest description to be unambiguous?
What good looks like:
What a good response looks like:
Here is what a good schema critique looks like (applied to a real filesystem MCP schema): 'read_file analysis: - Current description: "Read the complete contents of a file from the file system." - Problem: No trigger condition (when should I use this vs search_files?), no negative constraint, no example path. - Rewritten: "Returns the full text content of a single file at the given absolute path. Use this when you need to read an existing file before editing it. Do not use for directory listings or file search." - Parameter fix: path description should be "Absolute path to the file, e.g. /Users/jose/project/src/index.ts" not just "string". list_directory analysis: - Ambiguous overlap with read_file: a user asking "show me what is in the src folder" could trigger either tool. - Negative constraint to add: "Do not use to read file contents. Use read_file for that." Worst tool name in this schema: No verb phrase issue here, but if it were named file_reader instead of read_file, that would be a noun masquerading as an action.'
Go deeper (25 min)
Paste this into Claude:
Now write your own tool schema for a domain you know well. Pick an imaginary MCP for one of these: a project management tool (like Linear or Jira), a calendar system, or a deployment pipeline. Define exactly 3 tools. For each tool, write: a name (verb phrase), a description (2-3 sentences with trigger condition and constraints), and 2-3 parameters with types and descriptions. Then paste your schema and ask Claude to try to call each tool with a realistic user request. Check if it picks the right tool each time.
What good looks like:
What a good response looks like:
Example 3-tool schema for a deployment pipeline MCP:
```json
{
"tools": [
{
"name": "get_deployment_status",
"description": "Returns the current status of a deployment by ID (pending, running, succeeded, failed). Use this to check whether a deploy finished before taking further action. Do not use to trigger a new deployment.",
"parameters": {
"deployment_id": { "type": "string", "description": "The deployment ID, e.g. dep_8f3a2c" }
}
},
{
"name": "trigger_deployment",
"description": "Starts a new deployment for the given service and environment. Use only after the user has confirmed the target environment. Do not use to check status of an existing deploy.",
"parameters": {
"service": { "type": "string", "description": "Service name, e.g. api-gateway" },
"environment": { "type": "string", "description": "Target environment: staging or production" }
}
},
{
"name": "list_recent_deployments",
"description": "Returns the 10 most recent deployments for a service, newest first. Use when the user wants a history or wants to find a specific deployment ID. Do not use to start a new deployment.",
"parameters": {
"service": { "type": "string", "description": "Service name, e.g. api-gateway" }
}
}
]
}
```When this breaks
Claude can do it for you
Paste your tool schema to Claude and say: 'Critique this schema. Which descriptions are ambiguous? Which tool names overlap in meaning? Where would you call the wrong tool based on a natural request? Rewrite the weakest two descriptions.' It will find the gaps you missed.
You can now
Write a 3-tool schema for a domain you know and demonstrate the model picks the correct tool for three natural-language requests without being told which to use.
Key takeaways
The tool description is the interface. A vague description means a vague agent. Write descriptions for the model, not for a human reader.