클로드 코드 훅이 하는 일 — 부탁이 아니라 반드시 도는 규칙
CLAUDE.md에 «.env 파일은 고치지 마»라고 적어 둘 수 있다. 하지만 이것은 클로드에게 하는 부탁이다. 공식 권한 문서는 프롬프트나 CLAUDE.md의 지시가 클로드가 하려는 일에 영향을 줄 뿐, Claude Code가 허용하는 범위는 바꾸지 않는다고 적었다. 클로드가 규칙을 잊거나 다르게 읽으면 그대로 고칠 수 있다는 뜻이다.
훅은 다르다. 공식 안내서는 훅을 «사용자가 정의한 셸 명령»이라고 설명한다. 클로드 코드는 이 명령을 정해진 순간마다 실행한다. 클로드가 실행할지 말지 고르는 것이 아니다. 그래서 공식 문서는 이를 결정론적 제어(늘 같은 조건에서 같은 일이 일어나게 하는 제어)라고 부른다.
훅이 도는 순간과 matcher
훅을 걸 수 있는 순간을 이벤트(event)라고 한다. 공식 표에는 이벤트가 많지만, 처음에는 다음 여섯 개만 알면 된다.
SessionStart: 세션을 시작하거나 다시 열 때UserPromptSubmit: 요청을 보낸 뒤, 클로드가 처리하기 전PreToolUse: 클로드가 도구(파일 고치기, 명령 실행 같은 기능)를 쓰기 직전 · 여기서 막을 수 있음PostToolUse: 도구를 쓴 뒤Notification: 클로드 코드가 알림을 보낼 때Stop: 클로드가 답을 끝냈을 때
matcher(매처 · 훅이 반응할 대상을 좁히는 거름망)는 이벤트 안에서 범위를 더 좁힌다. 예를 들어 PreToolUse에 Edit|Write를 적으면 파일을 고치거나 쓰는 도구에만 반응한다. Bash나 Read 같은 다른 도구에는 반응하지 않는다. matcher를 비워 두면 그 이벤트가 생길 때마다 돈다.
훅은 대부분 셸 명령을 돌리는 command 형식이다. 훅은 표준 입력으로 JSON(정해진 모양의 글 데이터)을 받는다. 그 안에 어떤 도구를 쓰려는지와 어떤 파일 경로인지가 들어 있다. 훅은 끝날 때 종료 코드(프로그램이 끝나며 돌려주는 숫자)로 답한다. 0이면 «반대 없음»이고, 2면 «막음»이다. 2로 끝날 때 오류 출력에 쓴 글은 클로드에게 이유로 전달된다.
정리하면 훅은 «언제(이벤트) · 무엇에(matcher) · 무엇을 실행하나(명령)»의 세 칸으로 이루어진다. 이 글의 첫 예시는 PreToolUse · Edit|Write · 보호 파일 검사 스크립트의 조합이다. 둘째 예시는 Notification · 빈 matcher · 알림 창 띄우기의 조합이다.
첫 훅 만들기 — .env와 .git 고치기를 미리 막는 클로드 코드 훅
공식 안내서에는 .env, package-lock.json, .git/ 안의 파일을 클로드가 고치지 못하게 막는 예시가 있다. 원래 예시는 Bash 스크립트다. 여기서는 공식 참조 문서의 Windows PowerShell 예시 모양을 따라 PowerShell 스크립트로 옮겼다.
처음이라면 이 절의 3단계만 따라 하면 된다. 스크립트 파일 하나와 설정 파일 하나를 만들고, /hooks로 확인한 뒤 .env 고치기를 시켜 막히는지 본다. 알림 훅과 다른 예시는 그다음에 해도 늦지 않다.
- 프로젝트 폴더 안에
.claude\hooks폴더를 만들고, 아래 내용을protect-files.ps1로 저장한다.
# .claude/hooks/protect-files.ps1
$callInput = [Console]::In.ReadToEnd() | ConvertFrom-Json
$path = $callInput.tool_input.file_path
$protected = @('.env', 'package-lock.json', '\.git\')
foreach ($p in $protected) {
if ($path -like "*$p*") {
[Console]::Error.WriteLine("Blocked: $path is a protected file ($p)")
exit 2
}
}
exit 0이 스크립트는 클로드 코드가 넘겨준 JSON에서 고치려는 파일 경로를 꺼낸다. 경로에 보호할 이름이 들어 있으면 이유를 적고 2로 끝낸다. Windows에서는 파일 경로가 역슬래시(\)로 넘어오므로 .git 폴더는 \.git\ 모양으로 찾는다. 경로에 .env가 들어간 파일은 이름이 조금 달라도 모두 막힌다는 점도 알아 둔다.
- 프로젝트 폴더의
.claude\settings.json을 열고(없으면 만들고) 아래 내용을 넣는다. 이미hooks칸이 있으면 그 안에PreToolUse만 나란히 더한다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "powershell.exe",
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-File",
"${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-files.ps1"
]
}
]
}
]
}
}args 칸을 쓰면 셸을 거치지 않고 프로그램을 바로 실행한다. 그래서 따옴표가 꼬일 일이 적다. -NoProfile은 PowerShell 개인 설정을 읽지 않아 빨리 뜨게 하고, -ExecutionPolicy Bypass는 이 스크립트 파일을 실행할 수 있게 한다. ${CLAUDE_PROJECT_DIR}는 프로젝트 폴더 경로로 바뀐다.
- 클로드 코드 입력창에
/hooks를 쳐서 목록을 연다. 그다음 아래 요청을 보내 막히는지 시험한다.
.env 파일 맨 끝에 주석 한 줄을 넣어 줘.잘 됐으면 /hooks 목록의 PreToolUse 아래에 이 훅이 보인다. 시험 요청을 보내면 클로드 코드는 고치기 전에 막고, Blocked:로 시작하는 이유를 클로드에게 전달한다. .env 파일 내용은 그대로 남는다.
설정에 넣기 전에 스크립트만 따로 시험할 수도 있다. 공식 문서도 시험 JSON을 넣어 종료 코드를 보라고 권한다. 프로젝트 폴더의 PowerShell 창에서 아래를 실행한다.
'{"tool_name":"Write","tool_input":{"file_path":"C:\\work\\demo\\.env"}}' | powershell.exe -NoProfile -ExecutionPolicy Bypass -File .claude\hooks\protect-files.ps1
$LASTEXITCODE잘 됐으면 Blocked:로 시작하는 문구가 나오고, 다음 줄에 2가 보인다. 이 글을 정리한 Windows PC에서 같은 스크립트에 시험 JSON 세 개를 넣어 실행했다. .env와 .git\config 경로는 Blocked: 문구와 함께 2로 끝났다. 보통 문서 파일 report.md는 아무 출력 없이 0으로 끝났다.
인용 — Claude Code Docs «Automate actions with hooks»«Claude Code runs them at specific points in its lifecycle, which gives you deterministic control: certain actions always happen rather than relying on the LLM to choose to run them.» — 클로드 코드는 정해진 순간마다 훅을 실행하므로, 어떤 동작은 모델이 고르기를 기다리지 않고 늘 일어난다.
같은 문서는 판단이 필요한 일에는 클로드 모델이 조건을 따지는 프롬프트 훅이나 에이전트 훅도 쓸 수 있다고 덧붙였다.
입력을 기다릴 때 알림 받기 — Notification 훅과 저장 위치
클로드 코드에 긴 일을 맡기고 다른 창에서 일하다 보면, 승인을 기다리는 줄 모르고 시간을 보내기 쉽다. 이때 쓰는 것이 Notification 훅이다. 클로드가 입력이나 승인을 기다릴 때 돈다. 이 훅은 모든 프로젝트에 걸어 두는 편이 편하므로, 홈 폴더의 설정 파일에 넣는다.
- 홈 폴더의
.claude\settings.json을 연다. 경로는 보통C:\Users\내이름\.claude\settings.json이다. 파일이 없으면 만든다. - 아래 내용을 넣는다. 공식 안내서의 Windows PowerShell 예시 그대로다.
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
]
}
}/hooks로Notification아래에 보이는지 확인한다. 그다음Shift+Tab으로 승인을 묻는 모드로 바꾸고, 승인이 필요한 일을 시킨 뒤 다른 창으로 옮겨 간다.
잘 됐으면 «Claude Code needs your attention»이라는 작은 창이 뜬다. 다만 이 명령은 화면 구석 알림이 아니라 대화 상자를 연다. 그래서 터미널 창 뒤에 숨어 뜰 수 있다. 창이 안 보이면 작업 표시줄부터 살핀다.
matcher로 알림 종류 고르기와 훅을 두는 곳
빈 matcher는 모든 알림에 반응한다. 특정 때만 받고 싶다면 matcher에 알림 종류를 적는다. permission_prompt는 도구 승인을 기다리는 창이 약 6초 동안 그대로일 때 돈다. idle_prompt는 클로드가 답을 끝내고 약 60초 동안 입력창에 아무것도 치지 않았을 때 돈다. 승인 창만 알고 싶다면 "matcher": "permission_prompt"로 바꾸면 된다.
훅을 어느 설정 파일에 넣느냐에 따라 미치는 범위가 다르다.
~/.claude/settings.json(홈 폴더): 내 PC의 모든 프로젝트 · 저장소에 안 올라감.claude/settings.json(프로젝트): 그 프로젝트만 · 저장소에 올려 함께 쓸 수 있음.claude/settings.local.json(프로젝트): 그 프로젝트만 · 나만 씀
그래서 이 글에서는 알림 훅은 홈 폴더에, 보호 파일 훅은 프로젝트에 두었다. 회사 저장소라면 팀이 함께 지킬 규칙만 프로젝트 파일에 넣는 편이 깔끔하다. 설정 파일을 직접 고치면 실행 중인 클로드 코드가 보통 자동으로 다시 읽는다.
- 파일을 고친 뒤 자동으로 모양 맞추기:
PostToolUse에Edit|Writematcher를 걸고 정리 도구를 부른다(공식 예시는 Prettier). - 대화 압축 뒤 규칙 다시 알려 주기:
SessionStart에compactmatcher를 걸면 명령이 출력한 글이 클로드의 맥락에 들어간다. - 판단이 필요한 검사:
type을prompt나agent로 바꾸면 클로드 모델이 조건을 따진다. 에이전트 훅은 아직 실험 기능이다. - 스킬 안에서만 도는 훅: 스킬 파일 머리말에 훅을 적으면 그 스킬을 부른 뒤부터 돈다.
위 네 가지는 모두 공식 안내서에 예시가 있다. 압축 뒤 다시 알려 주기는 같은 규칙을 매번 읽혀야 할 때 쓴다. 다만 늘 같은 내용이라면 공식 문서도 CLAUDE.md를 먼저 권한다. 무엇을 CLAUDE.md에 적을지는 클로드 코드 CLAUDE.md 쓰는 법 — 무엇을 적고 어디에 두나에, 스킬은 클로드 스킬 — 반복하는 일을 규칙으로 저장하고 꺼내 쓰는 법에 정리했다.
클로드 코드 훅이 안 돌 때와 알아 둘 주의 — 확인 순서 · 보안
훅을 넣었는데 아무 일도 안 일어나면 공식 문서의 확인 순서를 따른다.
/hooks를 열어 훅이 맞는 이벤트 아래에 있는지 본다. 목록에 없으면 JSON 모양부터 의심한다. 끝에 붙은 쉼표나 주석은 허용되지 않는다.- matcher가 도구 이름과 똑같은지 본다. matcher는 대소문자를 가린다.
edit가 아니라Edit이다. - 이벤트가 맞는지 본다.
PreToolUse는 도구를 쓰기 전에,PostToolUse는 쓴 뒤에 돈다. - 작업 폴더를 신뢰했는지 본다. 대화형 세션에서는 그 폴더의 신뢰 확인 창을 받아들이기 전까지 홈 폴더의 훅까지 모두 돌지 않는다.
- 몇 초를 기다려도 목록에 안 나오면 세션을 다시 시작한다.
/hooks는 읽기 전용 목록이다. 훅을 고치거나 지우려면 설정 파일의 그 칸을 직접 고친다. 잠시 모든 훅을 끄려면 설정 파일에 "disableAllHooks": true를 넣는다.
훅 오류 메시지가 뜰 때와 Windows에서 막힐 때
대화에 PreToolUse hook error 같은 문구가 보이면 스크립트가 예상하지 못한 종료 코드로 끝난 것이다. 0과 2가 아닌 숫자로 끝나면 대부분의 이벤트에서 동작은 그대로 진행되고 오류만 표시된다. 위의 시험 명령으로 종료 코드를 먼저 확인한다. 자세한 기록이 필요하면 클로드 코드를 claude --debug로 시작하거나, 세션 중에 /debug를 실행해 디버그 로그를 본다.
Windows에서는 한 가지가 더 있다. 훅을 args 없이 한 줄 명령으로 적으면 Git Bash로 실행하고, Git Bash가 없으면 PowerShell로 실행한다. 그래서 Bash용으로 쓴 공식 예시를 그대로 붙이면 Git Bash가 없는 PC에서 실패할 수 있다. 오류에 blocking because Git Bash wasn't found가 보이면 Git for Windows를 설치하거나, 이 글처럼 PowerShell 스크립트를 args로 부르는 모양으로 바꾼다.
알아 둘 주의도 있다. 첫째, 명령 훅은 내 사용자 계정의 모든 권한으로 돈다. 내 계정이 열 수 있는 파일이면 고치고 지울 수도 있다. 남이 만든 저장소의 .claude/settings.json은 훅 칸부터 읽어 본다. 둘째, PostToolUse 훅은 이미 끝난 동작을 되돌리지 못한다. 막고 싶은 일은 반드시 PreToolUse에 건다. 셋째, Edit|Write matcher는 셸 명령으로 바꾼 파일까지는 보지 못한다. 모든 변경을 봐야 한다면 공식 문서처럼 Bash|PowerShell도 matcher에 넣거나 Stop 훅으로 한 번 더 훑는다.
훅과 권한 규칙의 관계도 정리해 둔다. PreToolUse 훅이 «허용»을 돌려줘도 설정의 거부 규칙을 넘지 못한다. 반대로 훅의 «거부»는 묻지 않고 진행하는 모드에서도 지켜진다. 허용 · 확인 · 거부 규칙을 정하는 법은 클로드 코드 권한 모드 — 묻게 할 일과 맡길 일 나누기에 따로 적었다.
표의 위 세 줄은 «훅이 제자리에 있느냐»의 문제다. 아래 세 줄은 «어떤 조건에서 어떻게 실행되느냐»의 문제다. 처음에는 /hooks 목록과 시험 명령의 종료 코드, 이 두 가지만 확인해도 대부분 풀린다. 설치 직후라 클로드 코드 자체가 낯설다면 클로드 코드 설치·요금제·첫 사용 (2026) — Windows에서 시작하기를 먼저 보면 된다.
자주 묻는 것
CLAUDE.md에 적은 규칙과 훅은 무엇이 다른가요?
CLAUDE.md의 지시는 클로드가 하려는 일에 영향을 주지만, 클로드 코드가 허용하는 범위를 바꾸지는 않습니다. 훅은 클로드 코드가 정해진 순간마다 반드시 실행하므로, 모델이 규칙을 잊어도 같은 검사가 돕니다.
훅은 어느 파일에 넣나요?
모든 프로젝트에 쓰려면 홈 폴더의 .claude/settings.json에, 한 프로젝트에만 쓰려면 프로젝트의 .claude/settings.json에 넣습니다. 나만 쓸 프로젝트 설정은 .claude/settings.local.json에 둡니다.
훅이 클로드의 동작을 막으려면 어떻게 끝나야 하나요?
PreToolUse 훅이 종료 코드 2로 끝나면 그 도구 호출이 막히고, 오류 출력에 쓴 이유가 클로드에게 전달됩니다. 종료 코드 0은 반대가 없다는 뜻이며, 그 뒤에는 보통의 권한 확인이 이어집니다.
넣은 훅이 /hooks 목록에 안 보여요.
JSON에 끝 쉼표나 주석이 있는지, 파일 위치가 맞는지 먼저 봅니다. 몇 초가 지나도 안 보이면 세션을 다시 시작합니다. 조직이 관리 설정에서 관리 훅만 허용했다면 개인 훅은 돌지도 보이지도 않습니다.
훅을 잠시 모두 끄고 싶어요.
설정 파일에 "disableAllHooks": true를 넣으면 됩니다. 하나만 없애려면 설정 파일에서 그 훅 칸을 지웁니다. 관리 설정에 들어간 훅은 관리 설정에서만 끌 수 있습니다.
정리 — 막을 일은 PreToolUse에, 확인은 /hooks로
훅은 클로드 코드가 정해진 순간마다 반드시 실행하는 내 명령이다. CLAUDE.md의 부탁과 달리 모델의 선택에 기대지 않는다. 고치면 안 되는 파일은 PreToolUse 훅이 종료 코드 2로 끝나게 해서 미리 막는다. 입력을 기다리는 순간은 Notification 훅으로 알림을 받는다. 안 돌면 /hooks 목록, matcher 대소문자, 작업 폴더 신뢰, 종료 코드 순서로 본다. 훅은 내 계정 권한으로 돌므로 남이 만든 훅은 먼저 읽어 본다. 훅 이벤트와 동작은 판마다 바뀔 수 있으니, 이 글은 2026년 11월 1일 기준으로 읽고 쓰기 전에 공식 문서를 한 번 더 확인한다. 지금 하나만 해 본다면, 보호 파일 스크립트를 저장하고 시험 명령으로 종료 코드 2가 나오는지부터 보자.
참고 자료
- Claude Code Docs. Automate actions with hooks — 훅의 정의와 결정론적 제어 · 첫 훅 설정 순서 · 알림 훅 Windows 예시와 matcher 값 · 보호 파일 차단 예시 · 이벤트 표 · 종료 코드 0과 2 · 저장 위치 표 · disableAllHooks · 시간 제한 · 안 돌 때 확인 순서 · Stop 훅 연속 차단 상한(2026-11-01 확인). code.claude.com
- Claude Code Docs. Hooks reference — Windows PowerShell 훅 예시(args 실행 형식 · -NoProfile · -ExecutionPolicy Bypass) · shell 칸 · Git Bash가 없을 때 · /hooks 메뉴는 읽기 전용 · 작업 폴더 신뢰 · 보안 주의 · 디버그 로그(2026-11-01 확인). code.claude.com
- Claude Code 문서. hooks를 사용하여 작업 자동화 — 한국어판 용어(훅 · matcher · 결정론적 제어 · 컨텍스트 압축)(2026-11-01 확인). code.claude.com
- Claude Code Docs. Configure permissions — 권한 규칙은 모델이 아니라 Claude Code가 지킴 · CLAUDE.md 지시는 허용 범위를 바꾸지 않음 · PreToolUse 훅은 거부 규칙을 넘지 못함(2026-11-01 확인). code.claude.com