Claude Code Tool Use: A Complete Developer Guide
What Actually Happens When Claude Code "Uses a Tool"
When you ask Claude Code to refactor a file, it does not just generate text. It orchestrates a sequence of tool calls — Read, Edit, Bash, Grep, Glob — and interprets the results in a loop until your task is done. Understanding this loop is the difference between "Claude Code seems magical" and "I know exactly why it did that."
This guide walks through Claude Code's tool-use architecture, what each tool does, how the model decides which tool to call, and how to debug when tool use goes wrong.
The Tool Loop at a High Level
A Claude Code session is a loop:
- You send a prompt
- The model responds with either a text message OR a tool call
- If a tool call: Claude Code executes it locally, captures the result, sends it back to the model
- The model decides: more tool calls or final response?
- Repeat until a text-only response is returned (no tool call)
Each tool call round-trips to the model. A session that touches 10 files typically involves 20-40 tool calls.
The Six Core Tools
Claude Code exposes a specific set of tools. Other agentic setups differ — these are Claude Code's defaults.
Read
Reads a file from disk. Accepts a path, optionally a line range.
Read(file_path="/path/to/file.ts", offset=100, limit=50)
When the model uses it: To understand existing code before modifying it, to verify what it just wrote, or to investigate an error.
Common pitfall: The model occasionally re-reads files already in its context. This wastes a tool call and some tokens but is not harmful.
Edit
Makes an exact-string replacement in a file. Accepts the file path, the exact old_string to replace, and the new_string to replace it with.
Edit(
file_path="/path/to/file.ts",
old_string="const x = 1",
new_string="const x = 2"
)
When the model uses it: For small, surgical changes to existing files.
Why exact-string instead of line numbers: Line numbers drift as edits happen. Exact strings are self-validating — if the string is not found, the edit fails explicitly rather than corrupting the wrong location.
Common pitfall: The model sometimes writes a proposed replacement that has slightly different whitespace than the actual file. The Edit tool then fails. The model usually self-corrects on retry.
Write
Overwrites a file entirely with new content, or creates it if it does not exist.
When the model uses it: For new files or when a rewrite is clearer than a series of edits.
Safety note: If the file already exists, Claude Code requires the model to have Read it first in the session. This is a guardrail against accidentally clobbering a file the model has not actually examined.
Bash
Runs a shell command.
Bash(command="npm test", description="Run tests")
When the model uses it: Running tests, linters, type checkers, git commands, package installs, anything that is a shell operation.
Security model: Every Bash call in Claude Code requires user approval by default. You will see a prompt with the command and can approve, deny, or approve-all-like-this.
Common pitfall: The model sometimes writes shell commands that assume unix utilities (like find, grep, cat). On Windows PowerShell these need to be adapted.
Grep
Searches file contents using ripgrep.
Grep(pattern="function setup", glob="*.ts", output_mode="content")
When the model uses it: Finding where a function is defined, where it is called, what imports a module, and similar structural queries.
Why ripgrep not grep: Ripgrep respects .gitignore, handles binary files cleanly, and is much faster on large repositories. Claude Code's Grep tool wraps ripgrep even though it is called "Grep."
Glob
Finds files matching a path pattern.
Glob(pattern="src/**/*.tsx")
When the model uses it: Enumerating all files of a type before doing something to each, or locating a file when you only remember part of its name.
How the Model Decides Which Tool to Call
The model is not running a hand-coded decision tree. It is reasoning about the task and choosing the tool that best advances the goal. A few patterns hold reliably:
- To understand before changing: Read → maybe Grep → Edit (or Write). The model almost always reads before editing.
- To find something: Grep if you know roughly what the code looks like; Glob if you know the filename shape.
- To verify after changing: Read the file back, or run tests via Bash.
- To explore an unfamiliar codebase: Glob to list structure, then Read the important-looking files.
If a tool call fails (wrong path, ripgrep pattern error, file not found), the model sees the error in the response and adapts.
Parallel Tool Calls
The model can request multiple tool calls in a single message. Claude Code executes them in parallel where possible. Common parallel patterns:
- Read 5 related files at once — useful when building context for a refactor
- Grep for multiple patterns simultaneously — faster than sequential greps
- One Read + one Glob — often done together to map a directory
This is a material speedup. A session that makes 20 tool calls serially (one-at-a-time round trips to the model) is meaningfully slower than the same 20 calls batched into 4 parallel-of-5.
What You Cannot See
A few things Claude Code deliberately does not expose as tools:
- No network access beyond the LLM API itself. The model cannot fetch URLs unless a tool with that capability is explicitly provided (some setups add a
WebFetchtool, but it is not default). - No package install without approval.
npm installruns via Bash with the normal approval prompt. There is no silent install. - No raw process management. Bash gives you shell, but there is no persistent daemon or long-running-task tool by default.
This is by design. Claude Code is an interactive agent, not a background process.
Debugging When Tool Use Goes Wrong
The three common failure modes:
1. Model Calls a Tool That Does Not Exist
The model was trained on many agentic patterns. It sometimes invents a tool name that does not exist in the current session. You will see an error like:
Error: Unknown tool: WebSearch
Fix: Either add the missing tool if the CLI or plugin supports it, or prompt the model explicitly: "Use only Read, Edit, Bash, Grep, Glob — no other tools."
2. Model Loops on the Same Tool
Sometimes the model re-reads the same file in a loop, or re-greps the same pattern. This is usually a sign that the task is ambiguous and the model is gathering evidence.
Fix: Give more context in your prompt so it does not need to rediscover things each time.
3. Tool Fails and Model Does Not Adapt
Occasionally the model will keep retrying the same failing command. This is rare but happens when the task is tightly constrained.
Fix: Interrupt the session, explain what went wrong, give a different approach. Claude Code's tool loop will not break out on its own if the model thinks retrying is the right call.
Pointing Claude Code at a Different Backend
Claude Code CLI supports the ANTHROPIC_BASE_URL environment variable as an officially documented configuration. This lets you route Claude Code through any Anthropic-API-compatible backend.
Services like LLM API provide such compatible backends — useful when you want different routing, multi-provider failover, or regional accessibility:
export ANTHROPIC_BASE_URL=https://llmapi.pro
export ANTHROPIC_API_KEY=your-llmapi-key
claude
Every tool — Read, Edit, Write, Bash, Grep, Glob — continues to work identically, because the tool contract is part of the Anthropic API protocol, not the backend behind it.
Bottom Line
Claude Code's tool use is simpler than it looks: six tools, a loop, and a model reasoning about which tool to call next. Understanding the loop makes Claude Code dramatically more predictable — you stop wondering "why is it doing that" and start directing it.
If you want to go deeper, the best next step is to run Claude Code with --verbose and watch the tool calls in real time on a task you know well. Reading the actual trace demystifies the system faster than any explanation.