The official TypeScript package embeds an agent directly into your process. A modern runtime version is required, and there is a choice of two modes set by exactly one key. Local mode executes the agent loop and file tools inside your process, though the reasoning still goes through hosted models: locality here is about where files are read and written, not about where the answer is computed. Cloud mode creates an isolated virtual machine. Those are fundamentally different trust models - in the first case you hand the tools access to your own file system, in the second to a temporary foreign one - and they are chosen deliberately.
The package's concepts are the same as in the programmatic interface: the agent is a durable container, a run is one prompt, events arrive in a normalized form identical for both modes. There is also a short form for a one-off task that creates an agent, sends the prompt, waits for the result and releases resources by itself. It is convenient exactly where no continuation of the conversation is needed: a one-off check, a one-off summary, a one-off edit against a clear statement. As soon as a second request over the same material appears, keeping the agent and sending it another run is cheaper than rebuilding the context from scratch.
It helps to see a minimal integration once. Below are creating an agent with a key, a model and local mode with isolation enabled, sending a prompt and reading the event stream. Note two details: explicitly enabling the sandbox and phrasing the task without edits. Neither is accidental, and both concern the same thing - the boundary of what the program may do to your working directory.
The most important warning here concerns default behavior. The local mode quickstart does not show approvals: shell commands, edits and file writes run automatically. That is logical for a programmatic interface - there is nobody to ask, and any wait for confirmation would block the process - but it means that running on a working tree with your credentials and without isolation is equivalent to giving full access to a script you have just written and never once tested.
Hence a practical rule: before the first run on a real directory, isolation is enabled and, if needed, event handlers. The sandbox in the start options is one line, while its absence turns an imprecision in the task's wording into file changes nobody expected. The same principle as in interactive work, except the cost of carelessness is higher: a human at the editor sees the proposed edit and can reject it, while a program will not stop and will not ask again.
Cloud mode removes some of those questions but adds its own: the environment, secrets, the network and artifacts. In exchange, results are available there as files, screenshots and videos. The choice between the modes usually comes down to one question - must the work run on your machine with its files or in a clean isolated environment. If the task amounts to reading a repository and preparing a change, locality offers nothing but risk.
There is one scenario where this is forgotten most often - running the package inside your own service or build pipeline. The process there is usually already loaded with environment variables: storage keys, deployment tokens, database credentials. The agent's tools work in that same process, which means a shell command it launches sees exactly the same environment. Hence a rule unrelated to the package itself: an executor is started with a minimal set of secrets rather than with the set it inherited from the parent process. The symptom of a broken boundary is recognizable: the agent solves the task by an unexpectedly quick route - it reaches an external service or a database the statement never mentioned, simply because the access was lying nearby.
Event handlers are the second control point, and they are worth thinking about as a construct rather than a setting. They let you step in before a tool acts and allow it, reject it or record it, that is, build the very check that automatic mode lacks by construction. They also serve auditing: without a record of which commands the agent ran, reviewing the consequences comes down to reading the file history. Their third duty is the resource lifecycle: the automatic disposal construct in the example is not decoration but a guarantee that a one-off task leaves behind no dangling agent that keeps counting as alive and costing money.
The engineering conclusion is simple: a language package turns the agent into a component of your service and must be treated as a component. It has configuration, boundaries, error handling and a resource lifecycle. A quickly written script that creates an agent with full rights over the working directory is not an integration but a way to one day explain to colleagues where those changes came from.
The typical failures are predictable. Running local mode on a working tree without isolation. Expecting approvals where there are none by construction. Handing the agent the parent process's entire environment along with unrelated secrets. Mixing both modes in one configuration instead of choosing explicitly. And not releasing resources, leaving durable agents behind after one-off tasks.
import { 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(),
// without the sandbox the agent writes to the working
// directory, runs shell commands and reaches the network
sandboxOptions: { enabled: true },
},
});
const run = await agent.send("Summarize this repository without edits");
for await (const event of run.stream()) {
console.log(event);
}