Claude Code Tool Use: How the CLI Calls Tools
Claude Code is Anthropic's terminal-based coding agent, and tool use is the mechanism that lets it actually do things instead of just talking about them. When you ask Claude Code to fix a bug, it doesn't just describe the fix — it reads the file, edits it, runs the test suite, and reports what happened. Every one of those steps is a tool call.
This article explains what tool use looks like specifically inside Claude Code (as opposed to the raw Messages API), which tools ship with it, how the permission system keeps it from doing anything destructive without asking, and how to build the same kind of tool-calling loop into your own application if you're working directly against the API.
What "tool use" means in Claude Code
Under the hood, Claude Code runs a loop: it sends your prompt plus the conversation history to the model, and the model responds either with plain text or with a request to call a specific tool — read a file, run a shell command, search the codebase, fetch a URL. Claude Code executes that tool locally, feeds the result back into the conversation, and the model decides what to do next. This repeats until the model is done and returns a final text response.
This is the same tool_use / tool_result pattern used by the underlying Claude API, just wired up to a set of tools that are useful for software engineering rather than tools you define yourself.
The built-in tools
Claude Code ships with a fixed set of tools rather than asking you to define schemas. The main ones you'll see it use:
- Read / Write / Edit — read a file's contents, create a new file, or apply a targeted diff to an existing one.
- Bash — run shell commands: install dependencies, run tests, start a dev server, check git status.
- Glob / Grep — find files by pattern or search file contents, which is how Claude Code navigates large codebases without reading every file.
- WebFetch / WebSearch — pull in documentation or check current information when local context isn't enough.
- Task — spin up a sub-agent for a self-contained piece of work, useful for large multi-step tasks.
You don't configure these tools yourself — they're part of Claude Code's runtime. What you do control is when Claude is allowed to use them.
Permissions: the part that actually matters day to day
The reason tool use in Claude Code feels safe to run against a real codebase is the permission layer sitting in front of every tool call. By default, read-only actions (Read, Glob, Grep) run without asking. Anything that changes state — Write, Edit, Bash — prompts you for approval the first time, and you can choose to allow it once, allow it for the session, or add it to a persistent allowlist in your project's settings.
This matters because tool use without permission boundaries is how you end up with an agent silently running rm -rf or pushing to main. A few practical habits:
- Keep destructive commands (
rm,git push --force, database migrations) out of the always-allow list. Approve them individually. - Use project-level settings to scope what Claude Code can touch — for example, restricting file writes to a specific directory in a monorepo.
- Review the Bash commands Claude proposes before approving, especially anything involving
curl | shor credentials.
Watching the tool loop in practice
If you run Claude Code with verbose output, you'll see the pattern clearly: a tool call, its result, then either another tool call or a final answer. A typical debugging session looks like:
Read src/api/client.ts
Grep "timeout" src/
Bash: npm test -- --grep "client"
Edit src/api/client.ts
Bash: npm test -- --grep "client"
Each line is a full round trip through the model: it decides which tool to call, Claude Code executes it, and the result becomes input to the next decision. The model only stops when it has enough evidence to give you a final answer — which is why Claude Code is noticeably slower than a single API call, but also why it can fix problems it hasn't seen the full context of upfront.
Building the same pattern with the API
Claude Code's tool loop isn't unique to the CLI — it's the standard tool_use pattern available through the Claude API, and you can implement your own version for a product, an internal bot, or a CI step. The shape is the same regardless of which tools you define:
- Send a message with a
toolsarray describing what's available (name, description, JSON schema for inputs). - If the model's response includes a
tool_useblock, execute that tool in your own code. - Send a follow-up message with a
tool_resultblock containing the output. - Repeat until the model returns plain text with no further tool calls.
If you're building this against Claude access issued through SubToAPI, the request and response format is unchanged — you're calling the standard Messages endpoint with a sub_live_... key instead of managing multiple credential sets:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"tools": [
{
"name": "run_tests",
"description": "Run the project test suite and return output",
"input_schema": {
"type": "object",
"properties": { "pattern": { "type": "string" } }
}
}
],
"messages": [
{ "role": "user", "content": "Fix the failing auth test." }
]
}'
You handle the tool_use block, run run_tests locally, and post the result back as a tool_result message — the same loop Claude Code runs internally, just with tools you define instead of Read/Write/Bash. SubToAPI adds usage metadata per key and team seats on top, which is useful if multiple developers or services are each running their own tool-calling agents against the same underlying account. The docs cover the request format in detail at /docs/messages and tool schemas specifically at /docs/tools; /docs/quickstart walks through getting a key set up.
questions
Does Claude Code let me add my own custom tools? Not directly — it ships with a fixed tool set (Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, Task) rather than user-defined schemas. If you need custom tools, build against the Claude API directly using the standard tools parameter.
Why does Claude Code ask for permission before running some commands? Read-only tools run automatically, but anything that writes files or executes shell commands requires approval by default. This prevents an agent loop from making destructive changes without a human checking first.
Is Claude Code's tool use the same mechanism as the API's tool use? Yes. Both use the same tool_use/tool_result message pattern. Claude Code just wraps it in a CLI runtime with a fixed toolset and permission system, while the raw API lets you define arbitrary tools for your own application.