Logo
본문으로 이동
고급20분 소요hooksautomationreference

Hooks 레퍼런스

Hooks는 Claude Code의 라이프사이클 이벤트에 쉘 명령어를 연결하는 기능입니다. 도구 실행 전후, 응답 생성 후, 세션 시작/종료 등 다양한 시점에 커스텀 로직을 실행할 수 있습니다.

개요

Claude Code hooks를 사용하면:

  • 도구 실행을 가로채고 검증하거나 차단할 수 있음
  • 자동화된 워크플로우를 트리거할 수 있음
  • 모든 작업의 감사 로그를 유지할 수 있음
  • 팀 전체에 일관된 동작을 강제할 수 있음
  • 외부 시스템과 통합할 수 있음

설정

hooks는 settings.jsonhooks 섹션에서 구성합니다:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "validate-command.sh"
          }
        ]
      }
    ]
  }
}

설정 파일 위치

범위 경로
사용자 전체 ~/.claude/settings.json
프로젝트 .claude/settings.json
프로젝트 공유 .claude/settings.shared.json

Hook 이벤트 유형

PreToolUse

도구가 실행되기 전에 실행됩니다. 종료 코드 2로 도구 실행을 차단할 수 있습니다.

입력 스키마:

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "hook_event_name": "PreToolUse",
  "tool_name": "string",
  "tool_input": {}
}

종료 코드 동작:

종료 코드 동작
0 도구 실행 계속
2 도구 실행 차단 (stdout이 Claude에게 피드백으로 전달됨)
그 외 도구 실행 계속 (stderr는 Claude에게 전달됨)

PostToolUse

도구가 실행된 후에 실행됩니다. 결과 검사 및 로깅에 활용합니다.

추가 입력 필드:

{
  "tool_response": {}
}

Notification

Claude Code가 알림을 보낼 때 실행됩니다.

추가 입력 필드:

{
  "message": "string"
}

Stop

Claude Code가 응답을 완료할 때 실행됩니다.

추가 입력 필드:

{
  "stop_hook_active": true
}

중요: stop_hook_activetrue일 때 hook이 재진입되는 경우입니다. 무한 루프 방지를 위해 반드시 확인하세요.

SubagentStop

서브에이전트가 완료될 때 실행됩니다. Stop과 동일한 스키마를 사용합니다.

Matcher 설정

matcher 필드로 특정 도구에만 hook을 적용할 수 있습니다.

{ "matcher": "Bash" }           // 정확한 이름
{ "matcher": "Bash|Write|Edit" } // 정규식
{ "matcher": "mcp__fs__write" }  // MCP 도구
// matcher 생략 시 모든 도구에 적용

환경 변수

변수 설명
CLAUDE_TOOL_INPUT JSON 형식의 도구 입력
CLAUDE_TOOL_RESPONSE JSON 형식의 도구 응답 (PostToolUse)
CLAUDE_NOTIFICATION_MESSAGE 알림 메시지 (Notification)
CLAUDE_STOP_HOOK_ACTIVE Stop hook 재진입 여부
CLAUDE_SESSION_ID 현재 세션 ID
CLAUDE_TRANSCRIPT_PATH 트랜스크립트 파일 경로

stdin으로도 동일한 데이터를 JSON으로 받을 수 있습니다.

실용적인 예시

위험한 명령어 차단

#!/bin/bash
COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')

if echo "$COMMAND" | grep -qE "rm -rf /|rm -rf ~"; then
  echo "보안: 위험한 명령어가 차단되었습니다."
  exit 2
fi

자동 코드 포맷팅

#!/bin/bash
FILE=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path // ""')

[[ "$FILE" == *.ts || "$FILE" == *.tsx ]] && npx prettier --write "$FILE" 2>/dev/null
[[ "$FILE" == *.py ]] && black "$FILE" 2>/dev/null

감사 로깅

#!/bin/bash
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
TOOL=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.tool_name // "unknown"' 2>/dev/null)
echo "$TIMESTAMP | $TOOL | $PWD" >> "$HOME/claude-audit.log"

Stop hook으로 자동 테스트

#!/bin/bash
# 무한 루프 방지
[ "$CLAUDE_STOP_HOOK_ACTIVE" = "true" ] && exit 0

npm test 2>&1
[ $? -ne 0 ] && echo "테스트 실패 - 수정 필요" && exit 1

보안 고려사항

  1. 무한 루프 방지: Stop hook에서 stop_hook_active 반드시 확인
  2. 명령어 주입 방지: hook 입력을 eval에 직접 전달하지 않기
  3. 최소 권한: hook 스크립트는 필요한 권한만 부여
  4. 민감 데이터: 트랜스크립트/로그에 비밀번호가 노출될 수 있음

디버깅

# 디버그 로그 활성화
echo "$(date): Hook triggered | Input: $CLAUDE_TOOL_INPUT" >> /tmp/hook-debug.log
문제 원인 해결
Hook 미실행 실행 권한 없음 chmod +x hook.sh
JSON 파싱 오류 jq 미설치 brew install jq
무한 루프 stop_hook_active 미확인 Stop hook에서 확인 추가

관련 항목

관련 가이드

Hooks 레퍼런스 | Claude Code 가이드 | GodDaeHee | GodDaeHee