Release Notes
Cursor SDK release notes
The latest features, improvements, and fixes shipping to the Cursor SDK, covering @cursor/sdk on npm and cursor-sdk on PyPI.
- Custom tools know which session called them. The
executecallback of alocal.customToolsentry now receivescontext.sessionId, the local session that invoked the tool. Subagents started withTaskpass their own id, so a host can keep separate state for each child agent. TypeScript only; unset when the runtime has no session id. - Fixes to local agents and TypeScript types. Local agents now work on FIPS-enabled hosts, and existing local agent stores move to the new location automatically. Agents restored from the same process or VM snapshot no longer reuse request and session IDs, so concurrent runs don't collide or get stuck. The
LocalSubagentInherittype declarations now resolve without an unpublished internal package, using the newly exportedLocalSubagentResourceProviderFieldsandLocalToolExecutortypes.
- Subagents can inherit the parent's executors and tool limits. Set
local.subagentInheritso that agents started by theTasktool, including nested ones, use the same custom read, write, and shell executors and reported workspace path as the parent, and the same allowed and excluded tools. Pass it onAgent.create()or override it for onesend. TypeScript local agents only. If you leave it unset, subagents behave as they did before. - Fixed requests stalling on dropped connections in long-running agents. When an agent sits idle between runs, the SDK now closes unused HTTP/2 connections after 29 seconds. It also checks a connection that has been quiet for about a minute before reusing it. Requests no longer get written into a connection the server has already closed, where they used to hang until the stall timeout aborted them.
- Stalled connections are retryable and bounded. When a connection stalls, the run fails with a retryable
NetworkErrorcarrying the codeconnection_stalled, and a streak of stall retries stops after 3 minutes instead of retrying indefinitely. - Fewer dependencies installed with the SDK. Installing
@cursor/sdkno longer adds@connectrpc/connect-nodeorundici5.x to your project's dependency tree, so installs are smaller and you no longer get version conflicts or audit warnings from those packages.
- Steer an agent while it waits on background subagents.
run.steer(text)used to resolverevert_to_followupwhen the agent had ended its turn to wait on background subagents, so your message waited until that work finished. Now the steer runs right away as the next turn, and background results still arrive afterward. TypeScript local runs only. - Know when a step has finished requesting tools.
onDeltanow receives atool-requests-listedupdate with acallCountonce the model finishes listing its tool calls for a step, while those tools may still be running. Use it to tell when every tool call in a step has started, for example to group or batch a step's tool calls in your UI. - Fixes to cloud agent creation. For cloud agents, the first
send(), which creates the agent on the server, no longer fails with an id conflict when the SDK generated the agent id: it retries with a fresh id, or continues with the agent if its own earlier create already succeeded. SDK-generated agent and run ids also no longer repeat when a process is restored from the same snapshot more than once. Ids you pin yourself still report the conflict. - The bridge ignores your project's
.envandbunfig.toml. The standalonecursor-sdk-bridgeexecutables no longer load.envorbunfig.tomlfrom the working directory, which is usually your project when the SDK starts the bridge. Files in a checkout can no longer change the bridge's endpoints, tokens, or preloaded code.
- Background subagents report back. When the agent runs a subagent in the background, its result now returns to the parent as a follow-up turn on the same run instead of being dropped when the parent turn ends.
run.stream()keeps yielding through those turns andrun.wait()resolves after them. Local agents, in TypeScript and Python. - Annotate custom tools.
annotationson alocal.customToolsentry passes MCP tool annotations (title,readOnlyHint,destructiveHint,idempotentHint,openWorldHint) through to the model. They are descriptive hints only; the SDK does not enforce them. TypeScript only.
- Long-running local agents keep their credentials fresh. Local runs in TypeScript and Python refresh the short-lived access token before it expires, so agents that run for more than an hour no longer fail with authentication errors. Cloud runs are unaffected.
- Output schemas on custom tools.
outputSchemain TypeScript andoutput_schemain Python declare a JSON Schema for a custom tool's structured result, advertised to the model as the tool's MCP output schema. Results are not validated against it. Local agents only.
- Ship the SDK as a single file. Under Bun,
@cursor/sdknow resolves to a flat single-file bundle, sobun build --compileworks with no import change and no moreCannot find module './986.js'.@cursor/sdk/bundledand@cursor/sdk/bundled/sqliteexpose the same build as explicit entries for other single-file bundlers such as esbuild. TypeScript only.
- Restrict the agent's toolset.
toolsallowlists the built-in tools offered to the model ([]means text-only), anddisallowedToolsremoves tools while keeping the rest. Both take public names like"read"or capability groups like"shell"and"mcp", in TypeScript and Python (tools,disallowed_tools). Local agents only for now, and not persisted acrossresume. - Log in from the browser in TypeScript.
Cursor.auth.login()opens a browser login, mints an API key, and stores it in~/.cursor/sdk/auth.json;Cursor.auth.status()andCursor.auth.logout()round it out. After login,Agent.create()and theCursor.*reads work withoutapiKeyorCURSOR_API_KEY. - Usage and cost for local agents.
agent.getUsage()in TypeScript andagent.get_usage()in Python now work for local agents too, returning a per-turn breakdown. Pass arunIdfrom a previous result to narrow to one turn. - Open PRs as the Cursor GitHub App.
cloud.openAsCursorGithubAppin TypeScript andopen_as_cursor_github_appin Python control PR authorship. Service-account keys default to the app; user keys default to the key's owner. - Multi-root local workspaces. Pass
local.dirsto load rules, skills, and project context from several folders;cwdstays the single primary working directory. Replaces thecwdarray form, which only ever used the first entry. - Clearer Python errors. Failures that previously surfaced as a bare "internal error" now carry the underlying message and code.
- Admin Admin command denylists apply to local runs. Shell commands matching your team's admin denylist are rejected with a policy message before they execute, including on paths that skip approval prompts.
- Warm up a local workspace before the first send.
platform.prewarmLocalWorkspace(options)resolves rules, skills, MCP servers, and ignore files ahead of time, so the firstsend()against that workspace starts immediately. It returns a release function to call on shutdown. - Control how long workspace scans stay cached.
configureCursorSdk({ local: { workspaceScanCacheTtlMs } })sets the cache lifetime for workspace scans, and theCURSOR_RIPWALK_CACHE_TTL_MSenvironment variable sets the same value for hosted deployments. Long-lived servers on stable checkouts can now skip repeated re-scans. - Custom tools run without approval prompts. Host-defined tools passed via
customToolsno longer fail with an interactive-approval error on sandboxed or auto-review local runs. Deny rules and sandbox limits still apply. - Signed macOS binaries. The
@cursor/sdkmacOS platform packages now ship code-signed binaries, so Gatekeeper and endpoint security tools no longer block them. - Cleaner Python exception hierarchy.
PermissionDeniedError,BadRequestError, andInternalServerErrornow inherit directly fromCursorSDKErrorinstead ofAuthenticationError,ConfigurationError, andNetworkError, soexceptblocks catch what their names say. - Fixed intermittent startup failures in Python. Roughly 1 in 64 agent launches failed before reaching the first send. Launches are now reliable.
- Billed usage and cost on demand.
agent.getUsage()in TypeScript andagent.get_usage()in Python return token usage, billed cost, and a per-run breakdown for cloud agents, andAgent.getUsage(agentId)works without a handle. Cost is server-derived, includes discounts, and settles shortly after a run ends. Cloud-only for now; local runs throw a typed configuration error.
- TypeScript and Python now release together. Starting with 1.0.24,
@cursor/sdkon npm andcursor-sdkon PyPI ship from the same release and share a version number. Python releases no longer trail TypeScript. - More reliable long-running streams. Streaming responses on heavy runs no longer drop mid-stream, which previously surfaced as network errors in Python clients on long turns.
Ships with Python SDK 0.1.9.
- Per-send environment variables for cloud runs. Pass
send(prompt, { cloud: { envVars } })to scope env vars to a single run, including the first send that creates the agent.Agent.create({ cloud: { envVars } })still sets agent-scoped defaults. - Error details on failed runs. Local and cloud runs that fail now expose a structured error with
messageandcodefields, so you can tell what went wrong without parsing logs.run.wait()behaves the same as before. - Token usage in Python. Run streams emit typed
usagemessages with per-turn token counts, and cumulative totals are available onrun.usageandRunResult.usage, matching TypeScript from 1.0.22. - Sturdier local run history. Run history on disk now survives interrupted writes, fixing a class of failures where a crashed process left runs that could not be resumed.
- Fixed streaming stalls on Bun. Run streams under Bun no longer stall on long responses.
- Token usage on every run. Local runs emit per-turn
usageevents onrun.stream()and cumulative totals onrun.wait(). Cloud runs surface the same usage on their stream andwait()results, and totals persist for detached local handles so a process that reattaches still gets them.
- Run agents under Bun.
agent.send()now works under Bun with the same behavior as Node. This also fixes fresh Node installs that could miss a required dependency. - Friendlier runtime names in Python. List APIs and
get_runacceptruntime="cloud","local", and"auto", matching the documented values.
- The SDK imports cleanly under Bun. Importing
@cursor/sdkno longer crashes under Bun. Running agents under Bun follows in 1.0.21.