Claude Code Hooksで開発を自動化する — 実際に使える5パターンを解説【2026年版】
Claude Code Hooksの設定方法と実践的な使い方を解説。PreToolUse・PostToolUse・SessionStart・Notificationなど主要イベントを使った自動化レシピ5選。副業・フリーランスエンジニア向けに実用性重視でまとめた。
エンジニアのゆとです。
Claude Codeを使い始めて気づくことがある。
「なんでClaude、毎回同じことで確認してくるんだろう」とか、「ファイル編集するたびに手動でフォーマットかけるのしんどい」とか、そういうやつ。
これ、Hooksで全部解決できる。
Hooksは「Claude Codeが何かをする直前・直後に、自分のスクリプトを自動実行できる仕組み」だ。AIが判断するんじゃなくて、確実に実行される。条件分岐も、ブロックも、通知も全部できる。
ただ、公式ドキュメントを開くとイベント一覧が25種類くらい並んでて「どこから手をつければ…」となる。
この記事では、実際に使っていて「これは便利」と思ったパターンを5つに絞って解説する。全イベント網羅より、まず動かすことを優先する。
Hooksの基本構造
まず最小限の理解から。
Hooksの設定は ~/.claude/settings.json(全プロジェクト共通)か、.claude/settings.json(プロジェクト固有)に書く。形式はこう:
{
"hooks": {
"イベント名": [
{
"matcher": "対象ツール名(省略可)",
"hooks": [
{
"type": "command",
"command": "実行するシェルコマンド"
}
]
}
]
}
}
フローはシンプル:イベントが発火 → Claude CodeがJSONデータをstdinに渡す → スクリプトが実行される → 終了コードとstdout/stderrでClaude Codeに結果を伝える。
終了コードの意味:
exit 0:続行exit 2:アクションをブロック(stderrに理由を書くとClaudeに伝わる)- それ以外:続行するがstderrはログに記録(Claudeには見えない)
これだけ理解できれば、あとはレシピをそのまま使えばいい。
パターン1: ファイル編集後に自動フォーマット
使うイベント: PostToolUse(Edit|Write)
一番シンプルで実用的なやつから。Claude Codeがファイルを編集するたびに、Prettierを自動でかける。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
matcher: "Edit|Write" で「EditツールかWriteツールを使ったとき」に限定している。ファイル操作以外では発火しない。
jq -r '.tool_input.file_path' で編集されたファイルパスを取得して、そのままPrettierに渡す。
事前に jq と npx prettier が使える環境が必要。macOSなら brew install jq。
ESLintに変えたければ xargs npx eslint --fix にするだけ。matcher を "Edit|Write|MultiEdit" に拡張すれば複数ファイル操作にも対応できる。
パターン2: 危険なコマンドをブロック
使うイベント: PreToolUse(Bash)
rm -rf とか drop table とか、「Claudeが自信満々に実行しようとしてるけど待って」となる瞬間はある。
PreToolUseで事前にチェックして、ヤバそうなら止める。
まずフックスクリプトを作る。.claude/hooks/check-dangerous.sh に保存:
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
# ブロックリスト
DANGEROUS_PATTERNS=(
"rm -rf /"
"drop table"
"truncate table"
"> /dev/sda"
"chmod -R 777 /"
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qi "$pattern"; then
echo "ブロック: '$pattern' を含むコマンドは実行できません" >&2
exit 2
fi
done
exit 0
実行権限を付与:
chmod +x .claude/hooks/check-dangerous.sh
settings.jsonに登録:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-dangerous.sh"
}
]
}
]
}
}
exit 2で止めて、stderrに理由を書くとClaudeがその内容をフィードバックとして受け取る。「このコマンドは実行できないので別の方法を試します」と代替案を考え始める。
保護ファイルのパターン(.env、package-lock.json 等)も同じ構成でできる。
パターン3: 作業完了の通知
使うイベント: Notification
長い処理を依頼してターミナルを離れたとき、終わったかどうか気になってたまに覗きに来る、あれが地味にストレスだった。
Notificationイベントで解決する。Claude Codeが入力待ち状態になったときに発火するやつ。
macOSならこれだけでいい:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"終わったよ\" with title \"Claude Code\"'"
}
]
}
]
}
}
初回に通知が来ない場合は、macOSの通知設定を確認する。ターミナルで一度 osascript -e 'display notification "test"' を手動実行してから、システム設定 > 通知 で「スクリプトエディタ」の通知をオンにする。
Telegram通知にしたければ:
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d "chat_id=${TELEGRAM_CHAT_ID}&text=Claude Code: 処理が完了しました"
これをスクリプトにして登録すれば、スマホで通知を受け取れる。副業の作業中に別のことやりながら待てる。
パターン4: セッション開始時にコンテキストを注入
使うイベント: SessionStart
Claude Codeのコンテキストウィンドウがいっぱいになると「compact」が走る。要約されて会話の前半が消える。そのたびに「えっと、このプロジェクトはAstroで…」と説明し直すのがしんどかった。
SessionStartにmatcher "compact" を設定すると、compactのたびに自動でコンテキストを再注入できる。
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "cat .claude/context-reminder.md"
}
]
}
]
}
}
.claude/context-reminder.md の中身は自分で書く。「このプロジェクトはAstro v5、TypeScript、Tailwind CSS使用。外部リンクはExternalLinkCardコンポーネント経由。---水平線は禁止」みたいな内容。
stdout に書き込んだテキストがClaudeのコンテキストに追加される。静的なファイルじゃなくて git log --oneline -3 を入れると直近コミットも一緒に渡せる:
{
"command": "cat .claude/context-reminder.md && echo '--- 最近のコミット ---' && git log --oneline -3"
}
パターン5: Bashコマンドのログを残す
使うイベント: PostToolUse(Bash)
「あれ、さっきClaude Codeが実行したコマンドなんだったっけ」となることがある。特に長いセッションで何をやったか追いたいとき。
全Bashコマンドをログファイルに記録するやつ:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '\"[\" + (.session_id[:8]) + \"] \" + (.tool_input.command // \"(empty)\")' >> ~/.claude/command-log.txt"
}
]
}
]
}
}
~/.claude/command-log.txt にセッションIDの先頭8文字とコマンドが記録される。後から grep で特定セッションの操作を追える。
これをベースにして、特定のコマンド(git commit とか npm publish とか)だけを通知する使い方もできる。
設定のコツと注意点
jqが必要なレシピが多い
stdin経由で受け取るJSONを解析するのに jq を使うケースが多い。brew install jq しておくとスムーズ。
スクリプトファイルは実行権限を忘れない
chmod +x を忘れると「command not found」じゃなくて「permission denied」で静かに失敗する。hookが動いてないと思ったらまずこれを疑う。
シェルプロファイルのechoに注意
~/.zshrc とかに無条件でechoを書いてると、それがhookの出力に混入してJSON解析に失敗する。インタラクティブシェルのときだけ実行されるように if [[ $- == *i* ]]; then echo ...; fi で囲む。
デバッグは Ctrl+O で詳細モード
hookが意図通りに動いてるか確認したいときは、Claude Code内で Ctrl+O を押すと詳細モードになる。hookの実行ログ、終了コード、stderr出力が全部見える。claude --debug でも同じ情報が出る。
/hooks コマンドで設定確認
Claude Code内で /hooks と入力すると、現在設定されているhookが一覧で確認できる。設定したはずなのに動かないときはここで確認する。
まとめ
Hooksでできることをまとめると:
- ファイル編集後に自動フォーマット(PostToolUse)
- 危険なコマンドをブロック(PreToolUse)
- 作業完了を通知(Notification)
- コンパクト後にコンテキストを再注入(SessionStart)
- コマンドのログを記録(PostToolUse)
共通するのは「Claude Codeの動作に確実性を持ち込む」という考え方。AIの判断に頼るんじゃなくて、「このイベントが起きたら、このコマンドが必ず実行される」という確定事項にする。
最初はパターン1(自動フォーマット)かパターン3(通知)だけ入れてみると雰囲気がつかみやすい。両方合わせて10行くらいのJSONで動く。
Hooksのイベントは全部で25種類以上あるけど、日常的に使うのは5種類あれば十分だった。残りは「そういえばこういうことできるんだ」くらいの知識でいい。




