Tools Module
140 files · ~65K linesThe 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.
Claude returns JSON: { name: 'BashTool', input: { command: 'ls -la' } }. This arrives as a streaming token.
The Zod input schema validates the JSON input. If invalid, the tool returns an error without executing.
The Permissions module is consulted. Depending on mode, this may show a terminal dialog, auto-approve, or block the call.
The tool's execute function runs. For BashTool, this goes through 5 security layers before a subprocess is spawned.
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.
nameUnique tool identifier used in tool_use blocks
descriptionShown to the LLM — heavily influences when Claude calls this tool
inputSchemaZod 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
checkPermissions()Called before invoke() — can block execution or prompt user
needsPermissions()Declares required permission types at construction time
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
maxConcurrencyHow many instances can run in parallel (default: 1)
timeoutMax 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.
BashPowerShellFileReadWebFetchNotebookReadFileEditFileWriteNotebookEditGrepGlobAgentSkillMCPLSPSleepTask*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.
checkPermissions() checks the command pattern against session rules and mode (default/acceptEdits/bypassPermissions).
bashParser.ts (4436 lines) builds a Tree-sitter AST of the command. Structural analysis, not regex matching.
The AST is analyzed for: network access, recursive deletes, path escapes, injection patterns, and privilege escalation.
File paths in the command are checked against the project root allowlist. Paths outside are blocked even in yolo mode.
The approved command runs in a sandboxed subprocess with stdout/stderr streaming back to StreamingToolExecutor.
Key Files
tools/BashTool/300KB / 5 filesCommand execution, AST-based security analysis, sandbox isolation
tools/FileEditTool/~40KBString find/replace with unified diff rendering
tools/AgentTool/~35KBSpawns isolated subagents with forked QueryEngine instances
tools/MCPTool/~15KBProxies external MCP server tools into the Claude tool namespace
tools/GrepTool/~12KBRipgrep wrapper for fast content search across files
Tool.ts~6KBbuildTool() factory — the interface all tools implement