Implement custom tools with effective name, description, and JSON Schema input_schema fields, and handle tool errors correctly.
Trace the tool_use / tool_result round-trip and distinguish client-side from server-side tools.
Explain MCP's host/client/server architecture, its three server primitives, and its transports.
Choose correctly among built-in tools, custom tools, Skills, and MCP servers for a given use case.
Section 1 — Pre-Check: Tool Implementation
1. Which three fields are required in every tool definition?
2. According to Anthropic's guidance, what is the single highest-leverage factor in tool performance?
3. Your tool function ran but failed because of an upstream rate limit. What is the correct way to report this?
4. You have separate create_pr, review_pr, and merge_pr tools and Claude keeps picking the wrong one. What is the recommended fix?
Section 1: Tool Implementation
Tool use (equivalently, function calling) is the mechanism by which Claude calls functions you define — or that Anthropic provides — based on the user's request and each tool's description. Claude never runs your code; it emits a structured intent to call, and your harness fulfills it. In the Messages API there is no special tool role: tool_use blocks live in assistant messages and tool_result blocks live in user messages.
Key Points
A tool definition has three required fields: name (matching ^[a-zA-Z0-9_-]{1,64}$), description, and input_schema (a JSON Schema / function schema).
The description is the highest-leverage part — write 3–4+ detailed sentences covering what it does, when (and when not) to use it, each parameter, and caveats.
Consolidate related operations under one action parameter, use meaningful namespacing (github_list_prs), and return only high-signal information.
Report execution failures with an instructive message and is_error: true so Claude can recover; missing-parameter errors usually mean the description lacked detail.
Treat tool_result content as untrusted (indirect prompt-injection risk); never promote it into the system prompt.
The three required fields
Field
What it is
Notes
name
Identifier for the tool
Must match ^[a-zA-Z0-9_-]{1,64}$
description
Detailed plaintext explanation
Highest-leverage field; 3–4+ sentences
input_schema
JSON Schema of parameters
Types, properties, enum, required, defaults
Optional additions include input_examples, strict, cache_control, and defer_loading.
Error categories
Category
Cause
How to report
Tool execution error
Your function ran but failed (rate limit, missing record)
tool_result with is_error: true and an instructive message
Invalid name / missing parameters
Usually a thin description
Return a tool_result error; Claude retries 2–3 times
Server tool error
Anthropic-run server tool failed
Handled transparently by Anthropic; do not set is_error
[Animation slot: a "job description" analogy morphing a vague tool description ("Gets the stock price") into a rich one ("Returns last-traded price in USD; US equities only; errors on crypto").]
Section 1 — Post-Check: Tool Implementation
1. Which three fields are required in every tool definition?
2. According to Anthropic's guidance, what is the single highest-leverage factor in tool performance?
3. Your tool function ran but failed because of an upstream rate limit. What is the correct way to report this?
4. You have separate create_pr, review_pr, and merge_pr tools and Claude keeps picking the wrong one. What is the recommended fix?
Section 2 — Pre-Check: Tool Usage Patterns
1. When Claude wants to call a client tool, which stop_reason does the response carry?
2. What connects a tool_result back to the request that produced it?
3. Which of these is a server-side tool that runs on Anthropic's infrastructure?
4. In the API pattern, where should an approval gate for a destructive action (like deleting data) be implemented?
5. Which tool_choice setting is incompatible with extended thinking?
Section 2: Tool Usage Patterns
When Claude decides to call a client tool, the response has stop_reason: "tool_use" and one or more tool_use blocks, each with an id, a name, and an input. Your harness runs the matching handler and replies with a user message containing a tool_result block that references the originating id via tool_use_id. Formatting is strict: the tool_result must immediately follow the assistant's tool_use message, and must come first in the user content array — violations produce an HTTP 400.
Key Points
The round-trip: Claude emits tool_use (id, name, input) → harness dispatches by name → returns tool_result (matching tool_use_id) → Claude continues until end_turn.
Client-side tools run in your app: all custom tools plus Anthropic-schema bash, text_editor, memory, and computer use.
Server-side tools run on Anthropic's infrastructure with no handler code: web_search, web_fetch, code_execution, advisor, tool_search.
tool_choice has four settings: auto (default), any, forced tool, and none; any and forced tool are not compatible with extended thinking.
Gate sensitive, irreversible actions behind an approval step in your dispatch layer, since your harness sees each tool_use before running it.
Figure 13.1: The tool_use / tool_result round-trip between Claude and your application
sequenceDiagram
participant User
participant Claude as Claude (Messages API)
participant Harness as Your Harness
participant Tool as get_weather Handler
User->>Claude: "What is the weather in Paris?"
Note over Claude: Decides a tool is needed
Claude-->>Harness: assistant message tool_use (id, name, input) stop_reason: "tool_use"
Harness->>Tool: Dispatch by name, run with input
Tool-->>Harness: "72F and sunny"
Harness->>Claude: user message tool_result (tool_use_id, content)
Note over Claude: Reasons over result
Claude-->>User: Final answer stop_reason: "end_turn"
Figure 13.2: The agentic loop — one full pass equals one API round-trip
flowchart TD
A["User request"] --> B["Claude reasons over context"]
B --> C{"stop_reason?"}
C -->|"tool_use"| D["Harness dispatches by name"]
D --> E["Handler runs, returns result"]
E --> F["Harness sends tool_result (matching tool_use_id)"]
F --> B
C -->|"end_turn"| G["Final answer to user"]
Client-side vs. server-side tools
Client-side
Server-side
Where code runs
Your application
Anthropic's infrastructure
Handler code needed
Yes (you return tool_result)
None; results appear in the response
Examples
Custom tools, bash, text_editor, memory, computer use
[Animation slot: the agentic loop cycling — user request, tool_use emitted, dispatch by name, handler runs, tool_result returned, repeat until end_turn.]
Section 2 — Post-Check: Tool Usage Patterns
1. When Claude wants to call a client tool, which stop_reason does the response carry?
2. What connects a tool_result back to the request that produced it?
3. Which of these is a server-side tool that runs on Anthropic's infrastructure?
4. In the API pattern, where should an approval gate for a destructive action (like deleting data) be implemented?
5. Which tool_choice setting is incompatible with extended thinking?
Section 3 — Pre-Check: MCP Server Development
1. In MCP's architecture, what is the relationship between an MCP client and an MCP server?
2. Which MCP primitive is model-controlled and used to take actions?
3. An MCP resource is best described as:
4. Which transport is recommended for a production, multi-client remote MCP server?
5. In FastMCP (Python), what does the @mcp.tool() decorator generate automatically?
Section 3: MCP Server Development
The Model Context Protocol (MCP) is an open protocol that standardizes how LLM applications connect to external data sources and tools. If custom tools are private phone lines you wire yourself, MCP is a standard wall socket: any MCP-speaking host can plug into any MCP server without bespoke integration code. Under the hood MCP is a stateful JSON-RPC 2.0 protocol with a data layer (messages, lifecycle, primitives) and a transport layer (channel and authentication). A connection begins with an initialize request negotiating protocolVersion and capabilities.
Key Points
Three-part architecture: an MCP host (Claude Code / Desktop / VS Code) coordinates MCP clients, each holding a 1:1 connection to one MCP server.
Three server primitives: model-controlled tools (tools/call), application-controlled resources (resources/read), and user-controlled prompts (prompts/get).
Mental model: tools are for doing, resources are for reading, prompts are for reusing.
Transports: stdio for local development; Streamable HTTP with OAuth for production and multi-client servers.
Author concisely with FastMCP (Python) or the TypeScript SDK; test with the MCP Inspector; the @mcp.tool() decorator auto-generates name, description, and inputSchema.
Figure 13.3: MCP host / client / server architecture — one client per server connection
Data sources that provide context, read not executed
Prompts
User
prompts/list → prompts/get
Reusable templates the user selects
MCP also defines client primitives a server can request of the host: sampling (sampling/createMessage), elicitation (elicitation/create), and logging. Because MCP is stateful, servers can send JSON-RPC notifications (no id, no response), e.g. notifications/tools/list_changed.
Figure 13.4: MCP transports — stdio for local, Streamable HTTP for remote/multi-client
flowchart LR
subgraph stdio["stdio transport (local)"]
LC["Client"] <-->|"stdin / stdout no network"| LS["Server process (same machine)"]
end
subgraph http["Streamable HTTP transport (remote)"]
HC1["Client A"] -->|"HTTP POST"| HS["Remote Server"]
HC2["Client B"] -->|"HTTP POST"| HS
HS -.->|"optional SSE stream"| HC1
HS -.->|"OAuth / bearer token"| HC2
end
[Animation slot: FastMCP building a server — a Python function with a docstring transforms into an auto-generated tool definition (name + description + inputSchema).]
Section 3 — Post-Check: MCP Server Development
1. In MCP's architecture, what is the relationship between an MCP client and an MCP server?
2. Which MCP primitive is model-controlled and used to take actions?
3. An MCP resource is best described as:
4. Which transport is recommended for a production, multi-client remote MCP server?
5. In FastMCP (Python), what does the @mcp.tool() decorator generate automatically?
Section 4 — Pre-Check: Choosing the Right Approach
1. Which one-line distinction best separates MCP from Skills?
2. Your team needs Claude to follow a consistent, repeatable procedure and house style for producing a financial report, and it should persist across conversations. Which approach fits best?
3. You want to expose a third-party service integration so that many different hosts can plug into it with standardized, reusable access. Which approach fits best?
4. Roughly what is the idle context cost of a Skill before it is invoked?
5. A setup with 5 MCP servers and 58 tools can consume ~55,000 tokens before any conversation begins. Which feature reduces this by about 85%?
6. A capability is specific to your own database and simple to wire directly into your single application. Which is the most appropriate choice?
Section 4: Choosing the Right Approach
You now have four ways to extend Claude: built-in tools, custom tools, Skills, and MCP servers. Built-in tools are the fastest path to common capabilities. Custom tools give full control over app-specific work. A Skill is a portable folder (SKILL.md plus scripts) loaded via progressive disclosure — ~30–50 tokens idle — that teaches Claude how to do a task. An MCP server provides standardized access to external data and actions.
Key Points
"MCP connects Claude to data; Skills teach Claude what to do with that data." MCP is about access; Skills are about specialization.
They are complementary, not competing — a mature agent commonly uses all four at once.
Reach for a built-in when a common capability exists off the shelf; a custom tool when the work is specific to your data/app and simple to wire.
Author a Skill for consistent, repeatable procedure; build an MCP server for live data or actions in systems you don't fully control, especially for reuse across many hosts.
Mind context cost: large MCP tool libraries can hit ~55,000 tokens (5 servers, 58 tools); Tool Search cuts this ~85%, while Skills stay ~30–50 tokens until invoked.
The four approaches at a glance
Dimension
Built-in tools
Custom tools
Skills
MCP servers
What it provides
Common capabilities
App-specific functions
Procedural knowledge (how)
Access to external data/actions
Who writes the code
Anthropic
You
You (instructions + scripts)
You (or a third party)
Handler code needed
None (server) / ref impl (client)
Yes
No
Yes (the server)
Idle context cost
Low
Low per tool
Very low (~30–50 tokens)
Can be high (~55k; Tool Search cuts ~85%)
Reusable across apps
Yes (Anthropic-standard)
Within your app
Yes (portable folder)
Yes (standard protocol)
Best when
A common capability exists off the shelf
Specific to your data/app
You need consistent procedure
Live data/actions in systems you don't fully control
Figure 13.5: Selection decision tree — built-in vs. custom tool vs. Skill vs. MCP
flowchart TD
Start["Need to extend Claude"] --> Q1{"Does a built-in tool already do it?"}
Q1 -->|"Yes"| Builtin["Use a built-in tool (web search, code exec, bash)"]
Q1 -->|"No"| Q2{"Is it live data or actions in a system you don't fully control?"}
Q2 -->|"Yes"| Q3{"Need standardized, reusable access across many hosts?"}
Q3 -->|"Yes"| MCP["Build an MCP server"]
Q3 -->|"No, app-specific + simple to wire"| Custom["Write a custom tool"]
Q2 -->|"No, it's a procedure or house style"| Skill["Author a Skill"]
[Animation slot: four extension mechanisms (built-in, custom, Skill, MCP) combining inside one agent, with a token meter showing MCP's cost shrinking when Tool Search activates.]
Section 4 — Post-Check: Choosing the Right Approach
1. Which one-line distinction best separates MCP from Skills?
2. Your team needs Claude to follow a consistent, repeatable procedure and house style for producing a financial report, and it should persist across conversations. Which approach fits best?
3. You want to expose a third-party service integration so that many different hosts can plug into it with standardized, reusable access. Which approach fits best?
4. Roughly what is the idle context cost of a Skill before it is invoked?
5. A setup with 5 MCP servers and 58 tools can consume ~55,000 tokens before any conversation begins. Which feature reduces this by about 85%?
6. A capability is specific to your own database and simple to wire directly into your single application. Which is the most appropriate choice?