# How to Set Up Webhook Integrations with Cursor SDK Agents: A Complete Implementation Guide

> Learn how to set up webhook integrations with Cursor SDK agents. Configure the cloud runtime for background processing in this complete implementation guide.

- Repository: [Cursor/plugins](https://github.com/cursor/plugins)
- Tags: how-to-guide
- Published: 2026-05-25

---

**Setting up webhook integrations with Cursor SDK agents requires configuring the cloud runtime via `Agent.create` with `runtime: "cloud"` to ensure background processing survives beyond the HTTP request lifecycle.**

Webhook integrations enable external services like GitHub, Stripe, or Slack to trigger AI-driven automation using the Cursor SDK. Unlike interactive sessions, webhook handlers in the `cursor/plugins` repository must account for asynchronous execution and state persistence across disconnected HTTP requests. This guide covers the architectural patterns, runtime selection, and error handling required for production webhook deployments.

## Webhook Architecture and Runtime Selection

Successful integrations rely on three architectural layers. First, the **webhook handler** receives external events via HTTP endpoints. Second, the **Cursor SDK Agent** executes business logic using `Agent.create` or `Agent.resume`. Third, the optional **MCP (Message Control Protocol) server** maintains state for long-running or multi-step workflows.

The runtime choice determines whether your agent survives the webhook request. According to [`cursor-sdk/skills/cursor-sdk/references/runtime-choice.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/references/runtime-choice.md), the SDK supports **local** and **cloud** runtimes. The local runtime terminates when the HTTP response returns, making it unsuitable for webhook use cases. The **cloud** runtime continues processing until task completion, even after the webhook returns HTTP 202.

Always specify `runtime: "cloud"` when instantiating agents from webhooks:

```typescript
const run = await Agent.create({
  model: "gpt-4o-mini",
  runtime: "cloud",  // Required for webhook handlers
  instructions: "Process the incoming event...",
});

```

## Basic Webhook Implementation

### One-Off Agent Pattern

For simple, fire-and-forget automations, create a cloud-runtime agent that processes the event without maintaining conversation history. This pattern works for CI notifications, data ingestion, or single-action workflows.

In [`cursor-sdk/skills/cursor-sdk/SKILL.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/SKILL.md), the recommended approach extracts payload data, instantiates the agent, and immediately returns HTTP 202:

```typescript
import express from "express";
import { Agent } from "@cursor/sdk";

const app = express();
app.use(express.json());

app.post("/github/push", async (req, res) => {
  const { repository, ref } = req.body;

  const run = await Agent.create({
    model: "gpt-4o-mini",
    runtime: "cloud",
    instructions: `
      You are a CI assistant. When a push occurs on ${repository.full_name},
      run tests for branch ${ref} and comment results back to GitHub.
    `,
  });

  res.status(202).json({ runId: run.id, message: "Job started" });
});

app.listen(3000);

```

Store the returned `run.id` in your database to query status later. The agent executes independently while your service responds immediately to the webhook provider.

### Stateful Workflows with MCP Servers

Multi-step workflows requiring conversation persistence across multiple webhook calls need **MCP servers**. As documented in [`cursor-sdk/skills/cursor-sdk/references/patterns.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/references/patterns.md), MCP servers keep agent state in memory, allowing subsequent webhook requests to re-attach to the same logical conversation.

Configure the `mcpServers` array when creating the agent:

```typescript
import { Agent } from "@cursor/sdk";

async function handleStripeEvent(event: any) {
  const mcp = [{ 
    host: "https://my-mcp.mycompany.com", 
    token: process.env.MCP_TOKEN 
  }];

  const run = await Agent.create({
    model: "claude-3.5-sonnet",
    runtime: "cloud",
    mcpServers: mcp,
    instructions: `
      You are a payment processor. Update order status and send 
      confirmation emails on each Stripe event.
    `,
  });

  await saveRunMetadata(event.id, { runId: run.id, mcp });
}

```

The SDK routes subsequent `Agent.send` or `Agent.resume` calls to the same MCP endpoint, maintaining conversation context across disconnected HTTP requests.

### Resuming Existing Agent Runs

If your webhook retries failed deliveries or continues multi-step processes, use `Agent.resume` to re-hydrate agent state from the remote run store. This method requires the stored `runId` and the same MCP configuration used during creation.

```typescript
import { Agent } from "@cursor/sdk";

async function retryWebhook(runId: string) {
  const run = await Agent.resume({
    runId,
    runtime: "cloud",
    // Model and instructions restore automatically from cloud state
  });

  await run.send({ 
    role: "user", 
    content: "Please retry the last step." 
  });
}

```

According to the SDK reference, `Agent.resume` retrieves the complete execution context, including conversation history and tool states, eliminating the need to re-declare configuration parameters.

## Error Handling and SDK Integration

Production webhooks must handle SDK-specific errors gracefully. The [`orchestrate/skills/orchestrate/scripts/core/agent-manager.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/core/agent-manager.ts) file defines **CursorAgentError**, which wraps all remote execution failures.

Implement try-catch blocks to translate SDK errors into appropriate HTTP status codes:

```typescript
import { CursorAgentError } from "@cursor/sdk";

app.post("/webhook", async (req, res) => {
  try {
    const run = await Agent.create({ /* ... */ });
    res.status(202).json({ runId: run.id });
  } catch (error) {
    if (error instanceof CursorAgentError) {
      console.error("SDK Error:", error.raw);
      res.status(500).json({ error: "Agent execution failed" });
    } else {
      res.status(400).json({ error: "Invalid payload" });
    }
  }
});

```

Log the raw SDK error for debugging while returning sanitized responses to webhook providers to prevent information leakage.

## Key Implementation Files in cursor/plugins

Understanding the source structure helps debug integration issues:

| File | Purpose |
|------|---------|
| [`cursor-sdk/skills/cursor-sdk/SKILL.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/SKILL.md) | Documents the three invocation patterns (`Agent.prompt`, `Agent.create`, `Agent.resume`) and runtime selection criteria |
| [`cursor-sdk/skills/cursor-sdk/references/patterns.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/references/patterns.md) | Explains cloud + MCP architecture for stateful webhook workflows |
| [`cursor-sdk/skills/cursor-sdk/references/runtime-choice.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/references/runtime-choice.md) | Decision matrix for local vs. cloud runtime selection |
| [`orchestrate/skills/orchestrate/scripts/core/agent-manager.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/core/agent-manager.ts) | Implements `CursorAgentError` and SDK loading utilities |
| [`orchestrate/skills/orchestrate/scripts/cli/forensics.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/cli/forensics.ts) | Provides cloud agent cancellation utilities for cleanup operations |
| [`orchestrate/skills/orchestrate/scripts/cli/inspect.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/cli/inspect.ts) | Validates SDK catalog entries against `/v1/agents` endpoint |

## Summary

- **Use `runtime: "cloud"`** for all webhook handlers to prevent termination when the HTTP response returns
- **Configure MCP servers** via the `mcpServers` parameter when workflows span multiple webhook calls
- **Persist `runId`** and MCP configuration to enable status queries and run resumption
- **Catch `CursorAgentError`** to handle SDK failures and return appropriate HTTP status codes
- **Reference [`cursor-sdk/skills/cursor-sdk/SKILL.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/SKILL.md)** for the core invocation patterns and runtime documentation

## Frequently Asked Questions

### Why must I use the cloud runtime for webhook integrations?

The local runtime terminates when the HTTP request handler returns, which immediately kills any in-progress agent. The cloud runtime maintains execution in Cursor's infrastructure, allowing agents to complete long-running tasks (like CI pipelines or data processing) even after your webhook returns HTTP 202. This separation is documented in [`cursor-sdk/skills/cursor-sdk/references/runtime-choice.md`](https://github.com/cursor/plugins/blob/main/cursor-sdk/skills/cursor-sdk/references/runtime-choice.md).

### How do I maintain state across multiple webhook calls from the same workflow?

Pass an `mcpServers` configuration array to `Agent.create` containing your MCP server host and authentication token. The SDK persists conversation state on the MCP server, allowing subsequent webhook handlers to resume the same logical agent using `Agent.resume` with the original `runId`. This pattern prevents state loss between disconnected HTTP requests.

### What is a CursorAgentError and how should I handle it?

`CursorAgentError` is the SDK's standardized error wrapper defined in [`orchestrate/skills/orchestrate/scripts/core/agent-manager.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/core/agent-manager.ts). It encapsulates all remote execution failures, network timeouts, and cloud runtime errors. Your webhook should catch these errors, log the raw error details for debugging, and return appropriate HTTP status codes (typically 500 for SDK failures, 400 for validation errors) to the webhook provider.

### Can I cancel a webhook-launched agent if something goes wrong?

Yes. Use the cancellation utilities demonstrated in [`orchestrate/skills/orchestrate/scripts/cli/forensics.ts`](https://github.com/cursor/plugins/blob/main/orchestrate/skills/orchestrate/scripts/cli/forensics.ts) to terminate running cloud agents. Store the `runId` returned from `Agent.create` in your database, then pass it to the SDK's cancellation methods when you need to clean up stuck or erroneous processes.