개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Hooks — Claude Code 이벤트에 셸 명령 자동 실행

2025년 12월 22일
Claude CodeHooks자동화이벤트제어

Claude Code가 파일을 수정할 때마다 린터를 자동으로 실행하고 싶습니다. 또는 특정 명령은 절대 실행하지 못하도록 막고 싶습니다. Hooks가 이를 가능하게 합니다.

Hooks란

Claude Code의 이벤트 생명주기에 셸 명령을 연결하는 기능입니다. 이벤트가 발생할 때 지정한 명령이 자동으로 실행됩니다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": "npm run lint" }]
      }
    ]
  }
}

설정 파일(settings.json)에 작성하며, 프로젝트별 또는 전역으로 적용할 수 있습니다.

이벤트 종류

SessionStart

Claude Code 세션이 시작될 때 실행됩니다.

"SessionStart": [
  {
    "hooks": [{ "type": "command", "command": "echo '세션 시작' >> .claude/session.log" }]
  }
]

환경 설정, 로그 기록, 초기화 작업에 씁니다.

UserPromptSubmit

사용자가 메시지를 입력할 때 실행됩니다.

"UserPromptSubmit": [
  {
    "hooks": [{ "type": "command", "command": "node scripts/check-policy.js" }]
  }
]

입력 내용 검사, 정책 확인, 컨텍스트 주입에 씁니다.

PreToolUse

도구가 실행되기 직전에 실행됩니다. 반환 값으로 실행을 허용하거나 거부할 수 있습니다. 스크립트가 0을 반환하면 허용, 비-0을 반환하면 해당 도구 실행을 차단합니다.

"PreToolUse": [
  {
    "matcher": "Bash",
    "hooks": [{ "type": "command", "command": "node scripts/validate-command.js" }]
  }
]

PostToolUse

도구 실행이 완료된 직후 실행됩니다.

"PostToolUse": [
  {
    "matcher": "Edit|Write",
    "hooks": [{ "type": "command", "command": "npm run lint --fix" }]
  }
]

린팅, 포맷팅, 테스트 실행 등 후처리 작업에 씁니다.

Stop

Claude Code가 응답을 완료했을 때 실행됩니다.

"Stop": [
  {
    "hooks": [{ "type": "command", "command": "notify-send '작업 완료'" }]
  }
]

알림 발송, 로그 기록, 정리 작업에 씁니다.

Notification

Claude Code가 알림을 보낼 때 실행됩니다.

"Notification": [
  {
    "hooks": [{ "type": "command", "command": "node scripts/send-slack.js" }]
  }
]

Matcher — 특정 도구에만 적용

matcher로 Hook을 적용할 도구를 필터링합니다.

"PostToolUse": [
  {
    "matcher": "Edit",
    "hooks": [{ "type": "command", "command": "npm run lint" }]
  },
  {
    "matcher": "Bash",
    "hooks": [{ "type": "command", "command": "echo 'Bash 실행됨' >> .claude/commands.log" }]
  }
]

matcher를 생략하면 모든 도구에 적용됩니다.

additionalContext — 컨텍스트 주입

Hook 스크립트가 텍스트를 반환하면 Claude의 컨텍스트에 추가됩니다. Claude는 이 정보를 참고해 더 적합한 응답을 생성합니다.

"UserPromptSubmit": [
  {
    "hooks": [{
      "type": "command",
      "command": "node scripts/inject-context.js"
    }]
  }
]
// scripts/inject-context.js
const branch = require('child_process')
  .execSync('git branch --show-current')
  .toString().trim();
process.stdout.write(`현재 브랜치: ${branch}`);

Claude가 현재 Git 브랜치, 환경 변수, 팀 정책 등을 자동으로 알게 할 수 있습니다.

Decision — 실행 허용/거부

PreToolUse Hook에서 도구 실행을 제어합니다.

// scripts/validate-command.js
const input = JSON.parse(process.env.CLAUDE_TOOL_INPUT);
const command = input.command;

// 위험한 명령 차단
if (command.includes('DROP TABLE') || command.includes('rm -rf /')) {
  process.exit(1);  // 거부
}

process.exit(0);  // 허용

설정 파일 위치

~/.claude/settings.json          # 전역 (모든 프로젝트)
.claude/settings.json            # 프로젝트 (해당 프로젝트만)
.claude/settings.local.json      # 로컬 (Git에 포함하지 않음)

/hooks 명령

claude> /hooks

현재 설정된 Hook 목록을 확인하고 편집할 수 있습니다.

← 이전 글Session & Context — 대화와 작업 상태 유지하기
다음 글 →Slash Commands — 반복 작업을 명령 하나로