Claude Code 훅을 몇 달간 무시했는데, Opus 5 나오기 전에 설정해보니 작업 방식이 완전히 바뀌었다.
Spent months ignoring Claude Code hooks. Set them up before Opus 5 and it changed how I work.
핵심 요약
Claude Code 훅을 활용해 도구 사용을 제어하고 워크플로우를 자동화하는 실용적인 팁 공유.
- 훅 활용 — 쉘 스크립트로 도구 호출 전후 제어 가능
- PreToolUse — 도구 실행 전 명령을 검증하고 차단
- Stop 훅 — 작업 완료 후 결과 검증 및 자동화
- 컨텍스트 관리 — 거부 사유를 모델에 전달해 스스로 수정 유도
진작에 좀 써두려고 했던 건데, Claude Code 쓰다가 하지 말라고 한 짓을 기어코 저지르는 꼴 많이 봤지? 그럴 때 hooks가 답이다. 설정하기 귀찮아서 몇 달을 미뤘는데, 막상 해보니 설정 지옥 같은 거 없고 그냥 셸 스크립트 하나면 끝이더라.
이게 뭔지 짧게 설명하자면, Claude Code가 루프 돌 때 특정 시점마다 이벤트를 쏘는데, 거기다 스크립트를 갖다 붙이는 거야. 제일 중요한 건 PreToolUse인데, 이건 툴 실행하기 직전에 돌아가서 아예 차단해버릴 수 있어. 그냥 하지 말라고 타이르는 수준이 아니라, 아예 막아버린다고. 스크립트가 stdin으로 툴 이름이랑 실제 명령어를 JSON 형태로 받으니까, 거기서 네가 판단하면 돼.
내가 이거 보고 무릎을 탁 친 게, 그냥 닥치고 막는 게 아니라는 거야. 네가 왜 막았는지 이유를 던져주면 그게 Claude 컨텍스트로 들어가서, 지가 알아서 수정까지 해. 내가 pnpm 쓰는 레포에서 npm 쓰려고 할 때 내 스크립트가 뱉는 건 이거야:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "this repo is managed by pnpm (found pnpm-lock.yaml), re-run with pnpm"
}
}
그럼 내가 뭐 칠 필요도 없이 지가 알아서 pnpm으로 다시 돌려. JSON 다루기 귀찮으면 그냥 exit 2 때리고 stderr로 이유만 출력해도 똑같이 작동해.
내가 실제로 쓰는 것들:
- secrets: API 키나 토큰 패턴 들어간 명령어, 파일 쓰기 무조건 차단
- destructive:
rm -rf /, 메인 브랜치 강제 푸시,DROP DATABASE같은 뻔한 사고 방지 - package manager: 락파일 읽어서 엉뚱한 거 쓰려고 하면 컷
- typecheck gate: 이건
PreToolUse가 아니라Stop훅이야. 에이전트가 작업 다 끝났다고 할 때tsc돌려서 에러 있으면 결과 넘기는 거 막아버림
지금 당장은 Stop 훅을 제일 추천해. 특히 Opus 5 나오면서 더더욱. 모델이 승인받으러 오기 전까지 혼자서 너무 멀리까지 가버리니까, 멈췄을 때 보면 검토 안 된 작업물이 산더미거든. 지가 알아서 타입 체크하게 시키면 꽤 많은 걸 걸러낼 수 있어. 하나 주의할 점은, Stop 훅 짤 때 무조건 막기만 하면 무한 루프 도니까, 첫 번째 시도에서 안 되면 포기하게 만들어야 해.
내가 쓴 스크립트랑 settings.json 연결 설정은 여기 올려뒀어. 사실 스크립트 짜는 것보다 설정 파일 만지는 게 더 귀찮더라: https://techpotions.com/products/claude-code-hooks MIT 라이선스고 가입 같은 거 없어.
혹시 Stop 훅으로 더 똑똑하게 활용하는 사람 있냐? PreToolUse에 비해서 너무 저평가된 것 같고, 나도 아직 겉핥기 수준이라 궁금하네.
