Appearance
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 事件
| 事件 | 触发时机 |
|---|---|
sessionStart | Agent 会话开始 |
sessionEnd | Agent 会话结束 |
beforeShellExecution | 终端命令执行前 |
afterShellExecution | 终端命令执行后 |
beforeReadFile | 文件读取前 |
afterFileEdit | 文件编辑后 |
beforeSubmitPrompt | 提交用户提示词前 |
stop | Agent 循环结束 |
两种 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 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 控制行为。