Skip to content

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


基本配置格式

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

脚本路径:

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

可用 Hook 事件

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

两种 Hook 类型

命令型(Shell 脚本)

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

sh
#!/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" })。适合做危险操作拦截:

sh
#!/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 判断)

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

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

Matcher:精细控制触发范围

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

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

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


Hook 脚本接收的数据

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

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

实用场景

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

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

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

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

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

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

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

与 Claude Code Hooks 的对比

Cursor HooksClaude Code Hooks
配置文件hooks.jsonsettings.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 控制行为。