How to Use Cursor SDK: Complete Tutorial for TypeScript Beginners
By Braincuber Team
Published on May 7, 2026
Cursor announced its TypeScript SDK in late April 2026 and released it as a public beta. The package is published as @cursor/sdk and runs from Node environments such as scripts, CI jobs, and backend services. This beginner guide walks you through setting up the SDK, running a local quickstart, and building a cloud agent that fixes bugs and opens pull requests.
What You'll Learn:
- What the Cursor SDK is and when to use it versus the Cursor app
- How to set up the SDK with Node.js, TypeScript, and API keys
- Run your first local Cursor agent and stream responses
- Build a cloud agent that fixes bugs and opens GitHub PRs
- Use MCP servers, skills, hooks, and subagents with the SDK
- Implement safety checks before deploying agents to production
What Is the Cursor SDK?
The Cursor SDK is a TypeScript package, @cursor/sdk, that lets you create and run Cursor agents from code. It gives you access to local and cloud agents, Cursor's codebase tools including indexing, search, grep, MCP servers, skills, hooks, and subagents, and the models available through your Cursor account.
The SDK uses the same agent system as the Cursor IDE, CLI, and web app. The difference is that you call it from TypeScript code rather than typing prompts in the editor.
Local and Cloud Agents
Run agents inline in your Node process with local file access, or run in isolated Cursor-managed VMs with repo cloning and PR creation capabilities.
Agent Tools Access
Access indexing, search, grep, MCP tool calls, skills, hooks, and subagents - the same tools available in the Cursor IDE.
Model Selection
Use Composer 2, GPT-5.5, Claude, or any model your Cursor account can access by setting the model id in agent config.
Same System, Different Interface
The SDK uses the same agent system as Cursor IDE, CLI, and web app - just called from TypeScript code instead of editor chat.
When to Use the SDK
The SDK fits tasks that should start from code instead of from a person typing in the editor. Use it for CI jobs that ask an agent to inspect failing tests, webhooks that create branches for bug fixes, or internal tools that run fixed agent tasks from a form.
SDK vs Cursor App
Use the IDE for editor chat. Use the CLI for terminal prompts. Use the SDK when TypeScript code needs to create the agent, send the task, and handle the result. The CLI does not support external provider keys; the SDK also authenticates through a Cursor API key only.
How the Cursor SDK Fits Together
Before writing code, it helps to know the objects and runtime choices the SDK exposes. The SDK supports three runtimes, and the code changes through the config key you pass: local or cloud.
| Runtime | What it does | When to use it |
|---|---|---|
| Local | Runs the agent inline in your Node process, with files read from disk | Dev scripts, CI checks against a working tree, fast iteration |
| Cursor Cloud | Runs in an isolated VM with your repo cloned in, managed by Cursor | Parallel agents, longer tasks, runs that continue after disconnects |
| Self-Hosted Cloud | Same shape as cloud but with your VMs and network | Teams needing code, secrets, and build output inside their environment |
Runtime, Tools, and Models
A run inside the SDK has three parts. The runtime is where it executes. The agent tools include indexing, search, MCP tool calls, skills, hooks, and subagents. The model is selected with model: { id: "composer-2" } or another id your account can use.
Agent and Run Objects
The two main objects in the SDK are the Agent and the Run. An agent holds conversation state, workspace config, and model settings. A run is one prompt sent to that agent, with its own stream, status, result, and cancel handle.
Cloud agents enforce one active run per agent. If you try to send a second prompt while the first is still going, the API returns 409 agent_busy. To run things in parallel, create separate agents, not separate runs on the same agent.
Setting Up the Cursor SDK: Step by Step Guide
Prerequisites
You need Node.js 22 or newer (the package formally supports Node 18 or newer, but Node 22 matches the official cookbook examples), a Cursor account on Pro ($20/month) or above for cloud agents, basic TypeScript familiarity, and tsx to run TypeScript without compiling.
Install the SDK
In a fresh folder, initialize the project and install dependencies:
npm init -y
npm install @cursor/sdk
npm install --save-dev typescript tsx @types/node
Add "type": "module" to your package.json so the imports work as ESM. Then add a tsconfig.json that supports top level await and explicit async disposal:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022", "ESNext.Disposable"],
"strict": true,
"esModuleInterop": true
}
}
Get a Cursor API Key
Generate a User API Key from the Cursor dashboard Integrations page. The key was originally generated under Cloud Agents but has moved to Integrations. If a guide points to "Cloud Agents," check Integrations instead.
Store the key as CURSOR_API_KEY in a .env file:
CURSOR_API_KEY=crsr_your_key_here
Add .env to your .gitignore. The SDK reads process.env directly; it does not load .env files for you.
Your First Local Cursor Agent
Create src/01-quickstart.ts with the following code to create a local agent, send a prompt, stream the response, and dispose the agent:
import { Agent, type SDKMessage } from "@cursor/sdk";
const agent = await Agent.create({
apiKey: process.env.CURSOR_API_KEY!,
model: { id: "composer-2" },
local: { cwd: process.cwd() },
});
try {
const run = await agent.send(
`Write a terminal-friendly summary for a screenshot.
Output exactly:
Local agent summary
- Purpose: demonstrates a local Cursor SDK agent.
- Key files: src/01-quickstart.ts, package.json, tsconfig.json.
- SDK action: creates an agent and streams assistant text.
Rules:
Print exactly those three bullets.
No Markdown bold.
No extra explanation.`,
);
for await (const event of run.stream()) {
if (event.type !== "assistant") continue;
for (const block of event.message.content) {
if (block.type === "text") {
process.stdout.write(block.text);
}
}
}
const result = await run.wait();
const duration = result.durationMs === undefined ? "" : `duration=${result.durationMs}ms`;
console.log(`\n[done] status=${result.status}${duration}`);
} finally {
await agent[Symbol.asyncDispose]();
}
The agent emits several event types including thinking, tool_call, and status. This example filters for assistant text because that is the visible answer. If you only need final text, skip the stream and read result.result after run.wait().
Run the Script
Save the file and run it with Node's --env-file flag and tsx:
node --env-file=.env --import tsx/esm src/01-quickstart.ts
Handle Errors
The SDK throws typed errors that extend CursorAgentError. Common cases include AuthenticationError for a bad key, ConfigurationError for an invalid model id, RateLimitError, IntegrationNotConnectedError, and NetworkError.
import { CursorAgentError } from "@cursor/sdk";
try {
// ... agent code
} catch (error) {
if (error instanceof CursorAgentError) {
console.error("[" + (error.code ?? "unknown") + "] " + error.message);
if (error.isRetryable) {
console.error("Retryable. Try again in a moment.");
}
} else {
throw error;
}
}
The isRetryable flag is what your retry logic should check. Network errors and rate limits are retryable; bad configuration and authentication are not.
Building a Cloud Bug Fixing Agent
The next example moves from a local folder to a GitHub repo cloned in Cursor's cloud. The task is to fix a failing auth test and open a pull request.
When to Reach for Cloud
Cloud agents run in VMs managed by Cursor. They clone the repo, set up a development environment, and continue if your local script exits. When they finish, they can push a branch and open a pull request. Use cloud when any of these is true:
Long-Running Tasks
The task may take longer than a local script session allows, requiring the agent to continue after disconnects.
PR or Branch Output
You want a PR or branch as the output, not just text. Cloud agents can open PRs when repo permissions allow it.
Parallel Agents
You want to run multiple agents in parallel against the same repo. Cloud agents support this through separate agent instances.
Isolated Environment
The agent needs to run code (tests, builds) in an isolated environment without affecting your local machine.
Configure the Cloud Agent
The cloud config replaces the local key with a cloud key. You list the repo to clone, optionally pin a starting branch, and set whether Cursor should open a PR when the run finishes.
import { Agent, CursorAgentError } from "@cursor/sdk";
const agent = await Agent.create({
apiKey: process.env.CURSOR_API_KEY!,
name: "Cloud bug fixer",
model: { id: "composer-2" },
cloud: {
repos: [
{ url: "https://github.com/your-org/your-repo", startingRef: "main" },
],
autoCreatePR: true,
},
});
console.log(`Started cloud agent ${agent.agentId}`);
repos is an array, but cloud v1 currently supports a single repo per agent. startingRef is the branch or commit the agent starts from. autoCreatePR: true asks Cursor to open a pull request when the run finishes. For the agent to clone the repo, your Cursor account needs the GitHub integration set up.
Send the Task and Reconnect
The pattern below sends a task and then waits on the result through Agent.getRun(). This lets another process reconnect later if the original script exits.
const run = await agent.send(
"Find the failing test in the auth module, fix the bug, and add a regression test.",
);
console.log(`Run ${run.id} in progress.`);
const handle = await Agent.getRun(run.id, {
runtime: "cloud",
agentId: agent.agentId,
apiKey: process.env.CURSOR_API_KEY!,
});
const result = await handle.wait();
const branch = result.git?.branches?.[0];
console.log(`Status: ${result.status}`);
if (branch?.prUrl) {
console.log(`PR: ${branch.prUrl}`);
} else if (branch?.branch) {
console.log(`Branch: ${branch.branch}`);
}
| Capability | Local | Cloud |
|---|---|---|
| Where it runs | Your Node process | A VM Cursor manages |
| File access | Your disk | Cloned repo only |
| Survives disconnects | No | Yes |
| Opens PRs | No | Yes, when repo permissions allow it |
| Returns artifacts | No | Yes (15-minute presigned URLs) |
MCP, Skills, Hooks, and Subagents
The SDK can read the same project agent config that Cursor uses in the IDE. These pieces matter once the agent works in a real repo.
MCP Servers
Connect agents to external tools via HTTP or stdio MCP servers. Pass servers inline in Agent.create() or define them in .cursor/mcp.json.
Skills
Markdown files in .cursor/skills/ give the agent project instructions, such as test framework choices, API conventions, or release rules.
Hooks
Live in .cursor/hooks.json and run at specific points in the agent loop. Common uses include formatting after file edits and blocking destructive shell commands.
Subagents
Named agents the main agent can call for focused work, such as code review or test writing. Define them in .cursor/agents/*.md or inline in config.
Safety Checks Before Production
Critical Safety Steps
Before agents touch a real repo, set boundaries: scope permissions tightly, keep secrets out of prompts, require human review for PRs, watch cost and model choice, and log the run for audit purposes.
Scope Permissions Tightly
Agents can read files, run commands, and use any credentials you expose. Give agents repo-scoped access, not broad service credentials.
Keep Secrets Out of Prompts
Prompts can land in transcripts. Use environment variables for CURSOR_API_KEY and any other token, not prompt text.
Require Human Review
If a cloud agent can open PRs, branch protection should require a human reviewer before merge. Do not combine autoCreatePR: true with auto-merge.
Watch Cost and Model Choice
SDK usage draws from Cursor's token-based usage pool. Call Cursor.models.list() to see which model ids your account can use.
Log the Run
run.conversation() returns a structured view of the agent's turns. Store it for runs you may need to debug or audit later.
Frequently Asked Questions
Does the Cursor SDK work with Python or other languages?
Not officially. The SDK is TypeScript only as of the public beta; Python users should call the Cloud Agents REST API directly.
Can I use the SDK on the free Hobby plan?
Yes for local agents, within free tier rate limits and usage caps. No for cloud agents; those require Pro or above subscription.
How do I cancel a run that is taking too long?
Call run.cancel(). The status moves to cancelled, the live stream aborts, and run.wait() resolves with the cancelled result.
Where do hooks fit if the SDK does not have a programmatic callback?
Hooks are repo policy, not per script logic. Put shared rules in .cursor/hooks.json, and keep run-specific logic around agent.send() or run.wait() in your TypeScript code.
Is the SDK ready for production use?
Use it first for low-risk tasks. The SDK surface is still in public beta. Pin @cursor/sdk, scope secrets, require review, and expect API changes before general availability.
Need Help with AI Agent Development?
Our experts can help you configure Cursor SDK, build custom coding agents, and implement safety checks for your AI-powered development workflow.
