0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code の Hooks を使ったら「確認待ち」が消えて開発速度が 2 倍になった話

0
Posted at

この記事で紹介する Claude Code Hooks に pay-per-call-mcp を組み合わせると、ツール実行のたびに外部 API を自動呼び出しするワークフローが作れます。

この記事でわかること

  • Claude Code の Hooks(PreToolUse / PostToolUse / Stop)の仕組みと設定方法
  • 「ファイル保存のたびに自動フォーマット」「コミット前に自動テスト」をゼロ設定で実現する方法
  • Hooks を使って Claude の行動を自動承認・自動拒否する実践パターン
  • よくある「確認ダイアログが邪魔」問題を Hooks で解消するテクニック
  • 実際に導入して開発速度が体感 2 倍になった具体的な設定例

はじめに

Claude Code を使い始めたとき、一番ストレスだったのは「本当に実行しますか?」という確認ダイアログの多さでした。

Claude が以下のコマンドを実行しようとしています:
npm run test
[許可] [拒否]

これが 1 日に何十回も出てくる。npm run test に毎回許可するのは完全に無駄です。

Claude Code の Hooks を設定したところ、確認ダイアログが劇的に減り、繰り返し作業が自動化されました。


Hooks の仕組み

Hooks は「Claude がツールを使う前後に特定のコマンドを自動実行する」仕組みです。

Claude がツールを実行しようとする
       ↓
  PreToolUse Hook が発火
  (ここでブロックしたり自動承認できる)
       ↓
  ツールが実行される
       ↓
  PostToolUse Hook が発火
  (ここで後処理を自動実行できる)
       ↓
  Claude が応答を止める
       ↓
  Stop Hook が発火
  (ここで完了通知や後処理ができる)

セットアップ

.claude/settings.json(プロジェクト) または ~/.claude/settings.json(グローバル)に書きます。

{
  "hooks": {
    "PreToolUse": [...],
    "PostToolUse": [...],
    "Stop": [...]
  }
}

実践パターン集

1. npm / npx コマンドを自動承認

毎回許可するのが面倒なコマンドを自動承認:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/auto-approve-safe.sh"
          }
        ]
      }
    ]
  }
}
# ~/.claude/hooks/auto-approve-safe.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))")

# 安全なコマンドは自動承認
SAFE_PATTERNS=(
  "npm run test"
  "npm run lint"
  "npm run build"
  "npx prettier"
  "npx tsc"
  "git status"
  "git diff"
  "git log"
)

for pattern in "${SAFE_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -q "$pattern"; then
    echo '{"decision": "approve"}'
    exit 0
  fi
done

# rm -rf や本番 DB への書き込みは自動拒否
DANGEROUS_PATTERNS=(
  "rm -rf"
  "DROP TABLE"
  "DELETE FROM.*WHERE.*1=1"
  "git push --force"
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qi "$pattern"; then
    echo '{"decision": "block", "reason": "危険なコマンドをブロックしました: '"$pattern"'"}'
    exit 0
  fi
done

# それ以外は通常の確認フロー
exit 0

2. ファイル保存のたびに自動フォーマット

Claude がファイルを書き換えたら Prettier を自動実行:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/auto-format.sh"
          }
        ]
      }
    ]
  }
}
# ~/.claude/hooks/auto-format.sh
INPUT=$(cat)
FILE=$(echo "$INPUT" | python3 -c "
import json,sys
d = json.load(sys.stdin)
print(d.get('tool_input',{}).get('file_path',''))
")

if [ -z "$FILE" ]; then exit 0; fi

# TypeScript / JavaScript のみフォーマット
if echo "$FILE" | grep -qE '\.(ts|tsx|js|jsx)$'; then
  npx prettier --write "$FILE" 2>/dev/null
  echo "✨ フォーマット完了: $FILE"
fi

3. テスト失敗を自動検知してフィードバック

Claude がコードを書いたあとに自動でテストを実行:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/auto-test.sh"
          }
        ]
      }
    ]
  }
}
# ~/.claude/hooks/auto-test.sh
INPUT=$(cat)
FILE=$(echo "$INPUT" | python3 -c "
import json,sys
d = json.load(sys.stdin)
print(d.get('tool_input',{}).get('file_path',''))
")

# テストファイルが変更されたとき
if echo "$FILE" | grep -q "\.test\."; then
  RESULT=$(npm run test -- --testPathPattern="$(basename $FILE)" 2>&1 | tail -5)
  echo "$RESULT"
fi

4. 作業完了を Slack に自動通知

Claude が応答を止めたら Slack に通知:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/notify-done.sh"
          }
        ]
      }
    ]
  }
}
# ~/.claude/hooks/notify-done.sh
INPUT=$(cat)
MESSAGE=$(echo "$INPUT" | python3 -c "
import json,sys
d = json.load(sys.stdin)
# 最後のアシスタントメッセージを取得
msgs = d.get('messages',[])
for m in reversed(msgs):
    if m.get('role') == 'assistant':
        content = m.get('content','')
        if isinstance(content, list):
            for c in content:
                if c.get('type') == 'text':
                    print(c['text'][:100])
                    exit()
        else:
            print(str(content)[:100])
        exit()
")

WEBHOOK_URL=$(cat ~/.claude/slack-webhook)
curl -s -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d "{\"text\": \"✅ Claude 作業完了: $MESSAGE\"}" > /dev/null

5. git コミット前に自動チェック

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/pre-commit-check.sh"
          }
        ]
      }
    ]
  }
}
# ~/.claude/hooks/pre-commit-check.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))")

# git commit の直前にテストを自動実行
if echo "$COMMAND" | grep -q "^git commit"; then
  echo "🔍 コミット前にテストを実行中..."
  if ! npm run test 2>&1 | tail -3; then
    echo '{"decision": "block", "reason": "テストが失敗しています。修正してからコミットしてください。"}'
    exit 0
  fi
  echo "✅ テスト通過。コミットを続けます。"
fi

Before / After

Before(Hooks なし)

[作業中]
Claude: npm run test を実行しますか? → 手動で[許可]
Claude: ファイルを保存しました
(手動で prettier を実行)
Claude: テストが通りました
Claude: git commit を実行しますか? → 手動で[許可]
---
確認操作: 1 タスクあたり平均 5〜8 回

After(Hooks あり)

[作業中]
Claude: ✨ フォーマット完了(自動)
Claude: テスト実行中... ✅ 通過(自動)
Claude: コミット完了(自動承認)
---
確認操作: 0 回

Hooks の設定場所

ファイル スコープ 用途
~/.claude/settings.json 全プロジェクト共通 Slack通知・自動フォーマットなど
.claude/settings.json プロジェクト固有 テスト・ビルド・DB操作など
.claude/settings.local.json 個人設定(gitignore推奨) 個人の自動承認ルール

まとめ

Hook タイミング 主な用途
PreToolUse ツール実行直前 自動承認・自動拒否・安全チェック
PostToolUse ツール実行直後 フォーマット・テスト・ログ記録
Stop Claude が応答終了 Slack通知・集計・後処理

Hooks を使うと「Claude を監視して手動で確認する」から「Claude が自律的に安全に動く」に変わります。最初は PostToolUse で Prettier を自動実行するだけでも十分効果があります。


よくある質問(FAQ)

Q. Hooks のスクリプトが失敗したらどうなりますか?
A. スクリプトが exit 0 以外で終わった場合、Claude はエラーメッセージを受け取り対処します。{"decision": "block"} を返すとツール実行がキャンセルされます。

Q. Hook スクリプトはどんな言語でも書けますか?
A. はい。bash、Python、Node.js など何でも使えます。command フィールドに実行コマンドを書くだけです。

Q. グローバル設定とプロジェクト設定が競合したらどうなりますか?
A. 両方が実行されます。競合ではなく「追加」です。プロジェクト設定 → グローバル設定の順で実行されます。

Q. matcher に使えるパターンは何がありますか?
A. BashEditWriteReadWebSearchWebFetch など Claude Code の全ツール名が使えます。* ですべてのツールにマッチします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?