CCA-F Study Day 9/20: Built-in Tools & Tool Distribution
Domain 2: Tool Design & MCP Integration (~18-20% of exam)
๐ Today's Focus
Yesterday you mastered MCP architecture โ the HostโClientโServer layering, the two protocol layers, and the three primitives. Today we complete Domain 2 by covering Claude's built-in tools, how to distribute tools across agents, and the critical rules around parallel vs sequential execution. This material directly feeds the "Developer Productivity with Claude" exam scenario โ one of the six scenarios you might encounter.
This is the last day of Domain 2. After today, you'll have covered all tool design and MCP integration concepts. Tomorrow we move to Domain 3 (Claude Code Configuration).
๐ Core Concepts
1. Claude's Built-in Tools (The Full Reference)
Claude Code ships with a suite of built-in tools that give it "access to a computer." The key design principle from Anthropic: "Claude needs the same tools that programmers use every day."
| Tool | Category | What It Does | Read-Only? |
|---|---|---|---|
| Read | File ops | Read file contents | โ Yes |
| Edit | File ops | Modify existing files (surgical edits) | โ No |
| Write | File ops | Create new files | โ No |
| Glob | Search | Find files by pattern (e.g., **/*.py) | โ Yes |
| Grep | Search | Search file content with regex | โ Yes |
| Bash | Execution | Run shell commands | โ No |
| WebSearch | Web | Search the web for information | โ Yes |
| WebFetch | Web | Fetch and parse web pages | โ Yes |
| Agent | Orchestration | Spawn subagents with isolated context | โ No |
| Skill | Orchestration | Invoke reusable skills | โ No |
| ToolSearch | Discovery | Dynamically find tools on-demand | โ Yes |
Exam tip: Know the full list. Expect questions like "Which tool would Claude use to find all Python files matching a pattern?" (Answer: Glob) or "Which tool searches file content?" (Answer: Grep).
2. Parallel vs Sequential Tool Execution โ THE Critical Rule
This is a high-frequency exam topic. The rules are simple but you MUST know them cold:
| Tool Type | Execution | Reason |
|---|---|---|
| Read-only (Read, Glob, Grep, WebSearch, WebFetch, read-only MCP tools) | Can run concurrently(in parallel) | No state conflicts possible |
| State-modifying (Edit, Write, Bash) | Must run sequentially | Concurrent writes could cause conflicts |
| Custom tools (via MCP or tool definitions) | Default to sequential | Conservative default |
The escape hatch for custom tools: Set readOnlyHint: true in the tool's annotations to enable parallel execution:
{
"name": "get_stock_price",
"description": "Fetches current stock price for a ticker symbol",
"annotations": {
"readOnlyHint": true // โ This enables parallel execution
},
"input_schema": {
"type": "object",
"properties": {
"ticker": {"type": "string"}
}
}
}
3. Tool Distribution Patterns
How you distribute tools across agents is an architectural decision with major implications:
Pattern A: Monolithic (Anti-Pattern for complex systems)
# โ DON'T: 15+ tools on one agent
agent = Agent(
tools=[search_files, read_file, write_file, run_tests,
deploy, search_web, send_email, query_db,
manage_git, lint_code, format_code, ...] # 15+ tools = confusion
)
Pattern B: Distributed Specialist Agents (โ Recommended)
# โ
DO: 4-5 tools per specialist agent
file_agent = Agent(
tools=[read_file, write_file, edit_file, glob_files, grep_content]
)
test_agent = Agent(
tools=[run_tests, lint_code, check_coverage, format_code]
)
deploy_agent = Agent(
tools=[build_project, deploy_staging, deploy_prod, rollback]
)
# Coordinator delegates to specialists
coordinator = Agent(
tools=[delegate_to_file_agent, delegate_to_test_agent, delegate_to_deploy_agent]
)
The 4-5 tool sweet spot: Anthropic's research shows that Claude performs optimally with 4-5 tools per agent. Beyond ~8 tools, selection accuracy degrades. Beyond 15+, it becomes unreliable.
4. MCP Server Configuration for Tool Distribution
In production, tools are distributed across MCP servers. Each server is isolated (own process, own permissions):
# .claude/mcp.json - MCP configuration
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-server-filesystem", "/workspace"],
"annotations": {
"readOnlyHint": true
}
},
"github": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"database": {
"command": "python",
"args": ["./mcp_servers/db_server.py"],
"annotations": {
"readOnlyHint": false
}
}
}
}
5. Built-in Tools for the Developer Productivity Scenario
The exam's "Developer Productivity with Claude" scenario tests your ability to select the right tools for codebase exploration tasks. Here's the decision framework:
| Task | Best Tool | Why NOT the Alternative |
|---|---|---|
| Find all files matching *.test.ts | Glob | Grep searches content, not filenames |
| Find all usages of deprecated_function() | Grep | Glob only matches filenames, not content |
| Read a specific config file | Read | Bash is overkill; Read is purpose-built |
| Run a test suite | Bash | No specific "test runner" built-in tool exists |
| Install a dependency | Bash | Write doesn't execute commands |
| Search the web for API docs | WebSearch | Bash + curl works but is less structured |
| Explore a large codebase structure | Glob then Read | Pattern: discover โ inspect |
โ ๏ธ Anti-Patterns & Exam Traps
Trap 1: "Use Bash for everything"
โ Wrong: "Use Bash to read files, search code, and find files" โ Right: Use the purpose-built tool (Read, Grep, Glob) โ they have better error handling, are faster, and enable parallel execution for read-only operations.
Why it's tested: Bash is a state-modifying tool that runs sequentially. Using Bash for read-only tasks means you lose parallelism.
Trap 2: "More tools = more capable agent"
โ Wrong: Give one agent 18 tools for maximum flexibility โ Right: 4-5 tools per agent, distribute across specialist subagents
Why it's wrong: Tool selection accuracy degrades significantly beyond 8 tools. The model wastes reasoning capacity deciding between too many options.
Trap 3: "Custom MCP tools can always run in parallel"
โ Wrong: All MCP tools execute concurrently by default
โ
Right: Custom tools default to sequential. You must explicitly set readOnlyHint: true in annotations for parallel execution.
Trap 4: "Grep and Glob are interchangeable"
โ Wrong: Use Grep to find files matching *.py
โ
Right: Glob matches file paths/names. Grep matches file content.
Trap 5: Confusing Edit vs Write
โ Wrong: Use Write to modify an existing file
โ
Right: Edit = modify existing files (surgical changes). Write = create new files.
๐ป Code Examples
Example 1: Codebase Exploration Agent with Correct Tool Selection
import anthropic
client = anthropic.Anthropic()
# Developer Productivity agent with well-distributed tools
tools = [
{
"name": "glob_files",
"description": "Find files matching a glob pattern. Use for discovering files by name/path/extension. Returns list of matching file paths.",
"input_schema": {
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Glob pattern (e.g., '**/*.py', 'src/**/*.test.ts')"
}
},
"required": ["pattern"]
}
},
{
"name": "grep_content",
"description": "Search file content using regex. Use when looking for specific code patterns, function usages, or text within files. Returns matching lines with file paths and line numbers.",
"input_schema": {
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Regex pattern to search for in file content"
},
"file_pattern": {
"type": "string",
"description": "Optional: limit search to files matching this glob (e.g., '*.py')"
}
},
"required": ["pattern"]
}
},
{
"name": "read_file",
"description": "Read the full contents of a file. Use after discovering files via glob or grep to inspect their content.",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to read"
}
},
"required": ["path"]
}
},
{
"name": "run_bash",
"description": "Execute a shell command. Use for running tests, installing packages, git operations, or any command-line task that modifies state.",
"input_schema": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute"
}
},
"required": ["command"]
}
}
]
# Task: "Find and fix all TODO comments in the codebase"
messages = [
{"role": "user", "content": "Find all TODO comments in Python files, read the relevant code context, then create a summary of technical debt."}
]
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
tools=tools,
messages=messages
)
# Claude will typically:
# 1. glob_files("**/*.py") - find all Python files (read-only, can parallelize)
# 2. grep_content("TODO|FIXME|HACK", "*.py") - search content (read-only, can parallelize)
# 3. read_file() for each match - inspect context (read-only, can parallelize)
# 4. Return structured summary (no tool needed - end_turn)
Example 2: Parallel Tool Execution with readOnlyHint
# MCP tool annotations that enable parallel execution
read_only_tools = [
{
"name": "get_user_profile",
"description": "Fetch user profile data",
"annotations": {
"readOnlyHint": True, # โ Enables parallel execution
"destructiveHint": False,
"idempotentHint": True
},
"input_schema": {...}
},
{
"name": "get_order_history",
"description": "Fetch user's order history",
"annotations": {
"readOnlyHint": True, # โ These two can run in parallel
"destructiveHint": False,
"idempotentHint": True
},
"input_schema": {...}
}
]
# State-modifying tools โ will ALWAYS run sequentially
write_tools = [
{
"name": "update_user_preferences",
"description": "Update user preferences in database",
"annotations": {
"readOnlyHint": False, # โ Sequential execution (default)
"destructiveHint": False,
"idempotentHint": True
},
"input_schema": {...}
}
]
Example 3: Tool Distribution Across MCP Servers
# Architecture: Tools split across isolated MCP servers
# Each server = own process, own permissions, own failure domain
# Server 1: Read-only codebase exploration
class CodeExplorerServer:
"""All tools here are read-only โ can execute in parallel"""
@tool(annotations={"readOnlyHint": True})
def glob(self, pattern: str) -> list[str]:
"""Find files matching glob pattern"""
return glob.glob(pattern, recursive=True)
@tool(annotations={"readOnlyHint": True})
def grep(self, pattern: str, path: str = ".") -> list[dict]:
"""Search file content with regex"""
# Returns [{file, line_num, content}, ...]
...
@tool(annotations={"readOnlyHint": True})
def read(self, path: str) -> str:
"""Read file contents"""
...
# Server 2: Code modification (sequential)
class CodeEditorServer:
"""State-modifying tools โ execute sequentially"""
@tool(annotations={"readOnlyHint": False})
def edit(self, path: str, old_text: str, new_text: str) -> dict:
"""Edit a file by replacing old_text with new_text"""
...
@tool(annotations={"readOnlyHint": False})
def write(self, path: str, content: str) -> dict:
"""Create a new file"""
...
# Server 3: Execution environment (sequential, higher risk)
class ExecutionServer:
"""Bash execution โ always sequential, requires explicit permission"""
@tool(annotations={"readOnlyHint": False, "destructiveHint": True})
def bash(self, command: str) -> dict:
"""Run a shell command"""
...
๐ Reading
Primary: Building agents with the Claude Agent SDK โ Anthropic's engineering blog post explaining the design philosophy of "giving Claude a computer" and how built-in tools enable agent capabilities. Focus on the "Gather context โ Take action โ Verify work" loop.
Secondary: Writing effective tools for AI agents โ using AI agents โ Essential reading on tool design principles including namespacing, token efficiency, and when NOT to implement a tool.
Reference: Claude Code Overview (docs.anthropic.com) โ Official docs covering all built-in tools and their behaviors.
๐ ๏ธ Hands-On Exercise (20 minutes)
Task: "Find and Fix All TODO Comments" โ Plan Your Tool Strategy
- You're building a "technical debt tracker" agent. The task: scan a codebase, find all TODO/FIXME/HACK comments, read surrounding context, categorize them by urgency, and generate a report.
- Write out the exact sequence of tool calls Claude should make, noting which can run in parallel:
- Step 1:
glob("**/*.{py,ts,js}")โ find all source files [read-only, parallelizable] - Step 2:
grep("TODO|FIXME|HACK")โ find all comments [read-only, parallelizable with step 1? YES!] - Step 3: For each match,
read(file_path)โ get context [read-only, ALL can run in parallel] - Step 4: Claude synthesizes and returns report โ
end_turn
- Step 1:
- Now redesign for a multi-agent system:
- Agent A (Explorer): glob + grep + read (4 read-only tools)
- Agent B (Classifier): Uses the report from A, classifies by urgency
- Agent C (Fixer): edit + write + bash (writes fixes for "easy" TODOs)
- Bonus: Write the MCP server configuration (
.claude/mcp.json) that implements this 3-server architecture.
๐ Quick Quiz
Question 1: A developer wants to search a large codebase for all files that import a deprecated library. Which built-in tool should Claude use?
A) Glob โ search for files matching a pattern
B) Grep โ search file content for the import statement
C) Read โ read each file and check for imports
D) Bash โ run grep -r "import deprecated_lib" .
Question 2: An agent needs to fetch a user's profile AND their order history simultaneously. Both tools are custom MCP tools. What must be true for them to execute in parallel?
A) They must be in the same MCP server
B) They must have readOnlyHint: true in their annotations
C) They must use the stdio transport
D) They will automatically run in parallel since they don't share dependencies
Question 3: You're designing an agent for codebase exploration that needs: file search, content search, file reading, and running tests. How should you distribute these tools?
A) All 4 tools on one agent โ keeps it simple B) Split into 2 agents: read-only tools (glob, grep, read) on one, execution (bash for tests) on another C) One tool per agent for maximum isolation D) Only use Bash for everything โ it can do all four tasks
Answers:
1. B โ Grep searches file content. Glob searches file names/paths. The question asks about finding import statements (content), so Grep is correct. D (Bash with grep) technically works but is wrong because: (a) Bash is a state-modifying tool that runs sequentially, and (b) the built-in Grep tool is purpose-built and enables parallelism.
2. B โ Custom MCP tools default to sequential execution. You must explicitly annotate them with readOnlyHint: true to enable parallel execution. Being in the same server (A) doesn't affect parallelism. Transport type (C) is irrelevant. There's no automatic dependency detection (D).
3. B โ The optimal split separates read-only tools (which can parallelize) from state-modifying tools (sequential). A has too many tools but isn't terrible for 4. C is over-engineered. D loses the benefits of purpose-built tools and forces sequential execution for everything.
๐ Tomorrow's Preview
We start Domain 3: Claude Code Configuration & Workflows with the CLAUDE.md hierarchy โ the 6-level configuration system that controls Claude Code's behavior. You'll learn about enterprise policies, project/subdirectory configs, imports, and how conflicts resolve. This is highly testable material.