A tool is only as good as its schema — the model never reads your code, only the description you hand it.
1The Schema Is the Entire Interface
From the model's point of view, a tool is nothing but its schema: a name it can reference, a description explaining what the tool does and when to use it, and an inputSchema (standard JSON Schema) describing exactly what arguments it accepts. There is no other channel — the model cannot read your implementation, so anything it needs to know to call the tool correctly has to live in that schema.
2required Tells the Model What's Mandatory
JSON Schema's required array lists which properties must be present. Leaving it off doesn't make an argument optional in any meaningful sense if your handler code assumes it exists — it just means the model has no signal that it's mandatory, and may omit it, causing your handler to fail on a missing key.
3Step-by-Step Breakdown
Describing a Tool So a Model Can Use It. A model never sees your server's source code — the only thing it ever sees is the tool's schema: a name, a plain-language description, and a JSON Schema describing its arguments. If the description is vague or an argument is unclear, the model will guess wrong or refuse to call it at all.
Write Your First Real Tool Schema. The path property is already described, but nothing tells the model path is mandatory. Add a required list so the model knows it can't call this tool without supplying a path.
Why does each property in the schema include a natural-language description, not just its type?
- →The model only ever sees the schema, not your source code — the description is its only source of context for filling in the argument correctly.
- →It's purely cosmetic, meant only for developers reading the code, and has no effect on the model's behavior.
One Tool Described, Time to Route It. You just wrote a real tool schema a model could actually reason about. But a schema alone doesn't run anything — your server still needs a way to take an incoming tool call and route it to real Python code. Next module: building that registry.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Write Tool Descriptions in Plain, Unambiguous Language
A description a human developer would also find clear and specific tends to be one a model can reason about correctly too — vague jargon confuses both.
"description": "Read the full contents of a file at the given path."SEO Implications
- 1
Target 'MCP tool schema example' and 'JSON Schema for LLM function calling' separately
Developers writing their first tool search for the MCP-specific shape and the underlying JSON Schema spec as distinct problems.
Best Practices
Name Tools After the Action They Perform, Not Your Internal Function Name
read_file is immediately clear to a model deciding whether to call it; an internal name like fs_op_3 gives it nothing to reason from.
Frequent Bugs
Describing a property's type but leaving its description empty.
A bare type tells the model the shape of the value but not its meaning — always pair type with a short description of what the value represents.
Real-World Examples
Overly Broad Tools
A single run_command tool that accepts any shell string is technically flexible, but its vague schema gives a model no guardrails on what's safe to run — narrower, well-described tools like list_files and read_file are safer and easier for a model to choose correctly.
# Prefer: read_file(path) over: run_command(cmd)