LevelUpWith

Explore / Agent-Ready Products: CLI, MCP Server or Skill / Lesson 2

Lesson 2: Tool Selection: Names and Descriptions Decide

See how an agent chooses between tools using only their names, descriptions and parameter schemas, and why vague or overlapping descriptions cause wrong picks.

Free to read, no account needed. Part of Agent-Ready Products: CLI, MCP Server or Skill.

By the end of this level you'll be able to

  • Predict which of several similar tools an agent will choose for a given request, and say why
  • Rewrite a vague tool description so it says what the tool does, when to use it and when not to
  • Find naming collisions and overlapping scopes that make an agent's choice ambiguous

The agent never sees your code

In Level 1 you followed one tool call through the agent loop. This level covers the step just before that call: choosing which tool to use. You know your API from the inside. The model doesn't. All it sees of each tool is three things:

  1. the name
  2. the description
  3. the parameter schema (property names, types, enums, which fields are required, and any per-parameter descriptions)

Nothing else gets to the model: not your README, not your implementation, not the intent behind the endpoint. On the Claude API, tool definitions are written into a special system prompt that comes before the conversation. In MCP, the client calls tools/list and hands those same fields to the model. Picking a tool is reading comprehension, not code analysis.

Think of a new hire on their first day, given a list of internal scripts and one line about each. Whatever that line leaves out, they will guess. Anthropic's engineering guidance (11 September 2025) puts it the same way: describe the tool as you would to a new hire.

Walkthrough: predict the pick

The running example for this course is Ledgerly, an invoicing API. Here is a first attempt at exposing it as tools:

[
  { "name": "search",
    "description": "Search Ledgerly.",
    "inputSchema": { "type": "object",
      "properties": { "q": { "type": "string" } } } },

  { "name": "get_invoice",
    "description": "Gets an invoice.",
    "inputSchema": { "type": "object",
      "properties": { "id": { "type": "string" } },
      "required": ["id"] } },

  { "name": "lookup_customer",
    "description": "Look up customer info and invoices.",
    "inputSchema": { "type": "object",
      "properties": { "customer": { "type": "string" } } } }
]

The user asks: "Has Acme paid INV-2041 yet?"

Now put yourself in the model's place:

  • get_invoice looks right, but is id the human number INV-2041 or an internal UUID? The schema doesn't say. And does the result include payment status? The description doesn't say.
  • lookup_customer also mentions invoices, so it competes. And should customer be a name or an ID?
  • search claims everything, so it's the safe fallback whenever the model is unsure.

The usual result: the agent calls search with q: "Acme INV-2041 paid" and gets back a fuzzy list. Or it passes INV-2041 to get_invoice as id, which expected a UUID, and gets a 404. Neither failure is the model being stupid. The descriptions overlap, so the model had to guess.

Gotcha: Give a model an overlapping set of tools and it tends to fall back on the most general one. A tool called search with a one-line description pulls in requests that belong elsewhere.

Rewriting a description: what, when, when not

Anthropic's tool-use docs (checked October 2026) say the description is "by far the most important factor in tool performance". They recommend at least 3–4 sentences, covering what the tool does, when to use it and when not to, what each parameter means, and what the tool does not return. Here is get_invoice rewritten:

{
  "name": "ledgerly_invoice_get",
  "description": "Fetch one invoice by its invoice number, including amount, due date and payment status (paid, partially_paid, unpaid, void). Use this when the user names a specific invoice, e.g. 'INV-2041'. Do not use it to find invoices by customer or date; use ledgerly_invoice_search for that. Does not return the customer's contact details.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "invoice_number": {                        // was "id": now says which ID
        "type": "string",
        "pattern": "^INV-[0-9]+$",              // the format is visible to the model
        "description": "Human-facing invoice number, e.g. INV-2041"
      }
    },
    "required": ["invoice_number"]
  }
}

What changed, and why it matters:

  • What it does lists the fields that answer "has it been paid?", so the model knows this tool is enough.
  • When to use connects the tool to how users phrase requests ("names a specific invoice").
  • When not to sends the model to the sibling tool. This one sentence does most of the work of separating overlapping tools.
  • The parameter name invoice_number replaces id. The guidance is to prefer unambiguous names (user_id, not user). The schema is part of the description.

Trade-off: Longer descriptions cost tokens on every request. Level 3 measures that cost. For now: a clear sentence costs much less than a wrong tool call.

Collisions: when two tools share a name

An agent seldom runs your server alone. Picture a user who connects Ledgerly and a CRM, and both expose search. The MCP spec (version 2026-07-28) addresses this directly. Tool names only have to be unique within one server. Clients that combine several servers SHOULD disambiguate, for example by adding a server identifier as a prefix. And serverInfo.name is not guaranteed to be unique, so clients shouldn't rely on it to tell servers apart.

Clients handle this differently. Claude Code shows MCP tools as mcp__<server>__<tool>, where <server> is whatever name the user gave when adding the server. So two search tools become mcp__ledgerly__search and mcp__crm__search. The prefix stops the names clashing, but the model still has to choose between two tools described as "Search." Don't rely on the client. Put your own namespace in the name and the scope in the description:

ledgerly_invoice_search    # resource + action, namespaced by product
ledgerly_invoice_get
ledgerly_customer_get

Anthropic reports that prefix-based and suffix-based naming score measurably differently in their evaluations, and that the effect varies by model. Choose one scheme, use it everywhere, and test it (Level 30-something will cover how).

Gotcha: name rules differ by layer. The MCP spec allows letters, digits, _, - and ., up to 128 characters. The Claude API's tool-name regex is ^[a-zA-Z0-9_-]{1,128}$, which has no dot. Claude Code replaces any character outside that set with _. So ledgerly.invoice.get may reach the model under a different name than the one you wrote. Stick to letters, digits and underscores and the name stays the same everywhere.

A quick collision audit

Before you ship, put all your tools side by side and ask:

1. Could two descriptions both honestly claim the same request?  -> add "when not" lines
2. Is any tool a catch-all (search, query, run, do)?             -> narrow or remove it
3. Do two tools share a verb but differ only in an unstated way? -> name the difference
4. Would your names clash with a popular server's (search, get)? -> namespace them
5. Are parameter names ambiguous (id, user, name, q)?            -> say which thing they are

Key takeaways

  • The agent picks a tool from its name, description and parameter schema alone. Anything you leave out, it guesses.
  • A good description covers what the tool does, when to use it, when not to (naming the alternative), and what it does not return.
  • Overlapping scope and catch-all tools cause wrong picks more often than the model does.
  • MCP names only have to be unique within one server. Namespace your own tools, because clients disambiguate in different ways.
  • Name rules differ between the MCP spec and model APIs. Plain snake_case with letters, digits and underscores survives every layer.

A 6-question knowledge check follows this lesson in the app, free and without an account.

Keep going: levels 3 and 4 are free

Create a free account to open the next two levels, save your progress and pick up where you left off. No card needed.

Next: Level 3, Context Cost: Every Tool Takes Up Space.

Create a free account →See the whole course

More like this

  • Google Cloud Generative AI Leader Certification Exam Prep

    Master all four sections of the current Generative AI Leader exam guide at business level, with no coding, from first principles to confident scenario "best an…

    Exam prep · Google · AI & Agents · Expert · 42 levels · 4 free · Professionally curated by levelupwith.com

  • AI Coder: Claude Code & Coding Agents

    Master vibe coding and autonomous workflows using Claude Code, Cursor, MCP servers, and modern AI coding agent frameworks.

    Beyond the Obvious · AI & Agents · Capable · 18 levels · 4 free · Professionally curated by levelupwith.com

  • Introduction to Generative AI

    Learn who invented generative AI, how it works, where the technology stands today, and where it's headed — all in a quick, beginner-friendly course.

    Course · AI & Agents · AI & Agents · Curious · 7 levels · 4 free · Professionally curated by levelupwith.com

  • Architecting for Coding Agents: Prescribe vs Delegate

    Decide how much architecture to prescribe to a coding agent and how much to leave to it, working from a catalogue of named patterns and anti-patterns that each…

    Beyond the Obvious · AI & Agents · Expert · 38 levels · 4 free · Professionally curated by levelupwith.com

  • AI Agents for Non-Developers: Understand, Try, Oversee

    Learn how AI agents differ from the chat assistants you already use, try research and browser agents safely without writing any code, and delegate tasks with c…

    Course · AI & Agents · AI & Agents · Capable · 18 levels · 4 free · Professionally curated by levelupwith.com

  • AI Proficiency: From Occasional User to Power User

    Get dependable, high-quality results from AI assistants such as ChatGPT, Gemini, Claude and Copilot. You will learn to give rich context, run multistep workflo…

    Course · AI & Agents · AI & Agents · Capable · 18 levels · 4 free · Professionally curated by levelupwith.com