Room 42, home

Tool use and function calling in Claude Code

How Claude Code uses tools: the built-in set, adding more with MCP servers, and how the agent decides when to call them.

Codingintermediate6 min readUpdated 12 Jun 2026

In short

  1. 01In the Claude Code CLI, tool use means working with a built-in toolbox and MCP servers, not writing schemas or driving a request loop yourself.
  2. 02The agent ships with tools like Read, Edit, Bash, and web search always on, and you extend it by registering MCP servers.
  3. 03Keep the tool list lean, since every extra server makes the agent more likely to hesitate or reach for the wrong tool.
  4. 04Guide tool choice with clear prompts and durable CLAUDE.md rules, and gate risky calls with permissions and hooks.
Contents · 11 sections
  1. 1What tools does Claude Code have out of the box?
  2. 2How does the agent decide to call a tool?
  3. 3How do I add tools with MCP?
  4. 4Tool hygiene: fewer is better
  5. 5Guiding tool choice in your prompts
  6. 6How do I control tool permissions?
  7. 7Hooks: run your own code around tool calls
  8. 8How do I see which tools Claude called?
  9. 9Parallel tool use
  10. 10Common mistakes
  11. 11Next steps

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 MCPModel Context Protocol · an open standard that lets Claude Code talk to external servers that expose tools, resources, and prompts 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.

ToolWhat it does
ReadOpens any file the agent can reach on disk
Edit / WriteMakes targeted edits or writes a new file
BashRuns shell commands (lint, test, build, grep, git)
WebSearchSearches the web for current information
WebFetchFetches a URL and returns its content
Glob / FindLocates files by pattern
NotebookEditReads and edits Jupyter notebooks
TodoRead / TodoWriteManages 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 filesystem

After 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 list and 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.

Try this prompt
Search the web for the current Node.js LTS version, then update the .nvmrc file to match.

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

HooksScripts Claude Code runs automatically before or after specific events, configured in settings.json 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.

/cost

For 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:

Try this prompt
Read src/auth/session.ts and src/auth/token.ts, then describe how the session token lifecycle works end to end.

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.