Claude Code に hooks という機能があることを知っていますか?
hooks を使えば、特定のイベントが発生したタイミングで自動的にスクリプトを実行することができます。テストの自動実行、フォーマッター呼び出し、エラー通知など、これまで手動でやっていた作業をゼロにできます。
この記事では hooks の仕組みから実際の設定例まで、開発者向けに徹底解説します。
Claude Code hooks とは?
hooks は .claude/hooks/ ディレクトリに配置したスクリプトで、イベントトリガー型の自動処理を定義できます。
イベントは30種類あり(SessionStart・Setup・UserPromptSubmit・PreToolUse・PostToolUse・PostToolUseFailure・Stop など)、代表的なものは以下です:
PreToolUse— ツール実行前PostToolUse— ツール実行後PostToolUseFailure— ツール実行失敗時SessionStart— セッション開始・再開時SessionEnd— セッション終了時Stop— Claude の応答完了時SubagentStart/SubagentStop— サブエージェント実行前後UserPromptSubmit— ユーザーがプロンプトを送信した時Notification— 通知イベント発生時
スクリプトは標準入力で JSON(コンテキスト情報)を受け取り、標準出力で JSON を返すことで Claude へのコンテキスト追加や処理のブロックが可能な仕組みです。設定は settings.json でイベント名とスクリプトのコマンドを紐づけるだけです。
実用的な hooks 設定例
例1:ファイル保存時に自動フォーマット
まず settings.json でイベントとスクリプトを紐づけます:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "node .claude/hooks/format.js" }]
}
]
}
}
次にスクリプト本体(ファイル名は任意。ここでは format.js としています):
// .claude/hooks/format.js
const { execSync } = require('child_process');
const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
const filePath = input.tool_input?.file_path || '';
let message = null;
try {
if (filePath.endsWith('.py')) {
execSync(`ruff format "${filePath}" && ruff check --fix "${filePath}"`);
message = `${filePath} を ruff でフォーマットしました。`;
} else if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
execSync(`npx prettier --write "${filePath}"`);
message = `${filePath} を prettier でフォーマットしました。`;
}
} catch (e) {
process.stderr.write(`フォーマット失敗: ${e.message}\n`);
process.exit(1);
}
if (message) {
process.stdout.write(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PostToolUse',
additionalContext: message
}
}));
}
例2:同じエラーが連続したら即エスカレーション
{
"hooks": {
"PostToolUseFailure": [
{
"matcher": ".*",
"hooks": [{ "type": "command", "command": "node .claude/hooks/error-tracker.js" }]
}
]
}
}
// .claude/hooks/error-tracker.js
const fs = require('fs');
const COUNTER_FILE = '/tmp/.claude_error_count';
let count = parseInt(fs.existsSync(COUNTER_FILE) ? fs.readFileSync(COUNTER_FILE, 'utf8') : '0') || 0;
count++;
fs.writeFileSync(COUNTER_FILE, String(count));
if (count >= 3) {
fs.writeFileSync(COUNTER_FILE, '0');
process.stdout.write(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PostToolUseFailure',
additionalContext: '同じエラーが3回連続しました。ソースコードを読んでから次の対策を立ててください。推測での試行錯誤を止めてください。'
}
}));
}
例3:セッション開始時に作業状況を自動ロード
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [{ "type": "command", "command": "node .claude/hooks/session-start.js" }]
}
]
}
}
// .claude/hooks/session-start.js
const fs = require('fs');
const currentWork = fs.existsSync('ai_wiki/current.md')
? fs.readFileSync('ai_wiki/current.md', 'utf8').slice(0, 500)
: '(作業記録なし)';
process.stdout.write(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'SessionStart',
additionalContext: `前回の作業状況:\n${currentWork}\n\n続きから始める場合は「続きから」と指示してください。`
}
}));
hooks の設定方法(5分で完了)
1. ディレクトリを作成
mkdir -p .claude/hooks
2. スクリプトファイルを作成(上記のサンプルをコピー。ファイル名は任意)
3. settings.json でイベントとスクリプトを紐づける
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "node .claude/hooks/your-script.js" }]
}
]
}
}
4. 動作確認
Claude Code で何かファイルを編集してみてください。PostToolUse イベントが発火します。
対応言語
| 言語 | 対応状況 |
|---|---|
| JavaScript / Node.js | ✅ 推奨 |
| Python | ✅ shebang で対応(#!/usr/bin/env python3) |
| Bash / Shell | ✅ shebang で対応 |
よくある質問
Q. hooks のデバッグはどうすればいい?
stderr に出力すると Claude Code のログに流れます。console.error('debug:', JSON.stringify(input)) で入力内容を確認できます。
Q. hook が失敗したら Claude の動作も止まる?
hook の終了コードによって動作が変わります。終了コード 0 は成功(JSON 出力を処理)、終了コード 2 はブロッキングエラー(PreToolUse ならツール呼び出しをブロック)、それ以外は非ブロッキングエラーで Claude Code は続行します。
Q. matcher とは何ですか?
どのツール名(Bash、Write、Edit 等)に対して hook を発火させるかを指定します。| で複数指定(例:"Write|Edit")、正規表現も使用可能です。".*" または省略で全ツールに適用されます。
Q. 複数のイベントに同じスクリプトを使えますか?
はい。settings.json の各イベントキーに同じコマンドを設定できます。
Q. hooks.enabled: true のような有効化フラグは必要ですか?
いいえ。そのような設定項目は存在しません。settings.json の hooks キーにイベントとコマンドを記述するだけで自動的に有効になります。
まとめ
Claude Code hooks は「特定のイベント発生時にスクリプトを自動実行する」仕組みです。設定は settings.json でイベント名(PreToolUse、PostToolUse などの PascalCase 形式)とコマンドを紐づけるだけです。
特に次の3つが即効性があります:
- フォーマッター自動化:
PostToolUseで書いた瞬間に整形 - エラー連続検出:
PostToolUseFailureでループを強制的に断ち切る - セッション引き継ぎ:
SessionStartで毎回前回の作業状況を自動ロード
まず PostToolUse から試してみてください。
コメント