> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mesa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel

> Use Mesa with Vercel Sandbox for secure agent workflows.

[Vercel Sandbox](https://vercel.com/docs/vercel-sandbox/quickstart) provides isolated Linux sandboxes for running agent workflows. This guide shows the full end-to-end flow: use the Mesa SDK outside the sandbox to set up resources, then use the Vercel Sandbox SDK to configure and mount Mesa inside the sandbox.

The general flow for any sandbox integration is:

1. **Outside the sandbox** — use the Mesa SDK (TypeScript or Python) to create repos, sign a short-lived access token, and orchestrate your workflow.
2. **Inside the sandbox** — install the `mesa` CLI, configure FUSE access, and start `mesa mount` as a detached sandbox command with `MESA_ACCESS_TOKEN` in its environment.
3. **Run your agent** — run commands in the Mesa mount path (ex. Claude Code, Codex, or a custom agent). Any file edits are automatically persisted back to Mesa.

For general information on FUSE setup, system dependencies, and container configuration, see [POSIX Mount](/content/mesafs/posix-mount).

## Sandbox setup

Vercel sandboxes run on Amazon Linux 2023, so install FUSE with `dnf`. The Mesa installer supports RPM-based Linux distributions, so the standard install script works on Vercel.

Vercel's `runCommand` takes an object where `cmd` is the executable and `args` are its arguments. Use `sh -c` only when you need shell syntax like pipes or redirection.

```typescript theme={null}
import { Sandbox } from "@vercel/sandbox";
import { Mesa } from "@mesadev/sdk";

const mesa = new Mesa({ privateKey: process.env.MESA_PRIVATE_KEY });

// --- Outside the sandbox: set up Mesa resources ---

// Create a repo (or use an existing one)
const repo = await mesa.repos.create({ name: "agent-workspace" });

// Sign a scoped, self-expiring access token for the sandbox. The token is
// signed locally with your private key, no network call, and the private
// key itself never enters the sandbox. Scope it to the repos the session
// needs, as full `org/repo` names.
const { token } = await mesa.tokens.create({
  authors: [{ name: "Sandbox Agent", email: "agent@example.com" }],
  scopes: ["read", "write"],
  repos: ["my-org/agent-workspace"],
  ttl_seconds: 60 * 60, // 1 hour; max 4 hours
});

// --- Inside the sandbox: install and mount Mesa ---

const sandbox = await Sandbox.create({
  teamId: process.env.VERCEL_TEAM_ID,
  projectId: process.env.VERCEL_PROJECT_ID,
  token: process.env.VERCEL_TOKEN,
});

// Install the Mesa CLI.
await sandbox.runCommand({
  cmd: "sh",
  args: ["-c", "curl -fsSL https://mesa.dev/install.sh | sh -s -- --version 0.46.0"],
});

// Install FUSE and enable non-root access to the FUSE mount.
await sandbox.runCommand({
  cmd: "dnf",
  args: ["install", "-y", "fuse3"],
  sudo: true,
});

await sandbox.runCommand({
  cmd: "sh",
  args: [
    "-c",
    [
      "echo user_allow_other >> /etc/fuse.conf",
      "chmod 666 /dev/fuse",
    ].join("\n"),
  ],
  sudo: true,
});

// Start Mesa as a detached command so Vercel keeps the long-running mount
// process alive.
await sandbox.runCommand({
  cmd: "mesa",
  args: ["mount"],
  detached: true,
  env: {
    MESA_ACCESS_TOKEN: token,
  },
});

// --- Run your agent ---

await sandbox.runCommand({
  cmd: "sh",
  args: ["-c", 'claude -p "Implement the feature described in TODO.md"'],
  cwd: "/home/user/.local/share/mesa/mnt/my-org/agent-workspace",
});
```

## Command snippets

When you already have a Vercel sandbox, these are the commands that run inside it:

```bash theme={null}
# Install the Mesa CLI.
curl -fsSL https://mesa.dev/install.sh | sh -s -- --version 0.46.0

# Install FUSE and enable non-root access.
sudo dnf install -y fuse3
sudo sh -c 'echo user_allow_other >> /etc/fuse.conf && chmod 666 /dev/fuse'

# Start Mesa as a long-running mount process.
MESA_ACCESS_TOKEN="$MESA_ACCESS_TOKEN" mesa mount

# --- Run your agent ---
cd ~/.local/share/mesa/mnt/my-org/agent-workspace
claude -p "Implement the feature described in TODO.md"
```

## Example

For a runnable TypeScript example with a small interactive shell, see [`examples/vercel-shell`](https://github.com/mesa-dot-dev/depot/tree/main/examples/vercel-shell).

## Tips

* **Use scoped, short-lived access tokens.** Sign a dedicated token for each sandbox session with only the scopes it needs. It's signed locally with your private key (which never enters the sandbox) and expires on its own. See [Authentication](/content/concepts/authentication) for details.
* **Pick a TTL that covers the session.** Tokens default to a 15 minute TTL and max out at 4 hours, and a mount keeps the token it started with for its whole lifetime. If the token expires mid-session, filesystem operations in the sandbox start failing with authentication errors; mint a fresh token on the host and start a new detached mount.
* **Use Vercel's detached commands.** Run `mesa mount` with `detached: true` instead of `mesa mount --daemonize`; this lets Vercel keep the long-running mount process alive.
* **Run commands from the mount path.** Set `cwd` to `~/.local/share/mesa/mnt/<org>/<repo>` when running your agent command.
* **Configure FUSE explicitly.** Vercel sandboxes need `fuse3`, `user_allow_other`, and non-root access to `/dev/fuse`.
