Sandbox Agent
Integrates with Google Gemini's API to provide LLM-powered chat capabilities within the sandboxed code execution environment.
Integrates with Ollama's API to provide LLM-powered chat capabilities within the sandboxed code execution environment.
Integrates with OpenAI's API to provide LLM-powered chat capabilities within the sandboxed code execution environment.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Sandbox AgentRun Python code to plot a sine wave"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Sandbox Agent
LangGraph agent with Docker-based sandboxed code execution. Each session runs in an isolated, hardened Docker container with a persistent kernel — IPython for Python, vm.createContext for Node.js, and a dedicated R environment. Supports 3 runtimes, provider-agnostic LLM configuration, and vision (auto-detection of multimodal models). Available as an interactive CLI, MCP server (Cursor, Claude Desktop), REST API (Aegra), and React frontend.
Features
Docker isolation — each session runs in its own container, no ports exposed, no host volumes
Hardened containers — non-root user (UID 65532), PID limits, memory+swap limits, tmpfs-only writable dirs,
no-new-privilegesCrash detection — OOM-kill, fork bombs, segfaults are detected and reported clearly to the agent
Persistent state — variables survive between code executions (like Jupyter cells)
Checkpointer PostgreSQL — conversation history persists across restarts (shared with Aegra)
Async support — Promises (Node.js) and coroutines (Python) are automatically awaited
Multi-runtime — Python, Node.js, and R
Rich display outputs — captures matplotlib/ggplot figures, Plotly charts, IPython Audio, HTML widgets, and more; auto-sends images to multimodal LLMs
Provider-agnostic — works with OpenAI, Anthropic, Google Gemini, Ollama, or any compatible provider via
langchain init_chat_modelRuntime package install —
pip install/npm install/install.packages()at session creation or via terminal6 tools —
create_session,execute_code,execute_terminal,import_files,export_files,stop_sessionMCP server — expose the same tools via Model Context Protocol (stdio transport)
REST API — full LangGraph Platform API via Aegra with OpenAPI docs, streaming, thread management
Input validation — Pydantic schemas validate all tool inputs before execution, returning structured errors on failure
React frontend — SPA with chat, tool visualization, file upload/download, settings dialog (React 19 + Vite + Tailwind CSS)
File upload — upload files to the API for import into sandbox sessions (
POST /threads/{id}/files/upload)File export — register files for download (no host copy); download via API or use in cross-session import
File import — import from host paths, inline content, or from another session (files exported in same conversation)
Cross-session transfer — export from session A, import into session B with
{session_id, path}Session garbage collection — idle timeout, max lifetime, thread eviction, orphan container cleanup
Auto-cleanup — all containers are stopped and removed when the agent exits
Related MCP server: Docker MCP Server
Prerequisites
Python 3.11+
Docker Engine
API key for your LLM provider (
CHAT_MODEL_API_KEY)PostgreSQL (for API/CLI mode — checkpointer + Aegra)
Node.js 18+ and npm (for the React frontend)
Setup
# Docker — installs (if needed), configures permissions, and builds all 3 images
sudo ./setup-docker.sh
# Install Python dependencies (open a new terminal so the docker group is active)
uv sync
# Install frontend dependencies
cd frontend && npm install && cd ..
# Configure environment
cp .env.example .env
# Edit .env with your CHAT_MODEL_API_KEY, POSTGRES_PASSWORD, and other settings
# Docker images are also built automatically on first use if not already presentPostgreSQL (required for CLI, API, and UI)
PostgreSQL is auto-started via Docker Compose when using localhost. The CLI detects if PostgreSQL is reachable and starts it automatically:
# Manual start (if needed)
docker compose up postgres -dOr point to an existing PostgreSQL instance via POSTGRES_* env vars in .env.
Usage
All commands use the unified sandbox-agent entry point:
uv run sandbox-agent cli # Interactive CLI (default)
uv run sandbox-agent mcp # MCP server (Cursor, Claude Desktop)
uv run sandbox-agent api # REST API (Aegra, no reload)
uv run sandbox-agent api dev # REST API with hot reload
uv run sandbox-agent ui # React UI (auto-starts API if needed)CLI
uv run sandbox-agent cli
# or simply
uv run sandbox-agentThe CLI operates as a thin client on top of the Aegra REST API. Requires the API to be running (uv run sandbox-agent api). Features:
Rich panels with syntax-highlighted tool I/O (per-runtime lexer)
Streaming agent output with Markdown rendering
Persistent thread across restarts (
~/.local/state/sandbox-agent/cli-thread.json)/newcommand to start a fresh conversationPasses model/provider/key settings to the API via
configurable
MCP Server
Run the MCP server (stdio transport) for integration with Cursor, Claude Desktop, or any MCP-compatible client:
uv run sandbox-agent mcpCursor or Claude Desktop
Add the following MCP config:
{
"mcpServers": {
"sandbox-agent": {
"command": "uv",
"args": ["--directory", "/path/to/sandbox-agent", "run", "sandbox-agent", "mcp"]
}
}
}The MCP server exposes the same 6 tools as the CLI agent with identical behavior. It maintains a persistent thread_id in ~/.local/state/sandbox-agent/mcp-thread.json for export URL consistency.
The import_files tool accepts file content directly (as text or base64 via file_content/encoding keys), host paths (via source/destination), or cross-session references (session_id+path). The export_files tool registers files for download via GET /threads/{thread_id}/files/download?session_id=...&path=....
REST API (Aegra)
Run the agent as a REST API via Aegra (self-hosted LangGraph Platform alternative):
uv run sandbox-agent api # Production mode (no reload, auto-starts PostgreSQL)
uv run sandbox-agent api dev # Development mode (hot reload via aegra dev)The production command auto-starts PostgreSQL via Docker Compose if it's not reachable on localhost. The server runs at http://localhost:8000 with OpenAPI docs at /docs. Use the LangGraph SDK or curl to create assistants, threads, and stream runs. Compatible with Agent Chat UI, LangGraph Studio, and CopilotKit.
Custom endpoints:
GET /threads/{thread_id}/files/download?session_id=...&path=...— streams exported files from containersPOST /threads/{thread_id}/files/upload— uploads files to be available for import into sandbox sessionsDELETE /threads/{thread_id}— also cleans up Docker sessions and storage for that thread (via middleware)GET /settings— returns persisted frontend settings merged over backend.envdefaultsPUT /settings— persist frontend settings to PostgreSQL (encrypted)
React Frontend
A web UI for chatting with the agent via the Aegra API (React 19 + Vite + Tailwind CSS):
# Install frontend dependencies (if not done during setup)
cd frontend && npm install && cd ..
# Start the UI (auto-starts API + PostgreSQL if needed)
uv run sandbox-agent uiThe frontend runs at http://localhost:5173 (Vite dev server with API proxy to :8000). Features:
Thread management (create, resume, delete conversations) via sidebar
Streaming responses with expandable tool blocks (syntax-highlighted per runtime)
File upload and download support
Thinking block visualization
Settings dialog (model, provider, API key, base URL, vision toggle)
Persistent settings via server-side API (
GET/PUT /settings), with backend.envdefaults as fallback
Programmatic
from sandbox_agent.sandbox import SandboxManager
manager = SandboxManager()
info = manager.create_session(
runtime="python",
dependencies={"pandas": "2.2.3", "matplotlib": ""},
)
sid = info.session_id
r1 = manager.execute_code(sid, """
import pandas as pd
df = pd.DataFrame({'x': [1, 2, 3], 'y': [4, 5, 6]})
print(df.describe())
""")
print(r1.stdout)
# Variables persist between calls
r2 = manager.execute_code(sid, "df.shape")
print(r2.result)
# Export files from the sandbox (registers for download, no host copy)
manager.execute_code(sid, "df.to_csv('/workspace/output.csv', index=False)")
export = manager.export_files(sid, [{"source": "output.csv"}])
print(export.files[0].session_id, export.files[0].path)
manager.stop_session(sid)Exporting Files
export_files registers files for download and cross-session import (no host copy). Files become available via the API (GET /threads/{thread_id}/files/download?session_id=...&path=...) and for import_files in other sessions:
# Export a single file
result = manager.export_files(sid, [{"source": "report.pdf"}])
# Export an entire directory
result = manager.export_files(sid, [{"source": "results/"}])
# Export multiple files at once
result = manager.export_files(sid, [
{"source": "data.csv"},
{"source": "chart.png"},
{"source": "/workspace/logs/"},
])
for f in result.files:
print(f"{f.session_id}:{f.path} ({'OK' if f.success else f.error})")Cross-Session File Transfer
Use export_files + import_files to move files between sessions (even across different runtimes):
# Session A (Python): produce data
sid_a = manager.create_session(runtime="python", dependencies={"pandas": ""}).session_id
manager.execute_code(sid_a, """
import pandas as pd
df = pd.DataFrame({'x': [1,2,3], 'y': [4,5,6]})
df.to_csv('/workspace/data.csv', index=False)
""")
export = manager.export_files(sid_a, [{"source": "data.csv"}])
path = export.files[0].path # /workspace/data.csv
# Session B (R): consume the same data
sid_b = manager.create_session(runtime="r", dependencies={"readr": ""}).session_id
manager.import_files(sid_b, [{"session_id": sid_a, "path": path, "destination": "data.csv"}])
manager.execute_code(sid_b, 'df <- readr::read_csv("/workspace/data.csv"); summary(df)')Importing Files
import_files copies files into the sandbox from the host or from another session:
# Import from host
result = manager.import_files(sid, [
{"source": "/home/user/data.csv", "destination": "data.csv"},
{"source": "/home/user/project/", "destination": "project/"},
])
# Import from another session (file must have been exported first)
result = manager.import_files(sid, [
{"session_id": "abc123", "path": "/workspace/out.csv", "destination": "out.csv"},
])Other runtimes work the same way — pass runtime="node" or runtime="r" to create_session.
Async Code
Node.js — if the last expression returns a Promise, the kernel awaits it before collecting output. Top-level await is also supported (falls back to an async IIFE wrapper when needed).
const axios = require('axios');
async function fetchData() {
const resp = await axios.get('https://api.example.com/data');
console.log(resp.data);
}
fetchData(); // Promise is awaited automaticallyPython — IPython's autoawait handles top-level await. If a cell returns an unawaited coroutine, the kernel detects it and runs it with asyncio.run().
import aiohttp
async def fetch_data():
async with aiohttp.ClientSession() as session:
resp = await session.get('https://api.example.com/data')
print(await resp.text())
fetch_data() # coroutine is detected and executed automaticallyContainer Security
Each container is created with the following protections:
Protection | Setting | Effect |
Memory limit |
| OOM-kill on overflow, host unaffected |
PID limit |
| Fork bombs are contained and killed |
CPU quota |
| Prevents CPU starvation on host |
Writable dirs | tmpfs ( | tmpfs dirs never touch host disk |
tmpfs size |
| Limits in-container disk usage |
User |
| No root inside container |
Privileges |
| Cannot escalate via setuid/setgid |
Network | Configurable (enabled by default) | Can be disabled per session |
When a container crashes, the agent receives a clear CONTAINER_DIED error with the reason (OOM-killed, SIGKILL, segfault, etc.) and a hint to recreate the session.
Session Lifecycle
Sessions are automatically managed with garbage collection:
Behavior | Default | Setting |
Idle timeout | 30 min |
|
Max lifetime | 2 hours |
|
GC interval | 60 sec |
|
Max active threads | 10 |
|
Max sessions (global) | 5 |
|
Max sessions per thread | 3 |
|
Orphan cleanup age | 5 min |
|
On startup, the manager removes orphan containers older than the minimum age. On exit, all containers are stopped and removed via atexit and signal handlers (SIGTERM/SIGINT).
Configuration
All settings can be overridden via environment variables or .env. Defaults are shown from settings.py:
# ── LLM (provider-agnostic) ──
CHAT_MODEL=gpt-4o # Model name
CHAT_MODEL_PROVIDER=openai # Provider: openai, anthropic, google_genai, ollama
CHAT_MODEL_API_KEY=sk-... # API key (required)
CHAT_MODEL_BASE_URL= # Custom API base URL (optional)
CHAT_MODEL_SUPPORTS_VISION= # Override vision detection (true/false, empty = auto)
# ── Container Limits ──
CONTAINER_MEMORY_LIMIT=2048m # Docker memory limit (no swap)
CONTAINER_CPU_QUOTA=200000 # CPU quota (100000 = 1 core)
CONTAINER_PIDS_LIMIT=512 # Max PIDs per container
CONTAINER_TMPFS_SIZE=200m # tmpfs size for writable dirs
CONTAINER_EXECUTION_TIMEOUT_SECONDS=30 # Default code execution timeout
CONTAINER_MAX_SESSIONS=5 # Max concurrent sessions (global)
CONTAINER_MAX_SESSIONS_PER_THREAD=3 # Max sessions per conversation
CONTAINER_EXECUTE_AS_ROOT=False # Run terminal commands as root
CONTAINER_NETWORK_ENABLED=True # Enable container networking (disable per session)
CONTAINER_ORPHAN_MIN_AGE_SECONDS=300 # Min age before orphan cleanup (5 min)
# ── Session Lifecycle / GC ──
SESSION_IDLE_TTL_SECONDS=1800 # Idle timeout (30 min)
SESSION_MAX_LIFETIME_SECONDS=7200 # Hard lifetime cap (2 hours)
SESSION_GC_INTERVAL_SECONDS=60 # GC check interval
SESSION_MAX_ACTIVE_THREADS=10 # Max active threads before eviction
# ── Output Truncation (characters) ──
MAX_STDOUT_CHARS=50000
MAX_STDERR_CHARS=120000
MAX_RESULT_CHARS=30000
MAX_TRACEBACK_CHARS=8000
# ── Encryption ──
ENCRYPTION_KEY= # Fernet key for settings encryption (optional)
# ── Storage ──
STORAGE_DIR=./storage # Base dir for uploads
IMPORT_ALLOWED_DIRS= # Comma-separated host dirs allowed for import (empty = all)
# ── API ──
API_BASE_URL=http://127.0.0.1:8000 # API URL (for export download URLs)
# ── Agent ──
MAX_ITERATIONS=25 # Max LangGraph iterations (recursion limit)
# ── PostgreSQL (checkpointer + Aegra) — all required, no defaults ──
POSTGRES_USER=sandbox_agent
POSTGRES_PASSWORD=sandbox_agent_secret
POSTGRES_DB=sandbox_agent
POSTGRES_HOST=localhost
POSTGRES_PORT=5432Runtimes
Runtime | Base Image | Kernel | IPC | Pre-installed |
Python |
| IPython shell | UNIX socket | IPython + system libs |
Node.js |
|
| UNIX socket | Bare runtime |
R |
| Dedicated R env | TCP | jsonlite, base64enc, tidyverse, data.table, readxl, haven, httr2, DBI, RSQLite, rmarkdown, knitr, devtools, glmnet, randomForest |
The R container uses a compiled C client binary for IPC, while Python and Node.js use native clients.
Architecture
flowchart TB
CLI["CLI · Rich REPL"]
MCP["MCP Server · FastMCP (stdio)"]
UI["React · Frontend"]
CLI --> API["Aegra REST API
(LangGraph Platform)"]
UI --> API
API --> Agent["LangGraph ReAct Agent"]
Agent --> Tools["LangChain Tools"]
MCP --> Core["Core Tool Functions"]
Tools --> Core
Core --> SM["SandboxManager
Docker SDK"]
SM -->|"docker exec -i + JSON pipe"| Docker
subgraph Docker ["Docker Containers
isolated, hardened"]
direction LR
PY["Python
IPython · UNIX socket"]
JS["Node.js
vm.createContext · UNIX socket"]
R["R
R env · TCP :8765"]
end
subgraph Storage ["Persistence"]
PG["PostgreSQL
checkpoints, exports"]
end
API --> PG
SM --> PGInside each container, a persistent kernel (PID 1) holds execution state, and an ephemeral client connects to it via UNIX socket (Python/Node.js) or TCP (R) for each docker exec call:
flowchart TB
SM["SandboxManager"] -->|"docker exec -i"| Client["Client (ephemeral)"]
subgraph container ["Container"]
Client -->|"UNIX socket / TCP"| Kernel["Kernel (PID 1, persistent)"]
Kernel --- State["State
variables, imports, data"]
endTesting
# Unit tests (no Docker required)
uv run pytest tests/test_cli.py tests/test_http_app.py -v
# Integration tests (requires Docker)
uv run pytest tests/test_manager.py tests/test_tools.py tests/test_export_files.py tests/test_mcp.py -v
# LangGraph debug trace (requires Docker + LLM API key)
uv run pytest tests/test_langgraph_debug.py -v -s
# API integration tests (requires Docker + running API: uv run sandbox-agent api dev)
uv run pytest tests/test_api.py -v -s
# Full suite
uv run pytest tests/ -vProduction Deployment
A production Dockerfile and docker-compose.yml are included:
# Start PostgreSQL + API
docker compose up -d
# Or build and run manually
docker build -t sandbox-agent-api .
docker run -p 8000:8000 --env-file .env sandbox-agent-apiThe production image uses aegra serve with a non-root app user.
License
MIT — Eduardo Ramon Resser
Available Tools
6 toolscreate_sessionA
Creates an isolated sandbox environment (Docker container).
The sandbox starts empty — specify ALL needed packages in dependencies.
For data analysis, always include pandas and numpy.
Args:
language: Sandbox language/runtime. Use "python", "node", or "r".
dependencies: Packages to pre-install. Keys are package names,
values are version strings (use "" for latest). Always use strings,
never numbers — e.g. "2.2" not 2.2. Null/None is treated as "".
Example: {"pandas": "", "numpy": "1.26", "matplotlib": "3.9.0"}.
Returns:
JSON with session_id and session info.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | python | |
| dependencies | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses isolation (Docker) and emptiness, but omits details like rate limits, authentication needs, or whether existing sessions are affected. Adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and well-structured: one-line purpose, followed by usage tip, then formatted Args and Returns sections. Every sentence is informative with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameter usage, and return format. Missing details like error handling or resource limits, but given low complexity (2 params, output schema present) and sibling tools, it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage, but description adds complete semantics: language options (python, node, r), dependency structure (package names, version strings, use quotes, null handling), and example. Adds high value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it creates an isolated sandbox environment (Docker container), with a specific verb and resource. Distinguishes from sibling tools (execute, file ops, stop) which focus on other actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: sandbox starts empty so specify all needed packages, and for data analysis include pandas and numpy. Implies when to use, but does not explicitly state when not to use or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_codeA
Executes code in the sandbox. State persists across calls (like Jupyter cells).
Args:
session_id: ID returned by create_session.
code: Code to execute (Python, Node.js, or R, depending on the session runtime).
timeout: Max execution time in seconds (max 300). Defaults to 30.
Returns:
JSON with success, stdout, stderr, result, error, and display_outputs.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | ||
| code | Yes | ||
| timeout | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses state persistence, the need for a session_id, code execution timeout limits, and the return format. However, it does not detail error handling, isolation, or what happens on invalid session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, starting with the core behavior (persistent state) and listing parameters in a clean, readable format. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (session-based, multiple languages, timeout), the description covers essential aspects like state persistence and return values. However, it lacks guidance on choosing between execute_code and execute_terminal, and could mention error behavior more explicitly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no descriptions (0% coverage), so the description adds significant meaning: session_id is from create_session, code supports multiple languages per runtime, timeout has a maximum of 300 and default of 30. This goes beyond the schema, though language support could be more explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it executes code in a sandbox with persistent state, similar to Jupyter cells. It mentions session_id which ties to create_session, but it does not explicitly differentiate from execute_terminal, though the context implies a session-based execution environment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for running code in a session with persistent state, and gives parameter defaults and limits. However, it does not specify when to use this tool over alternatives like execute_terminal, nor does it provide conditions when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_terminalA
Runs a shell command inside the sandbox.
Useful for listing files, installing Linux dependencies, etc.
Args:
session_id: ID returned by create_session.
command: Shell command to execute (e.g. "ls -la", "apt-get install -y curl").
Returns:
JSON with stdout, stderr, and exit_code.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | ||
| command | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that commands run inside a sandbox, requires a session ID from create_session, and returns stdout, stderr, and exit_code. It hints at mutability (installing dependencies) but could explicitly mention that the sandbox state persists across commands.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with a clear purpose statement, usage context, parameter explanations, and return format. Every sentence adds value and is well-structured without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the two simple parameters and presence of an output schema, the description fully covers required context: it explains the sandbox environment, session prerequisite, typical use cases, and return structure. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description fully compensates by explaining that session_id is the ID from create_session and command is a shell command with examples. This adds significant meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a shell command inside a sandbox, with examples like listing files and installing dependencies. It distinguishes itself from sibling tools like execute_code by focusing on shell commands, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides specific use cases (listing files, installing dependencies) and implies when to use it. However, it does not explicitly state when not to use it or mention alternative tools like execute_code for non-shell scripts, leaving some room for ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_filesA
Registers files for download and cross-session import (no host copy).
Files become available via the API download endpoint and for import_files
in other sessions. Result includes download_url for each file (API must
be running).
Args:
session_id: ID returned by create_session.
files: List of objects with "source" (path in container).
Example: [{"source": "report.pdf"}, {"source": "/workspace/data.csv"}]
Returns:
JSON with per-file results (session_id, path, success, size, error,
download_url). path is always absolute (e.g. /workspace/file.png).
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | ||
| files | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: no host copy, API must be running, and per-file result details. Lacks auth or rate limit info.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise with clear summary, args, returns. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, args, and returns adequately. Could mention error handling but overall complete given moderate complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description explains session_id and files with an example, adding significant meaning beyond raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool registers files for download and cross-session import, distinguishing it from siblings like import_files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains that files become available via download endpoint and for import_files in other sessions, but does not explicitly state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_filesA
Imports files into the sandbox from host or from another session.
Each entry can be:
- Host path: "source" (host path), optional "destination"
- Cross-session: "session_id" (source session), "path" (container path),
optional "destination" — file must have been exported from that session.
Args:
session_id: ID returned by create_session (destination).
files: List of file objects. Examples:
[{"source": "/tmp/report.pdf", "destination": "report.pdf"}]
[{"session_id": "abc123", "path": "/workspace/out.csv", "destination": "out.csv"}]
Returns:
JSON with per-file results (source, destination, success, size, error).
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | ||
| files | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden of behavioral disclosure. It describes the import process and return format but lacks details on permissions, overwrite behavior, or size limits. It is honest but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with sections and examples, though it is somewhat verbose. The return type is mentioned but redundant given the output schema. Overall, it is clear and efficiently organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and sibling tools, the description covers input formats, examples, and return value. It is mostly complete but could mention when to use this tool versus export_files or other alternatives.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description compensates well by explaining that session_id is the destination session and files is a list of objects with specific structures and examples, adding significant meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it imports files into the sandbox and distinguishes between host path and cross-session imports, specifying the required fields for each. This provides a specific verb and resource, differentiating from siblings like export_files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use each entry format (host path vs cross-session) and notes that cross-session files must have been previously exported. However, it does not explicitly state when not to use this tool or compare directly with sibling tools like create_session or export_files.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_sessionA
Stops and removes the sandbox completely. Use when done with a session.
Args:
session_id: ID returned by create_session.
Returns:
JSON with success status.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so description carries full burden. It indicates complete removal, but does not mention irreversibility or potential data loss explicitly, which would enhance transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise with three sentences covering purpose, usage, parameters, and returns. No wasted words, front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and an output schema, the description is complete: it explains the action, when to use, the parameter source, and return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds essential meaning by stating session_id is the ID returned by create_session, compensating for the schema's 0% coverage and clearly indicating the parameter's source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool stops and removes the sandbox completely, which distinguishes it from sibling tools like create_session or execute_code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises using it when done with a session, providing clear usage context. Does not mention when not to use or alternatives, but this is sufficient given the simple action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
v3.0.0- First observed
create_session - First observed
execute_code - First observed
execute_terminal - First observed
export_files - First observed
import_files - First observed
stop_session
TDQS
Each tool has a clear, distinct purpose: creating sessions, executing code, running terminal commands, exporting/importing files, and stopping sessions. No overlap in functionality.
All tool names follow a consistent verb_noun pattern (e.g., create_session, execute_code) with clear action and target.
6 tools is appropriate for a sandbox management server, covering the full lifecycle and common operations without being excessive or sparse.
The set covers the complete sandbox workflow: creation, code execution, terminal access, file import/export, and teardown. No obvious gaps.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Build, deploy, and host full-stack web apps from any MCP client. DB, auth, storage, cron included.
System-of-record notebook for AI coding agents: pages, datastores, tasks, skills over MCP.
Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides isolated Docker environments for code execution, enabling users to create and manage containers, execute multi-language code, save and reproduce development environments, ensuring security and isolation.17-
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to safely execute code in isolated Docker containers with resource limits and security controls, supporting session management and automatic dependency installation.MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for secure, session-based Python code execution in Docker containers, enabling LLM applications to run code, manage state, and access files.9MIT
- FlicenseNot gradedqualityBmaintenanceEnables secure execution of Python code, SQL queries, and metric fetching through MCP with ephemeral Docker sandboxing.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/eduresser/sandbox-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server