mcp-secure-sandbox
README.md
# Secure Python Sandbox & Data Validator MCP Server
A production-ready, highly secure, and containerized **Model Context Protocol (MCP)** server built in Python using **FastMCP**. This server isolates code executions within a sandboxed environment, offers automated data validation (JSON Schema and CSV structures), and maintains state snapshots to support deterministic testing pipelines.
---
## 🏗️ Architecture & Isolation Model
This server implements **four distinct layers of security** to ensure that code generated by LLMs cannot execute destructive operations or compromise the host system.
```mermaid
graph TD
Client[Client e.g., Claude Desktop] -->|MCP JSON-RPC| Server[FastMCP Server Process]
Server -->|Tool: run_sandbox_code| AST{AST Safety Checker}
AST -->|Safety Violations| Fail[Reject & return Traceback]
AST -->|Safe AST| Subprocess[Spawn Python Subprocess]
Subprocess -->|Preamble Injection| Closure[Intercept builtins.open]
Closure -->|Access within Workspace| Execute[Run Script]
Closure -->|Access outside Workspace| Block[PermissionError Blocked]
Execute -->|Capture stdout/stderr/time| Server
Server -->|Response| Client
```
### The 4 Layers of Defense:
1. **Container Isolation (Docker)**: The server runs as a non-root system user (`mcpuser`) inside a minimal `python:3.12-slim` container, ensuring zero access to the host's root filesystem or processes.
2. **Static AST Analysis**: Prior to execution, code is parsed into an Abstract Syntax Tree (AST). The AST visitor blocks dangerous built-in functions (`exec`, `eval`), double-underscore metadata attributes (`__class__`, `__subclasses__`), and unapproved imports (e.g. `os`, `sys`, `subprocess`, `socket`).
3. **Subprocess Isolation**: Code is executed inside a spawned Python subprocess rather than the server's parent process. This isolates the memory context, manages clean execution time-outs, and handles crashes without crashing the MCP server.
4. **Closure-based Path Interception**: The server injects a sandbox preamble that overrides python's built-in `open()` function using a closure factory. This factory validates all file paths and blocks directory traversal attempts (using `..` or absolute paths outside the workspace) with a `PermissionError`.
---
## 🛠️ MCP Specifications
### Tools
| Tool Name | Parameters | Description |
| :--- | :--- | :--- |
| `run_sandbox_code` | `code: str`, `timeout_sec: float` | Validates and executes code in the isolated workspace. |
| `validate_json_data` | `data: dict`, `schema_name_or_dict: any` | Validates JSON payloads against predefined or custom schemas. |
| `validate_csv_data` | `csv_content: str`, `required_headers: list`, `type_constraints: dict` | Enforces column headers and datatype rules on CSV data. |
| `create_state_snapshot` | `description: str` | Saves a snapshot of the workspace (files, hashes, metadata). |
| `restore_state_snapshot`| `snapshot_id: str` | Reverts the workspace filesystem to a saved snapshot. |
| `list_state_snapshots` | *None* | Lists all saved snapshots chronologically. |
| `delete_state_snapshot` | `snapshot_id: str` | Permanently deletes a saved snapshot file. |
| `get_sandbox_metrics` | *None* | Returns resource usage (memory, CPU) and tool execution statistics. |
### Resources
- **`sandbox://status`**: Returns JSON data outlining active configurations, workspaces, and snapshot counts.
- **`sandbox://logs`**: Retrieves the last 100 execution traces in memory (timestamp, log level, messages, and performance times).
- **`sandbox://schemas`**: Lists all pre-registered validation schemas (`config`, `user`, `dataset`).
### Prompts
- **`generate_secure_script`**: Prompts the LLM client to write a Python script complying with the AST safety and workspace file constraints.
- **`diagnose_validation_error`**: Diagnoses schema validation errors and generates corrected JSON payloads.
---
## 🚀 Installation & Setup
### Prerequisites
- Python 3.12+ (or Docker installed on the host machine)
- Python virtual environment tools (`venv`)
### Local Setup & Testing
1. Clone or copy the repository files.
2. Initialize virtual environment and install requirements:
```bash
python -m venv .venv
.venv/Scripts/activate # On Windows
source .venv/bin/activate # On Linux/macOS
pip install -r requirements.txt
```
3. Run the unit and integration tests:
```bash
python -m pytest -vv
```
4. Start the server locally in stdio transport mode:
```bash
python -m src.server
```
### Containerized Sandbox Setup (Docker)
To build and run the secure container using Docker:
```bash
# Build the Docker image
docker build -t mcp-secure-sandbox .
# Run the container in interactive stdio mode
docker run -i --rm -v "$(pwd)/sandbox_workspace:/sandbox/workspace" mcp-secure-sandbox
```
Using Docker Compose:
```bash
# Start the container with mounted volumes
docker-compose up -d
```
> [!NOTE]
> The workspace files are persisted locally in the `./sandbox_workspace` folder, and snapshots are saved in the `./sandbox_snapshots` folder. Both paths are automatically synchronized inside the container.
---
## ⚙️ Client Integration (Claude Desktop Config)
Add the following block to your Claude Desktop configuration file (typically located at `%APPDATA%\Claude\claude_desktop_config.json` on Windows or `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
```json
{
"mcpServers": {
"secure-sandbox": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"E:/mcp-secure-sandbox/sandbox_workspace:/sandbox/workspace",
"-v",
"E:/mcp-secure-sandbox/sandbox_snapshots:/sandbox/snapshots",
"mcp-secure-sandbox"
]
}
}
}
```
> [!IMPORTANT]
> Verify that the local folder paths mounted in the `-v` args exist on your host and are formatted correctly as absolute paths.
---
## 📦 State Snapshot Details
The snapshot engine saves the state of the workspace inside JSON records. A snapshot contains:
- **Snapshot Metadata**: UUID, ISO UTC timestamp, and descriptions.
- **File Registry**: Maps relative paths of all files in `/sandbox/workspace` to:
- File size (bytes)
- Modification timestamp (`mtime`)
- SHA-256 hash of contents
- Content payload (UTF-8 string for text files, Base64 encoding for binaries)
When `restore_state_snapshot` is triggered:
1. It compares the current workspace state with the snapshot registry.
2. Files not present in the snapshot registry are deleted.
3. Modified files (matching path but differing SHA-256) are rewritten to match.
4. Missing files are recreated.
5. All file modification times (`mtime`) are restored to ensure build tools function deterministically.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues