Under the Hood
Claude Code
Architecture
How the CLI works under the hood · AI-generated, may contain errors
2,000+ files
512K lines
43 tools
100+ commands
39 services
01
Folder Structure
src/ — 2,000+ files · ~512K lines of TypeScript
src/
├──
entrypoints/
│ ├──
cli.tsx
│ ├──
init.ts
│ ├──
mcp.ts
│ └──
sdk/
├──
commands/
│ ├──
commit.ts
│ ├──
config/
│ ├──
memory/
│ └──
... (100+ more)
├──
tools/
│ ├──
BashTool/
│ ├──
FileReadTool/
│ ├──
FileEditTool/
│ ├──
AgentTool/
│ ├──
MCPTool/
│ ├──
WebFetchTool/
│ └──
... (37+ more)
├──
services/
│ ├──
api/
│ ├──
mcp/
│ ├──
tools/
│ ├──
compact/
│ ├──
analytics/
│ ├──
oauth/
│ └──
plugins/
├──
components/
├──
hooks/
├──
ink/
│ ├──
reconciler.ts
│ ├──
layout/
│ └──
termio/
├──
utils/
│ ├──
permissions/
│ ├──
bash/
│ ├──
model/
│ ├──
settings/
│ ├──
computerUse/
│ └──
git.ts
├──
state/
├──
bridge/
├──
cli/
├──
memdir/
├──
tasks/
├──
coordinator/
├──
assistant/
├──
voice/
└──
schemas/
02
Boot Sequence
What happens when you type claude
-
01
cli.tsx loadsFast-path check — --version exits immediately with zero imports. Keeps startup under 50ms for simple flags.
-
02
Feature flags evaluatedbun:bundle eliminates dead code paths at build time — feature-gated tools are tree-shaken away.
-
03
main.tsx initializesCommander.js parses argv. Subcommand routing dispatches to the matching command handler.
-
04
Config loadedReads settings.json, all CLAUDE.md files in the project tree, and .envrc via direnv.
-
05
Auth checkedOAuth token from ~/.claude/auth.json or ANTHROPIC_API_KEY env var validated before any API call.
-
06
GrowthBook initializedRemote feature flags fetched asynchronously. Controls gradual rollouts of experimental features without deploys.
REPL initialization
-
07
Tools assembled43 built-in tools loaded from registry. MCP tool schemas merged in dynamically after server connection.
-
08
MCP servers connectedstdio, SSE, and WebSocket transports negotiated in parallel. Capability exchange completes before loop starts.
-
09
System prompt builtAssembled from 10+ component sources: role definition, tool schemas, CLAUDE.md, memory files, git context, OS info.
-
10
REPL launchedInk renders the terminal UI using a custom React reconciler backed by Yoga flexbox. Cursor positioned, input armed.
-
11
Query loop beginsEvent loop enters idle state, waiting for user input. Background tasks (MCP heartbeats, analytics flush) run on timers.
03
Query Loop — The Core Cycle
Input → API → Tools → Output
User types message
keyboard input or piped stdin
createUserMessage()
wraps text in Anthropic message format
Append to conversation history
in-memory array of messages
Build system prompt
CLAUDE.md + tools + context + memory files
Stream to Claude API
Anthropic SDK · server-sent events
Parse response tokens as they arrive
renders incrementally to terminal
if tool_use blocks found in response
findToolByName()
look up in combined tool registry
canUseTool()
check permissions: ask / allow / deny
StreamingToolExecutor
run tools — concurrent-safe, parallel-capable
Collect tool results
assemble tool_result message blocks
loop back to API with results
Display final response to user
markdown rendered in terminal
Post-sampling hooks
auto-compact · memory extract · dream mode
Wait for next input
cycle restarts
Key implementation details
Streaming by default
Tokens render to the terminal as they arrive from the API. Users see output immediately — no waiting for the full response.
Parallel tool execution
When Claude requests multiple tools simultaneously, StreamingToolExecutor runs them concurrently. Results are collected and sent back together.
Agentic loop
Tool use → result → next API call cycles automatically. Loop terminates only when Claude emits a response with no tool_use blocks, or a stop condition triggers.
React rendering
Terminal UI re-renders via Ink's reconciler on every state change. Yoga computes flexbox layout; ANSI sequences are diffed to minimise redraws.
Interrupt handling
Ctrl+C during a tool call aborts the executor and sends a cancellation signal. The conversation history is preserved; a new query can continue.
Post-sampling hooks
After each assistant turn: context compaction threshold checked, memory extraction runs, and optional "dream" consolidation pass fires if enabled.
04
Tool System — 43 Built-in Tools
File Operations & Execution
File Operations
Read
Edit
Write
Glob
Grep
NotebookEdit
Execution
Bash
PowerShell
Search & Fetch
WebFetch
WebSearch
ToolSearch
Agents, Planning & MCP
Agents
Agent
SendMessage
TaskCreate
TaskGet
TaskList
TaskUpdate
TaskStop
TaskOutput
Planning & Worktrees
EnterPlanMode
ExitPlanMode
EnterWorktree
ExitWorktree
MCP
MCPTool
ListMcpResources
ReadMcpResource
System & Utility
System
AskUserQuestion
TodoWrite
Skill
RemoteTrigger
CronCreate
CronDelete
CronList
Config
Feature-gated / Experimental
GrowthBook-controlled
Sleep
Brief
WebBrowser
TerminalCapture
Monitor
Workflow
CtxInspect
Snip
OverflowTest
VerifyPlanExecution
ListPeers
These tools are compiled into the binary but only surface in the tool registry when the corresponding GrowthBook feature flag is enabled for the account.
05
Permission System
3-layer permission model
1
Tool Registry Filter
filterToolsByDenyRules() removes denied tools before Claude's context is built. Claude never sees — and cannot call — tools blocked at this layer. Configured via settings.json deny list.
2
Per-call Permission Check
canUseTool() is called each time Claude attempts a tool call. Checks the allow/deny rule set against the specific invocation — tool name, arguments, and working directory pattern.
3
Interactive User Prompt
If no rule matches a tool call, execution halts and the user is asked. Choices: allow once · allow always · deny. "Allow always" writes a new rule to settings.
Plan mode — requires approval before execution
Auto mode — AI decides, no prompting
Default — prompt for risky tools only
Bash safety — AST-level analysis
The Bash tool includes a full shell AST parser in utils/bash/. Before executing any shell command, it parses the AST to detect dangerous patterns.
Flagged patterns
rm -rf /
fork bombs
curl | bash
sudo escalation
tty injection
history manipulation
Bash AST analysis runs before canUseTool(). If a pattern is flagged, the call is rejected immediately regardless of permission rules.
Settings.json rule format
{
"permissions": {
"allow": ["Bash(git *)"],
"deny": ["Bash(rm *)", "Write"]
}
}
06
Context Management
Token budget — 200K context window (Claude 3.5 / 3.7 / Sonnet)
⚡ Auto-compact triggers at ~80% context usage
- Old messages above the compact boundary summarized by Claude itself
- CompactBoundaryMessage marker inserted into history
- ~40–60% of context window freed — conversation continues seamlessly
- User can trigger manually with /compact command
- Custom compaction instructions configurable in settings
07
Extension Points
How users extend Claude Code
MCP Servers
Add unlimited tools via the Model Context Protocol. Servers communicate over stdio, SSE, or WebSocket. Configured in settings.json under mcpServers.
~/.claude/settings.json → mcpServers: { ... }
Custom Agents
Markdown files in ~/.claude/agents/ define reusable subagents with their own system prompts. Invoked via the Agent tool or /agent command.
~/.claude/agents/my-agent.md
Skills
Markdown files in ~/.claude/skills/ define reusable slash commands. Loaded via the Skill tool. Support parameters and compose with other skills.
~/.claude/skills/my-skill.md
Hooks
Shell commands that run before or after tool execution. Configured per-tool in settings.json. Use cases: linting after file edits, logging, notifications.
hooks: { "postToolUse": { "Write": "eslint $FILE" } }
Plugins
Community plugins distributed via the Claude Code marketplace. Installed with /plugin install. Can add tools, slash commands, and UI elements.
/plugin install @author/plugin-name
CLAUDE.md
Project-level instruction files. Discovered by walking up the directory tree. Content is injected into the system prompt. Support @import for composition.
./CLAUDE.md · ~/.claude/CLAUDE.md · /repo/CLAUDE.md
MCP architecture in depth
The MCP (Model Context Protocol) integration lives in services/mcp/ — 24 files implementing the full protocol spec including server lifecycle, capability negotiation, and transport layers.
Transports
• stdio (subprocess)
• SSE (HTTP streaming)
• WebSocket
Capabilities
• Tools
• Resources
• Prompts
Example settings.json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y",
"@modelcontextprotocol/server-filesystem",
"/Users/me/projects"
]
},
"remote-api": {
"url": "https://api.example.com/mcp",
"transport": "sse"
}
}
}
08
Key Numbers
2,000+
source files
512K
lines of TypeScript
43
built-in tools
100+
CLI commands
39
service modules
85
React hooks
144
UI components
24
MCP integration files
564
utility files
24
permission system files