Skip to main content
Glama
syed-muslim2603

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.