Claude Code Hooks - Quickly master how to use Claude Code hooks to add deterministic (or non-deterministic) control over Claude Code's behavior. Plus learn about Claude Code Sub-Agents, the powerful Meta-Agent, and Team-Based Validation with agent orchestration.

This requires: - Astral UV - Fast Python package installer and resolver - Claude Code - Anthropic's CLI for Claude AI
Optional: - ElevenLabs - Text-to-speech provider (with MCP server integration) - ElevenLabs MCP Server - MCP server for ElevenLabs - Firecrawl MCP Server - Web scraping and crawling MCP server (my favorite scraper) - OpenAI - Language model provider + Text-to-speech provider - Anthropic - Language model provider - Ollama - Local language model provider
This demo captures all 13 Claude Code hook lifecycle events with their JSON payloads:
flowchart TB
subgraph SESSION["🟢 Session Lifecycle"]
direction TB
SETUP[["🔧 Setup
(init/maintenance)"]]
START[["▶️ SessionStart
(startup/resume/clear)"]]
END[["⏹️ SessionEnd
(exit/sigint/error)"]]
end
subgraph MAIN["🔄 Main Conversation Loop"]
direction TB
PROMPT[["📝 UserPromptSubmit"]]
CLAUDE["Claude Processes"]
subgraph TOOLS["🛠️ Tool Execution"]
direction TB
PRE[["🔒 PreToolUse"]]
PERM[["❓ PermissionRequest"]]
EXEC["Tool Executes"]
POST[["✅ PostToolUse"]]
FAIL[["❌ PostToolUseFailure"]]
end
subgraph SUBAGENT["🤖 Subagent Lifecycle"]
direction TB
SSTART[["🚀 SubagentStart"]]
SWORK["Subagent Works"]
SSTOP[["🏁 SubagentStop"]]
end
NOTIFY[["🔔 Notification
(Async)"]]
STOP[["🛑 Stop"]]
end
subgraph COMPACT["🗜️ Maintenance"]
PRECOMPACT[["📦 PreCompact"]]
end
SETUP --> START
START --> PROMPT
PROMPT --> CLAUDE
CLAUDE --> PRE
PRE --> PERM
PERM --> EXEC
EXEC --> POST
EXEC -.-> FAIL
CLAUDE -.-> SSTART
SSTART --> SWORK
SWORK --> SSTOP
POST --> CLAUDE
CLAUDE --> STOP
CLAUDE -.-> NOTIFY
STOP --> PROMPT
STOP -.-> END
PROMPT -.-> PRECOMPACT
PRECOMPACT -.-> PROMPT
Fires: Immediately when user submits a prompt (before Claude processes it)
Payload: prompt text, session_id, timestamp
Enhanced: Prompt validation, logging, context injection, security filtering
Fires: Before any tool execution
Payload: tool_name, tool_input parameters
Enhanced: Blocks dangerous commands (rm -rf, .env access)
Fires: After successful tool completion
Payload: tool_name, tool_input, tool_response with results
Fires: When Claude Code sends notifications (waiting for input, etc.)
Payload: message content
Enhanced: TTS alerts - "Your agent needs your input" (30% chance includes name)
Fires: When Claude Code finishes responding
Payload: stop_hook_active boolean flag
Enhanced: AI-generated completion messages with TTS playback (LLM priority: OpenAI > Anthropic > Ollama > random)
Fires: When Claude Code subagents (Task tools) finish responding
Payload: stop_hook_active boolean flag
Enhanced: TTS playback - "Subagent Complete"
Fires: Before Claude Code performs a compaction operation
Payload: trigger ("manual" or "auto"), custom_instructions (for manual), session info
Enhanced: Transcript backup, verbose feedback for manual compaction
Fires: When Claude Code starts a new session or resumes an existing one
Payload: source ("startup", "resume", or "clear"), session info
Enhanced: Development context loading (git status, recent issues, context files)
Fires: When Claude Code session ends (exit, sigint, or error)
Payload: session_id, transcript_path, cwd, permission_mode, reason
Enhanced: Session logging with optional cleanup tasks (removes temp files, stale logs)
Fires: When user is shown a permission dialog
Payload: tool_name, tool_input, tool_use_id, session info
Enhanced: Permission auditing, auto-allow for read-only ops (Read, Glob, Grep, safe Bash)
Fires: When a tool execution fails
Payload: tool_name, tool_input, tool_use_id, error object
Enhanced: Structured error logging with timestamps and full context
Fires: When a subagent (Task tool) spawns
Payload: agent_id, agent_type, session info
Enhanced: Subagent spawn logging with optional TTS announcement
Fires: When Claude enters a repository (init) or periodically (maintenance)
Payload: trigger ("init" or "maintenance"), session info
Enhanced: Environment persistence via CLAUDE_ENV_FILE, context injection via additionalContext
logs/ directoryWarning: The
chat.jsonfile contains only the most recent Claude Code conversation. It does not preserve conversations from previous sessions - each new conversation is fully copied and overwrites the previous one. This is unlike the other logs which are appended to from every claude code session.
This project leverages UV single-file scripts to keep hook logic cleanly separated from your main codebase. All hooks live in .claude/hooks/ as standalone Python scripts with embedded dependency declarations.
Benefits: - Isolation - Hook logic stays separate from your project dependencies - Portability - Each hook script declares its own dependencies inline - No Virtual Environment Management - UV handles dependencies automatically - Fast Execution - UV's dependency resolution is lightning-fast - Self-Contained - Each hook can be understood and modified independently
This approach ensures your hooks remain functional across different environments without polluting your main project's dependency tree.
.claude/settings.json - Hook configuration with permissions.claude/hooks/ - Python scripts using uv for each hook typeuser_prompt_submit.py - Prompt validation, logging, and context injectionpre_tool_use.py - Security blocking and loggingpost_tool_use.py - Logging and transcript conversionpost_tool_use_failure.py - Error logging with structured detailsnotification.py - Logging with optional TTS (--notify flag)stop.py - AI-generated completion messages with TTSsubagent_stop.py - Simple "Subagent Complete" TTSsubagent_start.py - Subagent spawn logging with optional TTSpre_compact.py - Transcript backup and compaction loggingsession_start.py - Development context loading and session loggingsession_end.py - Session cleanup and loggingpermission_request.py - Permission auditing and auto-allowsetup.py - Repository initialization and maintenancevalidators/ - Code quality validation hooksruff_validator.py - Python linting via Ruff (PostToolUse)ty_validator.py - Python type checking (PostToolUse)utils/ - Intelligent TTS and LLM utility scriptstts/ - Text-to-speech providers (ElevenLabs, OpenAI, pyttsx3)tts_queue.py - Queue-based TTS management (prevents overlapping audio)llm/ - Language model integrations (OpenAI, Anthropic, Ollama)task_summarizer.py - LLM-powered task completion summaries.claude/status_lines/ - Real-time terminal status displaysstatus_line.py - Basic MVP with git infostatus_line_v2.py - Smart prompts with color codingstatus_line_v3.py - Agent sessions with historystatus_line_v4.py - Extended metadata supportstatus_line_v5.py - Cost tracking with line changesstatus_line_v6.py - Context window usage barstatus_line_v7.py - Session duration timerstatus_line_v8.py - Token usage with cache statsstatus_line_v9.py - Minimal powerline style.claude/output-styles/ - Response formatting configurationsgenui.md - Generates beautiful HTML with embedded stylingtable-based.md - Organizes information in markdown tablesyaml-structured.md - YAML configuration formatbullet-points.md - Clean nested listsultra-concise.md - Minimal words, maximum speedhtml-structured.md - Semantic HTML5markdown-focused.md - Rich markdown featurestts-summary.md - Audio feedback via TTS.claude/commands/ - Custom slash commandsprime.md - Project analysis and understandingplan_w_team.md - Team-based build/validate workflowcrypto_research.md - Cryptocurrency research workflowscook.md - Advanced task executionupdate_status_line.md - Dynamic status updates.claude/agents/ - Sub-agent configurationscrypto/ - Cryptocurrency analysis agentsteam/ - Team-based workflow agentsbuilder.md - Implementation agent (all tools)validator.md - Read-only validation agenthello-world-agent.md - Simple greeting examplellm-ai-agents-and-eng-research.md - AI research specialistmeta-agent.md - Agent that creates other agentswork-completion-summary.md - Audio summary generatorlogs/ - JSON logs of all hook executionsuser_prompt_submit.json - User prompt submissions with validationpre_tool_use.json - Tool use events with security blockingpost_tool_use.json - Tool completion eventspost_tool_use_failure.json - Tool failure events with error detailsnotification.json - Notification eventsstop.json - Stop events with completion messagessubagent_stop.json - Subagent completion eventssubagent_start.json - Subagent spawn eventspre_compact.json - Pre-compaction events with trigger typesession_start.json - Session start events with source typesession_end.json - Session end events with reasonpermission_request.json - Permission request audit logsetup.json - Setup events with trigger typechat.json - Readable conversation transcript (generated by --chat flag)ai_docs/ - Documentation resourcescc_hooks_docs.md - Complete hooks documentation from Anthropicclaude_code_status_lines_docs.md - Status line input schema and configurationuser_prompt_submit_hook.md - Comprehensive UserPromptSubmit hook documentationuv-single-file-scripts.md - UV script architecture documentationanthropic_custom_slash_commands.md - Slash commands documentationanthropic_docs_subagents.md - Sub-agents documentationruff.toml - Ruff linter configuration for Python code qualityty.toml - Type checker configuration for Python type validationHooks provide deterministic control over Claude Code behavior without relying on LLM decisions.
Run any Claude Code command to see hooks in action via the logs/ files.
Claude Code hooks provide powerful mechanisms to control execution flow and provide feedback through exit codes and structured JSON output.
Hooks communicate status and control flow through exit codes:
| Exit Code | Behavior | Description
$ claude mcp add claude-code-hooks-mastery \
-- python -m otcore.mcp_server <graph>