vercel-sandbox — скилл для Codex: что делает и установка
Скилл запускает пользовательский и сгенерированный код в изолированной Vercel Sandbox. Он пригодится для браузерной автоматизации и проверки кода без запуска в основном окружении.
npx skills add openai/plugins --skill vercel-sandbox -a codexЧто делает vercel-sandbox
vercel-sandbox поднимает временную Firecracker microVM, запускает в ней команды и останавливает окружение после работы. Внутри описан сценарий для agent-browser и headless Chrome: можно открыть страницу, получить заголовок, снять скриншот или взять accessibility snapshot.
Скилл поддерживает многошаговые сценарии. Состояние Sandbox сохраняется между командами, поэтому агент может открыть форму, найти элементы по snapshot, заполнить поля, нажать кнопку и дождаться загрузки. Для запуска нужны переменные VERCEL_TOKEN, VERCEL_TEAM_ID и VERCEL_PROJECT_ID, если требуются учётные данные Vercel. Без snapshot придётся установить системные зависимости Chromium, agent-browser и браузер; snapshot хранит эти зависимости заранее.
Ставьте его, если агенту нужно выполнять непроверенный код или браузерные команды в отдельной VM. Для обычных команд в локальном проекте этот скилл будет лишним.
Какие задачи решает
- запустить непроверенный код в отдельной VM
- открыть страницу и снять скриншот
- получить accessibility snapshot сайта
- заполнить и отправить веб-форму
- дождаться сетевой загрузки после клика
Примеры запросов агенту
- Запусти URL в Vercel Sandbox через `agent-browser` и верни заголовок со скриншотом.
- Открой страницу, получи accessibility snapshot, заполни поля формы и нажми кнопку отправки.
- Выполни этот код в изолированной Sandbox и останови VM после завершения.
Как установить vercel-sandbox
1Через Skills CLI (Vercel)
npx skills add openai/plugins --skill vercel-sandbox -a codex2Вручную: положить файлы
.agents/skills/vercel-sandbox/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add openai/plugins --skill vercel-sandbox -a claude-code2Вручную: положить файлы
~/.claude/skills/vercel-sandbox/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/vercel-sandbox/
Вручную: положить файлы
.cursor/skills/vercel-sandbox/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install openai/plugins vercel-sandbox2Вручную: положить файлы
.github/skills/vercel-sandbox/SKILL.mdКомандой платформы
gemini skills install https://github.com/openai/plugins --path plugins/vercel/skills/vercel-sandboxВручную: положить файлы
.devin/skills/vercel-sandbox/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Claude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
Из того же набора201
Весь набор →Похожие
Вопросы о vercel-sandbox
Как установить vercel-sandbox в Codex?
Выполните npx skills add openai/plugins --skill vercel-sandbox. Файл скилла появится по пути .agents/skills/vercel-sandbox/SKILL.md.
Что делает vercel-sandbox?
Он запускает команды, пользовательский или сгенерированный код во временной Firecracker microVM. Сценарии из скилла используют agent-browser и headless Chrome для браузерной автоматизации.
Что нужно для запуска браузера в Vercel Sandbox?
Без snapshot нужны системные зависимости Chromium, agent-browser и установленный браузер. Для доступа к Vercel могут понадобиться VERCEL_TOKEN, VERCEL_TEAM_ID и VERCEL_PROJECT_ID.
Исходный текст
SKILL.md · Apache-2.0
---
name: vercel-sandbox
description: Vercel Sandbox guidance — ephemeral Firecracker microVMs for running untrusted code safely. Supports AI agents, code generation, and experimentation. Use when executing user-generated or AI-generated code in isolation.
metadata:
priority: 4
docs:
- "https://vercel.com/docs/sandbox"
sitemap: "https://vercel.com/sitemap/docs.xml"
pathPatterns: []
importPatterns:
- '@vercel/sandbox'
bashPatterns:
- '\bnpm\s+(install|i|add)\s+[^\n]*@vercel/sandbox\b'
- '\bpnpm\s+(install|i|add)\s+[^\n]*@vercel/sandbox\b'
- '\bbun\s+(install|i|add)\s+[^\n]*@vercel/sandbox\b'
- '\byarn\s+add\s+[^\n]*@vercel/sandbox\b'
promptSignals:
phrases:
- "@vercel/sandbox"
- "sandbox"
- "code sandbox"
- "vercel sandbox"
- "isolated environment"
- "sandboxed execution"
allOf:
- [sandbox, code]
- [sandbox, execute]
- [sandbox, run]
- [sandbox, isolated]
- [sandbox, safe]
- [sandbox, environment]
- [isolated, execute]
- [isolated, code]
- [isolated, environment]
- [isolated, run]
- [safe, execute]
- [safe, code]
- [untrusted, code]
- [untrusted, execute]
- [code, runner]
- [code, playground]
- [execute, safely]
- [run, safely]
- [run, isolation]
- [execute, isolation]
- [ffmpeg, process]
- [ffmpeg, convert]
- [ffmpeg, compress]
- [student, code]
- [student, execute]
- [student, run]
anyOf:
- "sandbox"
- "isolated"
- "isolation"
- "untrusted"
- "safely"
- "microvm"
- "ffmpeg"
- "playground"
noneOf:
- "iframe sandbox"
- "sandbox attribute"
- "codesandbox.io"
- "stackblitz"
minScore: 4
---
# Browser Automation with Vercel Sandbox
Run agent-browser + headless Chrome inside ephemeral Vercel Sandbox microVMs. A Linux VM spins up on demand, executes browser commands, and shuts down. Works with any Vercel-deployed framework (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.).
## Dependencies
```bash
pnpm add @vercel/sandbox
```
The sandbox VM needs system dependencies for Chromium plus agent-browser itself. Use sandbox snapshots (below) to pre-install everything for sub-second startup.
## Core Pattern
```ts
import { Sandbox } from "@vercel/sandbox";
// System libraries required by Chromium on the sandbox VM (Amazon Linux / dnf)
const CHROMIUM_SYSTEM_DEPS = [
"nss", "nspr", "libxkbcommon", "atk", "at-spi2-atk", "at-spi2-core",
"libXcomposite", "libXdamage", "libXrandr", "libXfixes", "libXcursor",
"libXi", "libXtst", "libXScrnSaver", "libXext", "mesa-libgbm", "libdrm",
"mesa-libGL", "mesa-libEGL", "cups-libs", "alsa-lib", "pango", "cairo",
"gtk3", "dbus-libs",
];
function getSandboxCredentials() {
if (
process.env.VERCEL_TOKEN &&
process.env.VERCEL_TEAM_ID &&
process.env.VERCEL_PROJECT_ID
) {
return {
token: process.env.VERCEL_TOKEN,
teamId: process.env.VERCEL_TEAM_ID,
projectId: process.env.VERCEL_PROJECT_ID,
};
}
return {};
}
async function withBrowser<T>(
fn: (sandbox: InstanceType<typeof Sandbox>) => Promise<T>,
): Promise<T> {
const snapshotId = process.env.AGENT_BROWSER_SNAPSHOT_ID;
const credentials = getSandboxCredentials();
const sandbox = snapshotId
? await Sandbox.create({
...credentials,
source: { type: "snapshot", snapshotId },
timeout: 120_000,
})
: await Sandbox.create({ ...credentials, runtime: "node24", timeout: 120_000 });
if (!snapshotId) {
await sandbox.runCommand("sh", [
"-c",
`sudo dnf clean all 2>&1 && sudo dnf install -y --skip-broken ${CHROMIUM_SYSTEM_DEPS.join(" ")} 2>&1 && sudo ldconfig 2>&1`,
]);
await sandbox.runCommand("npm", ["install", "-g", "agent-browser"]);
await sandbox.runCommand("npx", ["agent-browser", "install"]);
}
try {
return await fn(sandbox);
} finally {
await sandbox.stop();
}
}
```
## Screenshot
The `screenshot --json` command saves to a file and returns the path. Read the file back as base64:
```ts
export async function screenshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", url]);
const titleResult = await sandbox.runCommand("agent-browser", [
"get", "title", "--json",
]);
const title = JSON.parse(await titleResult.stdout())?.data?.title || url;
const ssResult = await sandbox.runCommand("agent-browser", [
"screenshot", "--json",
]);
const ssPath = JSON.parse(await ssResult.stdout())?.data?.path;
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await sandbox.runCommand("agent-browser", ["close"]);
return { title, screenshot };
});
}
```
## Accessibility Snapshot
```ts
export async function snapshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", url]);
const titleResult = await sandbox.runCommand("agent-browser", [
"get", "title", "--json",
]);
const title = JSON.parse(await titleResult.stdout())?.data?.title || url;
const snapResult = await sandbox.runCommand("agent-browser", [
"snapshot", "-i", "-c",
]);
const snapshot = await snapResult.stdout();
await sandbox.runCommand("agent-browser", ["close"]);
return { title, snapshot };
});
}
```
## Multi-Step Workflows
The sandbox persists between commands, so you can run full automation sequences:
```ts
export async function fillAndSubmitForm(url: string, data: Record<string, string>) {
return withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", url]);
const snapResult = await sandbox.runCommand("agent-browser", [
"snapshot", "-i",
]);
const snapshot = await snapResult.stdout();
// Parse snapshot to find element refs...
for (const [ref, value] of Object.entries(data)) {
await sandbox.runCommand("agent-browser", ["fill", ref, value]);
}
await sandbox.runCommand("agent-browser", ["click", "@e5"]);
await sandbox.runCommand("agent-browser", ["wait", "--load", "networkidle"]);
const ssResult = await sandbox.runCommand("agent-browser", [
"screenshot", "--json",
]);
const ssPath = JSON.parse(await ssResult.stdout())?.data?.path;
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await sandbox.runCommand("agent-browser", ["close"]);
return { screenshot };
});
}
```
## Sandbox Snapshots (Fast Startup)
A **sandbox snapshot** is a saved VM image of a Vercel Sandbox with system dependencies + agent-browser + Chromium already installed. Think of it like a Docker image -- instead of installing dependencies from scratch every time, the sandbox boots from the pre-built image.
This is unrelated to agent-browser's *accessibility snapshot* feature (`agent-browser snapshot`), which dumps a page's accessibility tree. A sandbox snapshot is a Vercel infrastructure concept for fast VM startup.
Without a sandbox snapshot, each run installs system deps + agent-browser + Chromium (~30s). With one, startup is sub-second.
### Creating a sandbox snapshot
The snapshot must include system dependencies (via `dnf`), agent-browser, and Chromium:
```ts
import { Sandbox } from "@vercel/sandbox";
const CHROMIUM_SYSTEM_DEPS = [
"nss", "nspr", "libxkbcommon", "atk", "at-spi2-atk", "at-spi2-core",
"libXcomposite", "libXdamage", "libXrandr", "libXfixes", "libXcursor",
"libXi", "libXtst", "libXScrnSaver", "libXext", "mesa-libgbm", "libdrm",
"mesa-libGL", "mesa-libEGL", "cups-libs", "alsa-lib", "pango", "cairo",
"gtk3", "dbus-libs",
];
async function createSnapshot(): Promise<string> {
const sandbox = await Sandbox.create({
runtime: "node24",
timeout: 300_000,
});
await sandbox.runCommand("sh", [
"-c",
`sudo dnf clean all 2>&1 && sudo dnf install -y --skip-broken ${CHROMIUM_SYSTEM_DEPS.join(" ")} 2>&1 && sudo ldconfig 2>&1`,
]);
await sandbox.runCommand("npm", ["install", "-g", "agent-browser"]);
await sandbox.runCommand("npx", ["agent-browser", "install"]);
const snapshot = await sandbox.snapshot();
return snapshot.snapshotId;
}
```
Run this once, then set the environment variable:
```bash
AGENT_BROWSER_SNAPSHOT_ID=snap_xxxxxxxxxxxx
```
A helper script is available in the demo app:
```bash
npx tsx examples/environments/scripts/create-snapshot.ts
```
Recommended for any production deployment using the Sandbox pattern.
## Authentication
On Vercel deployments, the Sandbox SDK authenticates automatically via OIDC. For local development or explicit control, set:
```bash
VERCEL_TOKEN=<personal-access-token>
VERCEL_TEAM_ID=<team-id>
VERCEL_PROJECT_ID=<project-id>
```
These are spread into `Sandbox.create()` calls. When absent, the SDK falls back to `VERCEL_OIDC_TOKEN` (automatic on Vercel).
## Scheduled Workflows (Cron)
Combine with Vercel Cron Jobs for recurring browser tasks:
```ts
// app/api/cron/route.ts (or equivalent in your framework)
export async function GET() {
const result = await withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", "https://example.com/pricing"]);
const snap = await sandbox.runCommand("agent-browser", ["snapshot", "-i", "-c"]);
await sandbox.runCommand("agent-browser", ["close"]);
return await snap.stdout();
});
// Process results, send alerts, store data...
return Response.json({ ok: true, snapshot: result });
}
```
```json
// vercel.json
{ "crons": [{ "path": "/api/cron", "schedule": "0 9 * * *" }] }
```
## Environment Variables
| Variable | Required | Description |
|---|---|---|
| `AGENT_BROWSER_SNAPSHOT_ID` | No (but recommended) | Pre-built sandbox snapshot ID for sub-second startup (see above) |
| `VERCEL_TOKEN` | No | Vercel personal access token (for local dev; OIDC is automatic on Vercel) |
| `VERCEL_TEAM_ID` | No | Vercel team ID (for local dev) |
| `VERCEL_PROJECT_ID` | No | Vercel project ID (for local dev) |
## Framework Examples
The pattern works identically across frameworks. The only difference is where you put the server-side code:
| Framework | Server code location |
|---|---|
| Next.js | Server actions, API routes, route handlers |
| SvelteKit | `+page.server.ts`, `+server.ts` |
| Nuxt | `server/api/`, `server/routes/` |
| Remix | `loader`, `action` functions |
| Astro | `.astro` frontmatter, API routes |
## Example
See `examples/environments/` in the agent-browser repo for a working app with the Vercel Sandbox pattern, including a sandbox snapshot creation script, streaming progress UI, and rate limiting.
© Vercel Labs · Apache-2.0 · openai/plugins