CC
Claude Code
v2.1.88
Claude CodeTools Module

Tools Module

140 files · ~65K lines

The Tool Layer — 43 tools implementing a unified interface. Each tool is a self-contained unit with its own schema, permissions, and rendering. The query loop treats them all identically.

Tool Lifecycle: input → execute → render

Every tool call follows this exact sequence, no exceptions.

1
LLM generates tool_use block

Claude returns JSON: { name: 'BashTool', input: { command: 'ls -la' } }. This arrives as a streaming token.

2
validateInput()

The Zod input schema validates the JSON input. If invalid, the tool returns an error without executing.

3
checkPermissions()

The Permissions module is consulted. Depending on mode, this may show a terminal dialog, auto-approve, or block the call.

4
invoke()

The tool's execute function runs. For BashTool, this goes through 5 security layers before a subprocess is spawned.

5
renderResult()

The result is formatted: once for the terminal UI (ANSI-styled), and once for the next LLM turn (plain text/JSON).

The Tool Interface — 5 Groups

buildTool() enforces a unified shape. Every field has a purpose.

Identity
name

Unique tool identifier used in tool_use blocks

description

Shown to the LLM — heavily influences when Claude calls this tool

Execution
inputSchema

Zod schema — validated before invoke() is ever called

invoke()

The actual execution function, receives validated input

isReadOnly()

Hint to the query loop — read-only tools can run concurrently

Security
checkPermissions()

Called before invoke() — can block execution or prompt user

needsPermissions()

Declares required permission types at construction time

Rendering
renderResultForAssistant()

Formats tool output for the next LLM turn

renderToolUseMessage()

Shows the tool call in the terminal UI

renderToolResultMessage()

Shows the result in the terminal UI

Limits
maxConcurrency

How many instances can run in parallel (default: 1)

timeout

Max execution time before the tool is killed

The 43 Tools — Categorized

Tools grouped by what they do. Click a category to see how they're implemented.

Execution
BashPowerShell
Read
FileReadWebFetchNotebookRead
Write
FileEditFileWriteNotebookEdit
Search
GrepGlob
Agent
AgentSkill
Protocol
MCPLSP
Utility
SleepTask*Exit*

BashTool Deep Dive — 5 Security Layers

BashTool is 300KB — larger than most npm packages. It runs every command through 5 checks before a subprocess spawns.

1
Permission Check

checkPermissions() checks the command pattern against session rules and mode (default/acceptEdits/bypassPermissions).

2
AST Parse

bashParser.ts (4436 lines) builds a Tree-sitter AST of the command. Structural analysis, not regex matching.

3
Risk Classifier

The AST is analyzed for: network access, recursive deletes, path escapes, injection patterns, and privilege escalation.

4
Path Allowlist

File paths in the command are checked against the project root allowlist. Paths outside are blocked even in yolo mode.

5
Sandbox Execution

The approved command runs in a sandboxed subprocess with stdout/stderr streaming back to StreamingToolExecutor.

bashParser.ts is 4436 linesa full Tree-sitter-based Bash AST parser that does structural analysis on every command. It detects injection via operator chaining, heredoc abuse, and subshell escapes that regex could never catch.

Key Files

tools/BashTool/300KB / 5 files

Command execution, AST-based security analysis, sandbox isolation

tools/FileEditTool/~40KB

String find/replace with unified diff rendering

tools/AgentTool/~35KB

Spawns isolated subagents with forked QueryEngine instances

tools/MCPTool/~15KB

Proxies external MCP server tools into the Claude tool namespace

tools/GrepTool/~12KB

Ripgrep wrapper for fast content search across files

Tool.ts~6KB

buildTool() factory — the interface all tools implement