Part 2 · Building Tools That Drive Well

MCP Server Design · ~7 min

The Right Call, Obvious

A well-designed tool makes the correct call obvious. A poor one burns tokens on retries, confuses routing, and forces blind debugging. Three levers: the name, the schema, the error.

Why this, for you: tool search matches against your names and descriptions — so the craft of those strings is literally whether the agent finds and uses your tool. The same three levers that make a tool discoverable also make it self-correcting when a call goes wrong. This is the highest-leverage part of the whole course.

You've chosen the primitive (Lesson 1) and decided to expose data on demand (Lesson 2). Now you design the individual tool so the agent picks it, calls it right the first time, and recovers without a human when it doesn't.

1 Names the agent can route to

The spec allows 1–128 characters from A-Z a-z 0-9 _ - . with no spaces. The conventions that work in practice:

Tool search matches names and descriptions. Opaque names cause routing failures — the agent can't find a tool whose name doesn't read like the task it's trying to do.

2 Schemas that remove guesswork

inputSchema must be valid JSON Schema. But the schema defines types and constraints, not usage — so pair it with prose and examples. In Anthropic's tests, 1–5 realistic examples in the description raised tool-use accuracy from 72% to 90%.

# every part of this is doing work: "name": "search_logs", "description": "Search logs by time range and severity. Returns max 100. Use list_services first for valid names. Do NOT use for metrics — use query_metrics.", "properties": { "service": { "description": "Name from list_services, e.g. 'auth-api'" }, "severity": { "enum": ["debug","info","warn","error","fatal"], "default": "error" }, "since": { "description": "ISO 8601, within last 30 days. e.g. '2026-03-01T00:00:00Z'" } }, "additionalProperties": false

Enums kill guesswork, defaults handle the common case, descriptions pair each constraint with an example, and negative guidance (“do NOT use for metrics”) stops misrouting before it happens. Set additionalProperties: false so unexpected fields fail loudly instead of silently.

3 Errors the agent can act on

MCP has two error channels, and mixing them up is a common mistake. Protocol errors (JSON-RPC codes) are for the client — malformed requests, missing methods. Tool execution errors (isError: true in the result) are for the agent, and the spec is explicit that they should carry “actionable feedback that language models can use to self-correct and retry.”

Error messageAgent can self-correct?
"Error"No
"Invalid date format"Maybe
"Invalid departure date: must be in the future. Current date is 2026-03-13."Yes

Include what was wrong, the constraint, and the context to fix it. That's the poka-yoke principle applied to errors: eliminate the guesswork that drives retry loops.

One trap: enums vs. evolving upstreams

An enum encodes a snapshot. When the upstream API adds a value, agents hit validation failures until you redeploy. For fast-churning upstreams, a thin string type trades strict validation for durability. Use enums where the value set is genuinely stable.

↪ Your win: name, schema, error — each carrying its weight

Retrieval practice — recall, don't peek

Question 1The naming convention used by most public MCP servers is…

Question 2Adding 1–5 realistic examples to a tool description raised accuracy from…

Question 3An error with isError: true in the result is meant for…

Question 4"Do NOT use for metrics — use query_metrics" is an example of…

Question 5 · spaced recall from Lesson 2Just-in-time retrieval pays off only when the returned chunk is…

Ask me anything. Want me to review a real tool schema, or draft an actionable-error template for a validation case? Next in Part 2: The Onboarding Gate — why wiring in a new MCP server can hand an attacker all three legs of the lethal trifecta.
✎ Feedback