D2 · Tool Design & MCP Integration

18% of the exam · ≈11 of 60 questions · plain-language lesson first, full notes at the end

Step 5 of 9~20 min
The big idea Tools are the agent's hands — and the agent chooses which hand to use only by reading their descriptions. Most "the AI picked the wrong tool" problems are really "the tool was described like an afterthought." This domain: describing tools like you'd brief a new hire, failing loudly instead of silently, and knowing the plumbing standard (MCP) that connects it all.

Designing tools the agent picks correctly

📇

A description is a job ad

What it does (specifically) · WHEN to use it (trigger conditions) · when NOT to, and how it differs from its lookalike sibling · what each parameter means and its format.

Mis-routing between two similar tools? Fix BOTH descriptions first. Still failing? The system prompt's wording is creating the association — a clean accuracy split on one keyword (71% for "billing" requests, 94% otherwise) is the fingerprint.
✂️

One tool, one job

A do-everything analyze_document tool gets misused constantly. Split it into purpose-specific tools with clear contracts (extract / summarize / verify). A "mode" parameter is the same confused tool wearing a name tag.

And keep the toolbox small: an agent carrying 18 tools across four jobs will misuse out-of-role ones — scope each agent to its role's ~4–5. Tools that aren't there can't be misused.
🔒

Make misuse impossible, not discouraged

Agent using a general web-fetch tool to browse? Replace it with one that only accepts document links. Deleting things needs ceremony? Split into a preview tool that issues a one-time confirmation code and an execute tool that requires it — skipping the preview becomes physically impossible.

Constrain at the interface. A dry_run: true/false flag is a suggestion; a required preview token is a law.

When tools fail — fail loudly, fail usefully

Success vs genuinely-empty vs failure outcomes and the silent-failure trap
The silent-failure trap: a tool hits an error and returns an empty list. To the agent that looks like "search worked, nothing exists" — and it confidently tells the customer so. Every tool must distinguish three outcomes: success with data · genuinely empty (say so explicitly) · failure (marked as an error).
Error typeRetry?Right handling
Transient (timeout)✅ yesretry with backoff — inside the tool, if the tool can tell
Validation (bad input)✅ after fixingreturn immediately, say what's wrong
Business (against policy)customer-friendly explanation
Permissionescalate
🏷️

Errors the agent can act on

A uniform "Operation failed" gives the agent nothing to decide with. Structured errors carry the category, whether retrying makes sense, and a human-readable line.

errorCategory + isRetryable + actionable text.
👁️

Errors the model can even SEE

If tool code crashes and the exception escapes, it becomes a plumbing-level failure the model never sees — it can't adapt to what it can't see. Catch everything in the server and return the failure as a normal, marked result.

Catch → return in-band with isError: true. Uncaught = invisible protocol error.
🧾

Partial success is not success

A subagent translated 8 of 10 documents; 2 had an encoding it can't fix. Reporting just the 8 makes gaps look like complete coverage. Handle transient hiccups locally; report what stayed broken — loudly, with what was attempted.

Propagate unresolvable failures WITH type + attempts + the partial results. Never silently drop; never abort the whole job for one failure either.

MCP — the standard plug

MCP is how external systems (Jira, GitHub, databases) connect to Claude. Three kinds of things come through the plug, each controlled by a different party:

MCP host/client/server diagram with the three primitives and their controllers
PrimitiveWho decides to use itTypical exam use
Toolsthe modelactions the agent chooses to take
Resourcesthe applicationcontent catalogs — agent sees available data without wasting exploratory calls
Promptsthe userreusable templates a person invokes
⚙️

Team config without leaking secrets

The shared server config is committed to the repo so every teammate gets it; the API token is referenced as a variable each person sets locally — it never touches version control.

// .mcp.json — committed at repo root
{ "jira": { "env": { "JIRA_TOKEN": "${JIRA_TOKEN}" } } }
Project servers: .mcp.json (committed, ${ENV} secrets). Personal experiments: ~/.claude.json.
🛒

Build vs adopt

Jira and GitHub have battle-tested official/community servers — building your own is maintenance for nothing. Custom effort goes only where nothing standard exists (your in-house approval workflow).

Standard integration → community server. Bespoke workflow → custom. Agent ignores your better tool for a built-in? Enrich YOUR tool's description — it picks what it understands.
🔎

The built-in trio, disambiguated

Grep searches what's inside files; Glob matches file names/paths. When Edit can't find a unique anchor for a change: read the whole file and write the corrected version back — don't fight the anchor, don't shell out to sed.

Contents → Grep · names → Glob · ambiguous Edit → Read then Write.
Drill D2 now — quiz filtered to this domainAdaptive: anything you miss comes back in a new disguise until you convert it.

Flash-drill this domain (22 cards)

Tap a card to flip it — the same concepts the quiz drills adaptively.

Full study notes optional deep reading — the original study-kit text, code-free

1. Tool descriptions ARE the selection mechanism

The model chooses tools by reading their names and descriptions — nothing else. A mis-routing agent almost always has a description problem, and the exam's root-cause principle applies: fix the descriptions before adding a routing classifier, a bigger model, or more prompt.

A production-grade description states:

  1. What the tool does (specifically — not "handles data")
  2. When to call it (trigger conditions: "Call this when the user asks about...")
  3. When not to / how it differs from confusable siblings
  4. What each parameter means (in the schema's property descriptions)
Weak Strong
search — "Searches for things" search_orders — "Search the ORDER database by customer, date range, or status. Call when the user asks about an existing order's state, contents, or history. For refunds use issue_refund; for product catalog questions use search_catalog."

2. Designing input schemas

Schema choices that separate reliable tools from flaky ones:

  • Enums for closed sets"status": {"enum": ["open", "closed", "pending"]} beats a free string the model might invent values for.
  • Describe every property — property descriptions are read at call time; "date in ISO 8601 YYYY-MM-DD" prevents a whole class of format bugs.
  • Mark truly required fields only; give optional ones sensible defaults in your executor.
  • Prefer specific parameters over one opaque blob{"customer_id", "date_from", "date_to"} beats {"query": "..."} when the backend is structured: the schema is documentation, and the harness can validate it.
  • Names: verbs, specific, consistent (get_, search_, create_ prefixes). get_weather not weather; search_orders not handler2.

3. Errors: the silent-failure trap and is_error

The silent-failure trap (a named exam pattern): a tool that returns an empty string / empty list / null on failure looks successful to the model. It will happily proceed — "I found no orders for this customer" — when the truth was "the database call timed out."

Reliable tools distinguish three outcomes, explicitly and machine-readably:

Outcome Return
Success {"ok": true, "data": ...}
Genuinely empty result {"ok": true, "data": [], "note": "no orders matched customer 8813 in the last 90 days"}
Failure {"ok": false, "error": "orders-db timeout after 5s — result unknown, retry may succeed"}

Two layers of error signaling in the Claude API:

  1. Content: the error payload above, inside the tool_result content.
  2. Flag: "is_error": true on the tool_result block — tells the model "this call failed" at the protocol level. (MCP has the same concept spelled isError: true — §6.)

Good error messages are actionable: what failed, why (if known), and what would help ("retry", "narrow the date range", "invalid ID format — expected ORD-XXXX").

📊 Diagram — “Success vs genuinely-empty vs failure outcomes and the silent-failure trap” (a version appears earlier on this page)

4. MCP: architecture in one diagram

The Model Context Protocol is an open standard for connecting AI applications to external systems — "USB-C for AI tools": build a server once, use it from any MCP client.

┌─────────────── host application ───────────────┐
│  (Claude Code, Claude Desktop, your app)       │
│   ┌──────────┐        ┌──────────┐             │      ┌──────────────┐
│   │  model    │◄──────►│MCP client│◄────────────┼─────►│  MCP server  │
│   └──────────┘        └──────────┘  protocol   │      │ (GitHub, DB, │
│                       one client per server    │      │  Jira, ...)  │
└────────────────────────────────────────────────┘      └──────────────┘
  • Host: the application the user interacts with.
  • Client: the connector inside the host — one per server connection.
  • Server: exposes capabilities (tools/resources/prompts) for one system.

Servers run locally (stdio transport) or remotely (HTTP-based transport). Configuration in Claude Code lives in .mcp.json (page 02 §8 covers scopes).

📊 Diagram — “MCP host/client/server diagram with the three primitives and their controllers” (a version appears earlier on this page)

5. The three MCP primitives — ★ the most-tested table in this domain

Primitive What it is Who controls invocation Example
Tools Executable actions the model may call during generation Model-controlled create_issue, run_query
Resources Data/content exposed for context (file-like, addressable) Application-controlled file contents, DB schema, API response
Prompts Pre-built prompt templates/workflows User-controlled a "/summarize-pr" template the user picks

The control column is the exam's favorite discriminator. Anchors:

  • Model decides to act mid-conversation → tool.
  • The app decides what context to provide (attach this file, load that schema) → resource.
  • The user explicitly picks a canned workflow (slash-command-like) → prompt.

Question shape to expect: "The server should expose the database schema so the assistant can reference it while writing queries. Which primitive?" → Resource (the app supplies context; the model doesn't 'call' a schema). "...and expose query execution?" → Tool. "...and a standard 'optimize this query' workflow users trigger?" → Prompt.

6. MCP error handling: isError: true

MCP tool results carry an isError flag. The critical distinction:

Failure kind Mechanism Who handles it
Tool executed and failed (API 404, timeout, bad input) Result with isError: true + error content The model — it sees the error and can adapt/retry/apologize
Protocol-level failure (unknown tool, malformed request, server crash) JSON-RPC protocol error The client/harness — the model never receives a result

Exam-tested consequences:

  • A tool that catches an exception and returns isError: true with an actionable message lets the agent recover in-conversation — the reliable design.
  • A tool that lets the exception explode into a protocol error takes the whole exchange down — the model can't adapt to what it never sees.
  • Same silent-failure rule as §3: an MCP tool returning empty content with isError: false on failure is the worst case — a lie the model will build on.

7. MCP configuration & scoped distribution

Recap of the .mcp.json scope table (details in page 02):

Scope Distribution Use
Project (.mcp.json, committed) Everyone who clones Team-standard servers
User One person, all projects Personal tooling
Local One person, one project Experiments, personal credentials

Plus the security rules this domain re-tests:

  • Secrets via environment-variable expansion ("env": {"TOKEN": "${GITHUB_TOKEN}"}) — never literal keys in a committed file.
  • MCP tools flow through the same permission system as built-in tools — a server being configured doesn't mean every tool is auto-approved.
  • Third-party servers are supply chain: prefer official/vetted servers; an MCP server runs with whatever access you gave it.

8. Minimal tool surface

Fewer, sharper tools beat many overlapping ones:

  • Selection accuracy: every added tool is another chance to mis-route; overlapping tools ("search", "find", "lookup") are the classic self-inflicted wound.
  • Security: each tool is capability granted — least privilege applies to the definition list, not just permissions (Domain 1's allowedTools, Domain 3's allowlists — one principle, three domains).
  • Design smell: if two tools need a paragraph explaining when to use which, consider merging them behind one parameter ("scope": {"enum": ["orders", "catalog"]}) — or make the split's trigger conditions unmistakable in the descriptions.

Root-cause ladder for a mis-routing agent (exam-aligned order): 1) sharpen descriptions → 2) reduce/merge overlapping tools → 3) only then consider a routing layer.

9½. Official exam-guide addenda (v1.0)

Specifics from the official task statements (Exam Guide v1.0, July 2026):

Description interference (TS 2.1). Tool selection isn't decided by descriptions alone — keyword-sensitive wording in the system prompt can override well-written descriptions and create unintended tool associations. When routing misbehaves, review both. And the flip side of §8's "merge overlapping tools": a single too-generic tool should be split into purpose-specific tools with defined contracts (the guide's example: analyze_documentextract_data_points, summarize_content, verify_claim_against_source).

The official error taxonomy (TS 2.2). Four categories every MCP tool should distinguish: transient (timeout, service down — retryable), validation (bad input — fix and retry), business (policy violation — not retryable, needs a customer-friendly explanation), permission (not retryable, needs escalation). Structured metadata: errorCategory, isRetryable boolean, human-readable description. And the multi-agent rule: subagents recover locally from transient failures; they propagate only errors they can't resolve — together with partial results and what was attempted.

MCP integration details (TS 2.4). The user-level config file is ~/.claude.json (project level is .mcp.json). MCP resources have a tested use-case: exposing content catalogs (issue summaries, documentation trees, database schemas) so agents see what data exists without exploratory tool calls. If the agent keeps using built-in tools (Grep) instead of a more capable MCP tool, the fix is richer MCP tool descriptions — the agent prefers what it understands. And build-vs-buy: community MCP servers for standard integrations (Jira, GitHub); custom servers only for team-specific workflows.

Finished this page?Mark it complete — your progress updates everywhere instantly.
Next: D5 · Context Management & Reliability →