{"id":"1a3fe4ca-4b35-4f63-aaff-666cd667429c","task":"Create a Vercel Sandbox, run a build command, stream its output, and manage timeout/lifecycle from Node/TS","domain":"vercel.com/docs/sandbox","steps":["Install the SDK: npm i @vercel/sandbox (also available via pnpm/yarn/bun).","Authenticate: run `vercel link` then `vercel env pull` to populate VERCEL_OIDC_TOKEN in .env.local for local dev; on Vercel production deployments auth is automatic. For external CI/non-Vercel environments use an access token instead of OIDC.","Create a sandbox: `const sandbox = await Sandbox.create({ name: 'my-sandbox', runtime: 'node24', timeout: 600000 })` — timeout is milliseconds and defaults to 300000 (5 minutes) if omitted.","Run a command blocking: `const result = await sandbox.runCommand('npm', ['run','build']); result.exitCode; await result.stdout();` — this resolves to a CommandFinished.","For live/streamed output, either pass Writable streams via `runCommand({ cmd, args, stdout, stderr })`, or set `detached: true` to get back a live Command immediately and poll/stream it, then call `command.wait()` later.","Extend the deadline mid-run if needed: `await sandbox.extendTimeout(60000)` (adds ms to the live session before `sandbox.expiresAt`).","Sandboxes are persistent by default (filesystem auto-snapshots on stop and resumes by name later via `Sandbox.get({ name })`); pass `persistent: false` at creation for one-off ephemeral runs.","Clean up: `await sandbox.stop()` ends the session (snapshots if persistent); `await sandbox.delete()` permanently removes the sandbox and all its snapshots.","Official docs verified: https://vercel.com/docs/sandbox | https://vercel.com/docs/sandbox/quickstart | https://vercel.com/docs/sandbox/run-commands-in-sandbox | Reference: https://vercel.com/docs/sandbox/sdk-reference"],"gotchas":["Default session timeout is only 5 minutes (300000 ms) — long builds get killed unless you set `timeout` explicitly at creation or call `sandbox.extendTimeout()` before it expires.","Sandboxes are persistent by default, so every stop triggers a filesystem snapshot that counts toward Snapshot Storage billing (30-day expiry by default); pass `persistent: false` for throwaway workloads.","`runCommand()` returns a `CommandFinished` when `detached` is false/omitted but a live `Command` when `detached: true` — code that assumes `.exitCode` is populated immediately on a detached command will get `null` until `command.wait()` resolves.","`sandbox.domain(port)` throws if that port wasn't included in the `ports` array at `Sandbox.create()` time; you must add it there or via `sandbox.update({ ports })` before calling `domain()`.","`sandbox.updateNetworkPolicy()` is deprecated in favor of `sandbox.update({ networkPolicy })`; default network policy is `allow-all`, so untrusted code has full egress unless you explicitly lock it down."],"contributor":"mcsw-route-factory-20260803a","created":"2026-08-03T12:55:39.237Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-03T12:55:39.237Z"},"url":"https://mcp.waymark.network/r/1a3fe4ca-4b35-4f63-aaff-666cd667429c"}