클로드 코드 Hooks: AI 코딩 에이전트의 동작을 커스터마이징하기
클로드 코드를 사용하다 보면 “이 파일은 자동으로 수정되지 않았으면 좋겠는데”, “코드 수정 후에 자동으로 Prettier를 돌리고 싶은데”, “Claude가 작업을 마치면 알림을 받고 싶은데”와 같은 생각이 들 때가 있지 않으셨나요? 🤔
이런 요구사항들을 충족시키기 위해 클로드 코드는 Hooks라는 강력한 기능을 제공합니다. Hooks를 사용하면 클로드 코드의 라이프사이클 중 특정 시점에 사용자가 정의한 쉘 명령어나 스크립트를 자동으로 실행할 수 있습니다.
Hooks란 무엇인가요?
Hooks는 클로드 코드가 특정 작업을 수행하기 전이나 후에 자동으로 실행되는 사용자 정의 명령어입니다. LLM이 선택하는 동작이 아니라, 개발자가 미리 정해둔 규칙에 따라 결정론적(deterministic)으로 동작한다는 점이 핵심입니다.
예를 들어, Claude가 TypeScript 파일을 수정할 때마다 자동으로 Prettier를 실행하거나, 특정 디렉토리의 파일을 수정하려 할 때 차단하는 것이 가능합니다. Hooks를 활용하면 코드 포매팅 자동화, 커스텀 알림, 민감한 파일 보호, 명령어 로깅 등 다양한 워크플로우를 구축할 수 있습니다.
Hook 이벤트 종류
클로드 코드는 다양한 시점에 Hook을 실행할 수 있도록 여러 이벤트를 제공합니다.
PreToolUse는 Claude가 도구(Bash, Edit, Write 등)를 호출하기 직전에 실행됩니다.
이 Hook에서 도구 호출을 차단하거나 허용할 수 있어서, 민감한 파일 보호나 명령어 검증에 유용합니다.
PostToolUse는 도구 호출이 성공적으로 완료된 후에 실행됩니다.
파일 수정 후 자동 포매팅을 적용하거나, 변경 사항을 로깅하는 데 활용할 수 있습니다.
Notification은 클로드 코드가 알림을 보낼 때 실행됩니다.
권한 요청(permission_prompt)이나 사용자 입력 대기(idle_prompt) 상황에서 데스크톱 알림이나 Slack 메시지를 보내는 등 커스텀 알림을 구현할 수 있습니다.
Stop은 클로드 코드가 응답을 완료했을 때 실행됩니다.
작업 완료 후 정리 작업이나 알림을 보내는 데 활용할 수 있습니다.
그 외에도 사용자 프롬프트 제출 시 실행되는 UserPromptSubmit, 서브에이전트 작업 완료 시 실행되는 SubagentStop, 컨텍스트 압축 전에 실행되는 PreCompact, 세션 시작과 종료 시 실행되는 SessionStart와 SessionEnd 등이 있습니다.
Hooks 설정하기
Hooks는 /hooks 슬래시 명령어를 통해 대화형으로 설정하거나, 설정 파일을 직접 편집해서 구성할 수 있습니다.
설정 파일은 세 가지 위치에 저장할 수 있습니다.
~/.claude/settings.json은 사용자 전역 설정으로 모든 프로젝트에 적용됩니다.
.claude/settings.json은 프로젝트별 설정으로 Git에 커밋하여 팀과 공유할 수 있습니다.
.claude/settings.local.json은 로컬 프로젝트 설정으로 커밋하지 않고 개인적으로만 사용합니다.
환경 변수 이해하기
Hook을 작성할 때 가장 먼저 알아야 할 것은 클로드 코드가 제공하는 환경 변수입니다. 이 환경 변수들 덕분에 복잡한 JSON 파싱 없이도 간단하게 Hook을 작성할 수 있습니다.
$CLAUDE_FILE_PATHS는 현재 도구 호출에 관련된 파일 경로들을 공백으로 구분한 문자열입니다.
예를 들어 Claude가 src/App.tsx 파일을 수정하면, 이 환경 변수에 해당 파일의 절대 경로가 담깁니다.
$CLAUDE_PROJECT_DIR은 클로드 코드가 시작된 프로젝트 루트 디렉토리의 절대 경로입니다.
프로젝트 내 스크립트 파일을 참조할 때 유용합니다.
이제 이 환경 변수들을 활용한 실용적인 예제들을 살펴보겠습니다.
코드 자동 포매팅 Hook
개발 워크플로우에서 가장 유용한 Hook 중 하나는 코드 자동 포매팅입니다. Claude가 파일을 수정하면 자동으로 Prettier를 실행하도록 설정해보겠습니다:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bunx prettier --write \"$CLAUDE_FILE_PATHS\""
}
]
}
]
}
}
이 Hook은 Edit이나 Write 도구가 사용된 후에 실행됩니다.
$CLAUDE_FILE_PATHS 환경 변수에 수정된 파일 경로가 담겨 있어서, Prettier가 해당 파일을 자동으로 포매팅합니다.
Go 프로젝트에서는 gofmt를, Python 프로젝트에서는 black이나 ruff를 사용하도록 비슷하게 설정할 수 있습니다:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "ruff format \"$CLAUDE_FILE_PATHS\""
}
]
}
]
}
}
커스텀 알림 Hook
클로드 코드가 사용자 입력을 기다릴 때 데스크톱 알림을 받고 싶다면 Notification Hook을 활용할 수 있습니다:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Awaiting your input\" with title \"Claude Code\"'"
}
]
}
]
}
}
macOS에서는 osascript를, Linux에서는 notify-send를 사용할 수 있습니다.
Slack이나 Discord 웹훅을 호출하는 스크립트를 작성하면 원격에서도 알림을 받을 수 있습니다.
프로젝트 스크립트 활용하기
더 복잡한 로직이 필요하다면 별도의 스크립트 파일을 작성하고 $CLAUDE_PROJECT_DIR 환경 변수로 참조할 수 있습니다:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-style.sh"
}
]
}
]
}
}
이렇게 설정하면 프로젝트 루트 경로가 바뀌어도 Hook이 정상 동작합니다.
스크립트 파일은 .claude/hooks/ 디렉토리에 저장하고 실행 권한(chmod +x)을 부여하면 됩니다.
민감한 파일 보호 Hook
프로덕션 환경 설정 파일이나 환경 변수 파일처럼 실수로 수정하면 안 되는 파일들이 있습니다.
PreToolUse Hook을 활용하면 이런 파일들을 보호할 수 있습니다:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATHS\" in *.env*|*package-lock.json*|*.git/*) exit 2;; esac"
}
]
}
]
}
}
이 Hook은 Claude가 파일을 수정하려 할 때 파일 경로에 .env, package-lock.json, .git/ 등이 포함되어 있으면 종료 코드 2를 반환해서 작업을 차단합니다.
Hook의 종료 코드는 중요한 의미를 가집니다. 종료 코드 0은 성공을 의미하고 작업이 계속 진행됩니다. 종료 코드 2는 작업을 차단하라는 의미입니다. 그 외의 0이 아닌 종료 코드는 오류로 처리됩니다.
고급: stdin JSON 파싱
환경 변수만으로 충분하지 않은 경우도 있습니다. 예를 들어 Bash 명령어의 상세 정보를 로깅하거나, 도구 호출 결과를 분석해야 할 때는 stdin으로 전달되는 JSON 데이터를 파싱해야 합니다.
Hooks는 표준 입력(stdin)으로 다음과 같은 JSON 데이터를 받습니다:
{
"session_id": "abc123",
"tool_name": "Bash",
"tool_input": {
"command": "ls -la",
"description": "List files in current directory"
}
}
jq 명령어를 사용하면 이 JSON에서 필요한 정보를 추출할 수 있습니다.
예를 들어 Bash 명령어를 로그 파일에 기록하려면:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' >> ~/.claude/bash-command-log.txt"
}
]
}
]
}
}
더 복잡한 로직이 필요하다면 Python이나 JavaScript 스크립트를 작성해서 Hook으로 사용할 수 있습니다.
디버깅 팁
Hooks가 예상대로 동작하지 않을 때는 몇 가지 방법으로 디버깅할 수 있습니다.
우선 /hooks 명령어로 현재 설정된 Hooks를 확인합니다.
Hook 명령어에 로깅을 추가해서 입력 데이터와 실행 결과를 파일에 기록할 수도 있습니다.
tee /tmp/hook-input.json | your-hook-command
이렇게 하면 /tmp/hook-input.json 파일에서 Hook이 받은 입력을 확인할 수 있습니다.
마치며
클로드 코드 Hooks는 AI 코딩 에이전트의 동작을 세밀하게 제어할 수 있는 강력한 도구입니다. 코드 포매팅 자동화, 민감한 파일 보호, 커스텀 알림 등 다양한 워크플로우를 구축해서 개발 생산성을 높일 수 있습니다.
특히 팀 프로젝트에서 .claude/settings.json 파일을 Git에 커밋하면 모든 팀원이 동일한 Hook 설정을 공유할 수 있어서 일관된 개발 환경을 유지하는 데 도움이 됩니다.
클로드 코드에 대해 더 알고 싶다면 별도의 포스팅을 참고해 주세요.
도구별 권한 패턴, 권한 모드, 샌드박스 연동 같은 내용은 클로드 코드 권한 설정에서 다루고 있고, 모델 선택이나 환경 변수 등 settings.json의 전체 설정 옵션이 궁금하다면 클로드 코드 설정 가이드를 확인해보세요.
서브 에이전트에 Hooks를 적용해서 도구 사용을 세밀하게 제어하는 방법은 클로드 코드 서브 에이전트에서, 여러 세션에 걸친 작업을 의존성 그래프로 관리하는 방법은 클로드 코드 Tasks에서 다루고 있습니다.
Hooks와 함께 OS 레벨 격리까지 적용하고 싶다면 클로드 코드 샌드박스도 참고해보세요.
여러 Claude 인스턴스가 팀으로 협업하는 에이전트 팀에서는 TeammateIdle과 TaskCompleted Hook으로 팀원의 품질 기준을 강제할 수 있습니다.
Hooks를 포함한 스킬과 에이전트를 팀 전체에 배포하고 싶다면 클로드 코드 플러그인 사용법을 참고해보세요. 직접 만들어서 마켓플레이스로 공유하는 방법은 클로드 코드 플러그인 마켓플레이스에서 다룹니다.
공식 문서에서 더 자세한 내용을 확인할 수 있습니다.
This work is licensed under
CC BY 4.0