Claude Code, in your browser, with a real Linux desktop. Built on agentbox-sdk + E2B + Vercel.
A Next.js app that spawns an E2B Ubuntu+XFCE sandbox per
session, runs claude-code
inside it via agentbox-sdk,
exposes the desktop over noVNC in an iframe, and gives the agent
computer-use-style tools (screenshot / click / type / key) through a bundled
MCP server. The first session you start lazily builds the E2B template — every
subsequent session spawns instantly.
- Click Deploy with Vercel above.
- When Vercel prompts for env vars, paste:
E2B_API_KEY— from https://e2b.dev/dashboardANTHROPIC_API_KEY— either a real Anthropic key (sk-ant-…) or any OpenRouter key (sk-or-…). OR keys are auto-detected and routed via OpenRouter's Anthropic-compat endpoint.
- Open the deployed URL → click Start session. The first session waits ~5 minutes while the E2B desktop template builds. Build progress streams live into the gate UI. Subsequent sessions start in seconds.
git clone https://github.com/TwillAI/agentbox-desktop-demo.git
cd agentbox-desktop-demo
bun install
cp .env.example .env.local # fill in E2B_API_KEY + ANTHROPIC_API_KEY
bun run dev # http://localhost:3000The first session triggers the template build automatically. To pre-build it manually:
bun run mcp-desktop:build # bundle the MCP desktop server
bun run template:build # ~5 min, real E2B computeBrowser
├── Chat panel (AI Elements) ──POST /api/chat──┐
└── Desktop iframe (noVNC) │
▼
Next.js (Vercel)
│
│ agentbox-sdk
▼
E2B sandbox
├── XFCE + noVNC :6080
├── claude-code CLI
└── MCP desktop server
(xdotool/scrot)
Where each piece lives:
- Sandbox lifecycle —
lib/sandbox-pool.ts. Warm-pool by provider onglobalThis, OpenRouter key auto-detection, per-harness env var routing. - Streaming chat —
app/api/chat/route.ts+hooks/use-agent-chat.ts. The route streams agentboxNormalizedAgentEvents as NDJSON; the hook parses them and reconstructsChatMessagestate. - Template auto-build —
lib/template-bootstrap.tsapp/api/session/route.ts. The session route is a Server-Sent Events stream that emitsloglines while building, then areadyevent with the sandbox info.
- MCP desktop tools —
mcp-desktop/src/server.ts. Stdio MCP server exposingscreenshot/click/type/key/mouse_movebacked byscrotandxdotool. - E2B template definition —
template/template.ts. Ubuntu 22.04 + XFCE + noVNC + Chrome + Node 20 + claude-code + the bundled MCP server, wired together.
The demo ships with claude-code enabled by default. To enable another
agentbox harness:
-
Open
lib/harness-catalog.tsand uncomment the harness inHARNESSES:export const HARNESSES: HarnessName[] = [ AgentProvider.ClaudeCode, AgentProvider.Codex, // ← uncomment // AgentProvider.OpenCode, ]
-
Add the relevant API key to your env:
- Codex →
OPENAI_API_KEY - OpenCode → either
OPENAI_API_KEYorANTHROPIC_API_KEYdepending on model.
- Codex →
-
(Optional) To give the new harness the desktop MCP tools, copy the
mcpServersblock fromtemplate/claude-settings.jsoninto that harness's expected config path inside the sandbox and rebuild the template.
The chat UI auto-renders a harness picker as soon as more than one harness
is in HARNESSES.
- Model list —
lib/harness-catalog.tsHARNESS_MODELS. - Starter prompts —
components/chat-panel.tsxSTARTER_SUGGESTIONS. - Desktop tools — add a builder in
mcp-desktop/src/actions.ts, wire it up inmcp-desktop/src/server.ts, then rebuild the template (bun run mcp-desktop:build && bun run template:build). - Template config —
template/template.ts.
- First session ~5 min while the template builds. Subsequent sessions spawn in seconds. Progress streams live to the UI.
- Cost — each session = one E2B sandbox (per-second billing, default 10-minute idle timeout) + LLM token usage. Keep Vercel Deployment Protection on if you don't want random visitors burning your credits.
- OpenRouter routing — automatic when
ANTHROPIC_API_KEYstarts withsk-or-. Real Anthropic keys (sk-ant-…) are the canonical path. - claude-code model slugs —
claude-coderejects provider-prefixed slugs likeanthropic/claude-sonnet-4.6. Use Anthropic-native slugs (claude-sonnet-4-5,sonnet, etc.) — both work over OpenRouter's Anthropic-compat path. - Stop button — aborts server-side via
DELETE /api/chat/runs/:runId. Reliable inside a warm Vercel container; falls back to client-side fetch abort if the run-registry entry is on a different container.
- Next.js 16 App Router, React 19
agentbox-sdk+ E2B SDK- AI Elements for chat UI primitives
- shadcn/ui + Tailwind v4 + Geist
- Model Context Protocol SDK
- Bun (dev) / Node 20 (sandbox + Vercel runtime)
MIT — see LICENSE.
