mcpField
C
cursor-webhooks

cursor-webhooks

github.com/hookdeck开发95200 次安装今天更新
代码仓库

关于 cursor-webhooks

面向开发者的 Cursor Cloud Agent Webhook 处理技能,涵盖签名验证、状态变更负载和本地测试。

主要功能

  1. 01验证 Cursor Webhook 签名
  2. 02处理 Cloud Agent 状态变更
  3. 03查看状态变更负载
  4. 04使用 Hookdeck CLI 本地测试
  5. 05查找按框架提供的可运行示例

适用场景

  1. 01监控 Cloud Agent 完成状态
  2. 02响应 Agent 错误
  3. 03排查 Webhook 签名验证失败

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hookdeck/webhook-skills --skill cursor-webhooks

安装后在 Claude Code 中输入/cursor-webhooks确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples/express/
.env.example
package.json
README.md
examples/express/src/
index.js
examples/express/test/
webhook.test.js
examples/fastapi/
.env.example
main.py
README.md
requirements.txt
test_webhook.py
examples/nextjs/
.env.example
package.json
README.md
vitest.config.ts
examples/nextjs/app/webhooks/cursor/
route.ts
examples/nextjs/test/
webhook.test.ts
references/
overview.md
setup.md
verification.md

详细介绍

Cursor Webhooks

适用场景

  • 设置 Cursor Cloud Agent webhook 处理程序
  • 调试签名验证失败问题
  • 了解 Cursor webhook 事件类型和负载
  • 处理 Cloud Agent 状态变更事件(ERROR、FINISHED)

必备代码(请使用)

Cursor 签名验证(JavaScript)
const crypto = require('crypto');

function verifyCursorWebhook(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;

  // Cursor sends: sha256=xxxx
  const [algorithm, signature] = signatureHeader.split('=');
  if (algorithm !== 'sha256') return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  try {
    return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  } catch {
    return false;
  }
}
Express Webhook 处理程序
const express = require('express');
const app = express();

// CRITICAL: Use express.raw() - Cursor requires raw body for signature verification
app.post('/webhooks/cursor',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const signature = req.headers['x-webhook-signature'];
    const webhookId = req.headers['x-webhook-id'];
    const event = req.headers['x-webhook-event'];

    // Verify signature
    if (!verifyCursorWebhook(req.body, signature, process.env.CURSOR_WEBHOOK_SECRET)) {
      console.error('Cursor signature verification failed');
      return res.status(401).send('Invalid signature');
    }

    // Parse payload after verification
    const payload = JSON.parse(req.body.toString());

    console.log(`Received ${event} (id: ${webhookId})`);

    // Handle status changes
    if (event === 'statusChange') {
      console.log(`Agent ${payload.id} status: ${payload.status}`);

      if (payload.status === 'FINISHED') {
        console.log(`Summary: ${payload.summary}`);
      } else if (payload.status === 'ERROR') {
        console.error(`Agent error for ${payload.id}`);
      }
    }

    res.json({ received: true });
  }
);
Python 签名验证(FastAPI)
import hmac
import hashlib
from fastapi import Request, HTTPException

def verify_cursor_webhook(body: bytes, signature_header: str, secret: str) -> bool:
    if not signature_header or not secret:
        return False

    # Cursor sends: sha256=xxxx
    parts = signature_header.split('=')
    if len(parts) != 2 or parts[0] != 'sha256':
        return False

    signature = parts[1]
    expected = hmac.new(
        secret.encode(),
        body,
        hashlib.sha256
    ).hexdigest()

    # Timing-safe comparison
    return hmac.compare_digest(signature, expected)

常见事件类型

事件类型描述常见使用场景
statusChangeAgent 状态已变更监控 Agent 完成状态、处理错误
事件负载结构
{
  "event": "statusChange",
  "timestamp": "2024-01-01T12:00:00.000Z",
  "id": "agent_123456",
  "status": "FINISHED",  // or "ERROR"
  "source": {
    "repository": "https://github.com/user/repo",
    "ref": "main"
  },
  "target": {
    "url": "https://github.com/user/repo/pull/123",
    "branchName": "feature-branch",
    "prUrl": "https://github.com/user/repo/pull/123"
  },
  "summary": "Updated 3 files and fixed linting errors"
}

环境变量

# Your Cursor webhook signing secret
CURSOR_WEBHOOK_SECRET=your_webhook_secret_here

本地开发

若要在本地测试 webhook,请安装 Hookdeck CLI:

然后启动隧道:

npx hookdeck-cli listen 3000 cursor --path /webhooks/cursor

无需账号。提供本地隧道和 Web 界面,可用于检查请求。

资源

  • overview.md - Cursor webhook 的介绍和事件类型
  • setup.md - 在 Cursor 控制面板中配置 webhook
  • verification.md - 签名验证详情和注意事项
  • examples/ - 各框架的可运行示例

推荐:webhook-handler-patterns

若要实现适用于生产环境的 webhook 处理,也请使用 webhook-handler-patterns 技能:

相关技能

评论

支持 Markdown