Cursor Cloud Agents can now run in Vercel Sandbox instead of Cursor's hosted machines. This guide uses Cursor's Self-Hosted Machines APIs and Vercel Sandbox to create one isolated Linux microVM for each queued agent.
Cursor hosts the agent harness and inference loop. Vercel Sandbox supplies the computer where the agent clones code, runs commands, edits files, and executes tests.
Follow the walkthrough below to build it yourself.
Copy link to headingHow it works
The integration has two planes:
- Control plane (Vercel Functions + Vercel Workflow): a Function exposes the controller endpoint, while a durable discovery workflow checks the Cursor team pool with adaptive backoff (longer waits after consecutive empty checks). Cursor's claim endpoint assigns each pending request to one worker ID. Each claim starts an independent child workflow that manages one worker's provisioning, monitoring, and cleanup.
- Compute plane (Vercel Sandbox): boots from a snapshot with the Cursor Agent CLI preinstalled and starts a request-scoped Cursor worker. The worker exits after an idle grace period, and the Sandbox has a fixed upper-bound timeout.
Cursor's team pool remains registered when it has zero workers. That makes scale-to-zero possible: users can select the pool while no compute is running, and the controller creates capacity only when a request arrives.
Each request is claimed before its child workflow starts. Cursor's claim endpoint atomically assigns one pending request to one worker ID, so competing controllers cannot claim the same request. That guarantee covers request assignment only. Deterministic Workflow hooks deduplicate the pool controller and child workflow, while deterministic Sandbox names make provisioning idempotent across retries. Together, these safeguards prevent retries from creating competing workers or duplicate Sandboxes for the same Cursor request.
Copy link to headingPrerequisites
- A Vercel account with Vercel Sandbox access
- A Cursor Enterprise account with Self-Hosted Machines enabled
- A Cursor agent-scoped team service account API key, created by a Cursor team admin
- Node.js 22 or later
- The Vercel CLI
Cursor members can create user API keys, but only team admins can create the Enterprise service account this controller requires.
Copy link to headingSet up the project
Create a Next.js app and install the dependencies:
Enable Workflow's Next.js directives in next.config.ts:
Link the app to Vercel and pull a development OIDC token:
On Vercel, the Sandbox SDK authenticates automatically with OIDC. The pulled VERCEL_OIDC_TOKEN provides the same behavior during local development.
Add your Cursor service account key to .env.local:
The service account key stays in the Vercel Functions and Workflow control plane. It is used to inspect and claim work and to mint one-hour worker tokens; it is never copied into an agent's microVM.
Copy link to headingBuild the worker snapshot
Installing the Cursor Agent CLI for every request would add setup time before an agent can begin. Instead, start from a Vercel Managed Image, install the CLI once, and save the result as a Sandbox snapshot.
Create scripts/build-snapshot.ts:
Create the snapshot and save the printed ID:
Snapshotting stops the source Sandbox automatically. Rebuild the snapshot whenever you want to update the Cursor Agent CLI.
Copy link to headingRegister a scale-to-zero team pool
The pool must exist before a user or API request can target it. Register an any-repository team pool with no workers attached:
Cursor's pool registration reference defines workerReadyTimeoutSeconds as the time a claimed request waits for its offline worker to reconnect. Setting it to 0 makes a follow-up reacquire from the pool immediately, where the controller can claim it and create a fresh Sandbox.
For a pool limited to one repository, also pass repoOwner, repoName, and repoUrl. Repository-scoped service account keys must include the same repository filter when listing pending requests.
Copy link to headingBuild the control plane
The walkthrough creates the following files:
Copy link to headingConnect to Cursor's API
Each code block continues the named file from the preceding block. Create lib/cursor-workers.ts with its imports, configuration, and shared types:
Cursor accepts Basic or Bearer authentication. Add the API helper:
The module needs five Cursor operations: list pending work, claim it for one worker, mint a user-scoped token, read the agent status, and release the claim. Start with discovery and claiming:
Cursor's worker token reference documents POST /v1/sub-tokens as returning a one-hour token. Add token minting and status lookup:
Release the claim during cleanup. Cursor's claim release reference explicitly defines 404 as no live claim because it was already released, expired, or adopted, so cleanup should not retry that response:
Copy link to headingProvision a worker Sandbox
Use deterministic names so a retry resolves to the same claim and microVM:
Write the minted worker token to a file readable only by the Sandbox user:
Provisioning retrieves or creates the named Sandbox, then refreshes its token file on every attempt:
Then start a detached worker. --auth-token-file supplies the pre-minted token without placing it in the process arguments. The non-blocking flock prevents a retry from starting a second process in the same Sandbox:
Cursor's claim release reference documents CURSOR_WORKER_IDLE_RELEASE_TIMEOUT as the environment-variable form of --idle-release-timeout. This guide uses 600 for a ten-minute grace period.
Expose one provisioning function for the worker workflow:
The service account key remains in the Vercel Functions and Workflow control plane. Only the one-hour token for the requesting Cursor user enters the microVM.
Copy link to headingClaim pending requests
Claim one request at a time. Redispatch a claimed request only when its worker ID matches the deterministic ID owned by this controller:
Apply the concurrency cap and return the claimed jobs:
The cap is deliberate. It prevents one queue spike from creating unbounded compute and gives you a simple concurrency control to tune for your team.
Copy link to headingOrchestrate each worker
Create workflows/cursor-worker.ts. Begin with the dependencies used by the worker workflow:
Each claimed request gets its own workflow. Keep external operations in steps so Workflow can retry and record them independently:
Cleanup is also a step. It stops the named Sandbox and then releases the Cursor claim. Treat a missing Sandbox as already cleaned up.
The workflow lease deduplicates each request. After provisioning, the child checks the agent every 30 seconds and cleans up when it becomes idle or reaches the 45-minute limit:
Copy link to headingRun the discovery workflow
Now create workflows/cursor-pool-controller.ts with its imports:
The parent only discovers work and starts children. Starting a child inside a step gives every request its own Workflow run and event log:
Use a pool-level lease and adaptive polling in the parent:
The controller checks again quickly while draining a backlog, polls once per minute when recently idle, and backs off to five minutes after repeated empty checks. Hook leases deduplicate both the controller and per-request workers.
Copy link to headingExpose the controller endpoint
Create app/api/cursor-workers/controller/route.ts to start the controller:
Set the controller secret, deploy, and start the workflow once:
The controller reconciles immediately and then uses adaptive polling. Durable sleeps are not bound by Vercel Function duration and do not consume compute while suspended, so this design works on Hobby as well as Pro and Enterprise. The 45-minute Sandbox timeout is the Hobby maximum; Pro and Enterprise support longer sessions. For lower pickup latency, a persistent service can consume Cursor's pending-request SSE stream and keep the same claim-and-dispatch path.
Copy link to headingStart an agent on the team pool
Users can select vercel-sandbox from Cursor's Cloud Agents interface. You can also target the pool through the Cloud Agents API:
The request first appears in the durable pool. On the next discovery pass, the parent Workflow claims it and dispatches a child Workflow. The child retrieves or creates the request's named Sandbox, starts the worker, monitors the agent, and cleans up when the run becomes idle.
No inbound port, load balancer, or publicly reachable worker service is required.
Copy link to headingProduction considerations
This implementation is intentionally small. Before using it for a large fleet, account for reliability, security, and operating cost.
Copy link to headingReliability and lifecycle
Use Cursor's list-then-watch SSE flow when you need lower pickup latency than adaptive polling provides. Workflow runs stay pinned to the deployment that started them; because the controller starts children without overriding deploymentId, its children use the same deployment. After an incompatible change, cancel the old controller and start it again from the new production deployment. The hook lease prevents two controllers from remaining active for the same pool.
Workflow may retry an interrupted step. Cursor's atomic claim, deterministic worker IDs, per-request Workflow leases, and deterministically named Sandbox.getOrCreate() calls make those retries safe. Each child Workflow stops its Sandbox and releases its claim when the agent becomes idle, with the 45-minute Sandbox timeout as a final safety net. User-scoped worker tokens expire after one hour and cannot refresh themselves, so longer sessions require a secure refresh path or a different scoped credential strategy.
Copy link to headingCredentials and network access
Configure Cursor's Git provider integration or supply short-lived Git credentials through your organization's approved secret flow. Do not bake credentials into a snapshot. Restrict outbound traffic to the destinations required by the worker and its build; Vercel Sandbox supports egress allowlists and credential brokering at the microVM firewall.
Copy link to headingCapacity and maintenance
Tune MAX_WORKERS_PER_TICK, Sandbox vCPUs, and pool quotas for your Vercel plan and expected workload. Rebuild snapshots periodically to keep the Cursor Agent CLI and system packages current. Record request ID, worker ID, Sandbox ID, creation time, and termination reason in your telemetry, but never log worker tokens.
Copy link to headingWhat you built
The completed integration uses Vercel Functions and Workflow to discover, claim, and coordinate Cursor requests. Each request runs in a dedicated Vercel Sandbox created from a prebuilt snapshot, then shuts down automatically when the agent becomes idle.
This provides a scale-to-zero Cursor Self-Hosted Machines team pool without maintaining long-lived worker infrastructure. For implementation details, see Cursor's team pool APIs and the Vercel Sandbox documentation.