Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guide users building apps, scripts, CI pipelines, or automations on top of the Cursor SDK — TypeScript (@cursor/sdk) or Python (cursor-sdk / cursor_sdk). Covers Agent.create, Agent.prompt, Agent.resume, streaming, local vs cloud runtime, MCP servers, error handling, and production best practices. Use when the user mentions integrating or writing code against the Cursor SDK.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 47% | 0% |
The Cursor SDK runs Cursor agents programmatically. Two language variants share the same concepts:
@cursor/sdk, npm) - docs at cursor.com/docs/sdk/typescriptcursor-sdk, pip) - docs at cursor.com/docs/sdk/pythonBoth are in public beta and follow the same Agent → Run model across local (runs on the caller's machine against cwd) and cloud (runs on a Cursor-hosted VM against a cloned repo) runtimes.
pyproject.toml / .py files → Python. package.json / .ts files → TypeScript.Agent.prompt(...) - one-shotFire-and-forget scripts, GitHub Actions steps, "send prompt, get result, exit" flows. No streaming, no follow-ups, no cleanup to remember.
TypeScript:
typescriptimport { Agent } from "@cursor/sdk"; const result = await Agent.prompt("Refactor src/utils.ts for readability", { apiKey: process.env.CURSOR_API_KEY!, model: { id: "composer-2.5" }, local: { cwd: process.cwd() }, }); console.log(result.status, result.result);
Python:
pythonfrom cursor_sdk import Agent, AgentOptions, LocalAgentOptions result = Agent.prompt( "Refactor src/utils.py for readability", AgentOptions(api_key=os.environ["CURSOR_API_KEY"], model="composer-2.5", local=LocalAgentOptions(cwd=os.getcwd())), ) print(result.status, result.result)
Agent.create(...) + agent.send(...) - durable with follow-upsStreaming, multi-turn conversation, lifecycle operations (cancel, status listener).
TypeScript:
typescriptimport { Agent } from "@cursor/sdk"; await using agent = await Agent.create({ apiKey: process.env.CURSOR_API_KEY!, model: { id: "composer-2.5" }, local: { cwd: process.cwd() }, }); const run = await agent.send("Find the bug in src/auth.ts"); for await (const event of run.stream()) { if (event.type === "assistant") for (const block of event.message.content) if (block.type === "text") process.stdout.write(block.text); } await run.wait(); const run2 = await agent.send("Now write a regression test for it"); await run2.wait();
Python:
pythonfrom cursor_sdk import Agent, LocalAgentOptions with Agent.create(model="composer-2.5", api_key=os.environ["CURSOR_API_KEY"], local=LocalAgentOptions(cwd=os.getcwd())) as agent: run = agent.send("Find the bug in src/auth.py") for message in run.messages(): if message.type == "assistant": for block in message.message.content: if block.type == "text": print(block.text, end="") run.wait() run2 = agent.send("Now write a regression test for it") run2.wait()
Agent.resume(...) - pick up an existing agent laterCross-process boundaries: cron continuations, webhooks, interactive CLIs. Runtime is auto-detected from the ID prefix — bc- is cloud, anything else is local.
TypeScript:
typescriptawait using agent = await Agent.resume(previousAgentId, { apiKey }); const run = await agent.send("Also update the changelog"); await run.wait();
Python:
pythonwith Agent.resume(previous_agent_id, AgentOptions(api_key=os.environ["CURSOR_API_KEY"])) as agent: run = agent.send("Also update the changelog") run.wait()
Inline MCP servers are not persisted across resume — pass them again.
local or cloud explicitly — the SDK defaults to local silently.CursorAgentError = run never executed (auth, config). result.status == "error" = run executed and failed. Different fixes.await using (TS) or with ... as agent: (Python). Skipping disposal leaks child processes and memory.wait() is required: wait() returns the terminal result. Always call it.run.supports("cancel") before calling.cwd. Good for dev loops and CI with a repo checkout.bashexport CURSOR_API_KEY="cursor_..."
Both SDKs read CURSOR_API_KEY when no key is passed explicitly.
composer-2.5 is the current default. model="auto" lets the server pick. Cursor.models.list() returns valid IDs.
Both SDKs support HTTP (with headers or OAuth auth) or stdio (command / args / env). Pass servers inline on Agent.create or agent.send.
await using (TS) or with ... as agent: (Python).CursorAgentError, exit 2 for result.status == "error".run.id and agent.agentId immediately after send().error.isRetryable. Blind retries can cause duplicate cloud runs.apiKey explicitly in shared-infrastructure code.Agent.prompt(...) for true one-shots — it disposes for you.Other measured skills in the registry, with their headline benchmark lift.