About Sandbox
Sandbox is an MCP server published by agent-infra in the Developer Tools category: all-in-One Sandbox for AI Agents that combines Browser, Shell, File, MCP and VSCode Server in a single Docker container.
The repository has 6.2K stars and 560 forks, with the last commit a month ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/agent-infra/sandboxThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Sandbox
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 7 hours ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- ✓Dependencies pinnedA lockfile pins dependency versions.
- !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.
1 check has not been run yet.
Releases
README
AIO Sandbox - All-in-One Agent Sandbox Environment

🚀 Quick Start
Get up and running in 30 seconds:
# Recommended: Enable API Key authentication (protects all services: API, JupyterLab, VNC)
# - Supports three methods: X-AIO-API-Key header, Authorization: Bearer header, ?api_key= query parameter
# - Without SANDBOX_API_KEY, services remain open (backward compatible)
docker run --security-opt seccomp=unconfined --rm -it \
-e SANDBOX_API_KEY=your-secret-key \
-p 127.0.0.1:8080:8080 ghcr.io/agent-infra/sandbox:latest
For users in mainland China:
docker run --security-opt seccomp=unconfined --rm -it \
-e SANDBOX_API_KEY=your-secret-key \
-p 127.0.0.1:8080:8080 enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:1.11.0
For reproducible deployments, pin a release tag. Replace 1.11.0 with the release you want:
docker run --security-opt seccomp=unconfined --rm -it \
-p 127.0.0.1:8080:8080 ghcr.io/agent-infra/sandbox:1.11.0
# or use the pinned mainland China mirror
docker run --security-opt seccomp=unconfined --rm -it \
-p 127.0.0.1:8080:8080 enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:1.11.0
These examples intentionally bind the host side to 127.0.0.1 because the sandbox listens on 0.0.0.0 inside the container. For cloud deployment, keep port 8080 private and publish it through a reverse proxy or Ingress: Cloud Deployment Guide.
Once running, access the environment at:
- 📖 Documentation: http://localhost:8080/v1/docs
- 🌐 VNC Browser: http://localhost:8080/vnc/index.html?autoconnect=true
- 💻 VSCode Server: http://localhost:8080/code-server/
- 🤖 MCP Services: http://localhost:8080/mcp
🎯 What is AIO Sandbox?
AIO Sandbox is an all-in-one agent sandbox environment that combines Browser, Shell, File, MCP operations, and VSCode Server in a single Docker container. Built on cloud-native lightweight sandbox technology, it provides a unified, secure execution environment for AI agents and developers.
Why Choose AIO Sandbox?
Traditional sandboxes are single-purpose (browser, code, or shell), making file sharing and functional coordination extremely challenging. AIO Sandbox solves this by providing:
- ✅ Unified File System - Files downloaded in browser are instantly available in Shell/File operations
- ✅ Multiple Interfaces - VNC, VSCode, Jupyter, and Terminal in one unified environment
- ✅ Secure Execution - Sandboxed Python and Node.js execution with safety guarantees
- ✅ Zero Configuration - Pre-configured MCP servers and development tools ready to use
- ✅ Agent-Ready - MCP-compatible APIs for seamless AI agent integration
📦 Installation
SDK Installation
Python
pip install agent-sandbox
TypeScript/JavaScript
npm install @agent-infra/sandbox
Golang
go get github.com/agent-infra/sandbox-sdk-go
Basic Usage
Python Example
from agent_sandbox import Sandbox
# Initialize client
client = Sandbox(base_url="http://localhost:8080")
home_dir = client.sandbox.get_context().home_dir
# Execute shell commands
result = client.shell.exec_command(command="ls -la")
print(result.data.output)
# File operations
content = client.file.read_file(file=f"{home_dir}/.bashrc")
print(content.data.content)
# Browser automation
screenshot = client.browser.screenshot()
TypeScript Example
import { Sandbox } from '@agent-infra/sandbox';
// Initialize client
const sandbox = new Sandbox({ baseURL: 'http://localhost:8080' });
// Execute shell commands
const result = await sandbox.shell.exec({ command: 'ls -la' });
console.log(result.output);
// File operations
const content = await sandbox.file.read({ path: '/home/gem/.bashrc' });
console.log(content);
// Browser automation
const screenshot = await sandbox.browser.screenshot();
🌟 Key Features
🔗 Unified Environment
All components run in the same container with a shared filesystem, enabling seamless workflows:
🌐 Browser Automation
Full browser control through multiple interfaces:
- VNC - Visual browser interaction through remote desktop
- CDP - Chrome DevTools Protocol for programmatic control
- MCP - High-level browser automation tools
💻 Development Tools
Integrated development environment with:
- VSCode Server - Full IDE experience in browser
- Jupyter Notebook - Interactive Python environment
- Terminal - WebSocket-based terminal access
- Port Forwarding - Smart preview for web applications
🤖 MCP Integration
Pre-configured Model Context Protocol servers:
- Browser - Web automation and scraping
- File - File system operations
- Shell - Command execution
- Markitdown - Document processing
📚 Complete Example
Convert a webpage to Markdown with embedded screenshot:
import asyncio
import base64
from playwright.async_api import async_playwright
from agent_sandbox import Sandbox
async def site_to_markdown():
# Initialize sandbox client
c = Sandbox(base_url="http://localhost:8080")
home_dir = c.sandbox.get_context().home_dir
# Browser: Automation to download HTML
async with async_playwright() as p:
browser_info = c.browser.get_info().data
page = await (await p.chromium.connect_over_cdp(browser_info.cdp_url)).new_page()
await page.goto("https://example.com", wait_until="networkidle")
html = await page.content()
screenshot_b64 = base64.b64encode(await page.screenshot()).decode('utf-8')
# Jupyter: Convert HTML to markdown in sandbox
c.jupyter.execute_code(code=f"""
from markdownify import markdownify
html = '''{html}'''
screenshot_b64 = "{screenshot_b64}"
md = f"{{markdownify(html)}}\\n\\n"
with open('{home_dir}/site.md', 'w') as f:
f.write(md)
print("Done!")
""")
# Shell: List files in sandbox
list_result = c.shell.exec_command(command=f"ls -lh {home_dir}")
print(f"Files in sandbox: {list_result.data.output}")
# File: Read the generated markdown
return c.file.read_file(file=f"{home_dir}/site.md").data.content
if __name__ == "__main__":
result = asyncio.run(site_to_markdown())
print(f"Markdown saved successfully!")
🏗️ Architecture
┌─────────────────────────────────────────────────────────────┐
│ 🌐 Browser + VNC │
├─────────────────────────────────────────────────────────────┤
│ 💻 VSCode Server │ 🐚 Shell Terminal │ 📁 File Ops │
├─────────────────────────────────────────────────────────────┤
│ 🔗 MCP Hub + 🔒 Sandbox Fusion │
├─────────────────────────────────────────────────────────────┤
│ 🚀 Preview Proxy + 📊 Service Monitoring │
└─────────────────────────────────────────────────────────────┘
🛠️ API Reference
Core APIs
| Endpoint | Description |
|---|---|
/v1/sandbox |
Get sandbox environment information |
/v1/shell/exec |
Execute shell commands |
/v1/file/read |
Read file contents |
/v1/file/write |
Write file contents |
/v1/browser/screenshot |
Take browser screenshot |
/v1/jupyter/execute |
Execute Jupyter code |
MCP Servers
| Server | Tools Available |
|---|---|
browser |
navigate, screenshot, click, type, scroll |
file |
read, write, list, search, replace |
shell |
exec, create_session, kill |
markitdown |
convert, extract_text, extract_images |
🚢 Deployment
Docker Compose
services:
sandbox:
container_name: aio-sandbox
image: ghcr.io/agent-infra/sandbox:latest
security_opt:
- seccomp:unconfined
ports:
- "127.0.0.1:${HOST_PORT:-8080}:8080"
volumes:
- sandbox_data:/home/gem/workspace
extra_hosts:
- "host.docker.internal:host-gateway"
restart: "unless-stopped"
shm_size: "2gb"
environment:
SANDBOX_API_KEY: ${SANDBOX_API_KEY:-}
PROXY_SERVER: ${PROXY_SERVER:-}
WORKSPACE: ${WORKSPACE:-/home/gem/workspace}
TZ: ${TZ:-Asia/Singapore}
volumes:
sandbox_data:
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: aio-sandbox
spec:
replicas: 2
selector:
matchLabels:
app: aio-sandbox
template:
metadata:
labels:
app: aio-sandbox
spec:
containers:
- name: aio-sandbox
image: ghcr.io/agent-infra/sandbox:latest
ports:
- containerPort: 8080
resources:
limits:
memory: "2Gi"
cpu: "1000m"
🤝 Integration Examples
Browser Use Integration
import asyncio
from agent_sandbox import Sandbox
from browser_use import Agent, Tools
from browser_use.browser import BrowserProfile, BrowserSession
from browser_use.llm import ChatOpenAI
sandbox = Sandbox(base_url="http://localhost:8080")
print("sandbox", sandbox.browser)
cdp_url = sandbox.browser.get_info().data.cdp_url
browser_session = BrowserSession(
browser_profile=BrowserProfile(cdp_url=cdp_url, is_local=True)
)
tools = Tools()
async def main():
agent = Agent(
task='Visit https://duckduckgo.com and search for "browser-use founders"',
llm=ChatOpenAI(model="gcp-claude4.1-opus"),
tools=tools,
browser_session=browser_session,
)
await agent.run()
await browser_session.kill()
input("Press Enter to close...")
if __name__ == "__main__":
asyncio.run(main())
LangChain Integration
from langchain.tools import BaseTool
from agent_sandbox import Sandbox
class SandboxTool(BaseTool):
name = "sandbox_execute"
description = "Execute commands in AIO Sandbox"
def _run(self, command: str) -> str:
client = Sandbox(base_url="http://localhost:8080")
result = client.shell.exec_command(command=command)
return result.data.output
OpenAI Assistant Integration
from openai import OpenAI
from agent_sandbox import Sandbox
import json
client = OpenAI(
api_key="your_api_key",
)
sandbox = Sandbox(base_url="http://localhost:8080")
# define a tool to run code in the sandbox
def run_code(code, lang="python"):
if lang == "python":
return sandbox.jupyter.execute_code(code=code).data
return sandbox.nodejs.execute_nodejs_code(code=code).data
# Use OpenAI
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "calculate 1+1"}],
tools=[
{
"type": "function",
"function": {
"name": "run_code",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string"},
"lang": {"type": "string"},
},
},
},
}
],
)
if response.choices[0].message.tool_calls:
args = json.loads(response.choices[0].message.tool_calls[0].function.arguments)
print("args", args)
result = run_code(**args)
print(result['outputs'][0]['text'])
MiniMax Integration
MiniMax provides an OpenAI-compatible API, so you can use the same openai SDK with a different base_url:
from openai import OpenAI
from agent_sandbox import Sandbox
import json
client = OpenAI(
api_key="your_minimax_api_key",
base_url="https://api.minimax.io/v1",
)
sandbox = Sandbox(base_url="http://localhost:8080")
def run_code(code, lang="python"):
if lang == "python":
return sandbox.jupyter.execute_code(code=code).data
return sandbox.nodejs.execute_code(code=code).data
response = client.chat.completions.create(
model="MiniMax-M2.7",
messages=[{"role": "user", "content": "calculate 1+1"}],
tools=[
{
"type": "function",
"function": {
"name": "run_code",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string"},
"lang": {"type": "string"},
},
},
},
}
],
temperature=0.01, # MiniMax requires temperature > 0
)
if response.choices[0].message.tool_calls:
args = json.loads(response.choices[0].message.tool_calls[0].function.arguments)
result = run_code(**args)
print(result.outputs[0].text)
See the full minimax-integration example for more details.
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
📄 License
AIO Sandbox is released under the Apache License 2.0.
🙏 Acknowledgments
Built with ❤️ by the Agent Infra team. Special thanks to all contributors and the open-source community.
📞 Support
README fetched from the repository 7 hours ago. The original is authoritative.