この記事で紹介する 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. Bash、Edit、Write、Read、WebSearch、WebFetch など Claude Code の全ツール名が使えます。* ですべてのツールにマッチします。