Skip to content
Docs

Build an agent with Vercel and Flue

Build and deploy an agent with Flue, Vercel Sandbox, and AI Gateway

6 min read
Last updated June 17, 2026

Flue is a TypeScript framework for building autonomous agents, designed around a built-in agent harness. It's like Claude Code, but headless and programmable. No TUI, no GUI, just TypeScript. The agents you build act autonomously to solve problems and complete tasks, and most of the logic lives in Markdown: skills, context, and AGENTS.md. Write once, then deploy anywhere.

In this guide you will build and deploy a Flue agent to Vercel, connect it to a Vercel Sandbox MicroVM for isolated code execution, and route all model traffic through Vercel AI Gateway for spend tracking, failover, and observability.

A coding agent exposed over HTTP. It receives a repo URL and a prompt, clones the repo into an isolated Sandbox MicroVM with a real Linux shell, and uses an LLM to explore and work on the codebase. All LLM calls are routed through AI Gateway using a single provider/model string, with spend caps and rate limits available from the Vercel dashboard.

  • Node.js 22+
  • Vercel CLI (pnpm add -g vercel)
  • A Vercel project with AI Gateway enabled
  • pnpm installed

You should already have a Flue project that builds and runs. If you don't, scaffold one first:

pnpm create flue
cd my-agent

This gives you a project with the following layout:

.flue/
agents/
roles/
connectors/
flue.config.ts
package.json

Connect your Flue project to Vercel and pull a development OIDC token:

vercel link
vercel env pull

This creates a .env.local file with a VERCEL_OIDC_TOKEN, a short-lived JWT that authenticates requests to both AI Gateway and Sandbox. Both SDKs read it from the environment automatically. No provider API keys or manual wiring needed.

The token expires after 12 hours. Run vercel env pull again if you see auth errors. On Vercel deployments, token refresh is automatic.

Flue ships a first-party Vercel Sandbox connector. Install it with flue add and pipe the instructions to your coding agent:

flue add vercel --print | claude

This writes a .flue/connectors/vercel.ts adapter into your project. Any coding agent works here:

flue add vercel --print | opencode
flue add vercel --print | codex
flue add vercel --print | cursor-agent

Then install the Sandbox SDK:

pnpm add @vercel/sandbox

Create .flue/agents/coder.ts. Three things differ from a default Hello World agent: you import the Sandbox connector, create a MicroVM, and configure AI Gateway as the model provider.

import type { FlueContext } from '@flue/sdk/client';
import { Sandbox } from '@vercel/sandbox';
import { vercel } from '../connectors/vercel';
export const triggers = { webhook: true };
export default async function (
{ init, payload, env }: FlueContext
) {
const sandbox = await Sandbox.create({
source: { type: 'git', url: payload.repo, depth: 1 },
runtime: 'node24',
resources: { vcpus: 2 },
timeout: 30 * 60 * 1000,
});

The Sandbox boots a real Linux MicroVM with git, node, npm, and a full shell. resources: { vcpus: 2 } gives it 4 GB of RAM (2 GB per vCPU). The source option clones the target repo on creation.

Next, initialize the Flue agent with the sandbox and AI Gateway routing:

const agent = await init({
sandbox: vercel(sandbox),
model: 'anthropic/claude-sonnet-4.6',
providers: {
anthropic: {
baseUrl: 'https://ai-gateway.vercel.sh',
headers: {
Authorization: `Bearer ${env.VERCEL_OIDC_TOKEN}`,
},
},
},
});
const session = await agent.session();
return await session.prompt(payload.prompt);
}

The model string uses AI Gateway's provider/model format. You can swap to any model in the model catalog by changing that string. The providers block routes all Anthropic traffic through AI Gateway's endpoint, authenticated with your OIDC token. No ANTHROPIC_API_KEY needed.

Start the Flue dev server, pointing it at your .env.local:

flue dev --target node --env .env.local

Flue defaults to port 3583. Test the agent with curl:

curl http://localhost:3583/agents/coder/session-1 \
-H "Content-Type: application/json" \
-d '{
"repo": "https://github.com/your-org/your-repo.git",
"prompt": "Find all API routes and explain them."
}'

The response streams back via SSE. Reuse the same session ID (session-1) to continue the conversation. Use a new ID to start fresh.

Roles give your agent persistent instructions without polluting the user prompt. Create .flue/roles/coder.md:

You are a senior software engineer working inside a
Linux sandbox. You have full shell access.
When exploring a codebase:
1. Start by reading the project structure.
2. Read key config files (package.json, tsconfig).
3. Then dive into the specific area the user asks about.
Always explain what you find before suggesting changes.

Then pass the role in your prompt call:

return await session.prompt(payload.prompt, {
role: 'coder',
});

Roles can be set at the agent, session, or call level. Call-level roles (like above) take the highest precedence.

Use session.task() to run a focused subtask in a detached session. Tasks share the same sandbox and filesystem but get their own message history. This is useful for parallel exploration before a main prompt:

const research = await session.task(
'Find all API routes and summarize the key files.',
{ cwd: '/vercel/sandbox', role: 'researcher' }
);
const answer = await session.prompt(
`Use this research:\n\n${research.text}\n\n` +
payload.prompt,
{ role: 'coder' }
);
return answer;

The LLM can also spawn tasks on its own during prompt() and skill() calls, delegating parallel research or exploration work without you writing the orchestration.

The first Sandbox creation takes a few seconds while the MicroVM boots and clones the repo. For repeat sessions against the same repo, snapshots eliminate that wait:

const snapshot = await sandbox.snapshot();
console.log('Snapshot ID:', snapshot.snapshotId);

Calling snapshot() saves the entire MicroVM state, including cloned files and installed dependencies. Subsequent sessions boot from the snapshot in ~100ms:

const sandbox = await Sandbox.create({
source: {
type: 'snapshot',
snapshotId: 'snap_abc123',
},
ports: [3000],
});

Store the snapshot ID per repo and reuse it across agent invocations.

Common knobs you can set on Sandbox.create():

  • runtime: 'node24', 'node22', or 'python3.13'.
  • resources: { vcpus: 1 } through { vcpus: 8 }. Each vCPU comes with 2 GB of RAM.
  • ports: up to 4 exposed ports, each gets a public URL via sandbox.domain(port).
  • timeout: max lifetime. Up to 5 hours on Pro/Enterprise, 45 minutes on Hobby.
  • networkPolicy: restrict outbound access to specific domains or CIDRs if your agent should not reach arbitrary hosts.

For anything beyond these, treat the Sandbox SDK reference as the source of truth.

Build the deployable artifact and deploy:

flue build --target node
vercel deploy

On Vercel, the OIDC token auto-refreshes. AI Gateway spend caps, rate limits, and usage analytics apply to all production traffic from the dashboard.

Was this helpful?

supported.