Skip to main content

Command Palette

Search for a command to run...

自定义

钩子

钩子可让你通过自定义脚本观察、控制和扩展智能体循环。你可以在项目级或用户级的 hooks.json 文件中定义钩子,也可以通过 自定义 中的插件安装钩子。钩子是通过 stdio 使用 JSON 进行双向通信的子进程。它们会在智能体循环中定义的各个阶段之前或之后运行,并可观察、阻止或修改行为。

借助钩子,你可以:

  • 在编辑后运行格式化工具
  • 为事件添加使用分析
  • 扫描 PII 或机密信息
  • 限制高风险操作 (例如 SQL 写入)
  • 控制子智能体 (Task tool) 的执行
  • 在会话开始时注入上下文

钩子类别

钩子按触发条件分为三类:

智能体钩子 (Cmd+K/Agent Chat) 在智能体会话期间触发:

  • sessionStart / sessionEnd - 管理会话生命周期
  • preToolUse / postToolUse / postToolUseFailure - 通用工具使用钩子 (对所有工具触发)
  • subagentStart / subagentStop - 子智能体 (Task 工具) 生命周期
  • beforeShellExecution / afterShellExecution - 控制 shell 命令
  • beforeMCPExecution / afterMCPExecution - 控制 MCP 工具的使用
  • beforeReadFile / afterFileEdit - 控制文件访问和编辑
  • beforeSubmitPrompt - 在提交前验证提示词
  • preCompact - 监测上下文窗口压缩
  • stop - 处理智能体完成事件
  • afterAgentResponse / afterAgentThought - 跟踪智能体响应

**Tab 钩子 (行内补全) **在自主 Tab 操作期间触发:

  • beforeTabFileRead - 控制 Tab 补全的文件访问
  • afterTabFileEdit - 对 Tab 编辑进行后处理

应用生命周期钩子在任何智能体会话之外触发:

  • workspaceOpen - 在 Cursor 打开工作区以及每次工作区文件夹变更时触发。可返回要为当前工作区加载的额外插件路径。

这些独立的钩子入口可让您针对自主 Tab 操作、用户驱动的 Agent 操作和工作区启动应用不同的策略。

云端代理支持

云端代理会运行代码仓库中的基于命令的钩子。如果你在项目根目录的 .cursor/hooks.json 中定义了钩子,云端代理会自动加载并在工作过程中运行这些钩子。

在企业版方案中,云端代理还会运行通过网页仪表盘配置的团队钩子和由企业统一管理的钩子。

云端代理有时会在早期探索轮次中以只读环境启动。这些轮次不会运行钩子。智能体获得可写环境后,钩子便会开始运行。

支持的钩子

云端代理支持以下钩子:

钩子是否支持
beforeShellExecution
afterShellExecution
beforeReadFile
afterFileEdit
preToolUse
postToolUse
postToolUseFailure
subagentStart
subagentStop
beforeSubmitPrompt
preCompact
afterAgentResponse
afterAgentThought
stop

云端代理不支持的钩子

由于执行环境不同,部分钩子不适用于云端代理:

钩子原因
sessionStart因云端代理仍可能在只读环境中启动,暂不支持。在该环境中钩子不会加载,因此云端 sessionStart 会在首次写入后才触发,而非在会话真正开始时。
sessionEnd云端代理没有以编辑器生命周期为界的会话边界。sessionEnd 与 IDE 会话关联,而非云端代理聊天。
beforeMCPExecution / afterMCPExecution因云端代理仍可能在钩子不会加载的只读环境中启动,且 MCP 钩子的触发时机尚不明确,暂不支持。
beforeTabFileRead / afterTabFileEditTab 补全是 IDE 功能,不会在云端代理中运行。
workspaceOpen这是 IDE 生命周期钩子,不适用于云端代理。

配置来源

云端代理会从以下来源加载 hooks:

  • 项目 hooks (仓库中的 .cursor/hooks.json) :在云端代理执行任务时加载并运行。
  • 团队 hooks (企业版) :从仪表盘分发,并在云端代理中运行。
  • 企业版 hooks (企业版) :由系统统一管理,并在云端代理中运行。

用户级 hooks (~/.cursor/hooks.json) 无法在云端代理中使用。云端代理 VM 无法访问本地主目录中的配置。

执行类型限制

云端代理仅支持运行基于命令的钩子。基于提示词的钩子需要在钩子与智能体循环之间配置身份验证连接,而云端执行环境不提供此功能。

快速开始

创建 hooks.json 文件。你可以在项目级别 (<project>/.cursor/hooks.json) 或主目录 (~/.cursor/hooks.json) 中创建。项目 hooks 仅适用于特定项目,主目录 hooks 则全局适用。

如需创建全局适用的用户级 hooks,请创建 ~/.cursor/hooks.json

{  "version": 1,  "hooks": {    "afterFileEdit": [{ "command": "./hooks/format.sh" }]  }}

~/.cursor/hooks/format.sh 中创建钩子脚本:

#!/bin/bash# 读取输入,执行操作,然后以 0 退出cat > /dev/nullexit 0

将其设为可执行:

chmod +x ~/.cursor/hooks/format.sh

Cursor 会监视 hooks 配置文件并自动重新加载。每次编辑文件后,都会运行你的钩子。

钩子类型

钩子支持两种执行类型:基于命令 (默认) 和基于提示词 (由 LLM 评测) 。

基于命令的钩子

命令钩子会执行 shell 脚本,脚本通过 stdin 接收 JSON 输入,并通过 stdout 返回 JSON 输出。

{  "hooks": {    "beforeShellExecution": [      {        "command": "./scripts/approve-network.sh",        "timeout": 30,        "matcher": "curl|wget|nc"      }    ]  }}

退出码行为:

  • 退出码 0 - 钩子执行成功,使用 JSON 输出
  • 退出码 2 - 阻止该操作 (等同于返回 permission: "deny")
  • 其他退出码 - 钩子执行失败,操作仍会继续 (默认失败时放行)

基于提示词的钩子

提示词钩子使用 LLM 评估自然语言条件,适用于无需编写自定义脚本的策略执行。

{  "hooks": {    "beforeShellExecution": [      {        "type": "prompt",        "prompt": "Does this command look safe to execute? Only allow read-only operations.",        "timeout": 10      }    ]  }}

功能:

  • 返回结构化的 { ok: boolean, reason?: string } 响应
  • 使用快速模型进行快速评测
  • $ARGUMENTS 占位符会自动替换为钩子输入 JSON
  • 如果未提供 $ARGUMENTS,则会自动追加钩子输入
  • 可通过可选的 model 字段覆盖默认 LLM 模型

示例

{  "version": 1,  "hooks": {    "sessionStart": [      {        "command": "./hooks/session-init.sh"      }    ],    "sessionEnd": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeShellExecution": [      {        "command": "./hooks/audit.sh"      },      {        "command": "./hooks/block-git.sh"      }    ],    "beforeMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterShellExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterFileEdit": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeSubmitPrompt": [      {        "command": "./hooks/audit.sh"      }    ],    "preCompact": [      {        "command": "./hooks/audit.sh"      }    ],    "stop": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeTabFileRead": [      {        "command": "./hooks/redact-secrets-tab.sh"      }    ],    "afterTabFileEdit": [      {        "command": "./hooks/format-tab.sh"      }    ]  }}

TypeScript stop 自动化钩子

需要在同一钩子中使用类型化 JSON、持久化文件 I/O 和 HTTP 调用时,可选择 TypeScript。这个由 Bun 驱动的 stop 钩子会在磁盘上记录每个对话的失败次数,将结构化遥测数据转发到内部 API,并可在智能体连续失败两次后自动安排重试。

{  "version": 1,  "hooks": {    "stop": [      {        "command": "bun run .cursor/hooks/track-stop.ts --stop"      }    ]  }}

AGENT_TELEMETRY_URL 设置为接收运行摘要的内部端点。

Python 清单保护钩子

需要强大的解析库时,Python 是理想选择。此钩子会在运行 kubectl apply 前使用 pyyaml 检查 Kubernetes 清单;Bash 难以安全解析多文档 YAML。

{  "version": 1,  "hooks": {    "beforeShellExecution": [      {        "command": "python3 .cursor/hooks/kube_guard.py"      }    ]  }}

在运行钩子脚本的环境中安装 PyYAML (例如 pip install pyyaml) ,确保可成功导入解析器。

合作伙伴集成

我们与已为 Cursor 构建钩子支持的生态合作伙伴合作。这些集成涵盖安全扫描、治理、机密信息管理等。

MCP 治理与可见性

合作伙伴描述
MintMCP建立完整的 MCP 服务器清单,监控工具使用模式,并在响应到达 AI 模型前扫描敏感数据。
Oasis Security对 AI 智能体操作实施最小权限策略,并在企业系统中保留完整的审计追踪记录。
Runlayer封装 MCP 工具,并集成其 MCP 代理,以集中管控和监测智能体与工具之间的交互。

代码安全与最佳实践

合作伙伴描述
Corridor在编写代码的同时,针对代码实现和安全设计决策获得实时反馈。
Semgrep自动扫描 AI 生成的代码中的漏洞,并提供实时反馈以重新生成代码,直至解决安全问题。

依赖项安全

合作伙伴描述
Endor Labs拦截软件包安装并扫描恶意依赖项,在供应链攻击进入您的代码库前加以阻止。

智能体安全与防护

合作伙伴描述
Snyk借助 Evo Agent Guard 实时评审智能体操作,检测并防范提示词注入、危险工具调用等问题。

机密信息管理

合作伙伴描述
1Password在执行 shell 命令前,验证来自 1Password Environments 的环境文件是否已正确挂载,以便在不将凭据写入磁盘的情况下按需访问机密信息。

有关钩子合作伙伴的更多信息,请参阅博客文章 《面向安全和平台团队的 Hooks》

配置

hooks.json 文件中定义钩子。配置可存在于多个层级。所有来源中匹配的钩子都会运行;如果响应冲突,合并时优先采用优先级更高来源的响应:

~/.cursor/├── hooks.json└── hooks/    ├── audit.sh    └── block-git.sh
  • 企业版 (由 MDM 管理,适用于全系统) :
    • macOS:/Library/Application Support/Cursor/hooks.json
    • Linux/WSL:/etc/cursor/hooks.json
    • Windows:C:\\ProgramData\\Cursor\\hooks.json
  • 团队 (通过云端分发,仅限企业版) :
  • 项目 (项目专用) :
    • <project-root>/.cursor/hooks.json
    • 项目 hooks 会在任何受信任的工作区中运行,并随项目一同提交到版本控制
  • 用户 (用户专用) :
    • ~/.cursor/hooks.json

优先级顺序 (从高到低) :企业版 → 团队 → 项目 → 用户

hooks 对象将 hook 名称映射到 hook 定义数组。每个定义目前支持 command 属性,其值可以是 shell 字符串、绝对路径或相对路径。工作目录取决于 hook 的来源:

  • 项目 hooks (代码仓库中的 .cursor/hooks.json) :从项目根目录运行
  • 用户 hooks (~/.cursor/hooks.json) :从 ~/.cursor/ 运行
  • 企业版 hooks (全系统配置) :从企业版配置目录运行
  • 团队 hooks (通过云端分发) :从受管 hooks 目录运行

对于项目 hooks,请使用 .cursor/hooks/script.sh 这类路径 (相对于项目根目录) ,而不要使用 ./hooks/script.sh (后者会查找 <project>/hooks/script.sh) 。

配置文件

此示例展示用户级钩子文件 (~/.cursor/hooks.json) 。对于项目级钩子,请将 ./hooks/script.sh 之类的路径改为 .cursor/hooks/script.sh

{  "version": 1,  "hooks": {    "sessionStart": [{ "command": "./session-init.sh" }],    "sessionEnd": [{ "command": "./audit.sh" }],    "preToolUse": [      {        "command": "./hooks/validate-tool.sh",        "matcher": "Shell|Read|Write"      }    ],    "postToolUse": [{ "command": "./hooks/audit-tool.sh" }],    "subagentStart": [{ "command": "./hooks/validate-subagent.sh" }],    "subagentStop": [{ "command": "./hooks/audit-subagent.sh" }],    "beforeShellExecution": [{ "command": "./script.sh" }],    "afterShellExecution": [{ "command": "./script.sh" }],    "afterMCPExecution": [{ "command": "./script.sh" }],    "afterFileEdit": [{ "command": "./format.sh" }],    "preCompact": [{ "command": "./audit.sh" }],    "stop": [{ "command": "./audit.sh", "loop_limit": 10 }],    "beforeTabFileRead": [{ "command": "./redact-secrets-tab.sh" }],    "afterTabFileEdit": [{ "command": "./format-tab.sh" }],    "workspaceOpen": [{ "command": "./register-workspace-plugins.sh" }]  }}

智能体钩子 (sessionStartsessionEndpreToolUsepostToolUsepostToolUseFailuresubagentStartsubagentStopbeforeShellExecutionafterShellExecutionbeforeMCPExecutionafterMCPExecutionbeforeReadFileafterFileEditbeforeSubmitPromptpreCompactstopafterAgentResponseafterAgentThought) 适用于 Cmd+K 和 Agent Chat 操作。Tab 钩子 (beforeTabFileReadafterTabFileEdit) 专用于内联 Tab 补全。应用生命周期钩子 (workspaceOpen) 会在工作区打开时以及工作区文件夹发生更改时触发,与任何智能体会话无关。

全局配置选项

选项类型默认值描述
versionnumber1配置架构版本

单个脚本的配置选项

选项类型默认值描述
commandstring必填脚本路径或命令
type"command""prompt""command"
timeoutnumber平台默认值执行超时时间 (秒)
loop_limitnumbernull5
failClosedbooleanfalse当为 true 时,钩子失败 (崩溃、超时、无效 JSON) 会阻止该操作,而非允许其继续执行。适用于安全性要求较高的钩子。
matcherobject-钩子运行条件的筛选标准

匹配器配置

匹配器可用于筛选钩子的运行时机。匹配器适用于哪个字段取决于钩子类型:

{  "hooks": {    "preToolUse": [      {        "command": "./validate-shell.sh",        "matcher": "Shell"      }    ],    "subagentStart": [      {        "command": "./validate-explore.sh",        "matcher": "explore|shell"      }    ],    "beforeShellExecution": [      {        "command": "./approve-network.sh",        "matcher": "curl|wget|nc "      }    ]  }}
  • subagentStart:匹配器会匹配子智能体类型 (例如 exploreshellgeneralPurpose) 。可用于仅在启动特定类型的子智能体时运行钩子。上述示例仅对 explore 或 shell 子智能体运行 validate-explore.sh
  • beforeShellExecution:匹配器会匹配shell 命令字符串。可用于仅在命令匹配某个模式时运行钩子 (例如网络调用、删除文件) 。上述示例仅当命令包含 curlwgetnc 时运行 approve-network.sh

各钩子可用的匹配器:

  • preToolUse / postToolUse / postToolUseFailure:按工具类型筛选。可选值包括 ShellReadWriteGrepDeleteTask,以及采用 MCP:<tool_name> 格式的 MCP 工具。
  • subagentStart / subagentStop:按子智能体类型筛选 (generalPurposeexploreshell 等) 。
  • beforeShellExecution / afterShellExecution:按 shell 命令文本筛选;匹配器会与完整的命令字符串匹配。
  • beforeReadFile:按工具类型筛选 (TabReadRead 等) 。
  • afterFileEdit:按工具类型筛选 (TabWriteWrite 等) 。
  • beforeSubmitPrompt:匹配值 UserPromptSubmit
  • stop:匹配值 Stop
  • afterAgentResponse:匹配值 AgentResponse
  • afterAgentThought:匹配值 AgentThought

团队分发

可通过项目 hooks (使用版本控制) 、MDM 工具或 Cursor 云分发系统向团队成员分发 hooks。

项目 hooks (版本控制)

项目 hooks 是与团队共享 hooks 最简单的方式。将 hooks.json 文件放在 <project-root>/.cursor/hooks.json 路径下,并提交到代码仓库。团队成员在受信任的工作区中打开项目时,Cursor 会自动加载并运行项目 hooks。

云端代理在云端处理您的代码仓库时,也会加载这些项目 hooks。

项目 hooks:

  • 与代码一同存储在版本控制中
  • 会在受信任的工作区中为所有团队成员自动加载
  • 可以针对特定项目设置 (例如,为特定代码库强制执行格式规范)
  • 只能在受信任的工作区中运行 (出于安全考虑)

通过 MDM 分发

使用移动设备管理 (MDM) 工具在组织内分发钩子。在每台设备的目标目录中放置 hooks.json 文件和钩子脚本。

用户主目录 (按用户分发) :

  • ~/.cursor/hooks.json
  • ~/.cursor/hooks/ (存放钩子脚本)

全局目录 (系统级分发) :

  • macOS:/Library/Application Support/Cursor/hooks.json
  • Linux/WSL:/etc/cursor/hooks.json
  • Windows:C:\\ProgramData\\Cursor\\hooks.json

注意:基于 MDM 的分发完全由您的组织负责管理。Cursor 不会通过您的 MDM 解决方案部署或管理文件。请确保内部 IT 或安全团队按照组织策略处理配置、部署和更新。

云端分发 (仅限企业版)

企业版团队可使用 Cursor 原生的云端分发功能,自动将钩子同步给所有团队成员。在网页仪表盘中配置钩子后,团队成员登录时,Cursor 会自动将已配置的钩子部署到所有客户端设备。

云端分发提供:

  • 每三十分钟自动同步给所有团队成员
  • 可按操作系统为特定平台配置钩子
  • 通过仪表盘集中管理

企业管理员无需访问个人设备,即可通过仪表盘创建、编辑和管理团队钩子。

联系销售,获取企业版云端钩子分发功能。

参考

通用架构

输入 (所有钩子)

除钩子特有的字段外,所有钩子还会接收一组基础字段:

{  "conversation_id": "string",  "generation_id": "string",  "model": "string",  "model_id": "string",  "model_params": [{ "id": "string", "value": "string" }],  "hook_event_name": "string",  "cursor_version": "string",  "workspace_roots": ["<path>"],  "user_email": "string | null",  "transcript_path": "string | null"}
字段类型描述
conversation_idstring对话在多个轮次中保持不变的稳定 ID
generation_idstring随每条用户消息变化的当前 generation
modelstring为触发该钩子的 composer 配置的旧版模型 slug
model_idstring (optional)所选模型的结构化 ID (如有)
model_paramsarray (optional)所选模型的参数,如思考、上下文或 effort。每项均包含 idvalue
hook_event_namestring正在运行的钩子名称
cursor_versionstringCursor 应用版本 (例如 "1.7.2")
workspace_rootsstring[]工作区根文件夹列表 (通常只有一个,但多根工作区可以有多个)
user_emailstringnull已认证用户的电子邮件地址 (如有)
transcript_pathstringnull主对话会话记录文件的路径 (禁用会话记录时为 null)

钩子事件

preToolUse

在执行任何工具前调用。这是适用于所有工具类型 (Shell、Read、Write、MCP、Task 等) 的通用钩子。可使用匹配器按特定工具筛选。

// 输入{  "tool_name": "Shell",  "tool_input": { "command": "npm install", "working_directory": "/project" },  "tool_use_id": "abc123",  "cwd": "/project",  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ],  "agent_message": "Installing dependencies..."}// 输出{  "permission": "allow" | "deny",  "user_message": "<message shown in client when denied>",  "agent_message": "<message sent to agent when denied>",  "updated_input": { "command": "npm ci" }}
输出字段类型描述
permissionstring"allow" 表示允许继续,"deny" 表示阻止。架构接受 "ask",但目前不会对 preToolUse 强制执行。
user_messagestring (可选)操作被拒绝时向用户显示的消息
agent_messagestring (可选)操作被拒绝时反馈给智能体的消息
updated_inputobject (可选)要改用的修改后的工具输入

postToolUse

在工具成功执行后触发。可用于审计、使用分析和注入上下文。

// 输入{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_output": "{\"exitCode\":0,\"stdout\":\"All tests passed\"}",  "tool_use_id": "abc123",  "cwd": "/project",  "duration": 5432,  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ]}// 输出{  "updated_mcp_tool_output": { "modified": "output" },  "additional_context": "Test coverage report attached."}
输入字段类型描述
durationnumber执行耗时 (毫秒)
tool_outputstring工具返回的 JSON 字符串化结果负载 (而非原始终端文本)
输出字段类型描述
updated_mcp_tool_outputobject (optional)仅适用于 MCP 工具:替换模型所见的工具输出
additional_contextstring (optional)工具结果返回后注入对话的额外上下文

postToolUseFailure

在工具执行失败、超时或被拒绝时调用。适用于错误追踪和恢复逻辑。

// 输入{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_use_id": "abc123",  "cwd": "/project",  "error_message": "Command timed out after 30s",  "failure_type": "timeout" | "error" | "permission_denied",  "duration": 5000,  "is_interrupt": false}// 输出{  // 目前不支持任何输出字段}
输入字段类型描述
error_messagestring失败原因
failure_typestring失败类型:"error""timeout""permission_denied"
durationnumber发生失败前的时间 (毫秒)
is_interruptboolean此失败是否由用户中断或取消导致

subagentStart

在启动子智能体 (Task 工具) 之前调用。可允许或拒绝创建子智能体。

// 输入{  "subagent_id": "abc-123",  "subagent_type": "generalPurpose",  "task": "Explore the authentication flow",  "parent_conversation_id": "conv-456",  "tool_call_id": "tc-789",  "subagent_model": "claude-sonnet-4-20250514",  "is_parallel_worker": false,  "git_branch": "feature/auth"}// 输出{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
输入字段类型描述
subagent_idstring此子智能体实例的唯一标识符
subagent_typestring子智能体类型:generalPurposeexploreshell
taskstring分配给子智能体的任务描述
parent_conversation_idstring父智能体会话的对话 ID
tool_call_idstring触发该子智能体的工具调用 ID
subagent_modelstring子智能体将使用的模型
is_parallel_workerboolean此子智能体是否作为并行工作器运行
git_branchstring (optional)子智能体将操作的 Git 分支 (如适用)
输出字段类型描述
permissionstring"allow" 表示允许继续,"deny" 表示阻止。subagentStart 不支持 "ask",并将其视为 "deny"
user_messagestring (optional)子智能体被拒绝时向用户显示的消息

subagentStop

子智能体完成、出错或被中止时调用。可触发后续操作。

// 输入{  "subagent_type": "generalPurpose",  "status": "completed" | "error" | "aborted",  "task": "Explore the authentication flow",  "description": "Exploring auth flow",  "summary": "<subagent output summary>",  "duration_ms": 45000,  "message_count": 12,  "tool_call_count": 8,  "loop_count": 0,  "modified_files": ["src/auth.ts"],  "agent_transcript_path": "/path/to/subagent/transcript.txt"}// 输出{  "followup_message": "<auto-continue with this message>"}
输入字段类型描述
subagent_typestring子智能体类型:generalPurposeexploreshell
statusstring"completed""error""aborted"
taskstring提供给子智能体的任务描述
descriptionstring子智能体用途的简要说明
summarystring子智能体的输出摘要
duration_msnumber以毫秒为单位的执行时间
message_countnumber子智能体会话期间交换的消息数量
tool_call_countnumber子智能体发起的工具调用次数
loop_countnumber此子智能体已触发的 subagentStop 后续操作次数 (从 0 开始)
modified_filesstring[]子智能体修改的文件
agent_transcript_pathstringnull子智能体自身会话记录文件的路径 (与父对话分开)
输出字段类型描述
followup_messagestring (可选)使用此消息自动继续。仅当 status"completed" 时使用。

followup_message 字段支持循环式流程:子智能体完成后会触发下一次迭代。后续操作与 stop 钩子使用相同的可配置循环限制 (默认值为 5,可通过 loop_limit 配置) 。

beforeShellExecution / beforeMCPExecution

在执行任何 shell 命令或 MCP 工具前调用。返回权限判定。

// beforeShellExecution 输入{  "command": "<full terminal command>",  "cwd": "<current working directory>",  "sandbox": false}// beforeMCPExecution 输入{  "tool_name": "<tool name>",  "tool_input": "<json params>"}// 另外必须提供以下之一:{ "url": "<server url>" }// 或:{ "command": "<command string>" }// 输出{  "permission": "allow" | "deny" | "ask",  "user_message": "<message shown in client>",  "agent_message": "<message sent to agent>"}

afterShellExecution

在 shell 命令执行后触发;可用于审计或从命令输出中收集指标。

// 输入{  "command": "<full terminal command>",  "output": "<full terminal output>",  "duration": 1234,  "sandbox": false}
字段类型描述
commandstring已执行的完整终端命令
outputstring从终端捕获的完整输出
durationnumber执行 shell 命令耗时 (毫秒,不包括等待批准的时间)
sandboxboolean命令是否在沙盒环境中运行

afterMCPExecution

在 MCP 工具执行后触发;包含该工具的输入参数和完整的 JSON 结果。

// 输入{  "tool_name": "<tool name>",  "tool_input": "<json params>",  "result_json": "<tool result json>",  "duration": 1234}
字段类型描述
tool_namestring已执行的 MCP 工具的名称
tool_inputstring传递给工具的 JSON 参数 string
result_jsonstring工具响应的 JSON string
durationnumber执行 MCP 工具所用时长 (单位为毫秒,不包括等待批准的时间)

afterFileEdit

智能体编辑文件后触发;可用于格式化或统计智能体编写的代码。

// 输入{  "file_path": "<absolute path>",  "edits": [{ "old_string": "<search>", "new_string": "<replace>" }]}

beforeReadFile

在智能体读取文件前调用。可用于访问控制,防止将敏感文件发送给模型。

// 输入{  "file_path": "<absolute path>",  "content": "<file contents>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// 输出{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
输入字段类型描述
file_pathstring正在读取的文件的绝对路径
contentstring文件的完整内容
attachmentsarray与提示词关联的上下文附件。每个条目都包含 type ("file""rule") 和 file_path
输出字段类型描述
permissionstring"allow" 表示继续,"deny" 表示阻止
user_messagestring (optional)拒绝时向用户显示的消息

beforeTabFileRead

在 Tab (内联补全) 读取文件前调用。可在 Tab 访问文件内容前启用脱敏或访问控制。

beforeReadFile 的主要区别:

  • 仅由 Tab 触发,不会由智能体触发
  • 不包含 attachments 字段 (Tab 不使用提示词附件)
  • 可用于对自主运行的 Tab 操作应用不同策略
// 输入{  "file_path": "<absolute path>",  "content": "<file contents>"}// 输出{  "permission": "allow" | "deny"}

afterTabFileEdit

Tab (内联补全) 编辑文件后调用。适用于格式化工具或审计 Tab 写入的代码。

afterFileEdit 的主要区别:

  • 仅由 Tab 触发,不由智能体触发
  • 包含详细的编辑信息:rangeold_linenew_line,可精确跟踪编辑内容
  • 适用于对 Tab 编辑进行细粒度格式化或分析
// 输入{  "file_path": "<absolute path>",  "edits": [    {      "old_string": "<search>",      "new_string": "<replace>",      "range": {        "start_line_number": 10,        "start_column": 5,        "end_line_number": 10,        "end_column": 20      },      "old_line": "<line before edit>",      "new_line": "<line after edit>"    }  ]}// 输出{  // 目前不支持输出字段}

beforeSubmitPrompt

用户点击发送后、发起后端请求前立即调用。可阻止提交。

// 输入{  "prompt": "<user prompt text>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// 输出{  "continue": true | false,  "user_message": "<message shown to user when blocked>"}
输出字段类型描述
continueboolean是否允许继续提交提示词
user_messagestring (可选)提示词被阻止时显示给用户的消息

afterAgentResponse

智能体完成助手消息后调用。

// 输入{  "text": "<assistant final text>"}

afterAgentThought

智能体完成一个思考块后调用。可用于观察智能体的推理过程。

// 输入{  "text": "<fully aggregated thinking text>",  "duration_ms": 5000}// 输出{  // 目前不支持输出字段}
字段类型描述
textstring已完成块的完整聚合思考文本
duration_msnumber (可选)思考块的持续时间 (毫秒)

stop

智能体循环结束时触发。可选择自动提交后续用户消息,以继续迭代。

// 输入{  "status": "completed" | "aborted" | "error",  "loop_count": 0}
// 输出{  "followup_message": "<message text>"}
  • 可选的 followup_message 为 string。提供且非空时,Cursor 会自动将其提交为下一条用户消息。这支持循环式流程 (例如,迭代直至达成目标) 。
  • loop_count 字段表示 stop 钩子已为此对话自动触发后续消息的次数 (初始值为 0) 。默认情况下,每个脚本最多可自动发送 5 条后续消息,可通过 loop_limit 选项配置。将 loop_limit 设为 null 可取消此上限。同样的限制也适用于 subagentStop 后续消息。

sessionStart

创建新的 composer 对话时触发。此钩子以即发即弃方式运行;智能体循环不会等待或强制执行阻塞式响应。可用于设置会话专用环境变量或注入额外上下文。

// 输入{  "session_id": "<unique session identifier>",  "is_background_agent": true | false,  "composer_mode": "agent" | "ask" | "edit"}
// 输出{  "env": { "<key>": "<value>" },  "additional_context": "<context to add to conversation>"}
输入字段类型描述
session_idstring此会话的唯一标识符 (与 conversation_id 相同)
is_background_agentboolean此会话是后台智能体会话还是交互式会话
composer_modestring (可选)composer 启动时的模式 (例如 "agent"、"ask"、"edit")
输出字段类型描述
envobject (可选)为此会话设置的环境变量,可供后续所有钩子执行使用
additional_contextstring (可选)要添加到对话初始系统上下文中的额外上下文

sessionEnd

composer 对话结束时调用。这是一个即发即弃的钩子,适用于日志记录、使用分析或清理任务。响应会被记录,但不会使用。

// 输入{  "session_id": "<唯一会话标识符>",  "reason": "completed" | "aborted" | "error" | "window_close" | "user_close",  "duration_ms": 45000,  "is_background_agent": true | false,  "final_status": "<状态字符串>",  "error_message": "<当 reason 为 'error' 时的错误详情>"}
// 输出{  // 无输出字段——触发后不等待结果}
输入字段类型描述
session_idstring即将结束的会话的唯一标识符
reasonstring会话结束原因:"completed"、"aborted"、"error"、"window_close" 或 "user_close"
duration_msnumber会话总时长 (毫秒)
is_background_agentboolean是否为后台智能体会话
final_statusstring会话的最终状态
error_messagestring (optional)当原因是 "error" 时的错误消息

preCompact

在上下文窗口压缩/摘要之前调用。这是一个仅用于观察的钩子,无法阻止或修改压缩行为。可用于记录压缩发生的时间或通知用户。

// 输入{  "trigger": "auto" | "manual",  "context_usage_percent": 85,  "context_tokens": 120000,  "context_window_size": 128000,  "message_count": 45,  "messages_to_compact": 30,  "is_first_compaction": true | false}
// 输出{  "user_message": "<message to show when compaction occurs>"}
输入字段类型描述
triggerstring触发压缩的方式:"auto" 或 "manual"
context_usage_percentnumber当前上下文窗口用量百分比 (0-100)
context_tokensnumber当前上下文窗口的 token 数
context_window_sizenumber上下文窗口的最大 token 数
message_countnumber对话中的消息数量
messages_to_compactnumber将被摘要的消息数量
is_first_compactionboolean是否为该对话的首次压缩
输出字段类型描述
user_messagestring (可选)压缩时显示给用户的消息

workspaceOpen

Cursor 打开工作区时触发一次,此后每次工作区文件夹变更时都会再次触发。窗口中没有任何工作区文件夹时不会触发。可在 Cursor 桌面应用和命令行界面中运行。

// 输入{  "hook_event_name": "workspaceOpen",  "cursor_version": "string",  "workspace_roots": ["<absolute path>"],  "user_email": "string | null"}// 输出{  "pluginPaths": ["<absolute path>", "..."]}
输出字段类型描述
pluginPathsstring[] (可选)为当前工作区加载插件的目录绝对路径。

环境变量

钩子脚本执行时会接收环境变量:

变量描述始终可用
CURSOR_PROJECT_DIR工作区根目录
CURSOR_VERSIONCursor 版本字符串
CURSOR_USER_EMAIL已认证用户的电子邮件已登录时
CURSOR_TRANSCRIPT_PATH对话会话记录文件的路径已启用会话记录时
CURSOR_CODE_REMOTE在远程工作区中运行时设为字符串 "true"仅限远程工作区
CLAUDE_PROJECT_DIR项目目录的别名 (兼容 Claude)

sessionStart 钩子设置的会话级环境变量会传递给该会话中后续执行的所有钩子。

疑难排查

如何确认钩子是否已启用

自定义中,可通过钩子选项卡和钩子输出通道调试已配置和已执行的钩子,并查看错误。

如果钩子未正常工作

  • Cursor 会监视 hooks.json 文件,并在保存时重新加载。如果钩子仍无法加载,请重新启动 Cursor。
  • 检查钩子源文件的相对路径是否正确:
    • 对于项目钩子,路径相对于项目根目录 (例如 .cursor/hooks/script.sh)
    • 对于用户钩子,路径相对于 ~/.cursor/ (例如 ./hooks/script.shhooks/script.sh)

退出码阻止操作

命令钩子返回退出码 2 会阻止该操作 (等同于返回 permission: "deny") 。为保持兼容性,此行为与 Claude Code 一致。

企业版钩子和分发

企业版提供云端分发和团队级钩子管理。

Contact Sales