Cursor hooks 사용법, 에이전트 전후에 뭘 걸 수 있나
Cursor hooks는 에이전트 루프의 전·후 단계에 스크립트를 붙이는 장치입니다. 공식 Hooks 문서 기준으로 sessionStart→도구 before/after→stop/sessionEnd처럼 언제 도는지를 먼저 잡고, hooks.json과 /create-hook로 최소 구성을 올리면 됩니다. 가격·플랜 이야기는 없습니다.
이 글은 저장·커밋 전 가드(afterFileEdit·beforeShellExecution 중심)를 다시 쓰지 않습니다. 수명주기 before/after·hooks.json·/create-hook만 다룹니다.
hook이 실행되는 시점은?
한 줄 답: Agent Chat·Cmd+K에서는 세션 시작 → 프롬프트 제출 → 도구 전/후 → 응답/사고 후 → stop → 세션 종료 순으로 훅이 붙습니다. Tab·워크스페이스 오픈은 별 표면입니다.
공식 문서의 Agent hooks(에이전트 수명주기):
| 구간 | 훅 | 역할(요약) |
|---|---|---|
| 세션 | sessionStart / sessionEnd | 세션 환경·컨텍스트 주입 / 종료 감사(fire-and-forget) |
| 프롬프트 | beforeSubmitPrompt | 전송 직전 검증·차단(continue) |
| 도구 일반 | preToolUse / postToolUse / postToolUseFailure | 모든 도구 전·후·실패 |
| 서브에이전트 | subagentStart / subagentStop | Task 서브에이전트 생성·종료 |
| 셸·MCP | beforeShellExecution·afterShellExecution / beforeMCPExecution·afterMCPExecution | 셸·MCP 전후 통제·감사 |
| 파일 | beforeReadFile / afterFileEdit | 읽기 게이트 / 편집 후 후처리 |
| 컨텍스트 | preCompact | 컴팩션 관찰(차단 불가) |
| 응답 | afterAgentResponse / afterAgentThought | 응답·사고 블록 추적 |
| 루프 종료 | stop | 완료 시 followup_message로 자동 이어가기 가능 |
별 표면:
- Tab hooks:
beforeTabFileRead/afterTabFileEdit— 인라인 Tab 전용 - App:
workspaceOpen— 워크스페이스 오픈·폴더 변경(에이전트 세션 밖)
실무에서 수명주기를 걸 때 자주 쓰는 축은 세 가지입니다.
- 시작·주입 —
sessionStart로env·additional_context(차단은 현재 호출부가 강제하지 않음) - 도구 before/after — 좁은 이벤트(
beforeShellExecution등)를 먼저 쓰고, 전부 보려면preToolUse/postToolUse - 종료·루프 —
stop·subagentStop의followup_message+loop_limit(기본 5)
Cloud agent는 .cursor/hooks.json의 커맨드 훅을 로드합니다. sessionStart/sessionEnd·MCP before/after·Tab·workspaceOpen은 클라우드에서 없거나 지연되며, ~/.cursor/hooks.json 사용자 훅은 홈이 없어 적용되지 않습니다.
hooks.json 최소 예시는?
한 줄 답: version: 1과 hooks 맵이면 됩니다. 프로젝트는 /.cursor/hooks.json(경로는 루트 기준 .cursor/hooks/...), 전역은 ~/.cursor/hooks.json(경로는 ~/.cursor/ 기준). 빠른 생성은 Agent 채팅의 /create-hook.
/create-hook은 공식 Skills 목록에 있는 내장 스킬입니다. 자연어로 “세션 시작 시 감사 로그, stop에서 실패면 follow-up”처럼 요청하면 hooks.json과 스크립트를 스캐폴딩합니다. 손수 쓸 때는 Customize → Hooks 탭과 Hooks 출력 채널로 로드·실행을 확인합니다.
수명주기 최소 예(프로젝트):
{
"version": 1,
"hooks": {
"sessionStart": [
{ "command": ".cursor/hooks/session-init.sh" }
],
"preToolUse": [
{
"command": ".cursor/hooks/validate-tool.sh",
"matcher": "Shell|Task"
}
],
"stop": [
{
"command": ".cursor/hooks/track-stop.sh",
"loop_limit": 5
}
]
}
}
스크립트는 실행 권한이 필요합니다(chmod +x). stdin/stdout으로 JSON을 주고받으며, 기본 타입은 command입니다. 자연어 조건만 보려면 "type": "prompt" 훅도 가능하지만 Cloud에서는 커맨드 훅만 지원합니다.
정의 옵션 요약: command(필수), type, timeout, matcher(정규식 필터), failClosed(기본 false — 실패 시 fail-open), loop_limit(stop/subagentStop).
경로 규칙:
- 프로젝트 훅: 작업 디렉터리 = 프로젝트 루트 →
.cursor/hooks/format.sh - 사용자 훅: 작업 디렉터리 =
~/.cursor/→./hooks/format.sh
우선순위(높→낮): Enterprise → Team → Project → User. 같은 이벤트에 여러 소스가 있으면 모두 실행되고, permission은 deny > ask > allow로 병합됩니다.
실패하면 어디를 보나?
한 줄 답: Customize의 Hooks 탭과 Hooks 출력 채널을 먼저 보고, 경로·실행 권한·exit code·failClosed를 순서대로 점검합니다.
점검 순서:
- 로드 여부 —
hooks.json저장 시 Cursor가 다시 로드합니다. 안 보이면 Customize → Hooks, 그래도 안 되면 Cursor 재시작. - 경로 — 프로젝트는 루트 기준
.cursor/hooks/..., 사용자 훅은~/.cursor/기준../hooks/...를 프로젝트에 쓰면 루트의/hooks를 찾습니다. - 실행 권한·환경 —
chmod +x, 스크립트가 쓰는jq/python등이 훅 환경에 있는지. - exit code —
0= 성공(JSON 사용).2= 차단(permission: "deny"와 동등). 그 외 비정상 = 기본 fail-open(동작은 통과, 로그만). failClosed: true— 크래시·타임아웃·비정상 exit에서도 막고 싶을 때(보안 게이트용). permission 훅은 잘못된 JSON/스키마면failClosed가 false여도 차단합니다.- matcher — 이벤트가 안 뜨면 matcher가 너무 좁은지 확인합니다(
preToolUse는 도구명,beforeShellExecution은 명령 문자열 등).
Cloud에서 안 도는 경우: 사용자 훅만 두었거나, sessionStart/MCP/Tab/workspaceOpen처럼 클라우드 미지원 이벤트인지, 초기 read-only 턴(훅 미로드)인지 확인합니다.
마무리
Cursor hooks 사용법의 핵심은 에이전트 수명주기의 before/after에 무엇을 걸지입니다. sessionStart·도구 전후·stop을 hooks.json에 최소로 두고, 스캐폴딩은 /create-hook로 시작하시면 됩니다. 실패 시에는 Hooks 탭·출력 채널 → 경로·exit code·failClosed 순입니다. 저장·커밋 가드만 필요하면 별도 hooks 가드 글을 보시고, 이벤트 전체는 Hooks를 참고하시기 바랍니다.
출처
- Cursor Hooks — 이벤트 목록,
hooks.json, exit code·failClosed, Cloud 지원 표 - Agent Skills — 내장
/create-hook