Skip to main content
Glama
Prakhar021-hub

Local Sandbox MCP Environment

README.md
# Local Sandbox MCP Environment

An [MCP](https://modelcontextprotocol.io) server that gives an LLM a **secure local workspace**: it can write files, run code in a locked-down Docker container, and query an isolated SQLite database, with no access to the rest of your machine.

## The problem

An AI that only *suggests* code is limited. An AI that runs code directly on your computer is dangerous: it could delete files, read secrets, use the network, or loop forever. This project lets the model write, run, see errors, and fix its own code, safely.

## Demo

![Claude using the sandbox](docs/demo.gif)

## Architecture

```mermaid
flowchart LR
    A[Claude Desktop<br/>MCP client] -- stdio --> B[MCP Server<br/>FastMCP]
    B --> C[Workspace<br/>safe_path checks]
    B --> D[Executor]
    B --> E[(SQLite<br/>read-only)]
    D -- docker run --> F[Container<br/>no network, limited,<br/>read-only]
    F -. mounts read-only .-> C
```

## Tools

| Tool | Purpose |
|---|---|
| `list_files`, `read_file`, `write_file` | Manage files inside `workspace/` |
| `run_python` | Run a workspace script in an isolated container |
| `describe_schema` | Show the database tables |
| `query_db` | Run read-only `SELECT` queries |

## Threat model

| Threat | Defense | Tested by |
|---|---|---|
| Path traversal (`../`, absolute paths) | `safe_path` resolves paths and checks they stay inside `workspace/` | `tests/test_workspace.py` |
| Destructive SQL (`DROP`, `DELETE`, ...) | `SELECT`/`WITH`-only check **plus** SQLite `mode=ro` | `tests/test_database.py` |
| Stacked SQL statements | `sqlite3` rejects multiple statements | `test_multiple_statements_rejected` |
| Infinite loops / CPU hogging | 10s timeout; container force-removed | `test_infinite_loop_times_out` |
| Orphaned containers | Unique `--name` + `docker rm -f` in `finally` | `test_no_orphan_container_after_timeout` |
| Network access / data exfiltration | `--network none` | `test_network_blocked` |
| Modifying host files | Workspace mounted `:ro`, `--read-only` root filesystem | `test_workspace_is_read_only` |
| Memory / fork bombs | `--memory`, `--cpus`, `--pids-limit` | Manual |
| Privilege escalation | Non-root user, `--cap-drop ALL`, `no-new-privileges` | Configuration |
| Output flooding | Output truncated at 10,000 characters | Manual |

## Setup

Requirements: Python 3.10+, [uv](https://docs.astral.sh/uv/), Docker (running).

```bash
git clone https://github.com/Prakhar021-hub/local-sandbox-mcp.git
cd local-sandbox-mcp
uv sync
docker build -t sandbox-mcp-runner docker/
uv run pytest -v
```

### Try it in the MCP Inspector

```bash
PYTHONPATH=src uv run mcp dev dev_server.py
```

### Connect to Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` under `mcpServers`:

```json
"local-sandbox": {
  "command": "/path/to/uv",
  "args": ["--directory", "/path/to/local-sandbox-mcp",
           "run", "python", "-m", "local_sandbox_mcp.server"],
  "env": {
    "PYTHONPATH": "src",
    "PATH": "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin"
  }
}
```

Restart Claude Desktop (Cmd+Q) and try: *"Write a script that prints the first 10 Fibonacci numbers, run it, and show me the output."*

## Project structure

```
src/local_sandbox_mcp/   server, executor, database, workspace, config, logging
docker/Dockerfile        minimal non-root Python runner image
tests/                   pytest suite that attacks the sandbox
```

## Limitations

Docker containers share the host kernel, so this is strong isolation for local development, but not a substitute for a VM-level sandbox against a determined attacker. Intended for local, single-user use.

## License

MIT

TDQS

A3.6/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a clearly distinct resource and action: file CRUD, Python execution, and read-only database access are cleanly separated. The only adjacent pair, describe_schema and query_db, is well differentiated by one returning metadata and the other returning query results.

Naming Consistency5/5

All six tools follow a consistent snake_case verb_noun pattern (run_python, describe_schema, query_db, list_files, write_file, read_file). No mixed conventions or vague verbs.

Tool Count5/5

Six tools is a tight, well-scoped surface for a sandbox environment; every tool earns its place with no redundancy. Nothing feels padded or thin.

Completeness4/5

File read/write/list, code execution, and DB inspection cover the core sandbox workflow, but there is no delete_file or directory-creation operation, which agents may need when cleaning up or organizing the workspace. A way to pass arguments/stdin to run_python is also absent but workable.

Maintenance

ActivityMaintained
ResponsivenessNo issues