██████╗ ██████╗ ██████╗ ███████╗ ██████╗ ██████╗ ███╗ ███╗███╗ ███╗ █████╗ ███╗ ██╗██████╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝██╔═══██╗████╗ ████║████╗ ████║██╔══██╗████╗ ██║██╔══██╗
██║ ██║ ██║██║ ██║█████╗ ██║ ██║ ██║██╔████╔██║██╔████╔██║███████║██╔██╗ ██║██║ ██║
██║ ██║ ██║██║ ██║██╔══╝ ██║ ██║ ██║██║╚██╔╝██║██║╚██╔╝██║██╔══██║██║╚██╗██║██║ ██║
╚██████╗╚██████╔╝██████╔╝███████╗ ╚██████╗╚██████╔╝██║ ╚═╝ ██║██║ ╚═╝ ██║██║ ██║██║ ╚████║██████╔╝
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝
A self-hosted, sandboxed code interpreter for AI agents. Drop-in replacement for LibreChat's hosted code interpreter (code.librechat.ai).
Run Python code locally in secure Docker containers instead of sending it to external services.
Works seamlessly with LibreChat - Agents, Assistants, and regular chats. Just point LibreChat to your Code Command instance and everything works: code execution, file uploads, file downloads, charts, documents - no modifications needed.
- Privacy: Code never leaves your infrastructure
- Customization: Add any Python packages you need
- No rate limits: Execute as much as you want
- Cost: No per-execution fees
- Control: Full visibility into what's running
- Drop-in Replacement: Works with LibreChat out of the box - file uploads, downloads, and code execution just work
- Docker Sandboxing: Secure isolation with no network access, memory limits, and timeouts
- Multi-user Isolation: Each user's files are completely isolated
- Pre-loaded Packages: numpy, pandas, matplotlib, seaborn, scikit-learn, python-pptx, and more
- Shared Assets: Optional folder for your own icons, templates, and helper utilities
# Clone the repository
git clone https://github.com/ryanfortin/code-command.git
cd code-command
# Build the sandbox image first
docker build -t code-sandbox:latest .
# Copy and configure environment
cp .env.example .env
# Edit .env with your API key
# Start the service
docker-compose up -d# 1. Build the Docker sandbox image
docker build -t code-sandbox:latest .
# 2. Install Python dependencies
pip install -r requirements.txt
# 3. Run the API server
python code_interpreter.py --port 8095Code Command is a drop-in replacement for LibreChat's hosted code interpreter. Uploading files, executing code, generating charts and documents - everything works the same, just running on your own infrastructure.
Edit your Code Command .env file:
CODE_API_KEY=your-secret-key-hereAdd to your LibreChat .env file:
# Point to your Code Command instance
# Use host.docker.internal if LibreChat runs in Docker (most common)
# Use localhost if LibreChat runs directly on host
LIBRECHAT_CODE_BASEURL=http://host.docker.internal:8095
# Must match the CODE_API_KEY you set above
LIBRECHAT_CODE_API_KEY=your-secret-key-hereOnly needed if using custom config:
endpoints:
agents:
codeInterpreter:
url: "http://host.docker.internal:8095"
apiKey: "${LIBRECHAT_CODE_API_KEY}"# Restart Code Command
docker-compose restart
# Restart LibreChat
cd /path/to/librechat && docker-compose restartThat's it! LibreChat will now use your self-hosted Code Command instance.
┌─────────────────────────────────────────────────────────────────────┐
│ AI Agent / LibreChat │
│ (Uses @librechat/agents which calls code interpreter) │
└───────────────────────────────────┬─────────────────────────────────┘
│ HTTP API
▼
┌─────────────────────────────────────────────────────────────────────┐
│ code_interpreter.py (FastAPI) │
│ Running on port 8095 │
│ │
│ - Receives code execution requests │
│ - Manages sessions & user isolation │
│ - Spawns Docker containers for each execution │
│ - Returns stdout, stderr, and output files │
└───────────────────────────────────┬─────────────────────────────────┘
│ Docker API
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Docker Container (code-sandbox:latest) │
│ │
│ SECURITY CONSTRAINTS: │
│ - network_mode="none" (no internet access) │
│ - mem_limit="256m" (memory cap) │
│ - pids_limit=50 (prevent fork bombs) │
│ - read_only=True (immutable root filesystem) │
│ - no-new-privileges (no privilege escalation) │
│ - 120 second timeout (execution time limit) │
│ │
│ /workspace (read-write mount) ←→ Host session directory │
│ /mnt/shared (read-only mount) ←→ Shared assets (icons, helpers) │
└─────────────────────────────────────────────────────────────────────┘
| Endpoint | Method | Description |
|---|---|---|
/exec |
POST | Execute code, return stdout/stderr/files |
/upload |
POST | Upload file to session |
/files/{session_id} |
GET | List files in session |
/download/{session_id}/{file_id} |
GET | Download file |
/sessions/{session_id} |
DELETE | Clean up session |
/health |
GET | Health check |
curl -X POST http://localhost:8095/exec \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"code": "import pandas as pd\nprint(pd.DataFrame({\"a\": [1,2,3]}))",
"lang": "python"
}'Response:
{
"stdout": " a\n0 1\n1 2\n2 3\n",
"stderr": "",
"files": [],
"session_id": "uuid-here"
}The shared_assets/ folder is mounted read-only at /mnt/shared inside the sandbox. Use it to provide reusable resources to AI-generated code:
shared_assets/
├── icons/ # SVG icons for presentations
├── templates/ # PPTX/XLSX templates
├── fonts/ # Custom fonts (TTF/OTF)
└── utils/ # Python helper modules
Example usage in AI-generated code:
import sys
sys.path.append('/mnt/shared/utils')
from my_helpers import create_chartThis folder is optional - the sandbox works fine without any shared assets.
Every code execution runs in a fresh Docker container:
container = client.containers.run(
image="code-sandbox:latest",
network_mode="none", # No network access
mem_limit="256m", # Max 256MB RAM
memswap_limit="256m", # No swap
pids_limit=50, # Prevent fork bombs
read_only=True, # Read-only root filesystem
security_opt=["no-new-privileges"],
)| Attack | Protection |
|---|---|
| Data exfiltration | network_mode="none" |
| Crypto mining | No network + CPU limits |
| Fork bombs | pids_limit=50 |
| Disk filling | Read-only root + 100MB workspace limit |
| Container escape | no-new-privileges, non-root user |
| Infinite loops | 120 second timeout |
| Memory exhaustion | 256MB hard limit |
| CPU exhaustion | 0.5 CPU core limit |
Each session gets its own isolated workspace:
/tmp/code_command/
├── {session-id-1}/ # Session workspace
└── {session-id-2}/ # Cleaned up after 24h
Files exist only during the session and are automatically cleaned up after 24 hours.
| Variable | Default | Description |
|---|---|---|
CODE_API_KEY |
code-command-dev-key |
API authentication key |
CODE_WORK_DIR |
/tmp/code_command |
Base directory for sessions |
SHARED_ASSETS_PATH |
./shared_assets |
Path to shared assets |
CODE_EXEC_TIMEOUT |
120 |
Execution timeout (seconds) |
CPU_LIMIT |
0.5 |
CPU cores per execution (0.5 = half core) |
WORKSPACE_SIZE_LIMIT |
104857600 (100MB) |
Max workspace size per session |
SESSION_MAX_AGE_HOURS |
24 |
Auto-cleanup threshold |
CLEANUP_INTERVAL_MINUTES |
60 |
Cleanup frequency |
MAX_UPLOAD_SIZE |
52428800 (50MB) |
Max upload size |
CORS_ORIGINS |
localhost:3080,3000 |
Allowed CORS origins |
SANDBOX_IMAGE |
code-sandbox:latest |
Docker image for sandbox |
The sandbox includes these Python packages:
Data Science: numpy, pandas, scipy, scikit-learn, sympy
Visualization: matplotlib, seaborn, graphviz
Documents: python-pptx, openpyxl, xlrd, pillow
Web/Parsing: requests, beautifulsoup4, lxml
Fonts: Liberation Sans/Serif/Mono, DejaVu (for professional charts)
import matplotlib.pyplot as plt
plt.bar(['Jan', 'Feb', 'Mar'], [100, 150, 200])
plt.savefig('chart.png', dpi=150)from pptx import Presentation
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[1])
slide.shapes.title.text = "Q4 Results"
prs.save('report.pptx')from graphviz import Digraph
g = Digraph('MindMap', format='png')
g.attr('node', shape='box', fontname='Liberation Sans')
g.node('center', 'Main Topic')
g.node('a', 'Subtopic')
g.edge('center', 'a')
g.render('/workspace/mindmap', cleanup=True)Edit the Dockerfile and add packages to the pip install line:
RUN pip install --no-cache-dir \
numpy \
pandas \
# ... existing packages ...
your-new-packageThen rebuild: docker build -t code-sandbox:latest .
Add font files to the Dockerfile:
COPY fonts/*.ttf /usr/share/fonts/truetype/custom/
RUN fc-cache -fEdit your .env file:
CPU_LIMIT=1.0 # Full CPU core
WORKSPACE_SIZE_LIMIT=209715200 # 200MB
CODE_EXEC_TIMEOUT=300 # 5 minutesOr modify docker-compose.yml for the sandbox container's memory limits.
Yes! Add files to the shared_assets/ folder:
shared_assets/templates/- PowerPoint templates (.pptx)shared_assets/icons/- Icons organized by categoryshared_assets/utils/- Python helper modules
These are mounted read-only at /mnt/shared inside the sandbox.
Code Command implements a REST API compatible with LibreChat's code interpreter protocol. Other platforms could integrate if they support the same API format:
POST /exec- Execute codePOST /upload- Upload filesGET /download/{session_id}/{file_id}- Download files
Built for LibreChat - the powerful open-source AI chat platform.
MIT - See LICENSE for details.