Cursor Hooks 是在 Agent 操作前后自动触发的自定义脚本:文件编辑完自动格式化、终端命令执行前做安全审计、会话开始时注入上下文。通过 hooks.json 配置,支持命令型(Shell 脚本)和提示词型(LLM 判断)两种方式,脚本返回 exit code 2 可拦截 Agent 操作。本文介绍 Hooks 的配置格式、全部可用事件、JSON 通信协议和实际用例。

Cursor Hooks:监听并控制 Agent 行为

Agent 每次修改文件、执行命令、开始对话,背后都有一个事件触发点。Cursor Hooks 让你在这些节点插入自定义脚本,实现自动化处理或安全管控。


配置文件位置

  • 用户级(所有项目):~/.cursor/hooks.json
  • 项目级(当前项目):<project>/.cursor/hooks.json

配置优先级:Enterprise > Team > Project > User


基本配置格式

{
  "version": 1,
  "hooks": {
    "afterFileEdit": [
      { "command": "./hooks/format.sh" }
    ],
    "beforeShellExecution": [
      { "command": "./scripts/approve-network.sh" }
    ]
  }
}

脚本路径:

  • 用户级 Hooks 的脚本放 ~/.cursor/hooks/
  • 项目级 Hooks 的脚本放 .cursor/hooks/

可用 Hook 事件

事件 触发时机
sessionStart Agent 会话开始
sessionEnd Agent 会话结束
beforeShellExecution 终端命令执行前
afterShellExecution 终端命令执行后
beforeReadFile 文件读取前
afterFileEdit 文件编辑后
beforeSubmitPrompt 提交用户提示词前
stop Agent 循环结束

两种 Hook 类型

命令型(Shell 脚本)

通过 stdout 返回 JSON,控制 Agent 下一步行为:

#!/bin/bash
# audit.sh - 记录所有 Agent 操作
json_input=$(cat)
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] $json_input" >> /tmp/agent-audit.log
exit 0

关键:exit code 2 = 阻断操作

如果脚本返回 exit code 2,Cursor 会拒绝 Agent 当前操作(等同于返回 { "permission": "deny" })。适合做危险操作拦截:

#!/bin/bash
command=$(cat | python3 -c "import sys,json; print(json.load(sys.stdin).get('command', ''))")
# 禁止 DROP TABLE 操作
if echo "$command" | grep -qi "DROP TABLE"; then
  exit 2
fi
exit 0

提示词型(LLM 判断)

用语言模型来判断是否允许操作,适合需要语义理解的场景:

{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      {
        "prompt": "只允许执行与前端构建相关的命令(npm, vite, tsc)。如果命令与此无关,返回 deny。"
      }
    ]
  }
}

Matcher:精细控制触发范围

matcher 字段限制 Hook 只在特定条件下触发:

{
  "version": 1,
  "hooks": {
    "afterFileEdit": [
      {
        "command": "./hooks/lint.sh",
        "matcher": {
          "glob": "**/*.ts"
        }
      }
    ]
  }
}

只在 .ts 文件被编辑后运行 lint 脚本,避免每次文件变动都触发。


Hook 脚本接收的数据

脚本通过 stdin 接收 JSON 格式的事件数据,可读取:

  • 操作类型(读/写/命令)
  • 文件路径
  • 命令内容
  • Cursor 版本
  • 用户 email
  • 项目目录路径

实用场景

1. 文件编辑后自动格式化

"afterFileEdit": [{ "command": "./hooks/prettier.sh" }]

2. 防止 Agent 提交到保护分支

"beforeShellExecution": [{ "command": "./hooks/check-branch.sh" }]

3. K8s 部署前验证 manifest(Python 脚本检查命名空间是否在允许列表里)

4. 会话开始时注入上下文

"sessionStart": [{ "command": "./hooks/inject-context.sh" }]

与 Claude Code Hooks 的对比

Cursor Hooks Claude Code Hooks
配置文件 hooks.json settings.json
配置位置 ~/.cursor/.cursor/ ~/.claude/.claude/
拦截机制 exit code 2 {"decision":"block"}
提示词型 支持 支持
事件粒度 文件/命令/会话 工具/命令/会话

常见问题

Q: 写了 Hook 但没有触发,怎么排查?

① 检查 hooks.json JSON 格式是否正确;② 脚本是否有可执行权限(chmod +x);③ Cursor 会自动监听 hooks 配置文件变化,修改后无需重启。可以在脚本里加 echo 写日志来确认是否被调用。

Q: Hook 脚本运行失败(非 exit 2)会影响 Agent 吗?

脚本异常退出(exit 1)通常不会阻断 Agent,只有 exit 2 才触发拦截。建议在脚本里做好错误处理,避免意外行为。

Q: 能用 Node.js 或 Python 写 Hook 吗?

可以,任何可执行文件都行。只需在 command 字段写好调用命令(如 "command": "node ./hooks/my-hook.js"),通过 stdin 读取 JSON 输入,通过 exit code 控制行为。