Tool Use & MCP
Tool schemas, strict mode, MCP protocol architecture, server design, and integration patterns
Tool schemas, strict mode, MCP protocol architecture, server design, and integration patterns
Tool use lets Claude interact with external systems by generating structured requests that your code executes. Claude never calls APIs directly โ it produces a tool_use content block describing what it wants, your application runs the action, and you return the result as a tool_result block.
This creates a loop: send a message with available tools, Claude responds with a tool call, your code executes it, you send the result back, and Claude continues reasoning with the new information. The loop repeats until Claude has everything it needs to answer.
THE TOOL USE LOOP
Each tool is defined with a name, description, and an input_schema (JSON Schema). The description is the single most important field โ it tells Claude when and how to use the tool.
{
"name": "get_weather",
"description": "Get current weather for a city. Use when the user asks about weather conditions, temperature, or forecasts. Do NOT use for historical weather data โ use get_climate_history instead.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, e.g. 'San Francisco, CA'"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit. Defaults to celsius."
}
},
"required": ["city"]
}
}"auto"Claude decides whether to use a tool. Default behavior.
Required when using extended thinking โ the only compatible option.
"any"Claude must use at least one tool.
NOT compatible with extended thinking.
{type: "tool", name: "X"}Force Claude to use a specific tool.
NOT compatible with extended thinking.
Setting strict: true on a tool definition guarantees that Claude's tool calls will always match your schema exactly. The API validates tool names and input shapes before returning them.
{
"name": "create_user",
"description": "Create a new user account.",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"email": { "type": "string" },
"role": { "type": "string", "enum": ["admin", "user"] }
},
"required": ["email", "role"]
}
}When to use: Production systems where you need reliable parsing without manual validation. Eliminates the need for try/catch around schema mismatches.
Instead of separate create_user, update_user, delete_user tools, use a single tool with an action parameter for CRUD operations.
BAD: 4 separate tools
GOOD: 1 consolidated tool
Prefix tool names with the service name so Claude understands context at a glance.
Keep tool count to roughly 20 or fewer. Beyond that, Claude spends too many tokens reasoning about which tool to pick. Group related operations into consolidated tools to stay under the limit.
Return meaningful error info inside the tool_result, not just a bare "failed" string. This lets Claude recover or explain the issue.
BAD
GOOD
Keep read-only tools (queries, lookups) separate from write tools (create, update, delete). This lets you apply different permission levels and makes audit logging clearer.
MCP is an open standard created by Anthropic (November 2024) for connecting LLMs to external data sources and tools. Think of it as the "USB-C port for AI" โ one standardized protocol that replaces custom integrations for every service.
MCP uses JSON-RPC 2.0 as its wire protocol, providing a clean request/response pattern with built-in error handling and capability negotiation.
MCP uses a three-layer architecture: a Host (the AI application) contains an MCP Client that communicates with external MCP Servers which provide capabilities.
MCP ARCHITECTURE
MCP defines three interaction types, each controlled by a different layer. Knowing who controls each is a key CCA concept.
MCP INTERACTION TYPES
| Type | Controlled By | Description | Example |
|---|---|---|---|
| Tools | Model-controlled | Actions Claude decides to invoke | Query database, create file |
| Resources | Application-controlled | Context/data provided to Claude | File contents, DB schema |
| Prompts | User-controlled | User-invoked templates | Slash commands, workflows |
For local servers. The host spawns the server as a subprocess and communicates via stdin/stdout.
For remote servers. Communication happens over HTTP with server-sent events for streaming.
MCP servers define tools, handle requests, and connect to a transport layer. SDKs are available for Python and TypeScript.
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
server = Server("my-tools")
@server.list_tools()
async def list_tools():
return [
Tool(
name="lookup_user",
description="Look up a user by email address.",
inputSchema={
"type": "object",
"properties": {
"email": {"type": "string", "description": "User email"}
},
"required": ["email"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "lookup_user":
user = db.find_user(arguments["email"])
return [TextContent(type="text", text=str(user))]
async def main():
async with stdio_server() as (read, write):
await server.run(read, write)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "my-tools", version: "1.0.0" });
server.tool(
"lookup_user",
"Look up a user by email address.",
{ email: z.string().describe("User email") },
async ({ email }) => {
const user = await db.findUser(email);
return { content: [{ type: "text", text: JSON.stringify(user) }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);~/.claude.jsonโ User-scoped (global). Available in all projects..claude/settings.jsonโ Project-scoped. Checked into the repo for team sharing.MCP tools appear alongside Claude Code's built-in tools (Bash, Read, Write, etc.) and can be used in exactly the same way.
Distribute MCP servers as npm or pip packages for easy installation. Users add them with a single command.
Commit .claude/settings.json to your repo so every team member gets the same MCP servers. Project-scoped servers are automatically available when anyone opens the project in Claude Code.
DOMAIN 2 โ 18% OF EXAM
"auto" is compatible with extended thinking. Both "any" and {type: "tool"} will error when extended thinking is enabled.