Live
Black Hat USAAI BusinessBlack Hat AsiaAI BusinessDesktop Canary v2.1.48-canary.31LobeChat ReleasesThe Invisible Broken Clock in AI Video GenerationHackernoon AIMean field sequence: an introductionLessWrong AISwift package AI inference engine generated from Rust crateHacker News AI TopZeta-2 Turns Code Edits Into Context-Aware Rewrite SuggestionsHackernoon AIAI Tools That Actually Pay You Back: A Developer's Guide to Monetizing AIDev.to AIThe $6 Million Shockwave: How DeepSeek Just Broke the AI MonopolyMedium AIHow I Got My First Freelance Client in 3 Days (Using AI) — Beginner Guide (India 2026)Medium AIWhy Your Resume Gets Rejected Before a Human Sees It (And How to Fix It)Dev.to AII've Been Saying RAG Is Dead Since 2020Medium AIAI Print-on-Demand Passive Income: ₹400-2K/Design from HomeDev.to AIFaceless YouTube Automation with AI: Complete Guide 2026Dev.to AIBlack Hat USAAI BusinessBlack Hat AsiaAI BusinessDesktop Canary v2.1.48-canary.31LobeChat ReleasesThe Invisible Broken Clock in AI Video GenerationHackernoon AIMean field sequence: an introductionLessWrong AISwift package AI inference engine generated from Rust crateHacker News AI TopZeta-2 Turns Code Edits Into Context-Aware Rewrite SuggestionsHackernoon AIAI Tools That Actually Pay You Back: A Developer's Guide to Monetizing AIDev.to AIThe $6 Million Shockwave: How DeepSeek Just Broke the AI MonopolyMedium AIHow I Got My First Freelance Client in 3 Days (Using AI) — Beginner Guide (India 2026)Medium AIWhy Your Resume Gets Rejected Before a Human Sees It (And How to Fix It)Dev.to AII've Been Saying RAG Is Dead Since 2020Medium AIAI Print-on-Demand Passive Income: ₹400-2K/Design from HomeDev.to AIFaceless YouTube Automation with AI: Complete Guide 2026Dev.to AI
AI NEWS HUBbyEIGENVECTOREigenvector

Claude Code hooks: intercept every tool call before it runs

DEV Communityby brian austinApril 2, 20264 min read2 views
Source Quiz

<h1> Claude Code hooks: intercept every tool call before it runs </h1> <p>The Claude Code source leak revealed something most developers haven't discovered yet: a full hooks system that lets you intercept, log, or block any tool call Claude makes — before it executes.</p> <p>This isn't documented anywhere officially. Here's how it works.</p> <h2> What are Claude Code hooks? </h2> <p>Hooks are shell commands that run at specific points in Claude Code's execution cycle:</p> <ul> <li> <strong>PreToolUse</strong> — runs before Claude calls any tool (Bash, Read, Write, etc.)</li> <li> <strong>PostToolUse</strong> — runs after a tool completes</li> <li> <strong>Notification</strong> — runs when Claude sends you a notification</li> <li> <strong>Stop</strong> — runs when a session ends</li> </ul>

Claude Code hooks: intercept every tool call before it runs

The Claude Code source leak revealed something most developers haven't discovered yet: a full hooks system that lets you intercept, log, or block any tool call Claude makes — before it executes.

This isn't documented anywhere officially. Here's how it works.

What are Claude Code hooks?

Hooks are shell commands that run at specific points in Claude Code's execution cycle:

  • PreToolUse — runs before Claude calls any tool (Bash, Read, Write, etc.)

  • PostToolUse — runs after a tool completes

  • Notification — runs when Claude sends you a notification

  • Stop — runs when a session ends

You define them in your .claude/settings.json.

The config format

{  "hooks": {  "PreToolUse": [  {  "matcher": "Bash",  "hooks": [  {  "type": "command",  "command": "echo '[HOOK] Claude about to run Bash' >> /tmp/claude-audit.log"  }  ]  }  ],  "PostToolUse": [  {  "matcher": "Write",  "hooks": [  {  "type": "command",  "command": "echo '[HOOK] Claude wrote a file' >> /tmp/claude-audit.log"  }  ]  }  ]  } }

Enter fullscreen mode

Exit fullscreen mode

Every Bash call gets logged. Every file write gets logged. Full audit trail, zero effort.

Practical hook: block dangerous commands

Want to prevent Claude from ever running git reset --hard or rm -rf?

{  "hooks": {  "PreToolUse": [  {  "matcher": "Bash",  "hooks": [  {  "type": "command",  "command": "echo $CLAUDE_TOOL_INPUT | grep -E 'git reset --hard|rm -rf|drop table|DROP TABLE' && echo 'BLOCKED' && exit 1 || exit 0"  }  ]  }  ]  } }

Enter fullscreen mode

Exit fullscreen mode

If the command matches, the hook exits 1 — Claude Code sees the tool as blocked and doesn't proceed.

Practical hook: auto-backup before writes

{  "hooks": {  "PreToolUse": [  {  "matcher": "Write",  "hooks": [  {  "type": "command",  "command": "FILE=$(echo $CLAUDE_TOOL_INPUT | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))\" 2>/dev/null); [ -f \"$FILE\" ] && cp \"$FILE\" \"$FILE.$(date +%s).bak\" && echo \"Backed up $FILE\""  }  ]  }  ]  } }

Enter fullscreen mode

Exit fullscreen mode

Before Claude overwrites any file, it gets backed up automatically. No more lost work.

Practical hook: notify on session end

{  "hooks": {  "Stop": [  {  "matcher": ".*",  "hooks": [  {  "type": "command",  "command": "osascript -e 'display notification \"Claude Code session complete\" with title \"Claude Code\"' 2>/dev/null || notify-send 'Claude Code' 'Session complete' 2>/dev/null"  }  ]  }  ]  } }
*

Enter fullscreen mode

Exit fullscreen mode

Mac or Linux desktop notification when Claude finishes a long task. Useful for background runs.

The CLAUDE_TOOL_INPUT environment variable

Hooks receive tool call data via the CLAUDE_TOOL_INPUT environment variable as JSON. The schema depends on the tool:

  • Bash: {"command": "ls -la", "description": "List files"}

  • Write: {"file_path": "/path/to/file", "content": "..."}

  • Read: {"file_path": "/path/to/file"}

This means you can build arbitrarily sophisticated interceptors in any language.

Python interceptor example

Create /usr/local/bin/claude-bash-hook:

#!/usr/bin/env python3 import os import sys import json import subprocess from datetime import datetime

tool_input_str = os.environ.get('CLAUDE_TOOL_INPUT', '{}') try: tool_input = json.loads(tool_input_str) except: tool_input = {}

command = tool_input.get('command', '')

Blocklist

DANGEROUS = [ 'git reset --hard', 'rm -rf /', 'DROP TABLE', 'truncate', 'format c:' ]

for danger in DANGEROUS: if danger.lower() in command.lower(): print(f'BLOCKED: {danger}', file=sys.stderr) sys.exit(1)

Audit log

with open('/tmp/claude-commands.log', 'a') as f: f.write(f"{datetime.now().isoformat()} | {command[:200]}\n")

sys.exit(0)`

Enter fullscreen mode

Exit fullscreen mode

Then in .claude/settings.json:

{  "hooks": {  "PreToolUse": [  {  "matcher": "Bash",  "hooks": [  {  "type": "command",  "command": "claude-bash-hook"  }  ]  }  ]  } }

Enter fullscreen mode

Exit fullscreen mode

Now every bash command Claude runs goes through your Python script first.

The bigger picture

The hooks system is part of what makes Claude Code surprisingly powerful once you get past the defaults. Combined with a solid CLAUDE.md and settings.json, you essentially get:

  • CLAUDE.md → what Claude should do (instructions)

  • settings.json permissions → what Claude is allowed to do (capabilities)

  • hooks → what happens around what Claude does (observability + guardrails)

Three layers. Most developers only use the first one.

If you're using Claude via API directly (not Claude Code), the flat-rate proxy at simplylouie.com gives you full API access for $2/month — same model, no per-token billing anxiety. Useful for testing hooks without burning credits.

Was this article helpful?

Sign in to highlight and annotate this article

AI
Ask AI about this article
Powered by Eigenvector · full article context loaded
Ready

Conversation starters

Ask anything about this article…

Daily AI Digest

Get the top 5 AI stories delivered to your inbox every morning.

Knowledge Map

Knowledge Map
TopicsEntitiesSource
Claude Code…claudemodelclaude codeDEV Communi…

Connected Articles — Knowledge Graph

This article is connected to other articles through shared AI topics and tags.

Knowledge Graph100 articles · 178 connections
Scroll to zoom · drag to pan · click to open

Discussion

Sign in to join the discussion

No comments yet — be the first to share your thoughts!

More in Models