Claude Code Hooksとは — 開発効率を劇的に変える自動化の仕組み
Claude Code Hooksは、Claudeがツールを実行する前後に独自のスクリプトを自動実行できる機能です。これにより、手動で行っていたコードレビュー、テスト実行、セキュリティチェックなどを完全に自動化できます。
2026年のソフトウェア開発では、AIアシスタントとの協働が当たり前になっています。しかし、AIが生成したコードをそのまま本番環境に反映するのは危険です。Hooksを活用すれば、AIの出力に対して一貫した品質管理を自動で適用でき、安全性と効率を両立できます。
ここで扱うのはClaude Code Hooksの基本概念から、プロダクション環境で実際に使える高度な自動化パターンまで、コード例付きで徹底的に解説します。
Hooksの基本構造と設定方法
Claude Code Hooksは .claude/settings.json に定義します。フックには4つのタイプがあります。
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/pre-edit-check.sh \"$FILEPATH\""
}
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/post-edit-lint.sh \"$FILEPATH\""
}
}
],
"Notification": [
{
"matcher": "",
"hook": {
"type": "command",
"command": "bash .claude/hooks/notify-slack.sh \"$MESSAGE\""
}
}
],
"Stop": [
{
"matcher": "",
"hook": {
"type": "command",
"command": "bash .claude/hooks/on-stop.sh"
}
}
]
}
}
各フックタイプの役割は次のとおりです。
PreToolUse — ツール実行前のゲートキーパー
Claudeがファイルの編集やコマンド実行を行う前に呼び出されます。終了コード 2 を返すとツールの実行がブロックされるため、危険な操作の防止に最適です。
PostToolUse — ツール実行後の品質チェック
ファイル編集やコマンド実行の完了直後に呼び出されます。リントや型チェック、テスト実行を自動化するのに使います。
Notification — 通知の自動転送
Claudeが通知を発行したときに呼び出されます。Slack通知やメール送信に活用できます。
Stop — セッション終了時の後処理
Claudeがタスクを完了してレスポンスを返す直前に呼び出されます。ログ記録やクリーンアップ処理に使います。
実践テクニック1: セキュリティガードフック
本番環境で最も重要なのはセキュリティです。以下のフックは、Claudeがファイルを編集する前にセキュリティ上の問題がないかチェックします。
#!/bin/bash
# .claude/hooks/security-guard.sh
# PreToolUse フック — 機密ファイルへの書き込みを防止
FILEPATH="$1"
# 機密ファイルのパターン
SENSITIVE_PATTERNS=(
"*.env"
"*.env.*"
"*credentials*"
"*secret*"
"*.pem"
"*.key"
"*config/production*"
)
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
if [[ "$FILEPATH" == $pattern ]]; then
echo "🚫 セキュリティ警告: 機密ファイル '$FILEPATH' への書き込みをブロックしました"
echo "手動で編集するか、明示的に許可してください。"
exit 2 # exit 2 = ツール実行をブロック
fi
done
# ファイル内容に機密情報が含まれていないかチェック
if [ -f "$FILEPATH" ]; then
if grep -qiE '(api[_-]?key|secret[_-]?key|password|token)\s*[:=]\s*["\x27][^\s]+' "$FILEPATH" 2>/dev/null; then
echo "⚠️ 警告: ファイルにハードコードされた認証情報が検出されました"
echo "環境変数を使用してください。"
exit 2
fi
fi
exit 0 # 問題なし — ツール実行を許可
この設定を .claude/settings.json に追加します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/security-guard.sh \"$FILEPATH\""
}
}
]
}
}
実践テクニック2: 自動リント&フォーマット
ファイル編集後に自動的にリンターとフォーマッターを実行するフックです。
#!/bin/bash
# .claude/hooks/post-edit-lint.sh
# PostToolUse フック — 編集後に自動リント&フォーマット
FILEPATH="$1"
EXTENSION="${FILEPATH##*.}"
case "$EXTENSION" in
ts|tsx)
echo "🔍 TypeScript: ESLintを実行中..."
npx eslint --fix "$FILEPATH" 2>&1
echo "💅 Prettierでフォーマット中..."
npx prettier --write "$FILEPATH" 2>&1
;;
py)
echo "🔍 Python: Ruffを実行中..."
ruff check --fix "$FILEPATH" 2>&1
ruff format "$FILEPATH" 2>&1
;;
rs)
echo "🔍 Rust: cargo fmtを実行中..."
rustfmt "$FILEPATH" 2>&1
;;
go)
echo "🔍 Go: gofmtを実行中..."
gofmt -w "$FILEPATH" 2>&1
;;
*)
echo "📝 リント対象外のファイル形式です: .$EXTENSION"
;;
esac
exit 0
実践テクニック3: テスト自動実行フック
編集されたファイルに対応するテストを自動で見つけて実行するフックです。
#!/bin/bash
# .claude/hooks/auto-test.sh
# PostToolUse フック — 関連テストを自動実行
FILEPATH="$1"
DIR=$(dirname "$FILEPATH")
BASENAME=$(basename "$FILEPATH" | sed 's/\.[^.]*$//')
# テストファイルの候補を探す
TEST_FILES=()
for pattern in \
"${DIR}/${BASENAME}.test.ts" \
"${DIR}/${BASENAME}.test.tsx" \
"${DIR}/${BASENAME}.spec.ts" \
"${DIR}/__tests__/${BASENAME}.test.ts" \
"tests/${BASENAME}.test.ts"; do
if [ -f "$pattern" ]; then
TEST_FILES+=("$pattern")
fi
done
if [ ${#TEST_FILES[@]} -eq 0 ]; then
echo "📝 対応するテストファイルが見つかりませんでした"
exit 0
fi
echo "🧪 関連テストを実行中..."
for test_file in "${TEST_FILES[@]}"; do
echo " → $test_file"
npx vitest run "$test_file" --reporter=verbose 2>&1
done
# テスト失敗時もフック自体は成功とする(Claudeにフィードバックとして伝わる)
exit 0
実践テクニック4: Git操作の安全ガード
Claudeが危険なGitコマンドを実行しようとした場合に警告するフックです。
#!/bin/bash
# .claude/hooks/git-safety.sh
# PreToolUse フック — 危険なGit操作をブロック
COMMAND="$1"
# 危険なGitコマンドのパターン
DANGEROUS_PATTERNS=(
"git push.*--force"
"git push.*-f "
"git reset --hard"
"git checkout \."
"git clean -fd"
"git branch -D"
"git rebase.*main"
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qE "$pattern"; then
echo "🚫 危険なGit操作を検出しました: $COMMAND"
echo "この操作はデータ損失のリスクがあります。"
echo "手動で実行するか、安全な代替コマンドを使用してください。"
exit 2
fi
done
exit 0
実践テクニック5: Slack通知の連携
タスク完了時にSlackに通知を送るフックです。チーム開発でClaude Codeを使う際に便利です。
#!/bin/bash
# .claude/hooks/notify-slack.sh
# Notification フック — Slack Webhookで通知
MESSAGE="$1"
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}"
if [ -z "$SLACK_WEBHOOK_URL" ]; then
exit 0 # Webhook未設定の場合はスキップ
fi
# メッセージを整形してSlackに送信
PAYLOAD=$(cat <<EOF
{
"text": "🤖 Claude Code 通知",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Claude Code からの通知:*\n${MESSAGE}"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "📁 プロジェクト: $(basename $(pwd)) | ⏰ $(date '+%Y-%m-%d %H:%M')"
}
]
}
]
}
EOF
)
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-type: application/json' \
-d "$PAYLOAD" > /dev/null 2>&1
exit 0
フックの組み合わせ — 完全な自動化パイプライン
ここまで紹介した個別のフックを組み合わせて、包括的な自動化パイプラインを構築しましょう。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/security-guard.sh \"$FILEPATH\""
}
},
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "bash .claude/hooks/git-safety.sh \"$COMMAND\""
}
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/post-edit-lint.sh \"$FILEPATH\""
}
},
{
"matcher": "Edit|Write",
"hook": {
"type": "command",
"command": "bash .claude/hooks/auto-test.sh \"$FILEPATH\""
}
}
],
"Notification": [
{
"matcher": "",
"hook": {
"type": "command",
"command": "bash .claude/hooks/notify-slack.sh \"$MESSAGE\""
}
}
],
"Stop": [
{
"matcher": "",
"hook": {
"type": "command",
"command": "bash .claude/hooks/on-stop.sh"
}
}
]
}
}
パフォーマンスとデバッグのポイント
フックを本番運用する際に押さえておきたいポイントがあります。
タイムアウトの設定
フックにはデフォルトで60秒のタイムアウトが設定されています。重い処理を行うフックでは、非同期実行やバックグラウンド処理を検討してください。
#!/bin/bash
# 重い処理はバックグラウンドで実行
nohup bash -c "npm run test:coverage" > /tmp/test-results.log 2>&1 &
echo "🧪 テストをバックグラウンドで実行中(結果: /tmp/test-results.log)"
exit 0
デバッグログの出力
フックの動作を確認するために、ログ出力を仕込んでおくと便利です。
#!/bin/bash
# デバッグログ
LOG_FILE="/tmp/claude-hooks.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Hook: $0 | Args: $@" >> "$LOG_FILE"
# 本来の処理...
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Hook completed: $0 | Exit: $?" >> "$LOG_FILE"
環境変数の活用
フックの挙動を環境変数で制御すると、開発環境と本番環境で設定を切り替えやすくなります。
#!/bin/bash
# 環境に応じてフックの厳格さを変更
HOOK_MODE="${CLAUDE_HOOK_MODE:-strict}"
if [ "$HOOK_MODE" = "permissive" ]; then
echo "📝 許容モード: チェックをスキップします"
exit 0
fi
# strict モードの処理...
全体を振り返って — Hooksで実現する「守りの自動化」
Claude Code Hooksは、AIアシスタントとの協働において「安全で一貫した品質管理」を実現するための強力な仕組みです。セキュリティガード、自動リント、テスト実行、Git安全チェック、通知連携を組み合わせることで、人間の介入を最小限にしながら高い品質基準を維持できます。
まずはセキュリティガードフックから導入し、徐々に自動リントやテスト実行を追加していくのがおすすめです。小さく始めて、チームの開発フローに合わせて育てていきましょう。