CPN 한국어 자습서 · Claude Code in Action
3 · 훅과 SDK
Defining hooks
예제 프로젝트에서 우리만의 훅을 설계합니다. 목표는 Claude가 .env 파일을 절대 읽지 못하게 막는 것. 네 단계로 정합니다 — ① Pre냐 Post냐 ② 어떤 도구를 감시할지 ③ 도구 정보를 stdin으로 받아 처리 ④ 종료 코드로 허용·차단을 신호.
Stephen Grider · 강사
훅이 어떻게 동작하는지 더 잘 이해하기 위해 새 예제 프로젝트를 살펴봅니다. 이 강의에 Query.zip이라는 파일로 첨부해 두었으니, 내려받아 코드 에디터로 열어 보시길 권합니다. 에디터를 열었다면 터미널에서 npm run setup을 실행하세요. 의존성 몇 개를 설치하고 훅 몇 개를 쓸 수 있게 준비해 줍니다.
훅을 더 잘 이해하기 위해 이 프로젝트 안에서 직접 만들어 봅니다. 우리 훅이 할 일은 이렇습니다. 프로젝트 루트에 .env라는 파일이 있는데, 여기엔 민감한 정보가 들어 있습니다. 만일을 위해 Claude가 이 파일을 직접 읽는 일을 완전히 막고 싶습니다.
1단계 — Pre 훅이 필요한지 Post 훅이 필요한지 정합니다. 우리는 Claude가 특정 파일을 읽는 것 자체를 막고 싶습니다. 만약 Post 훅으로 막으려 하면, 이미 Claude가 파일을 읽은 뒤에 명령이 도는 셈이라 늦습니다. 그래서 읽기 작업이 일어나는 것을 막으려면 반드시 PreToolUse 훅이어야 합니다.
2단계 — 정확히 어떤 종류의 도구 호출을 감시할지 정합니다. Claude Code의 도구 이름을 전부 외우는 건 쉽지 않습니다. 게다가 MCP 서버로 직접 만든 도구까지 추가할 수 있으니 더 그렇죠. 작은 요령이 있습니다. Claude Code를 열어 지금 접근 가능한 도구 이름을 불릿 목록으로 정리해 달라고 직접 물어보면 됩니다.
그 목록 중 파일 내용을 아주 쉽게 읽을 수 있는 도구가 둘 있습니다. 하나는 당연히 Read 도구이고, 놓치기 쉽지만 또 하나는 Grep 도구입니다. Grep은 파일 내용을 검색할 수 있으니까요. 그래서 우리는 Read와 Grep, 두 도구 호출을 감시하려 합니다.
3단계 — Claude가 하려는 도구 호출의 정보를 받는 명령을 작성합니다. 동작 방식은 이렇습니다. 우리가 명령을 적어 두면 Claude가 그 명령을 자동으로 실행하고, 그 프로세스의 표준 입력(stdin)으로 도구 호출 데이터를 JSON으로 흘려보냅니다. 도구 이름과 도구 입력값 등이 담긴 큰 JSON 객체죠. 예를 들어 도구 이름이 read이고, 그 입력의 file_path가 .env 파일을 가리킬 수 있습니다 — 바로 우리가 막고 싶은 그 파일입니다.
그래서 우리 명령 안에서는 이 정보를 stdin으로 받아 JSON을 파싱하고, 도구 이름·입력 인자 등을 읽어 이 호출을 어떻게 할지 결정합니다.
4단계 — 명령이 그 도구 호출 데이터를 받은 뒤, 프로그램을 종료합니다. 그리고 그 종료 코드가 Claude Code에 신호를 보냅니다. 종료 코드 0은 모든 게 괜찮으니 이 도구 호출을 허용하겠다는 뜻입니다. 반면 종료 코드 2는 이 도구 호출을 차단하겠다는 신호입니다. 그리고 이건 PreToolUse 훅에만 적용됩니다 — Pre 훅에서만 실제로 도구를 막을 수 있으니까요.
종료 코드 2로 끝내면, 그동안 명령이 표준 에러(stderr)로 남긴 로그도 Claude에 피드백으로 함께 전달됩니다. 그래서 도구 호출을 거부하면서 동시에 그 이유까지 Claude에 알려 줄 수 있습니다. 이게 전체 과정입니다. 한 번에 많은 내용이라, 다음에는 이 훅을 프로젝트에 실제로 엮는 과정을 처음부터 끝까지 함께 해 보겠습니다.
이 장에서 배우는 것What you'll learn
약 4분목표: Claude가 .env를 못 읽게 차단
막으려면 Pre 훅 — Post는 이미 읽은 뒤라 늦다
감시 도구는 Read · Grep (Grep도 내용을 읽는다)
도구 이름 모를 땐 Claude에게 목록을 물어본다
도구 데이터는 stdin으로 JSON으로 전달
종료 코드 0=허용 · 2=차단 (2는 Pre 전용, stderr 피드백)
새 예제 프로젝트(Query.zip)를 열고 터미널에서 npm run setup을 실행합니다. 우리가 만들 훅의 목표는 하나 — 프로젝트 루트의 민감한 .env 파일을 Claude가 절대 읽지 못하게 막는 것입니다.
$ npm run setup # 의존성 설치 + 훅 준비 added 170 packages $ # 이제 .env 읽기를 막는 훅을 만든다
훅을 만들기 전에 네 가지를 정합니다. 탭을 눌러 각 단계의 질문과 답을 확인하세요.
목표가 "막는 것"이면 거의 항상 Pre 훅입니다. Post 훅은 도구가 이미 돈 뒤라 차단할 수 없기 때문입니다.
도구 이름이 헷갈리면 Claude에게 직접 물어보면 됩니다. 파일 내용을 읽을 수 있는 도구는 Read뿐 아니라 Grep도 있습니다 — Grep은 내용을 검색하니까요.
> 너가 지금 쓸 수 있는 도구 이름을 불릿 목록으로 정리해줘 ● 현재 사용 가능한 도구입니다: · Read # 파일 내용 읽기 · Write # 파일 쓰기 · Edit # 파일 수정 · Grep # 파일 내용 검색 ← 이것도 읽음! · Glob # 파일 경로 찾기 · Bash # 명령 실행
감시할 도구를 정했으면, 이제 명령이 도구 호출 정보를 어떻게 받는지 봅니다. Claude가 명령을 실행하고, 그 프로세스의 stdin으로 도구 데이터를 JSON으로 흘려보냅니다.
// Claude가 stdin으로 흘려보내는 도구 호출 데이터 (예시) { "session_id": "abc-123", "tool_name": "Read", "tool_input": { "file_path": "/home/project/.env" // 막고 싶은 그 파일! } }
명령이 데이터를 받아 판단한 뒤, 종료 코드로 Claude Code에 결과를 알립니다. 0이면 허용, 2면 차단입니다.
허용 (allow)
모든 게 괜찮음. 이 도구 호출을 그대로 진행한다.
차단 (block)
이 도구 호출을 막는다. Pre 훅 전용. stderr 로그가 Claude에 피드백으로 전달.
종료 코드 2로 끝내면, 그동안 stderr에 남긴 로그가 Claude에 피드백으로 전달됩니다. 그래서 거부하면서 동시에 "왜 막았는지"까지 알려 줄 수 있습니다.
Read와 Grep 둘 다. 두 가지를 감시한다.Q1.env 읽기를 막으려면 Pre 훅이어야 하는 이유는?
차단은 도구가 실행되기 전에만 가능합니다. 그래서 PreToolUse 훅이 필요합니다.
Q2파일 내용을 읽을 수 있어 함께 감시해야 하는 도구는?
Grep은 파일 내용을 검색하므로 사실상 내용을 읽습니다. 그래서 Read와 함께 막아야 합니다.
Q3훅 명령에서 도구 호출을 차단하려면?
0은 허용, 2는 차단입니다. 2로 끝내면 stderr 로그가 Claude에 피드백으로 전달됩니다.
설계가 끝났으니, 이제 settings.local.json과 read_hook.js를 실제로 작성해 동작하는 훅을 만들어 봅니다. → 훅 구현하기
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 16개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.