Verwendung der Cursor Cloud Agents API und des SDK

Die Cursor Cloud Agents API und das SDK bieten Ihnen programmatische Kontrolle über cloudbasierte Codierungs-Agenten. Anstatt Agenten manuell im Editor zu starten und zu überwachen, können Sie diese starten, während der Laufzeit steuern, ihre Bildschirmausgabe erfassen und Webhook-Rückrufe empfangen, wenn Aufgaben abgeschlossen sind. Dieser Leitfaden führt durch Authentifizierung, Lebenszyklusmanagement, SDK-Integrationsmuster und Tipps zur Fehlerbehebung aus realen Entwicklererfahrungen.
Voraussetzungen und Einrichtung
Stellen Sie vor der Integration mit der Cloud Agents API sicher, dass Sie Folgendes bereit haben:
- Ein Cursor-Konto mit aktiviertem Cloud Agents-Zugriff
- Ein API-Schlüssel, der über Ihr Cursor-Einstellungsdashboard generiert wurde
- Node.js 18 oder höher (für das TypeScript/JavaScript SDK)
- Grundlegendes Verständnis von Async-Programmiermustern
Speichern Sie Ihren API-Schlüssel in einer Umgebungsvariablen, anstatt ihn fest im Code zu hinterlegen. Verwenden Sie während der Entwicklung eine .env-Datei und in der Produktion einen Secrets Manager.
SDK-Installation
Installieren Sie das Cursor Cloud Agents SDK aus der öffentlichen Registry:
npm install @cursor/cloud-agents-sdk
# or
yarn add @cursor/cloud-agents-sdk
# or
pnpm add @cursor/cloud-agents-sdk
Überprüfen Sie die Installation, indem Sie die Paketversion abrufen:
npx @cursor/cloud-agents-sdk --version
API-Authentifizierung
Jede Anfrage an die Cloud Agents API erfordert einen Bearer-Token. Das SDK verarbeitet dies automatisch, wenn Sie einen Client initialisieren:
import { CursorCloudClient } from "@cursor/cloud-agents-sdk";
const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
// Optional: Standard-API-Endpunkt überschreiben
endpoint: "https://api.cursor.sh/v1",
// Optional: Standard-Timeout für alle Operationen festlegen
timeout: 300000, // 5 Minuten
});
Wenn Sie rohe HTTP-Aufrufe anstelle des SDK bevorzugen, fügen Sie den Header manuell hinzu:
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['CURSOR_API_KEY']}",
"Content-Type": "application/json",
}
response = requests.post(
"https://api.cursor.sh/v1/agents",
headers=headers,
json={
"repo": "https://github.com/my-org/my-repo",
"branch": "feature/auth-refactor",
"task": "Refactor the authentication module to use JWT",
},
)
print(response.json())
Committen Sie niemals Ihren API-Schlüssel in die Versionsverwaltung. Wenn ein Schlüssel kompromittiert wurde, widerrufen Sie ihn sofort über das Cursor-Dashboard und generieren Sie einen neuen. Rotieren Sie Schlüssel regelmäßig.
Lebenszyklus von Cloud-Agenten
Ein Cloud-Agent durchläuft einen klar definierten Lebenszyklus. Das Verständnis jedes Zustands hilft Ihnen, robuste Automatisierungs-Pipelines zu erstellen.
Lebenszyklus-Zustände
| Zustand | Beschreibung |
|---|---|
queued | Der Agent wurde erstellt und wartet auf einen Cloud-Slot |
running | Der Agent führt die Aufgabe aktiv aus |
paused | Der Agent wurde durch Mid-Run-Steering oder manuellen Eingriff pausiert |
completed | Der Agent hat die Aufgabe erfolgreich abgeschlossen |
failed | Der Agent ist auf einen nicht behebbaren Fehler gestoßen |
cancelled | Der Agent wurde vom Benutzer oder durch einen Timeout abgebrochen |
Einen neuen Agenten erstellen
const agent = await client.agents.create({
repo: "https://github.com/my-org/my-repo",
branch: "feature/payment-gateway",
task: "Integrate Stripe payment gateway with proper error handling",
// Optionale Einstellungen
model: "cursor-agent-pro",
maxSteps: 50,
autoMerge: false,
environment: {
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
},
});
console.log(`Agent created with ID: ${agent.id}`);
console.log(`Initial status: ${agent.status}`);
Agenten-Status überwachen
Sie können den Agenten-Status abfragen oder Echtzeit-Updates abonnieren:
// Polling-Ansatz
async function waitForCompletion(agentId: string) {
while (true) {
const status = await client.agents.get(agentId);
console.log(`[${new Date().toISOString()}] Status: ${status.state}`);
if (status.state === "completed") {
return status;
}
if (status.state === "failed" || status.state === "cancelled") {
throw new Error(`Agent ended in state: ${status.state}`);
}
await new Promise((resolve) => setTimeout(resolve, 10000)); // 10s Polling
}
}
// Streaming-Ansatz (empfohlen)
const stream = await client.agents.stream(agent.id, (event) => {
console.log(`Event: ${event.type}`, event.data);
});
stream.on("step", (data) => {
console.log(`Agent step: ${data.description}`);
});
stream.on("file_change", (data) => {
console.log(`File modified: ${data.path}`);
});
stream.on("error", (data) => {
console.error(`Agent error: ${data.message}`);
});
Bevorzugen Sie den Streaming-Ansatz gegenüber Polling. Er reduziert API-Aufrufe, bietet Aktualisierungen mit geringerer Latenz und vermeidet Rate-Limit-Probleme bei lang laufenden Aufgaben.
Mid-Run-Steering
Eines der leistungsstärksten Features der Cloud Agents API ist die Fähigkeit, einen Agenten während seiner aktiven Ausführung zu steuern. Dies ermöglicht es Ihnen, den Kurs zu korrigieren, Kontext hinzuzufügen oder die Richtung zu ändern, ohne von vorne zu beginnen.
Senden einer Steer-Nachricht
const steerResult = await client.agents.steer(agent.id, {
message: "Stop using the mock data approach. Please connect to the real database using the connection string in the .env file.",
// Optional: Dateireferenz anhängen
attachments: ["src/config/database.ts"],
// Optional: Modell während der Laufzeit ändern
model: "cursor-agent-pro",
});
console.log(`Steer accepted: ${steerResult.accepted}`);
console.log(`Agent now running with updated context`);
Häufige Steer-Szenarien
Mid-Run-Steering ist in mehreren Situationen nützlich:
- Falschen Ansatz korrigieren: Der Agent beginnt, Mock-Tests zu schreiben, wenn Sie Integrationstests wollten.
- Fehlenden Kontext hinzufügen: Der Agent kennt ein gemeinsames Utility-Modul nicht, das Sie letzte Woche erstellt haben.
- Umfang ändern: Sie möchten, dass der Agent auch Dokumentation für den gerade geschriebenen Code hinzufügt.
- Beschränkungen durchsetzen: Der Agent steht kurz davor, Dateien außerhalb des vorgesehenen Umfangs zu ändern.
// Beispiel: Steering zum Hinzufügen eines Dokumentationsumfangs
await client.agents.steer(agent.id, {
message: "Great progress on the API endpoints. Now also add JSDoc comments to every exported function and update the README with the new endpoint list.",
});
// Beispiel: Steering zum Durchsetzen einer Sicherheitsgrenze
await client.agents.steer(agent.id, {
message: "Do not modify any files in the src/legacy/ directory. Those are deprecated modules scheduled for removal.",
});
Steer-Nachrichten werden asynchron verarbeitet. Es gibt ein kurzes Zeitfenster zwischen dem Senden des Steers und der Übernahme durch den Agenten. Senden Sie nicht mehrere widersprüchliche Steer-Nachrichten in schneller Folge, da dies den Agenten verwirren und zu inkonsistentem Verhalten führen kann.
Agenten pausieren und fortsetzen
// Einen laufenden Agenten pausieren
await client.agents.pause(agent.id);
console.log("Agent paused");
// Aktuellen Zustand überprüfen
const state = await client.agents.get(agent.id);
console.log("Files changed so far:", state.filesChanged);
// Fortsetzen, wenn bereit
await client.agents.resume(agent.id);
console.log("Agent resumed");
RecordScreen-API
Die RecordScreen-API erfasst visuelle Schnappschüsse vom Bildschirm des Cloud-Agenten zu bestimmten Zeitpunkten. Dies ist unschätzbar für Debugging, Auditing und die Erstellung visueller Dashboards.
Erfassen eines Screenshots
// Einen einzelnen Screenshot erfassen
const screenshot = await client.agents.recordScreen(agent.id, {
format: "png",
// Optional: nur einen Bereich erfassen
region: { x: 0, y: 0, width: 1920, height: 1080 },
// Optional: Cursor-Position-Overlay einblenden
showCursor: true,
});
// Der Screenshot wird als Base64-Zeichenfolge zurückgegeben
const fs = require("fs");
fs.writeFileSync(`agent-${agent.id}-screenshot.png`, Buffer.from(screenshot.data, "base64"));
console.log(`Screenshot saved. Size: ${screenshot.width}x${screenshot.height}`);
Aufnehmen eines Videoclips
// Bildschirmaufnahme starten
const recording = await client.agents.recordScreen(agent.id, {
mode: "video",
duration: 30000, // 30 Sekunden
fps: 15,
format: "webm",
});
// Die Aufnahme gibt eine herunterladbare URL zurück
console.log(`Recording available at: ${recording.url}`);
console.log(`Recording expires at: ${recording.expiresAt}`);
Fehlerbehebung bei RecordScreen-Fehlern
RecordScreen-Aufrufe können aus mehreren Gründen fehlschlagen. Hier sind die häufigsten Probleme und ihre Lösungen:
RecordScreen gibt einen 409 Conflict-Fehler zurück, wenn sich der Agent nicht im Zustand running befindet. Stellen Sie sicher, dass der Agent aktiv läuft, bevor Sie versuchen, seinen Bildschirm zu erfassen. Wenn der Agent pausiert oder abgeschlossen war, können Sie seinen Bildschirm nicht aufzeichnen.
// Sichere RecordScreen-Wrapper mit Fehlerbehandlung
async function safeRecordScreen(agentId: string, options: any) {
const agent = await client.agents.get(agentId);
if (agent.state !== "running") {
console.warn(`Cannot record screen: agent is in ${agent.state} state`);
return null;
}
try {
return await client.agents.recordScreen(agentId, options);
} catch (error: any) {
if (error.code === "SCREEN_CAPTURE_UNAVAILABLE") {
console.error("Screen capture is not available for this agent configuration.");
console.error("Make sure the agent was launched with screen capture enabled.");
} else if (error.code === "RATE_LIMITED") {
console.error("Too many screen capture requests. Please wait before retrying.");
console.log(`Retry after: ${error.retryAfter} seconds`);
} else {
throw error;
}
return null;
}
}
Um die Bildschirmaufzeichnung bei der Erstellung eines Agenten zu aktivieren, setzen Sie die Option screenCapture:
const agent = await client.agents.create({
repo: "https://github.com/my-org/my-repo",
branch: "main",
task: "Fix the flaky integration tests",
screenCapture: {
enabled: true,
autoCapture: true, // Automatisch bei jedem Schritt erfassen
captureInterval: 5000, // Alle 5 Sekunden erfassen
},
});
Das Aktivieren von autoCapture erzeugt eine visuelle Zeitleiste der Arbeit des Agenten. Sie können die gesamte Sitzung später für Debugging oder Compliance-Überprüfungen abspielen. Beachten Sie, dass dies den Speicherverbrauch erhöht und die Agentenleistung leicht beeinträchtigen kann.
Webhook-Rückrufe
Webhooks ermöglichen es Ihnen, Echtzeit-Benachrichtigungen zu erhalten, wenn Agenten-Ereignisse auftreten. Dies ist unerlässlich für den Aufbau automatisierter CI/CD-Pipelines und Überwachungs-Dashboards.
Registrieren eines Webhooks
const webhook = await client.webhooks.create({
url: "https://my-app.com/api/cursor-webhook",
events: [
"agent.created",
"agent.step_completed",
"agent.completed",
"agent.failed",
"agent.steer_received",
],
// Optional: ein Secret für die Signaturprüfung hinzufügen
secret: process.env.WEBHOOK_SECRET,
});
console.log(`Webhook registered with ID: ${webhook.id}`);
Verarbeiten von Webhook-Payloads
Hier ist ein Beispiel für einen Express-Endpunkt, der Webhook-Rückrufe empfängt und verifiziert:
const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/api/cursor-webhook", (req, res) => {
// Webhook-Signatur verifizieren
const signature = req.headers["x-cursor-signature"];
const expectedSignature = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (signature !== expectedSignature) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(req.body.toString());
switch (event.type) {
case "agent.created":
console.log(`Agent ${event.data.agentId} created for repo ${event.data.repo}`);
break;
case "agent.step_completed":
console.log(`Agent ${event.data.agentId} completed step ${event.data.stepNumber}`);
console.log(` Files changed: ${event.data.filesChanged.join(", ")}`);
break;
case "agent.completed":
console.log(`Agent ${event.data.agentId} completed successfully`);
console.log(` Pull request: ${event.data.pullRequestUrl}`);
// Downstream-CI-Pipeline auslösen
triggerCIPipeline(event.data.agentId);
break;
case "agent.failed":
console.error(`Agent ${event.data.agentId} failed: ${event.data.error}`);
// Alert an Team-Kanal senden
sendAlert(event.data);
break;
}
// Immer mit 200 antworten, um den Empfang zu bestätigen
res.status(200).send("OK");
});
app.listen(3000, () => {
console.log("Webhook server listening on port 3000");
});
Verifizieren Sie immer Webhook-Signaturen. Ohne Signaturprüfung könnte ein Angreifer gefälschte Webhook-Payloads an Ihren Endpunkt senden. Der x-cursor-signature-Header enthält einen HMAC-SHA256-Hash des rohen Anfragekörpers, der mit Ihrem Webhook-Secret signiert wurde.
Webhook-Wiederversuchsverhalten
Wenn Ihr Endpunkt nicht innerhalb von 10 Sekunden mit einem 200-Status antwortet, versucht die API die Zustellung erneut. Der Wiederversuchsplan lautet:
| Versuch | Verzögerung |
|---|---|
| 1. Wiederholung | 1 Minute |
| 2. Wiederholung | 5 Minuten |
| 3. Wiederholung | 30 Minuten |
| 4. Wiederholung | 2 Stunden |
| Letztmalig | 12 Stunden |
Nach dem letzten Versuch wird die Webhook-Zustellung als fehlgeschlagen markiert, und Sie müssen den Agenten-Status manuell über die API überprüfen.
Wenn Ihre Webhook-Verarbeitung lang laufende Operationen umfasst, antworten Sie sofort mit 200 und schieben Sie die Arbeit in eine Hintergrund-Warteschlange. Dies vermeidet Timeouts und stellt eine zuverlässige Webhook-Zustellung sicher.
SDK-Integrationsmuster
Muster 1: CI/CD-Pipeline-Integration
Automatisch einen Cloud-Agenten starten, wenn ein Pull Request geöffnet wird:
import { CursorCloudClient } from "@cursor/cloud-agents-sdk";
const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
});
export async function onPullRequestOpened(pr: any) {
const agent = await client.agents.create({
repo: pr.repositoryUrl,
branch: pr.headBranch,
task: `Review and improve this pull request. Focus on: ${pr.description}`,
autoMerge: false,
screenCapture: { enabled: true },
});
// Auf dem PR mit dem Agenten-Link kommentieren
await pr.addComment(
`A Cursor Cloud Agent is now reviewing this PR. ` +
`Track progress: https://cursor.sh/agents/${agent.id}`
);
return agent;
}
Muster 2: Multi-Agenten-Orchestrierung
Mehrere Agenten parallel auf verschiedenen Aufgaben ausführen:
async function runParallelAgents(repo: string) {
const tasks = [
"Write unit tests for the authentication module",
"Write unit tests for the payment module",
"Write integration tests for the API endpoints",
"Update API documentation with OpenAPI specs",
];
const agents = await Promise.all(
tasks.map((task) =>
client.agents.create({
repo,
branch: "main",
task,
model: "cursor-agent-pro",
})
)
);
console.log(`Launched ${agents.length} agents in parallel`);
// Warten, bis alle Agenten abgeschlossen sind
const results = await Promise.allSettled(
agents.map((agent) => waitForCompletion(agent.id))
);
// Ergebnisse zusammenfassen
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Task ${index + 1}: Completed - ${result.value.filesChanged.length} files changed`);
} else {
console.error(`Task ${index + 1}: Failed - ${result.reason.message}`);
}
});
}
Das parallele Ausführen mehrerer Agenten verbraucht schnell Cloud-Ressourcen. Überwachen Sie Ihre Nutzung und setzen Sie ein angemessenes maxSteps-Limit für jeden Agenten, um die Kosten zu kontrollieren. Prüfen Sie das gleichzeitige Agenten-Limit Ihres Plans, bevor Sie große Stapel starten.
Muster 3: Human-in-the-Loop-Überprüfung
Webhooks mit Mid-Run-Steering kombinieren, um einen Überprüfungs-Checkpoint zu erstellen:
// Wenn der Agent einen bestimmten Schritt erreicht, für menschliche Überprüfung pausieren
const stream = await client.agents.stream(agent.id, async (event) => {
if (event.type === "step" && event.data.stepNumber === 10) {
// Agent für menschliche Überprüfung pausieren
await client.agents.pause(agent.id);
// Benachrichtigung an den Überprüfungskanal senden
await sendSlackNotification({
channel: "#code-review",
text: `Agent ${agent.id} has paused for review. Check the changes before resuming.`,
});
// Der menschliche Prüfer wird den Agenten manuell fortsetzen oder steuern
}
});
Muster 4: Automatische Fehlerbehebung
async function runWithRetry(repo: string, task: string, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const agent = await client.agents.create({
repo,
branch: "main",
task,
maxSteps: 30,
});
try {
const result = await waitForCompletion(agent.id);
if (result.state === "completed") {
return result;
}
} catch (error) {
console.error(`Attempt ${attempt} failed: ${error.message}`);
if (attempt < maxRetries) {
// Den nächsten Versuch mit dem Fehlerkontext steuern
task = `${task}\n\nPrevious attempt failed with: ${error.message}. Please avoid this approach.`;
}
}
}
throw new Error(`Agent failed after ${maxRetries} attempts`);
}
Fehlerbehebung bei häufigen Problemen
Agent im Warteschlangen-Zustand steckengeblieben
Wenn ein Agent über einen längeren Zeitraum im Zustand queued verbleibt, bedeutet dies normalerweise, dass alle Cloud-Slots belegt sind.
// Aktuelle Kontonutzung überprüfen
const usage = await client.usage.get();
console.log(`Active agents: ${usage.activeAgents}/${usage.maxConcurrentAgents}`);
console.log(`Queue length: ${usage.queueLength}`);
if (usage.activeAgents >= usage.maxConcurrentAgents) {
console.log("All slots are in use. Consider upgrading your plan or waiting for agents to complete.");
}
SDK-Authentifizierungsfehler
Wenn Sie einen 401 Unauthorized-Fehler erhalten, überprüfen Sie Folgendes:
- Ihr API-Schlüssel ist gültig und wurde nicht widerrufen
- Der Schlüssel hat den Scope
cloud-agentsaktiviert - Sie verwenden die richtige Endpunkt-URL
- Die Umgebungsvariable ist korrekt geladen
// Authentifizierung debuggen
const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
});
try {
const me = await client.auth.verify();
console.log("Authentication successful");
console.log(`Account: ${me.accountName}`);
console.log(`Plan: ${me.plan}`);
console.log(`Scopes: ${me.scopes.join(", ")}`);
} catch (error) {
console.error("Authentication failed:", error.message);
console.log("Check your API key and ensure it has the 'cloud-agents' scope.");
}
Webhook-Zustellungsfehler
Wenn Webhooks Ihren Endpunkt nicht erreichen:
- Stellen Sie sicher, dass die Webhook-URL öffentlich zugänglich ist (nicht localhost)
- Bestätigen Sie, dass Ihr Server innerhalb von 10 Sekunden 200 zurückgibt
- Prüfen Sie, ob Ihr SSL-Zertifikat gültig ist
- Stellen Sie sicher, dass Ihre Firewall eingehende Verbindungen von den IP-Bereichen von Cursor zulässt
// Webhook-Endpunkt-Erreichbarkeit testen
const test = await client.webhooks.test(webhook.id);
console.log(`Test result: ${test.status}`);
console.log(`Response time: ${test.responseTime}ms`);
if (test.error) {
console.error(`Error: ${test.error}`);
}
Verwenden Sie während der Entwicklung einen Dienst wie webhook.site oder ngrok, um die Webhook-Zustellung schnell zu testen, ohne einen vollständigen Server bereitzustellen. Dies hilft zu isolieren, ob das Problem bei Ihrem Endpunkt oder der Webhook-Konfiguration liegt.
Zusammenfassung der Best Practices
Hier ist eine Checkliste der Best Practices, die Sie beim Aufbau mit der Cursor Cloud Agents API und dem SDK befolgen sollten:
- Speichern Sie API-Schlüssel immer in Umgebungsvariablen oder einem Secrets Manager
- Verwenden Sie Streaming statt Polling für Echtzeit-Updates
- Implementieren Sie die Webhook-Signaturprüfung an jedem Endpunkt
- Setzen Sie angemessene
maxSteps-Limits, um Kosten zu kontrollieren und entlaufene Agenten zu verhindern - Verwenden Sie Mid-Run-Steering, um den Kurs zu korrigieren, anstatt Agenten neu zu starten
- Aktivieren Sie die Bildschirmaufzeichnung für Debugging und Audit-Trails bei kritischen Aufgaben
- Implementieren Sie exponentielles Backoff beim Wiederholen fehlgeschlagener API-Aufrufe
- Überwachen Sie Ihre gleichzeitige Agenten-Nutzung, um Warteschlangen-Aushungerung zu vermeiden
- Testen Sie Webhook-Endpunkte mit dem integrierten Test-Endpunkt, bevor Sie live gehen
- Protokollieren Sie alle Agenten-Ereignisse für Post-Mortem-Analyse und Compliance
Achten Sie auf Rate-Limits. Die API erzwingt ein Standardlimit von 100 Anfragen pro Minute. Wenn Sie dieses Limit überschreiten, erhalten Sie eine 429 Too Many Requests-Antwort. Implementieren Sie exponentielles Backoff mit Jitter, um Rate-Limit-Wiederholungen ordnungsgemäß zu behandeln.
Fazit
Die Cursor Cloud Agents API und das SDK bieten eine leistungsstarke programmatische Schnittstelle zur Automatisierung von Codierungsaufgaben im großen Maßstab. Durch die Kombination von Agenten-Lebenszyklusmanagement, Mid-Run-Steering, der RecordScreen-API und Webhook-Rückrufen können Sie anspruchsvolle Automatisierungs-Pipelines aufbauen, die sich nahtlos in Ihren bestehenden Entwicklungs-Workflow integrieren.
Beginnen Sie mit einem einfachen Einzel-Agenten-Setup und fügen Sie schrittweise Webhook-Integration, parallele Orchestrierung und Human-in-the-Loop-Überprüfungs-Checkpoints hinzu, wenn Ihr Vertrauen wächst. Das TypeScript-first-Design des SDK erleichtert die Integration in moderne Node.js-Anwendungen, während die rohe HTTP-API jede Programmiersprache unterstützt.