hooks-settings-json

Claude Code Hooks 완벽 가이드 – 자동화 훅 설정법

claude code hooks 한 줄 요약

Claude Code Hooks는 세션이나 도구 호출 사이에 스크립트를 끼워 넣는 자동화 규칙이에요. 2026년 4월 15일 기준 공식 Hooks 레퍼런스는 이벤트를 26개로 적고 있고, 훅 타입은 command, http, prompt, agent 네 가지로 나뉘어요. 매번 꼭 지켜야 하는 포맷팅, 위험 명령 차단, 작업 종료 알림은 Hooks에 넣고, 보통 지키면 좋은 코딩 스타일은 CLAUDE.md에 두면 됩니다.

훅 처음 켰다가 터미널이 안 멈춰서 식은땀 난 적 있죠. Claude Code Hooks는 잘만 잡으면 포맷팅, 위험 명령 차단, 알림, 세션 시작 준비 작업을 자동으로 붙여주는데요. 반대로 한 줄 잘못 넣으면 Stop 훅이 자기 자신을 다시 깨우거나, 성공한 훅이 계속 hook error로 찍혀서 세션 흐름이 꼬이기도 해요. 여기서 많이들 시간을 써요.

이번 글은 2026년 4월 15일 기준 공식 문서, 공식 가격 페이지, 최근 GitHub 이슈, 보안 리서치를 다시 맞춰서 정리한 초안이에요. 특히 예전 글 몇 개는 훅 이벤트를 19개로 적어두는데, 지금 공식 레퍼런스는 26개로 잡고 있거든요. 이 차이부터 바로잡아야 헷갈림이 줄어요. 아래에서는 claude code hooks를 어디에 써야 하는지, settings.json을 어떻게 나눠야 하는지, 바로 붙여 넣을 수 있는 레시피 3개, 그리고 stop hook 무한 루프hook error 대응까지 실무 기준으로 묶어둘게요. Claude Code 자체가 아직 낯설면 Claude Code 사용법: 설치부터 첫 실행까지 5분 가이드부터 먼저 보고 와도 좋아요.

Hook과 CLAUDE.md는 언제 갈라지나

무조건 실행돼야 하는 규칙은 Hooks에 넣고, 보통 지키면 좋은 규칙은 CLAUDE.md에 두면 돼요. 둘을 섞어 써야 세션이 덜 삐걱거리거든요. 근데 CLAUDE.md에만 적어두면 안 되냐고요?

CLAUDE.md는 말 그대로 지침에 가까워요. “포맷터 돌려줘”, “테스트 먼저 봐줘”, “이 파일은 건드리지 마” 같은 문장을 적어둘 수는 있죠. 문제는 그게 항상 강제되진 않는다는 점이에요. 세션이 길어지거나 우선순위가 바뀌면 Claude가 놓칠 때가 있어요. 직접 써보면 여기서 차이가 꽤 나더라고요.

Hooks는 반대예요. 특정 이벤트가 오면 정해둔 동작을 항상 실행해요. PreToolUse에서 위험한 Bash 명령을 막고, PostToolUse에서 포맷터를 돌리고, Stop에서 알림을 띄우는 식이죠. 그래서 팀 규칙, 보안 규칙, 자동 후처리처럼 “빠지면 사고 나는 것”은 Hooks 쪽이 맞아요.

이 기준만 잡아도 세팅 절반은 끝나요. 서브에이전트까지 엮어서 판단형 검증을 하고 싶다면 AI 에이전트 만들기: 도구 호출부터 워크플로우까지 실전 가이드도 같이 보면 연결이 빨라요.

항목 Hooks CLAUDE.md
성격 결정론적 자동 실행 권고성 지침
실패 시 영향 툴 호출 차단, 후처리 누락 방지 Claude가 놓칠 수 있음
형식 JSON 설정 + 스크립트 마크다운 문서
잘 맞는 일 포맷터, 차단, 알림, 감사 로그 코딩 스타일, 네이밍, 리뷰 습관
디버깅 포인트 exit code, stderr, transcript 프롬프트 맥락

체크리스트로 보면 더 쉬워요.

  • 매번 꼭 돌아야 한다: Hooks
  • 빠지면 보안 사고 난다: Hooks
  • 팀 스타일 가이드다: CLAUDE.md
  • 사람이 읽고 판단하면 된다: CLAUDE.md

Claude Code Hooks 이벤트와 설정 구조

이벤트 이름이 많아 보여도 실전에서 자주 만지는 건 몇 개 안 돼요. 설정 위치, 이벤트 묶음, 종료 코드만 먼저 잡아두면 훅이 갑자기 쉬워집니다. 이벤트가 많으면 다 외워야 하냐고요?

그럴 필요는 없어요. 실무에서 많이 쓰는 축은 대략 다섯 묶음이면 충분합니다. 2026년 4월 15일 기준 공식 Hooks 레퍼런스는 이벤트를 26개로 적고 있는데, 예전 요약 글에서 보이는 19개 숫자는 지금 기준으로는 낡은 정보예요.

묶음 대표 이벤트 언제 주로 쓰나
세션 SessionStart, SessionEnd, PreCompact, PostCompact 의존성 준비, 로그 정리, 컨텍스트 재주입
UserPromptSubmit, Stop, StopFailure 입력 검사, 완료 판단, 실패 후처리
도구 PreToolUse, PostToolUse, PostToolUseFailure 차단, 포맷팅, 실패 메시지 보강
권한/알림 PermissionRequest, PermissionDenied, Notification 자동 승인, 보안 경고, 입력 대기 알림
파일/설정/MCP ConfigChange, CwdChanged, FileChanged, Elicitation, ElicitationResult 디렉터리 이동, 파일 감시, 외부 도구 입력 처리

훅 타입 네 가지도 역할이 분명해요.

타입 언제 쓰나 메모
command 쉘 스크립트, 포맷터, 차단 로직 가장 흔함
http 웹훅, 팀 공용 감사 서버 외부 엔드포인트 필요
prompt 간단한 yes/no 판단 모든 이벤트에서 되는 건 아님
agent 코드베이스를 읽어가며 검증 느리지만 유연함

설정 파일도 나눠서 봐야 덜 꼬여요. 글로벌은 ~/.claude/settings.json, 프로젝트 공용은 .claude/settings.json, 개인 전용은 .claude/settings.local.json으로 두는 방식이 기본이죠. MCP, 그러니까 Claude에 외부 도구를 붙이는 연결 규칙까지 함께 다루려면 MCP 서버 사용법: Claude Code 연결 가이드를 같이 보는 편이 편해요.

그리고 이거 하나는 꼭 기억하세요. 대부분의 차단성 훅은 exit 1이 아니라 exit 2로 막아요. 처음엔 이 부분에서 꼭 한 번 걸립니다.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(git commit *)",
            "command": "./hooks/check-commit.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

if 필드는 2026년 3월 말 Claude Code 주간 업데이트로 공식 문서에 올라왔어요. 그래서 예전 예제처럼 matcher만 넓게 걸어두면 훅이 과하게 발화할 수 있죠.

claude code 훅 설정 레시피 3개

처음엔 거창하게 만들지 말고, 바로 체감되는 것부터 넣는 게 좋아요. 포맷팅, 차단, 알림 이 셋만 돌아가도 손이 꽤 덜 갑니다. 매번 “포맷터 돌려줘”라고 프롬프트에 적는 반복, 훅 한 줄이면 끝납니다.

1. PostToolUse로 자동 포맷팅

파일 저장 뒤에 포맷터를 붙이면 반복 프롬프트가 바로 사라져요. 이건 진짜 체감이 빨라요.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "./hooks/format-changed-files.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
#!/usr/bin/env bash
# 프로젝트 포맷터 실행
npm run format:changed
exit 0

2. PreToolUse로 위험 명령과 보호 파일 막기

가장 먼저 넣을 만한 건 이쪽이에요. git reset --hard, rm -rf, .env 수정 같은 건 진짜 한 번만 당해도 바로 넣게 되거든요.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(git reset --hard*)|Bash(rm -rf*)",
            "command": "./hooks/block-dangerous.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
#!/usr/bin/env bash
# 위험 명령 차단
echo "차단: 위험한 명령이라 직접 확인이 필요해요." >&2
exit 2

3. Stop 훅으로 완료 알림 붙이기

작업 끝나면 알림 하나 오는 것만으로도 컨텍스트 스위칭이 편해져요. 근데 여기서 stop_hook_active를 안 보면 바로 루프 구덩이로 들어갑니다.

#!/usr/bin/env bash
# Stop 훅 입력 읽기
INPUT=$(cat)

# 이미 Stop 훅이 다시 돌고 있으면 즉시 종료
if [ "$(printf '%s' "$INPUT" | jq -r '.stop_hook_active // false')" = "true" ]; then
  exit 0
fi

# macOS 예시 알림
osascript -e 'display notification "작업이 끝났어요" with title "Claude Code"'
exit 0

알림만 필요하면 Notification 이벤트가 덜 까다로운 편이에요. 팀 채널로 넘기고 싶으면 command 대신 http 훅으로 웹훅을 붙이면 되고요.

실제 워크플로우

아래 순서대로 하면 돼요.

1단계: 설정 파일 문법 먼저 보기

# hooks 설정 파일 JSON 검사
jq . ~/.claude/settings.json

2단계: Claude Code 세션 시작

# 프로젝트 디렉터리에서 시작
cd my-project
claude

3단계: 차단 규칙 재현해 보기

# 의도적으로 위험 명령을 시도해서 훅 동작 확인
git reset --hard

체크리스트도 같이 보세요.

  • 포맷터는 PostToolUse
  • 차단은 PreToolUse + exit 2
  • 완료 알림은 Stop 또는 Notification
  • 팀 공용 규칙은 프로젝트 .claude/settings.json
  • 개인 실험은 .claude/settings.local.json

서브에이전트 검증형 훅까지 가고 싶으면 AI 에이전트 만들기: 도구 호출부터 워크플로우까지 실전 가이드 쪽이 자연스럽게 이어져요.

Claude Code 공식 문서의 PostToolUse 자동 포맷팅 hook 설정 JSON 예시
공식 문서가 보여주는 PostToolUse + Edit/Write matcher + Prettier 실행 레시피 구조 (출처: Anthropic 공식 문서)

stop hook 무한 루프와 hook error 대응법

여기는 설정법보다 더 중요해요. 제대로 막지 않으면 훅을 켠 뒤부터 세션이 더 불안정해질 수도 있거든요. 설마 Stop 훅이 이렇게 쉽게 무한 루프에 빠진다고요?

맞아요. 공식 문서도 Stop 입력에 stop_hook_active가 들어오고, 이 값을 체크해서 무한 실행을 막으라고 적고 있어요. 이 필드 안 보고 continue 흐름을 잘못 주면 Claude가 멈춘 뒤 다시 달리고, 다시 멈춘 뒤 또 달리는 식으로 꼬일 수 있죠.

그리고 hook error는 라벨만 못생긴 문제가 아니에요. 2026년 3월 15일에 올라온 GitHub 이슈 #34713은 exit 0, stderr 0바이트, JSON 정상 출력인데도 transcript에 계속 hook error가 찍힌다고 정리해놨어요. 플러그인 훅이 많은 세션일수록 이 줄이 계속 누적돼서 흐름이 깨진다는 보고였죠. 2026년 4월 15일 기준 그 이슈는 open 상태로 보였어요.

증상 보통 원인 바로 할 일
Stop 훅이 계속 돈다 stop_hook_active 체크 없음 가드 추가, continue 남용 중단
성공했는데 hook error 라벨이 뜬다 transcript 라벨 버그 가능성 훅 수 줄이고, 프로젝트 설정에 직접 등록 검토
Windows에서 입력이 멈춘다 플러그인 command hook freeze 보고 최신 버전 확인, 프로젝트 훅 우선, Windows 네이티브/리눅스 셸 동작 차이 체크
SessionEnd 로그가 끝까지 안 남는다 종료 전에 자식 프로세스가 끊김 무거운 작업은 백그라운드 분리
JSON 파싱이 이유 없이 깨진다 셸 시작 파일의 echo 출력 셸 프로필의 출력문 정리

짧은 점검표도 두고 갈게요.

  • Stop 훅엔 stop_hook_active 가드 넣기
  • 차단은 exit 2로 하기
  • .zshrc 같은 셸 파일에 무조건 echo 찍지 않기
  • hook error가 반복되면 플러그인 훅 수부터 줄여보기
  • Windows에선 플러그인 기반 command 훅보다 프로젝트 설정 훅부터 확인하기

서브에이전트와 Task 흐름이 같이 섞이면 SubagentStop, TaskCreated, TaskCompleted까지 엮여서 더 헷갈릴 수 있어요. 이 부분은 AI 에이전트 만들기: 도구 호출부터 워크플로우까지 실전 가이드를 같이 보면 맥락이 정리됩니다.

보안과 사용 환경 체크

훅은 기능만 보면 편한데, 보안과 사용 환경(surface) 차이까지 같이 봐야 사고를 덜 만나요. 어디서 세팅하고 어디서 상속되는지 모르면 금방 꼬입니다. 로컬에서 잘 돌던 훅이 웹 세션에선 왜 안 먹는지부터 같이 정리해볼게요.

사용 환경별 hooks 동작

2026년 4월 15일 기준 Claude Code 공식 개요는 Claude Code를 터미널, IDE, 데스크톱 앱, 브라우저에서 쓸 수 있다고 적고 있어요. 그리고 같은 개요 페이지는 Web, Desktop, VS Code, JetBrains, Chrome 확장 베타, Slack, GitHub Actions/GitLab CI/CD, iOS 이어보기, Agent SDK까지 따로 잡아두고 있죠. 중요한 건 훅을 어디서 “작성”하느냐보다 세션이 어디서 “실행”되느냐예요.

사용 환경 지금 상태 훅 메모
터미널 CLI 가장 직접적 ~/.claude/settings.json, 프로젝트, 로컬 설정 다 만지기 좋음
VS Code / Cursor 공식 확장 CLI 엔진과 설정을 공유해요
JetBrains 공식 플러그인 IDE 안에서 diff를 보되 설정은 같은 축을 따름
Desktop 앱 공식 Code 탭 GUI로 쓰지만 설정 파일은 CLI와 공유
Web / Cloud 공식 지원 저장소의 .claude/settings.json은 따라오고, 사용자 홈 설정은 안 따라와요
Claude iOS 앱 원격 세션 이어보기 로컬 훅 작성용보단 web 세션 확인/이어받기 쪽
Chrome 확장 beta 공식 surface 브라우저 작업용, 훅 authoring 중심 surface는 아님
Slack 공식 연동 Slack에서 직접 훅을 짜는 게 아니라 연결된 세션/프로젝트 규칙이 중요
GitHub Actions / GitLab CI/CD 공식 자동화 surface headless CLI나 SDK 흐름으로 보는 게 자연스러움
SDK / API Python, TypeScript, CLI 프로젝트 설정을 읽게 하면 hooks도 함께 가져갈 수 있어요

웹과 로컬 차이는 특히 조심하세요. 공식 웹 가이드는 cloud session에서 저장소의 .claude/settings.json 훅은 따라오지만, 사용자 ~/.claude/settings.json은 안 따라온다고 적고 있어요. 그래서 로컬에서만 되던 훅이 web에선 갑자기 안 도는 경우가 나옵니다.

보안 체크와 CVE 주의점

보안은 더 중요해요. 2026년 2월 25일 공개된 Check Point Research 보고서는 악성 프로젝트 설정으로 원격 코드 실행과 API 키 유출이 가능했던 흐름을 정리했어요. 여기 붙은 취약점 식별자가 CVE-2025-59536CVE-2026-21852예요. 그래서 모르는 저장소에서는 trust prompt를 습관처럼 넘기면 안 돼요.

보안 체크리스트는 이 정도면 시작하기 좋아요.

  • 처음 보는 저장소는 훅부터 의심하기
  • 필요하면 disableAllHooks로 전체 비활성화하기
  • 공용 규칙과 개인 실험 규칙을 파일로 분리하기
  • 프로젝트 .claude/settings.json 변경은 코드 리뷰로 보기
  • 웹 세션에선 user-level 설정이 안 따라온다는 점 기억하기

참고로 개인 요금은 2026년 4월 15일 기준 공식 가격표와 도움말 기준으로 Pro 월 $20, Max 5x 월 $100, Max 20x 월 $200이었어요. 무료 Claude 플랜은 Claude Code access가 없고요. surface 차이와 가격 감을 같이 보고 싶으면 GitHub Copilot vs Claude Code: 가격부터 실사용까지 비교도 붙여서 보면 좋아요.

자주 묻는 질문

Q1. 훅이랑 CLAUDE.md 뭐가 달라요?

A: 매번 꼭 실행돼야 하면 훅이 맞아요. 코딩 스타일이나 네이밍처럼 지침 성격이면 CLAUDE.md 쪽이 더 편하죠. 둘은 대체 관계보다 역할 분담에 가까워요.

Q2. Stop 훅은 왜 무한 루프에 빠져요?

A: Stop 입력 JSON의 stop_hook_active를 안 보고 다시 이어서 돌리면 루프가 날 수 있어요. 공식 문서도 이 값을 체크해서 바로 exit 0 하라고 적고 있거든요.

Q3. 성공했는데 hook error라고 떠요. 정상인가요?

A: 정상으로 보기 어렵죠. 2026년 4월 15일 기준 공개 이슈 중에는 exit 0, stderr 없음인데도 라벨이 hook error로 찍힌 사례가 남아 있었어요. 그래서 transcript를 같이 보고, 플러그인 훅이 많은 세션이면 먼저 수를 줄여보는 편이 낫습니다.

Q4. 웹이나 Desktop에서도 같은 hooks가 먹어요?

A: 대체로 같은 설정 축을 공유해요. 근데 web/cloud는 저장소에 커밋된 .claude/settings.json은 따라오고, 사용자 홈의 ~/.claude/settings.json은 안 따라와요. 여기서 많이 헷갈려요.

Q5. 무료 플랜에서도 hooks 쓸 수 있어요?

A: 개인 기준으로는 Claude Code access 자체가 무료 플랜에 포함되지 않아요. 2026년 4월 15일 기준 개인 요금은 Pro 월 $20, Max 5x 월 $100, Max 20x 월 $200으로 안내돼 있었어요.

다음 단계

오늘은 PreToolUse 차단 훅 하나만 먼저 켜보세요. 그다음 포맷터 훅을 붙이면 체감이 바로 옵니다. Claude Code 기본 흐름부터 다시 보고 싶으면 Claude Code 시작하기로 이어가고, 외부 도구까지 묶고 싶으면 MCP 서버 연결 방법까지 같이 보면 됩니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다