Hooks로 동작 자동화하기
기준일: 2026-07-26
공식 기준: Automate actions with hooks
개요
Hooks는 Claude Code 라이프사이클 특정 시점에 실행되는 사용자 정의 셸 명령(및 prompt/agent/HTTP 훅)입니다. LLM이 선택할 때까지 기다리지 않고, 포맷·알림·검증·감사처럼 항상 일어나야 하는 동작을 결정적으로 보장합니다.
판단이 필요하면 prompt-based 또는 agent-based hooks를 사용합니다. 다른 확장: skills, subagents, plugins.
이벤트 스키마·JSON I/O·async·MCP tool hooks: Hooks reference.
핵심 개념
| 항목 | 내용 |
|---|---|
| 정의 | settings "hooks" 키 (플러그인은 hooks/hooks.json) |
| matcher | 도구명 필터. Edit|Write, v2.1.191+ Edit,Write |
| exit 2 | 많은 PreToolUse 시나리오에서 차단 |
| 검증 | /hooks (읽기 전용 메뉴), claude --debug hooks |
상세
첫 훅: Notification
~/.claude/settings.json:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
기존 hooks가 있으면 이벤트 키를 형제 추가. Claude에게 훅 작성을 요청해도 됩니다. /hooks → Notification 확인. 권한 필요한 작업 후 터미널을 떠나 알림 테스트.
Linux: notify-send 'Claude Code' '...'
Windows PowerShell: MessageBox 로드 명령 (원문 Windows 탭).
macOS에서 알림 없으면 Script Editor 알림 권한: 한 번 osascript -e 'display notification "test"' 후 System Settings → Notifications → Script Editor 허용.
빈 matcher는 모든 알림. 특정만:
| Matcher | 시점 |
|---|---|
permission_prompt |
도구 승인 필요 |
idle_prompt |
다음 프롬프트 대기 |
auth_success |
인증 완료 |
elicitation_* |
MCP elicitation |
agent_needs_input / agent_completed |
agent view 배경 세션 (v2.1.198+) |
편집 후 자동 포맷
프로젝트 .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
jq 필요 (brew/apt). v2.1.191+ matcher Edit,Write 가능.
보호 파일 편집 차단
.claude/hooks/protect-files.sh:
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
exit 2
fi
done
exit 0
chmod +x .claude/hooks/protect-files.sh
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
차단 사유가 Claude에 피드백되어 접근을 바꿉니다. 보안 경계는 CLAUDE.md가 아니라 hooks/permissions.
Compaction 후 컨텍스트 재주입
SessionStart + matcher compact — 명령 stdout이 컨텍스트에 추가됩니다. 프로젝트 규칙 리마인더 예:
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use Bun, not npm. Run bun test before committing.'"
}
]
}
]
}
}
그 외 공식 가이드 사례 (요지)
- 설정 변경 감사 — settings 관련 도구 후 로그 append
- 디렉터리/파일 변경 시 env 리로드 — cwd·env 파일 변경 감지
- 권한 프롬프트 자동 승인 — PermissionRequest 계열에서 안전한 패턴만 (matcher 좁히기)
원문 각 절의 완성 JSON을 프로젝트에 맞게 복사하세요.
동작 방식
이벤트 → matcher → 훅 실행 → stdout JSON/exit code. 다중 훅 결과 결합 규칙은 Combine results. stdin JSON 필드 스키마는 레퍼런스.
Prompt-based hooks
type: "prompt" — 셸 대신 모델(기본 Haiku, model 필드로 변경)이 yes/no JSON (ok true/false).
- Stop/SubagentStop:
ok:false의 reason이 Claude에 피드백되어 작업 계속 - PreToolUse: 도구 deny; 기본은 턴 종료,
continueOnBlock: true면 reason을 Claude에 반환
Agent-based hooks
격리 에이전트 컨텍스트에서 더 무거운 검증.
HTTP hooks
외부 URL로 이벤트 POST — 중앙 감사·티켓.
제한·트러블슈팅
안 뜸
/hooks이벤트·등록 확인- matcher 대소문자·도구명 정확 일치
- PreToolUse vs PostToolUse 시점
-pnon-interactive에서 PermissionRequest 대신 PreToolUse
Hook error
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh
echo $?
- command not found → 절대 경로/
CLAUDE_PROJECT_DIR, 또는"args": []exec form - jq missing → 설치 또는 Python/Node 파싱
- 실행 권한
chmod +x
/hooks 비어 있음
- 수 초 후 미반영 시 세션 재시작
"hooks"키 위치, JSON 유효성, managed strip
Stop hook block cap — 과도한 차단 시 cap. 로직 수정.
JSON validation failed — 스키마 대조. shell 프로필 의존성.
권한 모드 — 훅 deny는 모드와 독립적으로 강제 가능.
디버그: claude --debug hooks.
체크리스트
- settings에 이벤트·matcher·command를 넣었다
-
/hooks에 보인다 - 보호 파일은 exit 2 PreToolUse로 검증했다
- 실패 시 수동 stdin 파이프·debug 로그를 확인했다
다음 단계
기준일
- 문서 작성·동기화 기준일: 2026-07-26
- 원문: https://code.claude.com/docs/en/hooks-guide