Skip to content

deep-agent/sandbox

Repository files navigation

Sandbox

English | 简体中文

AI Agent Sandbox - A sandbox execution environment for AI Agents, built with Golang

Quick Start

Docker Deployment

mkdir /path/to/memory
mkdir /path/to/memory/workspaces

# Set the host path for persistent storage (workspace, prompts, etc.)
export LOCAL_MEMORY="/path/to/memory"
# On Linux, the container runs as UID 1000 which may differ from the host user, fix directory permissions to avoid Permission Denied
sudo chown -R 1000:1000 "/path/to/memory"

make docker-start

Access Services

Local Development (without Docker)

Run sandbox-server and mcp-hub on the host, merge stdout/stderr into a single log, and tail it:

make run-all      # build, start both services, tail merged log at /tmp/sandbox.log
make stop-all     # stop both services
make tail-log     # re-attach to the merged log

Architecture

cover

Two Integration Methods:

  • MCP Hub: Built-in MCP protocol service providing standardized Tool interfaces (bash, file, web, etc.). Directly integrates with AI models supporting MCP like Claude and OpenAI. Combined with the Eino framework, you can implement a complete ReAct Agent with just a few lines of code.

  • Sandbox SDK: Provides a Go SDK for programmatic access to Bash, FileSystem, Grep, Web, JSONL, and other services. Can be wrapped as Tools for AI Agent calls or used directly for product development (file browser, Git management, LSP services, etc.).

Project Structure

sandbox/
├── cmd/
│   ├── sandbox-server/main.go    # Main server entry
│   └── mcp-hub/main.go           # MCP Hub entry
├── internal/
│   ├── api/
│   │   ├── router.go             # Router configuration
│   │   ├── middleware/           # JWT auth, Logger, Context
│   │   └── handlers/             # Bash/File/Grep/JSONL/Terminal/Web/WS/Sandbox/Swagger
│   ├── services/
│   │   ├── bash/                 # Bash command execution
│   │   ├── filesystem/           # Filesystem operations (manager, glob, grep, read, write, replacer, operations)
│   │   ├── jsonl/                # JSONL append / read / count
│   │   ├── terminal/             # Web terminal (PTY)
│   │   └── web/                  # Web services (fetch, search)
│   ├── mcp/
│   │   ├── registry.go           # MCP Tool registration
│   │   ├── server.go             # MCP protocol server
│   │   └── tools/                # MCP Tools implementation
│   └── config/config.go
├── types/
│   ├── consts/                   # Constants (env, headers)
│   └── model/                    # Shared data models (bash, file, grep, web, jsonl, response)
├── pkg/
│   ├── ctxutil/                  # Context utilities (cwd, log ID)
│   ├── logger/                   # Plain-text logger wrapper
│   └── safe/                     # Safety utility functions
├── docker/
│   ├── Dockerfile
│   ├── nginx/nginx.conf          # Nginx gateway config
│   ├── scripts/
│   │   ├── supervisord.conf      # Process management
│   │   └── entrypoint.sh
│   └── volumes/                  # Volume mount examples
├── docs/
│   └── ENV.md                    # Environment variables reference
├── web/
│   ├── index.html                # Web homepage
│   └── terminal/index.html       # Web terminal frontend (xterm.js)
├── sdk/
│   └── go/                       # Go SDK (bash, file, grep, web, jsonl)
├── examples/
│   ├── filesystem/               # Filesystem examples
│   └── web/                      # Web examples
├── docker-compose.yaml
├── Makefile
└── go.mod

Core Services

Service Port Description
Nginx 8080 Unified entry, reverse proxy
Sandbox Server 8000 HTTP API + WebSocket API
MCP Hub 8001 MCP protocol service
noVNC 6080 VNC Web client
VNC Server 5900 VNC service
Chromium CDP 9222 Chrome DevTools Protocol (internal, used by agent-browser)

Process Management (Supervisord)

The container manages 8 processes via Supervisord, started in priority order:

# Program Command Priority Purpose
1 xvfb Xvfb :99 -screen 0 1280x1024x24 100 Virtual framebuffer X server, creates virtual display :99
2 fluxbox fluxbox 200 Lightweight window manager
3 x11vnc x11vnc -display :99 -forever -shared -rfbport 5900 -nopw 300 VNC server, shares virtual display to port 5900
4 websockify websockify --web=/usr/share/novnc 6080 localhost:5900 400 WebSocket proxy, enables noVNC web access
5 chromium chromium-browser --no-sandbox --remote-debugging-port=9222 ... 500 Chromium browser with CDP remote debugging
6 sandbox-server sandbox-server 600 Sandbox main service (Bash/File/Grep/JSONL/Web API)
7 mcp-hub mcp-hub 700 MCP Hub service (MCP protocol + Tool interfaces)
8 nginx nginx -g "daemon off;" 800 Nginx reverse proxy gateway

Startup Order: Xvfb → Fluxbox → x11vnc → websockify → Chromium → sandbox-server → mcp-hub → Nginx

Architecture Notes:

  • Programs 1-4 form the VNC Remote Desktop stack, allowing browser access to virtual desktop
  • Program 5 is the Chromium Browser, used internally (e.g. by the external agent-browser) via CDP port 9222
  • Programs 6-7 are Business Services, providing API and MCP protocol
  • Program 8 is the Gateway, unified external service exposure

API Endpoints

System

Endpoint Method Description
/health GET Health check
/docs GET Swagger UI documentation
/v1/openapi.json GET OpenAPI specification
/v1/sandbox GET Get sandbox environment info

Bash

Endpoint Method Description
/v1/bash/exec POST Execute Bash command
/v1/bash/exec/stream POST Stream execute Bash command

Filesystem

Endpoint Method Description
/v1/file/read POST Read file
/v1/file/write POST Write file
/v1/file/append POST Append to file
/v1/file/list POST List directory
/v1/file/delete POST Delete file
/v1/file/move POST Move file
/v1/file/copy POST Copy file
/v1/file/mkdir POST Create directory
/v1/file/exists GET Check if file exists
/v1/file/stat POST Get file metadata
/v1/file/upload POST Upload file (multipart)
/v1/file/download GET Download file (inline preview for browsers)
/v1/grep/search POST Grep search file content

JSONL

Endpoint Method Description
/v1/jsonl/count POST Count lines in a JSONL file
/v1/jsonl/read POST Read lines from a JSONL file
/v1/jsonl/append POST Append line(s) to a JSONL file

Web

Endpoint Method Description
/v1/web/fetch POST Fetch web content
/v1/web/search POST Web search

WebSocket

Endpoint Method Description
/mcp WebSocket MCP protocol endpoint
/websockify WebSocket VNC (noVNC) remote desktop proxy
/terminal/ GET Web terminal page
/v1/terminal/ws WebSocket Terminal WebSocket connection
/v1/ws WebSocket General WebSocket interface

Go SDK Usage Example

package main

import (
    "fmt"
    "github.com/deep-agent/sandbox/sdk/go/http"
    "github.com/deep-agent/sandbox/types/model"
)

func main() {
    client := http.NewClient("http://localhost:8080")

    // Get sandbox info
    ctx, _ := client.GetContext()
    fmt.Printf("HomeDir: %s\n", ctx.HomeDir)

    // Execute Bash command
    result, _ := client.BashExec(&model.BashExecRequest{
        Command: "ls -la",
    })
    fmt.Println(result.Output)

    // Read file
    content, _ := client.FileRead(&model.FileReadRequest{
        File: "/home/sandbox/.bashrc",
    })
    fmt.Println(content.Content)

    // Check if file exists
    exists, _ := client.FileExists("/home/sandbox/.bashrc")
    fmt.Printf("File exists: %v\n", exists.Exists)

    // Append to a JSONL file
    _ = client.JSONLAppendLine(&model.JSONLAppendRequest{
        File:       "/home/sandbox/workspaces/events.jsonl",
        JSONString: []string{`{"event":"hello"}`},
    })
}

MCP Tools

MCP Hub provides the following tools:

Filesystem

Tool Description
Bash Execute Bash command
Glob File glob matching
Grep File content search
Read Read file content
Write Write file content
Edit Edit file (search & replace)

Web

Tool Description
WebFetch Fetch web content
WebSearch Web search

Environment Variables

Container Runtime Configuration

Variable Default Description
SANDBOX_SRV_PORT 8000 Sandbox Server port
MCP_HUB_PORT 8001 MCP Hub port
SUPERVISOR_CONF_DIR /home/sandbox/app.supervisor.d Supervisord config directory
APP_SERVICE_PORT 9000 User HTTP service port (proxied via /app/)
JWT_SECRET - JWT HMAC shared secret (optional)
JWT_AUTH_REQUIRED false Enforce authentication (optional)
ENABLE_MCP true Enable MCP Hub process
ENABLE_BROWSER true Enable Chromium process
ENABLE_VNC true Enable VNC/noVNC processes
TZ Asia/Shanghai Timezone

JWT Authentication (Optional)

Setting JWT_SECRET enables Authorization: Bearer <token> validation (HS256/384/512) for /v1 routes.

If JWT_AUTH_REQUIRED=true is set, all requests will be rejected (returning 401) even if JWT_SECRET is not configured, preventing accidental exposure of unauthenticated services.

Example:

export JWT_SECRET="your-secret-key"
export JWT_AUTH_REQUIRED="true"            # Optional, enforce auth

Docker Compose Variables

These variables are consumed by docker-compose on the host side.

Variable Default Description
HOST_PORT 8080 Host port mapped to container port 8080
LOCAL_MEMORY ./docker/volumes Host base path for persistent storage; workspaces subdirectory is mounted to /home/sandbox/workspaces
LOCAL_SUPERVISOR_CONF ./docker/volumes/app.supervisor.d Host path mounted to /home/sandbox/app.supervisor.d
LOCAL_USERDATA ./docker/volumes/userdata Host path mounted to /home/sandbox/userdata
LOCAL_INIT_SCRIPTS ./docker/volumes/init.d Host path mounted to /docker-entrypoint.d

Docker Build Arguments (Optional)

Variable Default Description
HTTP_PROXY - Proxy for docker build
HTTPS_PROXY - Proxy for docker build
NO_PROXY localhost,127.0.0.1 No-proxy list for docker build

Extensibility

Sandbox supports user-injected custom programs and scripts through the following extension mechanisms:

Directory Structure

docker/volumes/
├── workspaces/         # User workspace, mounted to /home/sandbox/workspaces
├── app.supervisor.d/   # Supervisord config dir, mounted to /home/sandbox/app.supervisor.d
├── userdata/           # User data dir, mounted to /home/sandbox/userdata (scripts, binaries)
└── init.d/             # Init scripts dir, mounted to /docker-entrypoint.d

1. Supervisord Configuration (app.supervisor.d)

Place Supervisord configuration files in docker/volumes/app.supervisor.d/ directory to register background services.

Auto-register with Supervisord: Create .conf files in the app.supervisor.d directory:

docker/volumes/app.supervisor.d/
└── my-service.conf         # supervisord config

my-service.conf example:

[program:my-service]
command=/home/sandbox/userdata/my-service --port=9000
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=900

2. User Data (UserData)

Place user scripts or binaries in docker/volumes/userdata/ directory, accessible at /home/sandbox/userdata/ after container startup.

docker/volumes/userdata/
├── my-service              # Executable program
├── script.sh               # Shell script
└── data.json               # Data file

3. Init Scripts

Place scripts in docker/volumes/init.d/ directory, automatically executed in alphabetical order at container startup:

docker/volumes/init.d/
├── 01-setup-env.sh         # Environment setup
├── 02-install-deps.sh      # Install dependencies
└── 03-start-services.sh    # Start services

Script example:

#!/bin/bash
echo "Setting up environment..."
pip install requests numpy
npm install -g typescript

Execution Rules:

  • .sh files: Execute if executable, otherwise source
  • Other files: Execute if executable

4. User HTTP Service Proxy

If your user program is an HTTP service, access it via the /app/ path. Nginx automatically forwards requests to the APP_SERVICE_PORT (default 9000).

User request: http://localhost:8080/app/api/hello
    ↓
Nginx forwards: http://127.0.0.1:9000/api/hello
    ↓
User service handles

Usage:

  1. User service listens on APP_SERVICE_PORT
  2. Access via /app/ path

Custom Port:

APP_SERVICE_PORT=3000 docker-compose up

5. Extend from Sandbox Image

Users can create custom images based on the Sandbox image:

FROM your-registry/sandbox:latest

USER root
RUN apt-get update && apt-get install -y your-package

COPY --chown=sandbox:sandbox my-binary /home/sandbox/userdata/
COPY --chown=sandbox:sandbox my-init.sh /docker-entrypoint.d/

USER sandbox

Environment Variable Configuration

Customize mount paths via docker-compose or environment variables:

LOCAL_MEMORY=/path/to/memory \
LOCAL_SUPERVISOR_CONF=/path/to/app.supervisor.d \
LOCAL_USERDATA=/path/to/userdata \
LOCAL_INIT_SCRIPTS=/path/to/init.d \
APP_SERVICE_PORT=3000 \
docker-compose up

License

Apache License 2.0

About

An integrated, secure, and isolated environment provides the AI ​​Agent with capabilities such as shell execution, file operations, browser control, and web terminal access.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors