new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

MCP Server Development in Practice · all subjects

Tool description engineering

6 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Why does the agent never call my tool even though it's installed?

Because tool descriptions are prompts, not documentation — they are the only signal the model has for WHEN to reach for your tool, and a description that only describes gets ignored. 'Search the knowledge base' tells the model what the tool does; it says nothing about when that beats answering from memory, so the model answers from memory. Working pattern: name the trigger condition ('Call this whenever the answer depends on project-specific conventions not already in this conversation — before answering from general knowledge'), name the cost ('cheap — call before searching'), and name the next step ('excerpts are cut short; read gives the full note'). Rewrite descriptions as instructions to the model, then measure call rates — this is the highest-leverage change on a live MCP server.

What does a before/after description rewrite look like?

Before: 'Searches brains. Takes a query string and returns results.' — the model cannot tell when this beats its own knowledge, so it never fires. After: 'Search a brain for knowledge relevant to your current task. Call this whenever the answer depends on project-specific conventions, layouts, rules or decisions that are not already in this conversation — before answering from general knowledge. Prefer several short, specific queries over one long one. Returns ranked excerpts with note ids — excerpts are cut short; brain_read gives the full note.' Every clause is doing work: trigger condition, usage pattern, output shape, follow-up tool. Notice nothing here documents the API — a human will never read this text; only the model will.

Should error messages also be written for the model?

Yes — the reader of every tool response, success or failure, is the model, and it will take the next action based on your wording. A good tool error says what happened, whether to retry, and what to do instead: 'Rate limited: more than 60 calls in the last minute. Wait a moment and prefer fewer, more specific queries' gives the agent a corrective behavior. 'Quota reached on the free plan. Tell the user to upgrade at /settings — do not retry' prevents a retry loop AND routes the message to the human. Anti-patterns: raw stack traces (wasted tokens, leaked internals), bare 'Internal error' (agent retries the identical call), and silent empty results (agent concludes the data does not exist). Phrase every failure as an instruction.

Does the initialize response matter for agent behavior?

More than most developers expect: the optional `instructions` field in the initialize result is injected into the client's context as standing guidance from your server, and it shapes behavior across the whole session — not per-tool, but per-server. Use it for the one-paragraph operating manual: when to call your server at all ('call list once at the start of a session'), the ordering between your tools ('brief before searching'), and your house rules ('save durable lessons with write'). Keep it under ~100 words — it competes with the user's context budget on every session. Do not duplicate per-tool trigger conditions here; those belong in the tool descriptions where the model sees them at selection time.

How many tools is too many?

Every tool you expose costs context (the full name+description+schema list rides along in every conversation) and selection accuracy — models get measurably worse at picking the right tool as the menu grows past a few dozen, and wrong-pick failures look like your server being broken. Practical ceilings: a focused server should fit in 5–10 tools; if you have 30, merge CRUD verbs into one tool with an `action` enum, or split into multiple servers. Consolidation pattern that works in production: one search tool that returns ids and excerpts, one read tool for full content — instead of a read per entity type. Fewer, sharper tools with strong descriptions beat an exhaustive API mirror every time.

Should I A/B test tool descriptions? How?

Yes, but not by serving random variants to users — measure first, then iterate. The minimal harness: log every tools/call with tool name, the caller's client (from headers/config), and whether the call succeeded; you are looking for tools that are listed but never called (description problem) versus called but failing (schema or implementation problem). Then replay realistic task prompts against your server with the MCP client of choice — 'debug why deploys fail on Fridays' — and observe whether the agent picks your tool unprompted. Change ONE clause at a time: the trigger condition is usually the lever. Treat description edits like prompt engineering, because that is literally what they are.

Give your agent this brain