오늘만 무료

CLAUDE.md 완전 정복 - Hooks 완전 가이드

이벤트 구동으로 AI 코딩을 자동화·강제화하는 7가지 패턴

by AI개발자
CLAUDE.md 완전 정복.png

Hooks란 무엇인가

Claude Code Hooks는 특정 이벤트가 발생했을 때 셸 커맨드를 자동으로 강제 실행하는 기능입니다.

CLAUDE.md에 작성하는 규칙이 "이렇게 해줬으면 한다"는 부탁이라면, Hooks는 "반드시 이렇게 된다"는 강제입니다.

CLAUDE.md가 "규칙"이라면 Hooks는 "가드레일"입니다. 규칙은 AI가 컨텍스트 상황에 따라 놓칠 가능성이 있지만, Hooks는 이벤트가 발생하는 한 반드시 실행됩니다.


CLAUDE.md 완전 정복002.png


설정 파일 위치

Hooks는 .claude/settings.json에 설정합니다. CLAUDE.md에 작성하는 것이 아닙니다.

{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "echo '파일 변경을 체크 중...'"
}
]
}
}

팀 공유가 필요한 Hook은 .claude/settings.json(프로젝트 설정)에, 개인용 Hook은 ~/.claude/settings.json(사용자 설정)에 작성합니다. 두 설정이 모두 있으면 양쪽 모두 실행됩니다.



Hook 이벤트 4종류

PreToolUse

툴(Edit, Write, Bash 등)이 실행되기 전에 발화합니다.

주 용도: 사전 검증, 위험 조작 차단

{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "/path/to/check-command.sh \"$TOOL_INPUT\""
}
]
}
}

PostToolUse

툴이 실행된 후에 발화합니다.

주 용도: 자동 포맷, 결과 검증, 로그 기록

{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
}

Notification

Claude Code가 사용자에게 알림을 보내는 타이밍에 발화합니다.

주 용도: Slack·카카오워크 알림, 사운드 재생

{
"hooks": {
"Notification": [
{
"matcher": "",
"command": "afplay /System/Library/Sounds/Glass.aiff"
}
]
}
}

Stop

Claude Code가 태스크를 완료하고 턴을 종료할 때 발화합니다.

주 용도: 완료 알림, 후처리 스크립트 실행



실용적인 Hook 패턴 7가지

패턴 1: 자동 포맷 (Prettier)

파일을 쓸 때마다 Prettier로 자동 정형합니다.

{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
}
}

이후로는 CLAUDE.md에 "Prettier 포맷에 따라"라고 명시할 필요가 없어집니다. Hook이 항상 강제 적용하기 때문입니다.


패턴 2: 프로덕션 DB 직접 접근 방지

프로덕션 DB에 대한 실수 접근을 강제로 차단합니다.

{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$TOOL_INPUT\" | grep -q 'DATABASE_URL.*production'; then echo 'BLOCKED: 프로덕션 DB에 대한 직접 접근은 금지되어 있습니다' >&2; exit 1; fi"
}
]
}
}

Hook이 exit 1을 반환하면 해당 툴 실행이 즉시 블록됩니다. CLAUDE.md에 "프로덕션 DB 직접 접근 금지"라고 적어도 AI가 실수할 수 있지만, Hook은 그런 실수 자체를 원천 차단합니다.


패턴 3: 테스트 자동 실행

TypeScript 소스 파일을 변경하면 대응하는 테스트를 자동 실행합니다.

{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'FILE=\"$TOOL_INPUT_FILE_PATH\"; if [[ \"$FILE\" == *.ts ]] && [[ \"$FILE\" != *.test.ts ]]; then TEST=\"${FILE%.ts}.test.ts\"; if [ -f \"$TEST\" ]; then npx vitest run \"$TEST\" --reporter=dot 2>&1 | tail -5; fi; fi'"
}
]
}
}

패턴 4: 커밋 메시지 형식 강제

Conventional Commits 형식이 아닌 커밋 메시지를 차단합니다.

{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "bash -c 'if echo \"$TOOL_INPUT\" | grep -q \"git commit\"; then MSG=$(echo \"$TOOL_INPUT\" | grep -oP \"(?<=-m \\\").*?(?=\\\")\"); if [ -n \"$MSG\" ] && ! echo \"$MSG\" | grep -qE \"^(feat|fix|refactor|docs|test|chore):\"; then echo \"BLOCKED: 커밋 메시지는 Conventional Commits 형식으로 작성해 주세요\" >&2; exit 1; fi; fi'"
}
]
}
}

패턴 5: 완료 사운드 (macOS)

태스크가 완료되면 사운드로 알려줍니다.

{
"hooks": {
"Stop": [
{
"matcher": "",
"command": "afplay /System/Library/Sounds/Glass.aiff"
}
]
}
}

패턴 6: Slack·카카오워크 완료 알림

장시간 작업 완료 시 메신저로 알림을 받습니다. 국내 팀 환경에서는 카카오워크 Incoming Webhook도 병행 설정할 수 있습니다.

{
"hooks": {
"Stop": [
{
"matcher": "",
"command": "bash -c 'curl -s -X POST \"$SLACK_WEBHOOK_URL\" -H \"Content-Type: application/json\" -d \"{\\\"text\\\": \\\"✅ Claude Code 작업 완료: $(pwd | xargs basename)\\\"}\" || true'"
}
]
}
}

패턴 7: 민감 파일 보호

.env.production, config/secrets/ 등 절대 수정해서는 안 되는 파일의 편집을 차단합니다.

{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "bash -c 'FILE=\"$TOOL_INPUT_FILE_PATH\"; PROTECTED_PATTERNS=(\".env.production\" \".env.staging\" \"config/secrets\" \"terraform/\" \"k8s/production\"); for pattern in \"${PROTECTED_PATTERNS[@]}\"; do if [[ \"$FILE\" == *\"$pattern\"* ]]; then echo \"BLOCKED: $FILE 은 보호된 파일입니다. 편집하려면 인프라 팀에 문의하세요\" >&2; exit 1; fi; done'"
}
]
}
}



CLAUDE.md vs Hooks - 무엇을 어디에 쓸까

CLAUDE.md 완전 정복003.png


판단 기준:

규칙·방침·배경 설명 → CLAUDE.md

자동 실행·강제·차단 → Hooks

이유가 필요한 강제 → CLAUDE.md에 이유를 쓰고, Hooks로 실행



Hook 스크립트 파일 분리 관리

커맨드가 길어지면 외부 셸 스크립트 파일로 분리하는 것이 좋습니다. 가독성이 높아지고, 스크립트 단독 테스트도 가능해집니다.

.claude/
├── settings.json
└── hooks/
├── pre-bash-guard.sh # 위험 커맨드 차단
├── post-write-format.sh # 자동 포맷
├── pre-file-protect.sh # 민감 파일 보호
└── notify-completion.sh # 완료 알림
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": ".claude/hooks/pre-bash-guard.sh"
},
{
"matcher": "Write|Edit",
"command": ".claude/hooks/pre-file-protect.sh"
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": ".claude/hooks/post-write-format.sh \"$TOOL_INPUT_FILE_PATH\""
}
],
"Stop": [
{
"matcher": "",
"command": ".claude/hooks/notify-completion.sh"
}
]
}
}

스크립트 파일은 반드시 실행 권한을 부여합니다:

chmod +x .claude/hooks/*.sh


Hook 작성 시 주의 사항

exit 코드를 올바르게 반환한다

exit 0: 정상 → 툴 실행을 계속한다

exit 1: 이상 → PreToolUse의 경우 툴 실행을 차단한다


PostToolUse에서 exit 1을 반환해도 이미 실행된 툴은 되돌릴 수 없습니다. 차단이 목적이라면 반드시 PreToolUse를 사용하세요.


치명적이지 않은 에러는 억제한다

포맷 실패 등 치명적이지 않은 오류는 || true로 억제합니다. Hook 실패로 Claude Code의 정상 작업이 중단되지 않도록 합니다.

# ✅ 실패해도 계속 진행
npx prettier --write "$FILE" 2>/dev/null || true

# ❌ 실패 시 의도치 않게 중단
npx prettier --write "$FILE"

무거운 처리를 PostToolUse에 집어넣지 않는다

매번 파일 편집 시 무거운 처리가 실행되면 Claude Code의 응답이 느려집니다. 전체 빌드·전체 테스트 실행 같은 무거운 작업은 워크플로우(5장)로 정의하고, Hook에는 빠르게 끝나는 검사만 넣으세요.



©2024-2026 MDRules dev., Hand-crafted & made with Jaewoo Kim.

이메일문의: jaewoo@mdrules.dev


AI강의/개발/기술자문, AI 업무 자동화 컨설팅 문의: https://talk.naver.com/ct/w5umt5


AI 업무 자동화/에이전트/워크플로우설계 컨설팅/AI교육: https://mdrules.dev


이 작가의 멤버십 구독자 전용 콘텐츠입니다.
작가의 명시적 동의 없이 저작물을 공유, 게재 시 법적 제재를 받을 수 있습니다.

brunch membership
AI개발자작가님의 멤버십을 시작해 보세요!

AI Workflow Architect, LLM Engineer, Vibe Engineering, Claude Code, AI 업무 자동화 컨설팅/AI강의

86 구독자

오직 멤버십 구독자만 볼 수 있는,
이 작가의 특별 연재 콘텐츠

  • 최근 30일간 43개의 멤버십 콘텐츠 발행
  • 총 63개의 혜택 콘텐츠
최신 발행글 더보기
이전 05화CLAUDE.md 완전 정복 - 워크플로우 자동화