Skip to content

jdrolls/sandbar-public

Repository files navigation

Sandbar

Provision isolated cloud computers for AI agents. Give any LLM a full Ubuntu desktop to use.

License: MIT Docker


What is Sandbar?

Sandbar spins up isolated Ubuntu 22.04 Docker containers — each with a full XFCE desktop, a pre-configured OpenClaw AI agent, and a REST API for computer control. Point an AI agent at it and it has a real computer to use.

Browser / External Agent / Claude Code MCP
         │
         ▼
  ┌─────────────────────────────────────┐
  │  Traefik v3  (HTTPS, Let's Encrypt) │
  └─────┬─────┬──────┬─────┬───────────┘
        │     │      │     │
       /api  /vnc  /term  /agent-api
        │     │      │     │
  ┌─────▼─────▼──────▼─────▼───────────┐
  │      Ubuntu 22.04 Container         │
  │  ┌─────────────────────────────┐   │
  │  │  XFCE Desktop (noVNC)       │   │
  │  │  Chrome · VS Code · nvim    │   │
  │  │  OpenClaw AI Agent (TUI)    │   │
  │  │  Computer Control API       │   │
  │  └─────────────────────────────┘   │
  └─────────────────────────────────────┘

What's included in each container

Component Details
OS Ubuntu 22.04 (isolated Docker container)
Desktop XFCE4, accessible via browser (noVNC)
AI Agent OpenClaw with Playwright browser control, session memory
Terminal ttyd web terminal in the browser sidebar
Apps Google Chrome, VS Code, LibreOffice, Neovim
Runtime Python 3, Node.js 22, git, curl, wget
Control API Screenshot, bash, click, type, key, scroll — all via REST

What Sandbar provides

  • Multi-tenant platform — users get their own isolated computers, scoped by JWT auth
  • Browser UI — tab bar with one tab per computer, VNC desktop pane + terminal pane
  • REST API — create/delete computers, control them programmatically
  • MCP server — use Sandbar computers as native Claude Code tools
  • Discord integration — connect your AI agent to a Discord bot, no pairing codes
  • Per-user Anthropic keys — each user's agent uses their own API key

Quick Start

Prerequisites

  • Docker + Docker Compose (Docker 24+)
  • A Linux server with a public IP (for production HTTPS)
  • A domain name pointed at your server
  • An Anthropic API key

1. Clone and configure

git clone https://github.com/jdrolls/sandbar.git
cd sandbar
cp .env.example .env

Edit .env with your values:

ANTHROPIC_API_KEY=sk-ant-...         # Your Anthropic key
SANDBAR_API_KEY=your-master-key      # Generate: openssl rand -hex 32
JWT_SECRET=your-jwt-secret           # Generate: openssl rand -hex 32
DOMAIN=sandbar.yourdomain.com        # Your public domain
ACME_EMAIL=you@yourdomain.com        # For Let's Encrypt
SANDBAR_BASE_URL=https://sandbar.yourdomain.com

2. Build the base container image

docker build -t sandbar-base docker/base/

This takes 5–10 minutes on first run (downloads Chrome, VS Code, OpenClaw).

3. Start the stack

docker compose up -d

Traefik will automatically provision a Let's Encrypt TLS certificate for your domain.

4. Create the first user

# Wait a moment for the backend to initialize, then:
curl -X POST https://sandbar.yourdomain.com/api/admin/users \
  -H "Authorization: Bearer $SANDBAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@yourdomain.com",
    "name": "Admin",
    "password": "change-me-on-first-login",
    "anthropic_api_key": "sk-ant-..."
  }'

5. Open the browser

Visit https://sandbar.yourdomain.com → log in → click + to create a computer.

The container takes ~30 seconds to boot. Once ready, the VNC desktop and OpenClaw terminal appear side by side.


Local Development

For local dev without HTTPS:

# Use the dev docker-compose override
cp .env.example .env
# Set SANDBAR_BASE_URL=http://localhost and leave DOMAIN/ACME_EMAIL blank

docker build -t sandbar-base docker/base/
docker compose -f docker-compose.dev.yml up -d

Visit http://localhost:9090. The backend API is at http://localhost:9090/api.


API Reference

Authentication

Method How Used for
JWT cookie POST /api/auth/login Browser sessions
Bearer token Authorization: Bearer sbx_... Agents, MCP, scripts
Master key Authorization: Bearer $SANDBAR_API_KEY Admin operations

Computer Management

# Create a computer
curl -X POST https://sandbar.yourdomain.com/api/computers \
  -H "Authorization: Bearer $YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template": "sandbar-base"}'

# List your computers
curl https://sandbar.yourdomain.com/api/computers \
  -H "Authorization: Bearer $YOUR_API_KEY"

# Delete a computer
curl -X DELETE https://sandbar.yourdomain.com/api/computers/{id} \
  -H "Authorization: Bearer $YOUR_API_KEY"

Computer Control API

Each computer exposes a control API at /agent-api/{id}:

BASE=https://sandbar.yourdomain.com/agent-api/COMP_ID
AUTH="Authorization: Bearer $YOUR_API_KEY"

curl "$BASE/screenshot" -H "$AUTH"               # Base64 PNG screenshot
curl -X POST "$BASE/bash" -H "$AUTH" \
  -d '{"command": "ls /root"}'                   # Run shell command
curl -X POST "$BASE/click" -H "$AUTH" \
  -d '{"x": 500, "y": 400}'                      # Click at coordinates
curl -X POST "$BASE/type" -H "$AUTH" \
  -d '{"text": "hello world"}'                   # Type text
curl -X POST "$BASE/key" -H "$AUTH" \
  -d '{"key": "Return"}'                         # Press key

Full API docs available at /api/docs (Swagger UI) after deployment.

API Keys

# Create a user API key (login as that user first, or use cookie)
curl -X POST https://sandbar.yourdomain.com/api/auth/keys \
  -H "Content-Type: application/json" \
  -d '{"label": "my-agent"}'

MCP Server (Claude Code)

Use Sandbar computers as native tools in Claude Code:

cd mcp && npm install

Add to ~/.claude/settings.json:

{
  "mcpServers": {
    "sandbar": {
      "command": "npx",
      "args": ["-y", "sandbar-mcp"],
      "env": {
        "SANDBAR_BASE_URL": "https://sandbar.yourdomain.com",
        "SANDBAR_API_KEY": "<your-api-key>"
      }
    }
  }
}

Available MCP tools: create_computer, list_computers, delete_computer, screenshot, bash, click, type_text, key_press, scroll, computer_info


Discord Integration

Connect an AI agent to a Discord bot — responds to server messages and DMs:

  1. Create a bot at Discord Developer Portal
  2. Enable Message Content Intent under Bot → Privileged Gateway Intents
  3. Log into Sandbar → select a computer → click the chat icon in the terminal pane
  4. Paste your bot token → click Connect

The agent is live in ~30 seconds. No pairing codes required.


Architecture

See docs/architecture.md for full technical details.

Key design decisions:

  • No self-serve signup — admin creates users. Prevents resource abuse on self-hosted deployments.
  • Containers run as root — required for Chrome/VS Code --no-sandbox flags in Docker. Containers are isolated from each other and the host.
  • Docker socket access — the backend controls containers via the Docker socket (effectively host root for container operations). Treat the backend as a trusted process.
  • SQLite — single-file database, sufficient for small-to-medium deployments. No external DB dependency.
  • Raw IP routing — Traefik routes to container IPs directly (Docker DNS can be flaky). See docs/quirks.md.

Deployment

See docs/deployment.md for production deployment instructions, backup setup, and upgrade procedures.


Contributing

PRs welcome. Please:

  1. Fork the repo and create a feature branch
  2. Keep changes focused — one concern per PR
  3. Test with a real docker compose up before submitting
  4. Don't commit .env or any secrets

License

MIT — see LICENSE.

About

Provision isolated cloud computers for AI agents — full Ubuntu desktop, OpenClaw AI agent, Computer Control API, MCP server

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors