How to Set Up Webhook Integrations with Cursor SDK Agents: A Complete Implementation Guide
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, 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:
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, the recommended approach extracts payload data, instantiates the agent, and immediately returns HTTP 202:
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, 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:
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.
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 file defines CursorAgentError, which wraps all remote execution failures.
Implement try-catch blocks to translate SDK errors into appropriate HTTP status codes:
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 |
Documents the three invocation patterns (Agent.prompt, Agent.create, Agent.resume) and runtime selection criteria |
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 |
Decision matrix for local vs. cloud runtime selection |
orchestrate/skills/orchestrate/scripts/core/agent-manager.ts |
Implements CursorAgentError and SDK loading utilities |
orchestrate/skills/orchestrate/scripts/cli/forensics.ts |
Provides cloud agent cancellation utilities for cleanup operations |
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
mcpServersparameter when workflows span multiple webhook calls - Persist
runIdand MCP configuration to enable status queries and run resumption - Catch
CursorAgentErrorto handle SDK failures and return appropriate HTTP status codes - Reference
cursor-sdk/skills/cursor-sdk/SKILL.mdfor 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.
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. 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →