In Claude Code, "tool use" means something different from what the API docs describe. You are not writing JSON Schema definitions or driving a request loop yourself. Claude Code ships with a built-in toolbox, and you extend it by connecting MCP servers. Claude decides when to reach for a tool. Your job is to know which tools are available, add new ones when you need them, and write the prompts and configs that help the agent choose well.
What tools does Claude Code have out of the box?
Claude Code arrives with a set of built-in tools it can call with no configuration from you.
| Tool | What it does |
|---|---|
| Read | Opens any file the agent can reach on disk |
| Edit / Write | Makes targeted edits or writes a new file |
| Bash | Runs shell commands (lint, test, build, grep, git) |
| WebSearch | Searches the web for current information |
| WebFetch | Fetches a URL and returns its content |
| Glob / Find | Locates files by pattern |
| NotebookEdit | Reads and edits Jupyter notebooks |
| TodoRead / TodoWrite | Manages the agent's in-session task list |
These tools are always on. You cannot remove them, but you can constrain them
through permissions (see .claude/settings.json).
How does the agent decide to call a tool?
Claude does not call tools at random. It reads your prompt, works out what information or action it needs, and picks the right tool for that step. The cycle looks like this:
The loop runs inside Claude Code automatically. You never write it yourself. What you do control is the quality of the tools on offer and the clarity of the instructions that decide when each one gets used.
How do I add tools with MCP?
When the built-in tools are not enough, add an MCP server. Each one registers its own named tools, which Claude then calls the same way it calls the built-ins.
Register a server
# stdio server (local process)
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/project
# SSE server (remote URL, useful for shared team servers)
claude mcp add my-api --transport sse https://tools.example.com/mcp
# Check what is registered
claude mcp list
# Inspect a server's exposed tools
claude mcp get filesystemAfter adding a server, restart Claude Code. The agent picks up the new tools
on next launch.Common gotchaA live session will not see a newly added server, so if the agent insists the tool does not exist, you almost certainly skipped the restart rather than misconfigured it.Quit and relaunch, then confirm with claude mcp list before assuming the server is broken.
Scope MCP servers to a project
Committing a .mcp.json file means every teammate gets the same tools without
running claude mcp add manually.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"type": "stdio"
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"type": "stdio",
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
}
}
}Use ${ENV_VAR} syntax for secrets. Claude Code expands them at runtime from
the process environment, so the file itself stays safe to commit. See MCP
Configuration for the full set of scopes and secret-handling options.
Tool hygiene: fewer is better
Every active MCP server adds to the tool list Claude reasons over. A bloated list makes the agent hesitate, pick the wrong tool, or fire off calls it did not need. The same principle as good function design applies: narrow, well-named, single-purpose tools beat wide, ambiguous ones.
Practical rules:
- Register only servers whose tools you need in this project.
- Prefer a focused server (
server-github) over a general shell executor if the task is scoped. - Audit your registered servers occasionally with
claude mcp listand remove stale ones.
Guiding tool choice in your prompts
Claude reads your prompt to decide which tool fits. Vague prompts lead to guessed tool choices. Specific prompts produce reliable ones.
That prompt signals two tools: WebSearch first, then Write. Claude does not guess. It follows the sequence you described.
For repeated workflows, encode the guidance in your project's CLAUDE.md so
every session inherits it:
## Tool rules
- Always use the `github` MCP tool for PR and issue operations. Do not use Bash + gh CLI for these.
- Run `npm test` via Bash before proposing any edit.
- Never call WebFetch on internal hostnames; use the `filesystem` MCP tool instead.CLAUDE.md lives at the repo root and is read automatically at session start.
That makes it the right home for durable tool-routing rules that apply to every
task in the project.
How do I control tool permissions?
Claude Code asks for permission before running Bash commands or writing files
the first time. You can lock down or loosen these defaults in
.claude/settings.json:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git log *)",
"Read(**)"
],
"deny": [
"Bash(rm -rf *)"
]
}
}Rules use glob patterns. allow entries skip the confirmation prompt. deny
entries block the call outright; the agent reports a permission error and keeps
planning without that tool.
Keep deny rules explicit for dangerous commands rather than trying to list
every safe one. Allowlisting common read-only and build commands removes
friction without opening up destructive paths.Common gotchaAn allow glob like Bash(npm run *) is looser than it looks: the trailing * also matches a chained command, so npm run build && rm -rf dist slips through the same pre-approval and runs without a prompt.Anchor allow patterns to the exact subcommand you mean and keep a deny for shell chaining (&&, ;, |) and rm -rf, because allow rules never override the safety of a too-broad wildcard.
Hooks: run your own code around tool calls
Hooks let you attach shell commands to agent lifecycle events. They are not MCP servers and they are not tools the model calls. They are deterministic sidecars you control.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "echo '[hook] bash call incoming'" }
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{ "type": "command", "command": "npm run lint --silent" }
]
}
]
}
}PreToolUse fires before the agent calls the matched tool. PostToolUse fires
after it. Use them to enforce conventions (auto-lint after every write), log
tool calls for auditing, or put a check in front of dangerous operations. The
hooks and guardrails guide covers every lifecycle event and how to wire them up.
How do I see which tools Claude called?
You do not need to instrument anything to see which tools Claude called. The
session output prints each tool invocation and its result inline. Run /cost
at any point to see token consumption broken down by turn, which tracks how
many round trips of tool use happened.
/costFor long tasks, watch the tool calls scroll past and use Escape to interrupt
if the agent is heading in the wrong direction. Resume with claude --continue
to pick up from the last checkpoint.
Parallel tool use
Claude Code can call several independent tools in one step without waiting for your input between them. In the output it shows up as a burst of tool calls that resolve before the agent writes its next response. The agent handles the ordering. Two independent calls (reading two separate files, searching two URLs) run together. When one call's output feeds the next, it sequences them for you.
You do not configure this. Writing clear, parallel-friendly prompts helps:
That prompt lets the agent read both files in parallel before it pieces the answer together, rather than reading one, waiting, then reading the other.
Common mistakes
Registering servers you do not use. Every extra server increases the tool
list Claude reasons over and can cause it to reach for the wrong tool. Run
claude mcp list and prune unused entries.
Vague CLAUDE.md tool rules. "Prefer MCP tools" is too loose. Write "use the
github MCP tool for all PR operations, not Bash + gh CLI." Precise rules
produce consistent behaviour.
Leaning on tool descriptions instead of a clear prompt. MCP server tool descriptions help, but the task prompt matters more. Describe what you want and the agent picks the right tool. Naming the tool and the reason is a useful backup, not a substitute for a clear goal.
Blocking all Bash with deny rules. If Bash is fully blocked, Claude cannot
run tests, lint, or build. Deny specific dangerous patterns (rm -rf,
curl | bash), not the whole command runner.
Next steps
With your tool set configured and permissions dialled in, two topics follow naturally: multi-agent workflows, where several Claude Code sessions hand tasks to each other, and deeper MCP patterns, like wrapping your own internal APIs as MCP servers so every project agent can reach them. See Multi-Agent Architectures and MCP Fundamentals for both.