📚Academy
likeone
online

Tool Definitions

The tool definition is how Claude knows what your tool does, what inputs it needs, and when to use it. A great definition means Claude calls your tool correctly without any prompt engineering. A bad one means it guesses wrong or ignores your tool entirely.

What Claude Sees

When Claude connects to your MCP server, it calls tools/list and receives a JSON array of tool definitions. Each definition has three parts Claude uses to decide when and how to call your tool:

name Unique identifier Claude uses to invoke the tool. Convention: snake_case.
description Plain English explanation of WHEN to use this tool and WHAT it does. This is the most important field.
inputSchema JSON Schema defining parameter names, types, descriptions, and which are required.

Good vs Bad Descriptions

The description field is what Claude reads to decide whether to use your tool. It is more important than the tool name. Here are real examples showing the difference:

❌ Bad Description
"Searches stuff"

Too vague. Claude does not know what "stuff" means, when to use it instead of other search tools, or what kind of results to expect.

✅ Good Description
"Search through the project's documentation files by keyword. Returns matching file names and a preview of the matching paragraph. Use this when the user asks about how something works in the project."

Tells Claude exactly what it searches, what it returns, and when to use it.

❌ Bad Parameter Description
query: z.string()

No .describe(). Claude has to guess what format the query should be in.

✅ Good Parameter Description
query: z.string().describe( "Search keyword or phrase. Case-insensitive. Partial matches work." )

Claude knows the format, case behavior, and matching strategy.

Zod Schema Patterns

Zod is the schema library MCP uses. Here are the patterns you will use most often when defining tool inputs:

Common Zod PatternsTypeScript
// ── Basic Types ────────────────────────────────────────── z.string().describe("The user's full name") z.number().describe("Maximum number of results to return") z.boolean().describe("Include archived items in results") // ── Constrained Types ──────────────────────────────────── z.string().min(1).max(200).describe("Search query, 1-200 characters") z.number().int().min(1).max(100).describe("Page size, 1-100") // ── Enums — give Claude a fixed set of choices ────────── z.enum(["asc", "desc"]).describe("Sort order: ascending or descending") z.enum(["title", "date", "relevance"]).describe("Sort field") // ── Optional Parameters ────────────────────────────────── // Optional params let Claude omit them when not needed z.number().optional().describe("Max results. Defaults to 10 if not provided.") z.string().optional().describe("Filter by category. Omit for all categories.") // ── Defaults ───────────────────────────────────────────── z.number().default(10).describe("Max results (default: 10)") z.boolean().default(false).describe("Include deleted items (default: false)") // ── Arrays ─────────────────────────────────────────────── z.array(z.string()).describe("List of tag names to filter by") // ── Nested Objects ─────────────────────────────────────── z.object({ lat: z.number().describe("Latitude"), lng: z.number().describe("Longitude"), }).describe("Geographic coordinates")
🔒

This lesson is for Pro members

Unlock all 520+ lessons across 52 courses with Academy Pro.

Already a member? Sign in to access your lessons.

Academy
Built with soul — likeone.ai