클로드 코드(Claude Code)를 사용하다 보면 "매번 같은 명령을 반복하라고 요청하는 게 번거롭다", "AI가 실수로 중요한 파일을 수정하면 어쩌지?"라는 생각이 들 때가 있습니다. 이런 고민을 한 방에 해결해 주는 기능이 바로 후크(Hooks) 입니다.
이번 글에서는 클로드 코드의 후크 기능이 무엇인지, 어떻게 작동하는지, 그리고 실제로 어떤 식으로 활용할 수 있는지를 공식 문서를 기반으로 쉬운 예제와 함께 자세히 설명해 드리겠습니다.
1. 후크(Hooks)란 무엇인가요?
후크는 클로드 코드의 특정 시점에 자동으로 실행되는 사용자 정의 셸 명령, HTTP 엔드포인트, 또는 LLM 프롬프트입니다. 쉽게 말해, "클로드가 ~을 하기 전에 / ~을 한 후에 무조건 ~을 실행해라" 라는 규칙을 미리 설정해 두는 기능이라고 이해하시면 됩니다.
깃(Git)을 사용해 보신 분이라면 pre-commit이나 post-commit 훅을 떠올리시면 됩니다. 깃 훅이 커밋 전후에 자동으로 린터나 테스트를 실행하는 것처럼, 클로드 코드 훅은 AI가 작업하는 과정의 특정 시점에 자동으로 원하는 명령을 실행해 줍니다.
후크와 일반 프롬프트의 차이점
CLAUDE.md 파일에 "코드 수정 후에는 항상 prettier를 실행해줘"라고 적어두는 것과 후크를 설정하는 것에는 결정적인 차이가 있습니다.
- 프롬프트(지시문): AI에게 주는 "권장사항"입니다. 대화가 길어지면 컨텍스트 윈도우에서 밀려나거나 우선순위가 떨어져 무시될 수 있습니다.
- 후크: "강제 규칙"입니다. 해당 이벤트가 발생하면 100% 확정적으로 실행됩니다.
즉, 후크는 LLM의 판단에 의존하지 않고 결정론적(deterministic) 으로 동작한다는 점이 가장 큰 강점입니다.
📚 공식 문서 링크: Automate workflows with hooks
2. 후크의 생명주기(Lifecycle) - 언제 실행되나요?
후크는 클로드 코드의 동작 흐름 중 정해진 시점에 발화됩니다. 공식 문서에 따르면 후크 이벤트는 발화 빈도에 따라 크게 세 가지로 나뉩니다.
- 세션당 한 번 발생:
SessionStart,SessionEnd - 턴(turn)당 한 번 발생:
UserPromptSubmit,Stop,StopFailure - 에이전트 루프 안에서 도구 호출마다 발생:
PreToolUse,PostToolUse
대표적인 후크 이벤트들을 표로 정리하면 다음과 같습니다.
| 이벤트 이름 | 발화 시점 |
|---|---|
SessionStart |
세션을 새로 시작하거나 재개할 때 |
UserPromptSubmit |
사용자가 프롬프트를 제출했을 때(클로드가 처리하기 전) |
PreToolUse |
도구(파일 수정, 셸 실행 등)를 사용하기 직전. 차단 가능 |
PostToolUse |
도구가 성공적으로 실행된 직후 |
PostToolUseFailure |
도구 실행이 실패했을 때 |
Notification |
클로드가 알림을 보낼 때(권한 요청, 유휴 상태 등) |
Stop |
클로드가 응답을 마쳤을 때 |
PreCompact / PostCompact |
컨텍스트 압축 전/후 |
SessionEnd |
세션이 종료될 때 |
이 중에서 가장 많이 사용하는 것은 PreToolUse(도구 사용 전 차단)와 PostToolUse(도구 사용 후 후처리)입니다.
📚 전체 이벤트 목록: Hooks reference - Hook events
3. 후크 설정 파일은 어디에 두나요?
후크는 JSON 형식의 설정 파일에 정의합니다. 어디에 두느냐에 따라 적용 범위가 달라집니다.
| 위치 | 적용 범위 | 공유 가능 여부 |
|---|---|---|
~/.claude/settings.json |
모든 프로젝트 | ❌ (내 컴퓨터에만 적용) |
.claude/settings.json |
현재 프로젝트 | ✅ (Git 저장소에 커밋 가능) |
.claude/settings.local.json |
현재 프로젝트 | ❌ (gitignore 처리됨) |
팀원들과 동일한 후크 규칙을 공유하고 싶다면 프로젝트 폴더의 .claude/settings.json에 두고 Git에 커밋하시면 됩니다.
4. 후크 설정의 기본 구조
후크 설정은 세 단계로 중첩된 JSON 구조를 가집니다.
{
"hooks": {
"이벤트이름": [
{
"matcher": "필터조건",
"hooks": [
{
"type": "command",
"command": "실행할 명령"
}
]
}
]
}
}
이를 풀어서 설명하면:
- 이벤트 이름:
PreToolUse,PostToolUse같은 어떤 시점에 실행할지 지정 - matcher: 어떤 도구나 상황일 때만 실행할지 필터링 (예:
"Bash","Edit|Write") - hooks 배열: 실제로 실행할 명령(셸 명령, HTTP 요청 등)
5. 가장 쉬운 첫 번째 예제: 알림 후크 만들기
공식 문서의 첫 번째 튜토리얼을 따라가 보겠습니다. 클로드가 사용자 입력을 기다릴 때 데스크톱 알림을 받는 후크입니다.
macOS 사용자
~/.claude/settings.json 파일을 열고 아래 내용을 추가합니다.
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Linux 사용자
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
}
]
}
]
}
}
Windows(PowerShell) 사용자
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
]
}
}
동작 확인 방법
- 클로드 코드 안에서
/hooks명령을 입력하면 등록된 모든 후크를 확인할 수 있습니다. - 클로드에게 권한 승인이 필요한 작업을 시키고 다른 창으로 전환해 봅니다.
- 데스크톱 알림이 뜨면 성공입니다.
Notification 이벤트는 클로드가 권한을 요청할 때뿐만 아니라, 응답이 끝나 사용자 입력을 기다리는 유휴(idle) 상태일 때도 발화됩니다. 따라서 다른 작업을 하다가도 클로드가 자신을 필요로 하는 시점을 즉시 알 수 있습니다.
💡 macOS 팁: 알림이 뜨지 않는다면,
osascript가 Script Editor 앱을 통해 알림을 발송하는데 권한이 없는 경우입니다. 터미널에서osascript -e 'display notification "test"'를 한 번 실행한 뒤, 시스템 설정 > 알림에서 Script Editor를 찾아 알림을 허용해 주세요.
6. 실전 예제 1: 코드 수정 후 자동 포맷팅
가장 유용하게 쓰이는 후크 중 하나입니다. 클로드가 파일을 수정할 때마다 자동으로 Prettier를 실행해 코드 스타일을 맞춰주는 후크입니다.
프로젝트 루트의 .claude/settings.json에 다음을 추가합니다.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
코드 풀이
PostToolUse: 도구 실행이 끝난 직후에 발화되는 이벤트입니다."matcher": "Edit|Write": 파일 편집 도구(Edit)나 파일 쓰기 도구(Write)가 사용되었을 때만 실행됩니다.Bash,Read같은 다른 도구에는 반응하지 않습니다.jq -r '.tool_input.file_path': 후크에 stdin으로 들어온 JSON 데이터에서file_path값을 추출합니다.xargs npx prettier --write: 추출한 파일 경로를 Prettier에 넘겨 포맷팅을 적용합니다.
💡 사전 준비: 이번 글의 여러 예제에서
jq라는 JSON 파싱 도구를 사용합니다. macOS에서는brew install jq, Debian/Ubuntu에서는apt-get install jq명령으로 설치할 수 있습니다. 설치하지 않은 경우 Python이나 Node.js로 JSON을 파싱하셔도 됩니다.
7. 실전 예제 2: 보호된 파일 수정 차단하기
.env 파일이나 package-lock.json 같은 민감한 파일을 클로드가 실수로 수정하지 못하도록 막는 후크입니다.
1단계: 후크 스크립트 생성
.claude/hooks/protect-files.sh 파일을 만듭니다.
#!/bin/bash
# protect-files.sh
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
2단계: 스크립트에 실행 권한 부여 (macOS / Linux)
chmod +x .claude/hooks/protect-files.sh
3단계: 후크 등록
.claude/settings.json에 아래 내용을 추가합니다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
코드 풀이
PreToolUse: 도구가 실행되기 전에 발화되어 작업을 차단할 수 있습니다.exit 2: 종료 코드 2는 "차단(blocking error)"을 의미합니다. 클로드 코드는stderr로 출력된 메시지를 클로드에게 피드백으로 전달하고, 실제 도구 실행은 막아버립니다.$CLAUDE_PROJECT_DIR: 프로젝트 루트 경로를 가리키는 환경 변수입니다. 작업 디렉터리와 무관하게 항상 같은 경로를 참조할 수 있습니다.
8. 종료 코드(Exit Code)의 의미
후크 스크립트는 셸의 종료 코드를 통해 클로드 코드와 소통합니다. 가장 중요한 두 가지 코드를 기억해 두세요.
| 종료 코드 | 의미 |
|---|---|
| 0 | 성공. 작업이 정상 진행됩니다. |
| 2 | 차단 에러. 작업이 막히고 stderr 내용이 클로드에게 피드백으로 전달됩니다. |
| 그 외 | 대부분의 경우 차단되지 않는 에러. 작업은 진행되지만 디버그 로그에 기록됩니다. |
특히 주의할 점은, 일반적인 유닉스 관습과 달리 종료 코드 1은 차단되지 않는다는 점입니다. 정책을 강제하고 싶다면 반드시 exit 2를 사용해야 합니다.
단, 종료 코드 2의 효과는 이벤트마다 다릅니다. 대표적으로:
PreToolUse: 도구 호출을 차단합니다.UserPromptSubmit: 프롬프트 처리를 차단하고 프롬프트를 지웁니다.Stop: 클로드가 멈추지 못하게 막고 대화를 계속하게 합니다.PostToolUse: 차단할 수 없습니다(이미 도구가 실행됨).stderr만 클로드에게 전달됩니다.
📚 이벤트별 상세 동작: Exit code 2 behavior per event
9. 후크에 전달되는 입력 데이터(JSON)
후크 스크립트는 stdin을 통해 JSON 형식의 데이터를 받습니다. 예를 들어, PreToolUse 이벤트에서 클로드가 npm test를 실행하려 할 때 다음과 같은 JSON이 전달됩니다.
{
"session_id": "abc123",
"transcript_path": "/home/user/.claude/projects/.../transcript.jsonl",
"cwd": "/home/user/my-project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
}
}
이 데이터를 jq나 Python, Node.js 등으로 파싱해서 원하는 로직을 구현하시면 됩니다.
모든 이벤트에 공통으로 전달되는 필드
session_id: 현재 세션의 고유 식별자transcript_path: 대화 기록 JSON 파일 경로cwd: 후크가 호출된 시점의 작업 디렉터리hook_event_name: 발화된 이벤트 이름
도구 관련 이벤트에는 추가로 tool_name(도구 이름)과 tool_input(도구 인자)이 전달됩니다.
10. 후크 종류 5가지
클로드 코드는 5가지 후크 핸들러 타입을 지원합니다.
- Command 후크 (
type: "command"): 셸 명령을 실행합니다. 가장 빠르고 유연합니다. - HTTP 후크 (
type: "http"): JSON 데이터를 지정된 URL로 POST 요청을 보냅니다. 외부 서비스 연동에 유용합니다. - MCP Tool 후크 (
type: "mcp_tool"): 이미 연결된 MCP 서버의 도구를 호출합니다. - Prompt 후크 (
type: "prompt"): 클로드 모델(기본은 Haiku)에 프롬프트를 보내 단일 턴 평가를 받습니다. 모델은{"ok": true/false}형태로 yes/no 결정을 반환합니다. - Agent 후크 (
type: "agent"): 도구를 사용할 수 있는 서브에이전트를 띄워 조건을 검증합니다. (실험적 기능)
대부분의 경우 Command 후크 하나만 알아도 충분합니다.
11. 실전 예제 3: 위험한 명령(rm -rf) 차단하기
공식 문서에서 소개하는 가장 대표적인 예제입니다. rm -rf 같은 파괴적인 셸 명령을 차단합니다.
후크 설정
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm *)",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-rm.sh"
}
]
}
]
}
}
후크 스크립트 (.claude/hooks/block-rm.sh)
#!/bin/bash
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive command blocked by hook"
}
}'
else
exit 0
fi
동작 흐름
- 클로드가
Bash도구로 명령을 실행하려 할 때PreToolUse이벤트가 발화됩니다. matcher: "Bash"가 일치하므로 이 후크 그룹이 활성화됩니다.if: "Bash(rm *)"조건이 추가로 평가되어,rm으로 시작하는 명령에만 스크립트가 실행됩니다.- 스크립트가 실제 명령을 검사해
rm -rf가 포함되어 있으면 JSON으로 거부 결정을 출력합니다. npm test같은 안전한 명령이었다면if조건에서 걸러져 스크립트 자체가 실행되지 않으므로 성능 오버헤드도 없습니다.
이 예제는 후크의 두 가지 핵심 패턴을 동시에 보여줍니다.
- 종료 코드만 사용하는 단순한 차단 방식 (앞선 보호 파일 예제)
- JSON 출력으로 더 정교하게 결정 제어 (이번 예제의
permissionDecision)
12. 후크는 어떻게 디버깅하나요?
방법 1: /hooks 메뉴 활용
클로드 코드 세션 안에서 /hooks를 입력하면 현재 등록된 모든 후크를 이벤트별로 확인할 수 있습니다. 어떤 설정 파일에서 왔는지(User, Project, Local, Plugin 등)도 표시되어 매우 편리합니다.
방법 2: 수동 테스트
JSON 입력을 직접 만들어 후크 스크립트에 넘겨보면 클로드 코드를 거치지 않고도 동작을 확인할 수 있습니다.
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh
echo $? # 종료 코드 확인
방법 3: 디버그 로그
클로드 코드를 실행할 때 --debug-file 옵션을 사용하면 모든 후크 실행 내역이 기록됩니다.
claude --debug-file /tmp/claude.log
다른 터미널에서 다음 명령으로 실시간 모니터링이 가능합니다.
tail -f /tmp/claude.log
이미 세션이 시작된 상태라면 /debug 명령으로 도중에 디버그 로그를 켤 수도 있습니다.
13. 자주 겪는 문제와 해결법
공식 문서에서 안내하는 대표적인 트러블슈팅 케이스입니다.
"Stop 후크가 무한 루프에 빠져요"
Stop 이벤트로 클로드를 계속 작업시키는 후크를 만들 때, 종료 조건을 두지 않으면 영원히 멈추지 않습니다. 입력 JSON의 stop_hook_active 필드를 확인해서 일찍 종료하도록 만들어야 합니다.
#!/bin/bash
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0
fi
# 이후 후크 로직
"JSON 파싱 에러가 나요"
클로드 코드가 후크를 실행할 때 셸 프로필(~/.zshrc, ~/.bashrc)을 함께 로드합니다. 만약 프로필에 무조건 실행되는 echo 문이 있다면 그 출력이 후크 JSON 앞에 붙어버려 파싱이 실패합니다. 다음과 같이 인터랙티브 셸에서만 실행되도록 감싸주세요.
if [[ $- == *i* ]]; then
echo "Shell ready"
fi
"후크가 아예 실행되지 않아요"
/hooks로 후크가 올바르게 등록되어 있는지 확인하세요.- matcher 패턴이 도구 이름과 정확히 일치하는지 확인하세요. 매처는 대소문자를 구분합니다.
- 스크립트 파일에 실행 권한(
chmod +x)이 있는지 확인하세요.
📚 더 많은 트러블슈팅: Limitations and troubleshooting
14. 후크 사용 시 보안 주의사항
후크는 사용자의 시스템 권한 전체로 실행됩니다. 따라서 다음 사항을 꼭 지켜주세요.
- 신뢰할 수 없는 출처의 후크 설정을 그대로 가져다 쓰지 마세요.
- 후크 명령을 추가하기 전에 반드시 코드를 직접 검토하세요.
- 외부 입력 값을 그대로 셸 명령에 넘기는 일은 피하세요(쉘 인젝션 위험).
.env, 비밀 키 같은 민감 파일에 후크가 접근하지 않도록 주의하세요.
특히 후크 설정은 .claude/settings.json을 통해 Git 저장소에 공유될 수 있으므로, 팀에서 공유되는 후크는 코드 리뷰를 거치는 것이 안전합니다.
15. 후크 활용 아이디어 모음
공식 문서와 가이드에서 소개하는 활용 사례입니다.
- 자동 포맷팅: 파일 수정 후 Prettier, Black, Ruff 등 자동 실행
- 자동 린팅: 코드 작성 후 ESLint, Pylint 등으로 검사
- 자동 테스트: 변경된 파일에 대한 단위 테스트 자동 실행
- 민감 파일 보호:
.env,secrets/등 수정 차단 - 위험 명령 차단:
rm -rf,DROP TABLE등 차단 - Git 브랜치 보호:
main,master브랜치 직접 푸시 차단 - 세션 시작 시 컨텍스트 주입: 현재 브랜치, 진행 중인 이슈 등 자동 입력
- 알림: Slack, 데스크톱 알림으로 작업 완료 통보
- 감사 로그: 모든 도구 사용 내역을 파일에 기록
- 컨텍스트 압축 후 재주입: 압축으로 손실된 중요 정보 복구
16. 마무리
후크는 클로드 코드를 단순한 AI 도우미에서 신뢰할 수 있는 자동화된 개발 파트너로 진화시키는 핵심 기능입니다. 처음에는 설정이 복잡해 보일 수 있지만, 이 글에서 소개한 알림 후크나 자동 포맷팅 후크처럼 작은 것부터 시작해서 조금씩 늘려가시면 됩니다.
처음 시도해 볼 만한 후크 추천 순서는 다음과 같습니다.
- 데스크톱 알림 후크 (Notification): 가장 간단하고 즉시 효과를 체감할 수 있습니다.
- 자동 포맷팅 후크 (PostToolUse + Edit/Write): 코드 품질을 자동으로 유지할 수 있습니다.
- 민감 파일 보호 후크 (PreToolUse): 실수를 원천 차단해 안심하고 클로드를 사용할 수 있습니다.
후크의 진정한 가치는 단순히 작업을 자동화하는 것을 넘어, AI에게 더 많은 자율성을 안전하게 부여할 수 있게 해준다는 점에 있습니다. 자동 검증 레이어가 있으면 클로드를 더 적극적으로 활용해도 불안하지 않으니까요.
더 깊이 공부하고 싶다면
- Claude Code 공식 문서 - Hooks 빠른 시작 가이드
- Claude Code 공식 문서 - Hooks 레퍼런스
- Anthropic 공식 GitHub - Bash 명령 검증 후크 예제
여러분의 클로드 코드 워크플로우가 더 안전하고 효율적이 되기를 바랍니다.