김과장
Hooks — 자동 실행 규칙 만들기

Step 19 / 22

Hooks — 자동 실행 규칙 만들기

파일 저장 후 자동 정리, 위험 명령 차단, 작업 완료 알림 설정

Hooks = 자동으로 실행되는 규칙

Claude Code를 쓰다 보면 이런 생각이 들 때가 있어요. “파일 저장할 때마다 자동으로 코드 정리 좀 해주면 좋겠는데…” “위험한 명령어는 아예 못 쓰게 막을 수 없나?”

바로 이런 걸 해주는 게 Hooks예요. Claude Code가 특정 행동을 할 때 자동으로 실행되는 규칙을 미리 설정해두는 거예요.

비유하자면 자동 알람과 같아요. 아침 7시가 되면 알람이 울리듯이, Claude가 파일을 저장하면 자동으로 코드를 정리하고, 위험한 명령어를 쓰려고 하면 자동으로 차단하는 거예요.

일상 속 자동 알람Claude Code Hooks
아침 7시 → 알람 울림파일 저장 → 자동 포맷팅
현관문 열림 → 카메라 녹화명령어 실행 → 안전 검사
냉장고 온도 높음 → 알림에러 발생 → 텔레그램 알림
화재 감지 → 스프링클러 작동rm -rf 감지 → 실행 차단
퇴근 시간 → 컴퓨터 잠금세션 종료 → 작업 로그 저장

한 줄 요약

Hooks = “이런 상황이 되면, 이걸 자동으로 실행해줘” 라는 규칙을 미리 설정해두는 거예요. 한번 설정하면 매번 신경 쓸 필요 없이 알아서 돌아가요.

7가지 훅 이벤트 — 언제 실행될까?

Hooks가 자동으로 실행되려면, “언제” 실행할지를 정해야 해요. Claude Code는 7가지 시점(이벤트)을 제공해요. 이 중에서 실제로 자주 쓰는 건 3~4개 정도예요.

PreToolUse

Claude가 도구를 사용하기 직전에 실행돼요. 위험한 명령어를 미리 검사해서 차단할 때 써요.

★ 가장 많이 쓰는 훅

PostToolUse

Claude가 도구를 사용한 직후에 실행돼요. 파일 저장 후 자동 포맷팅할 때 써요.

★ 가장 많이 쓰는 훅

🔔

Notification

Claude가 사용자 입력을 기다릴 때 실행돼요. 작업 완료 알림을 텔레그램이나 슬랙으로 보낼 때 써요.

🚀

SessionStart

Claude Code 세션이 시작될 때 실행돼요. 환경 체크나 초기 설정 자동화에 써요.

🚫

SessionEnd

Claude Code 세션이 종료될 때 실행돼요. 작업 로그 저장이나 정리 작업에 써요.

💬

PreSendMessage

Claude가 응답을 보내기 직전에 실행돼요. 응답 내용을 검사하거나 수정할 때 써요.

📝

PostSendMessage

Claude가 응답을 보낸 직후에 실행돼요. 응답 로깅이나 후처리에 써요.

전부 외울 필요 없어요

7가지나 되지만, 실제로 처음에 쓰는 건 PreToolUse(위험 차단)와 PostToolUse(자동 포맷팅) 이 2개면 충분해요. 나머지는 필요할 때 하나씩 추가하면 돼요.

Hooks = Claude Code의 자동 알람

한번 설정하면, 매번 수동으로 하던 작업을 Claude가 알아서 처리해요

설정하는 법 — settings.json 한 곳에서

Hooks는 settings.json 파일에 설정해요. 어렵게 생각하지 마세요. 규칙을 JSON 형식으로 적어두기만 하면 돼요.

설정 파일 위치 — 3가지

범위파일 위치설명
이 프로젝트만.claude/settings.json현재 프로젝트 폴더 안에 저장. 팀원과 공유 가능
내 모든 프로젝트~/.claude/settings.json홈 폴더에 저장. 어떤 프로젝트든 적용
이 프로젝트 (나만).claude/settings.local.jsongit에 올라가지 않는 개인 설정

처음에는 프로젝트별 설정(.claude/settings.json)으로 시작하는 게 좋아요. 나중에 모든 프로젝트에 적용하고 싶은 훅이 생기면 홈 폴더로 옮기면 돼요.

기본 구조

.claude/settings.json
{
  "hooks": {
    "이벤트 이름": [
      {
        "matcher": "어떤 도구에 적용할지",
        "hooks": [
          {
            "type": "command",
            "command": "실행할 명령어"
          }
        ]
      }
    ]
  }
}

구조가 복잡해 보이지만, 패턴이 있어요. 핵심은 3가지예요.

1
이벤트 이름 (언제?)

PreToolUse, PostToolUse 등 7가지 중 하나

2
matcher (어떤 도구에?)

Bash, Write, Edit 등 특정 도구에만 적용하거나, 전체 적용

3
command (뭘 실행할지?)

실행할 셸 명령어나 스크립트 경로

종료 코드의 의미

훅에서 실행한 스크립트가 돌려주는 숫자(종료 코드)에 따라 Claude Code의 동작이 달라져요. 이것만 기억하면 돼요.

종료 코드의미Claude Code 동작
0성공 (문제 없음)그대로 진행
1알림 (경고 표시)진행하되, 사용자에게 경고 메시지를 보여줌
2차단 (실행 거부)해당 도구 사용을 완전히 차단

외우기 쉬운 방법

0 = OK (통과), 1 = 경고등 (노란불, 주의하고 진행), 2 = 빨간불 (정지, 차단). 신호등이라고 생각하면 돼요.

실전 1: 파일 저장 시 자동 포맷팅

가장 많이 쓰는 훅 중 하나가 자동 포맷팅이에요. Claude가 파일을 수정할 때마다 Prettier나 ESLint가 자동으로 돌아가서 코드 스타일을 맞춰줘요.

손으로 매번 npx prettier --write를 실행하는 대신, 훅으로 설정하면 한번만 설정하고 영원히 자동이에요.

.claude/settings.json — Prettier 자동 실행
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ]
  }
}

이 설정의 의미를 하나씩 풀어볼게요.

설정 해석

PostToolUse

도구를 사용한 직후에 실행

Write|Edit

파일 쓰기(Write) 또는 수정(Edit) 도구일 때만

command

$CLAUDE_FILE_PATH는 Claude가 수정한 파일 경로로 자동 치환돼요. 즉, 수정된 파일만 정확히 포맷팅하는 거예요.

환경 변수 — 훅에서 쓸 수 있는 정보

훅 스크립트에서는 Claude Code가 제공하는 환경 변수를 사용할 수 있어요. 어떤 파일을 수정했는지, 어떤 명령어를 실행하려는지를 알 수 있거든요.

환경 변수들어있는 값사용 예시
$CLAUDE_FILE_PATH수정된 파일 경로해당 파일만 포맷팅
$CLAUDE_TOOL_INPUT도구에 전달된 입력값 (JSON)명령어 내용 검사
$CLAUDE_SESSION_ID현재 세션 ID로그 기록

ESLint + Prettier 조합

.claude/settings.json — ESLint + Prettier 동시 적용
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix $CLAUDE_FILE_PATH && npx prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ]
  }
}

Prettier가 설치되어 있어야 해요

이 훅이 동작하려면 프로젝트에 Prettier가 설치되어 있어야 해요.npm install -D prettier로 미리 설치해두세요. ESLint도 마찬가지로 npm install -D eslint로 설치하면 돼요.

실전 2: 위험한 명령어 자동 차단

Claude Code는 강력한 도구지만, 가끔 위험한 명령어를 실행하려 할 수 있어요. 예를 들어 rm -rf / 같은 명령어는 시스템 전체를 날려버릴 수 있잖아요.

이런 위험한 명령어를 자동으로 차단하는 훅을 만들어볼게요. 이번에는 PreToolUse 이벤트를 사용해요. 도구를 사용하기 직전에 검사해서, 위험하면 차단하는 거예요.

.claude/settings.json — 위험 명령어 차단
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/safety-check.sh"
          }
        ]
      }
    ]
  }
}

이번에는 명령어가 좀 길어질 수 있으니까, 별도의 스크립트 파일로 분리했어요..claude/hooks/safety-check.sh 파일을 만들어서 검사 로직을 넣으면 돼요.

.claude/hooks/safety-check.sh — 안전 검사 스크립트
#!/bin/bash
# Claude Code 안전 검사 훅
# 종료 코드: 0=통과, 1=경고, 2=차단

# 입력된 명령어를 환경변수에서 읽기
INPUT="$CLAUDE_TOOL_INPUT"

# 위험 패턴 목록
DANGEROUS_PATTERNS=(
  "rm -rf /"
  "rm -rf ~"
  "rm -rf *"
  "mkfs"
  "dd if="
  "> /dev/sda"
  "chmod -R 777 /"
  ":(){ :|:& };:"
)

# 각 패턴을 검사
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if echo "$INPUT" | grep -q "$pattern"; then
    echo "BLOCKED: 위험한 명령어가 감지되었습니다."
    echo "패턴: $pattern"
    exit 2  # 차단
  fi
done

# 경고 패턴 (차단은 안 하지만 주의 표시)
WARNING_PATTERNS=(
  "sudo"
  "npm publish"
  "git push --force"
  "git reset --hard"
)

for pattern in "${WARNING_PATTERNS[@]}"; do
  if echo "$INPUT" | grep -q "$pattern"; then
    echo "WARNING: 주의가 필요한 명령어입니다."
    echo "패턴: $pattern"
    exit 1  # 경고 (진행은 가능)
  fi
done

# 문제 없으면 통과
exit 0

종료 코드별 동작

🟢

exit 0

통과

안전한 명령어, 그대로 실행

🟠

exit 1

경고

주의 메시지 표시 후 진행

🔴

exit 2

차단

실행 자체를 막음

간단한 인라인 차단 (스크립트 없이)

별도 스크립트 파일을 만들기 귀찮다면, 간단한 명령어를 직접 넣을 수도 있어요.

한 줄로 rm -rf 차단
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo $CLAUDE_TOOL_INPUT | grep -q 'rm -rf' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

스크립트에 실행 권한을 줘야 해요

별도 스크립트 파일을 만들었다면 실행 권한이 있어야 해요.chmod +x .claude/hooks/safety-check.sh를 한번만 실행하면 돼요. Windows에서는 따로 안 해도 괜찮아요.

실전 3: 작업 완료 알림 보내기

Claude Code에게 오래 걸리는 작업을 시키면, 끝날 때까지 화면을 지켜보고 있어야 하잖아요.Notification 훅을 쓰면, 작업이 끝나면 자동으로 알림을 받을 수 있어요.

데스크톱 알림 (가장 간단)

macOS 데스크톱 알림
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code 작업 완료!\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}
Windows 데스크톱 알림 (PowerShell)
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code 작업 완료!')\""
          }
        ]
      }
    ]
  }
}

텔레그램 알림 (외출 중에도 받기)

텔레그램 봇 API를 사용하면, 집 밖에 있어도 스마트폰으로 알림을 받을 수 있어요.

텔레그램 알림 스크립트 (.claude/hooks/notify-telegram.sh)
#!/bin/bash
# 텔레그램으로 Claude Code 알림 보내기

BOT_TOKEN="your-bot-token"
CHAT_ID="your-chat-id"
MESSAGE="Claude Code 작업이 완료되었습니다."

curl -s -X POST \
  "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
  -d "chat_id=$CHAT_ID" \
  -d "text=$MESSAGE" \
  > /dev/null

exit 0
settings.json에 등록
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/notify-telegram.sh"
          }
        ]
      }
    ]
  }
}

matcher가 비어있으면?

"matcher": ""는 “모든 경우에 실행”이라는 뜻이에요. Notification 이벤트는 특정 도구와 관계없이 발생하니까, matcher를 비워두는 게 일반적이에요.

직접 해보기

읽기만 하면 감이 안 잡혀요. 아래 실습을 따라해보세요. 가장 쉬운 것부터 시작해요.

실습 1: 자동 포맷팅 훅 설정하기 (가장 쉬움)

Prettier가 설치된 프로젝트에서 해보세요. 설정 후 Claude에게 파일 수정을 시키면, 자동으로 포맷팅되는 걸 확인할 수 있어요.

1단계: .claude 폴더 만들기
mkdir -p .claude
2단계: settings.json 만들기
# .claude/settings.json 파일을 만들고 아래 내용을 넣으세요
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ]
  }
}
3단계: Claude에게 파일 수정 시키기
index.js 파일에 console.log("hello world") 추가해줘.

Claude가 파일을 수정한 뒤, 자동으로 Prettier가 돌아가는 걸 확인하세요!

실습 2: 위험 명령어 차단 훅 만들기

rm -rf를 감지하고 차단하는 훅을 직접 설정해보세요.

settings.json에 추가
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo $CLAUDE_TOOL_INPUT | grep -q 'rm -rf' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}
테스트: Claude에게 위험한 명령어 시키기
rm -rf / 실행해줘

“차단되었습니다” 메시지가 뜨면 성공이에요!

실습 3: Claude Code에게 직접 시키기

사실 가장 쉬운 방법은 Claude Code에게 직접 만들어달라고 하는 거예요.

이렇게 말해보세요
Claude Code 훅을 설정해줘.
1. 파일 수정 후 자동으로 prettier 실행
2. rm -rf 명령어 차단
3. 작업 완료 시 데스크톱 알림
.claude/settings.json에 설정해줘.

확인 체크리스트

훅이 동작하지 않으면, 스크립트 파일에 실행 권한이 있는지 확인하세요.chmod +x .claude/hooks/스크립트.sh를 실행하면 돼요. 그래도 안 되면 Claude에게 “훅이 안 돼, 확인해줘”라고 하면 원인을 찾아줘요.

활용 팁 + 출처

Hooks를 효과적으로 활용하기 위한 실용적인 팁들이에요.

1. 작은 것부터 시작하세요

처음부터 복잡한 훅을 만들지 마세요. 자동 포맷팅 하나만 설정해보고, 감이 오면 차단 훅, 알림 훅을 하나씩 추가하세요. 복잡한 훅은 디버깅이 어려워요.

2. 여러 훅을 조합할 수 있어요

하나의 이벤트에 여러 훅을 등록할 수 있어요. 예를 들어 PostToolUse에 포맷팅 + 린트 + 타입체크를 순서대로 걸 수 있어요. 앞의 훅이 실패하면 뒤의 훅은 실행되지 않아요.

3. matcher에 정규식을 쓸 수 있어요

Write|Edit처럼 |로 여러 도구를 묶을 수 있어요. .*로 모든 도구에 적용할 수도 있고, 특정 도구 이름만 정확히 지정할 수도 있어요.

4. 팀 프로젝트에서 공유하세요

.claude/settings.json은 Git에 커밋할 수 있어요. 팀 전체가 같은 안전 규칙과 자동 포맷팅을 쓰면 코드 품질이 자동으로 유지돼요. 개인 설정은 settings.local.json에 넣으면 돼요.

5. Claude에게 훅 만들어달라고 하세요

직접 JSON을 손으로 쓰기 어려우면, Claude Code에게 “이런 훅 만들어줘”라고 하면 돼요. Claude가 settings.json 파일을 만들고, 필요한 스크립트까지 같이 생성해줘요.

Hooks = Claude Code의 자동 알람

파일 저장하면 자동 정리, 위험한 명령은 자동 차단, 작업 끝나면 자동 알림. 한번 설정하면 여러분은 신경 쓸 게 없어요.

한 개만 설정해도 달라져요

자동 포맷팅 훅 하나만 설정해도 “아, 이게 이렇게 편한 거구나” 하는 순간이 올 거예요. 그때부터 하나씩 추가하면 돼요. 처음부터 완벽하게 만들 필요 전혀 없어요.

참고 자료