# Exec Sandbox [Health: Active]

**Category:** 👨‍💻 Code Execution  
**Repository:** https://github.com/inhuman/mcp-exec  
**GitHub Stars:** 1  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/exec-sandbox

## Description
Single exec tool running caller Python in a network-isolated locked-down sandbox.

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `uvx` (confidence: low):

```json
"mcpServers": {
  "exec-sandbox": {
    "command": "uvx",
    "args": ["exec-sandbox"]
  }
}
```

## Documentation & README

# mcp-exec

**English** | [Русский](https://github.com/inhuman/mcp-exec/blob/HEAD/README.ru.md)

[![Version](https://img.shields.io/github/v/tag/inhuman/mcp-exec?sort=semver&style=flat-square&label=version)](https://github.com/inhuman/mcp-exec/tags)
[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.inhuman%2Fmcp--exec-blue?style=flat-square)](https://registry.modelcontextprotocol.io)
[![Docker Pulls](https://img.shields.io/docker/pulls/idconstruct/mcp-exec?style=flat-square&logo=docker)](https://hub.docker.com/r/idconstruct/mcp-exec)
[![Docker Image Version](https://img.shields.io/docker/v/idconstruct/mcp-exec?sort=semver&style=flat-square&logo=docker&label=image)](https://hub.docker.com/r/idconstruct/mcp-exec/tags)
[![Build](https://img.shields.io/github/actions/workflow/status/inhuman/mcp-exec/docker-publish.yml?style=flat-square&logo=github)](https://github.com/inhuman/mcp-exec/actions/workflows/docker-publish.yml)
[![Go Version](https://img.shields.io/github/go-mod/go-version/inhuman/mcp-exec?style=flat-square&logo=go)](https://go.dev/)
[![Go Report Card](https://goreportcard.com/badge/github.com/inhuman/mcp-exec?style=flat-square)](https://goreportcard.com/report/github.com/inhuman/mcp-exec)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE)
[![Issues](https://img.shields.io/github/issues/inhuman/mcp-exec?style=flat-square)](https://github.com/inhuman/mcp-exec/issues)
[![Last Commit](https://img.shields.io/github/last-commit/inhuman/mcp-exec?style=flat-square)](https://github.com/inhuman/mcp-exec/commits/main)

Public OSS MCP server (Go, MIT) exposing a single powerful tool — **`exec`** — that runs
caller-supplied **Python** code in a **network-isolated, locked-down sandbox** and returns
`stdout` / `stderr` / `exit_code`. It is the "code-execution mode" building block: instead of
flooding an agent's context with hundreds of tool schemas, the agent writes code that orchestrates
the work.

Works over three transports — **stdio / HTTP / SSE** — with an identical tool set everywhere
(official [`modelcontextprotocol/go-sdk`](https://github.com/modelcontextprotocol/go-sdk)).

## The `exec` tool

**Input**: `{ code: string (required), timeout_s?: int, stdin?: string }`
**Output**: `{ stdout, stderr, exit_code, duration_ms, truncated, timed_out }`

- A non-zero `exit_code` or `timed_out=true` is a **normal result**, not a tool error. Only invalid
  input (empty `code`, oversized `stdin`) is a tool-call error.
- Sandbox v1: Python 3 with stdlib + **PyYAML**, **Jinja2**, **Pillow**, **numpy**, **pandas**, **matplotlib**.

## Security model (invariants)

Per execution: **no network**, non-root, `cap-drop=ALL`, `no-new-privileges`, read-only rootfs,
**no CAP_SYS_ADMIN**, ephemeral tmpdir (cleaned up), wall-clock timeout (kills the whole
process-group), memory/PID/CPU limits, capped output (1 MiB → `truncated`). Runs are **serialized**
within an instance; scale out with replicas. Caller data (`code`/`stdin`/output) is never persisted
and never logged in full — only metadata.

> `exec` is the most powerful surface there is. When embedding it in an agent, gate it behind that
> agent's tool-policy (trusted roles only).

**Network note:** `--network none` only applies to **stdio**. In **HTTP/SSE** the container needs
networking to serve its port, so sandboxed code would inherit egress — deny it at the orchestrator.
In k8s, a `NetworkPolicy` that allows ingress to the port and denies all egress:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: mcp-exec-lockdown }
spec:
  podSelector: { matchLabels: { app: mcp-exec } }
  policyTypes: [Ingress, Egress]
  ingress: [{ ports: [{ port: 8080 }] }]
  egress: []   # deny all egress → sandbox has no network
```

## Run

```bash
go build -o mcp-exec ./cmd/mcp-exec
MCP_EXEC_TRANSPORT=stdio ./mcp-exec
```

Docker (recommended production posture):

```bash
docker run --rm -i --network none --read-only --cap-drop ALL \
  --security-opt no-new-privileges --user 65532:65532 \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --memory 256m --pids-limit 128 --cpus 1 \
  idconstruct/mcp-exec
```

`--tmpfs /tmp` is required: the rootfs is read-only, and each run needs a writable
ephemeral workspace (cleaned up after).

### Optional auth (HTTP/SSE)

Set `MCP_EXEC_AUTH_TOKEN` to require every HTTP/SSE request to carry a matching `X-MCP-AUTH` header
(constant-time compare; `401` otherwise). Empty token disables it. Not applicable to stdio.

## Configuration

| Env var | Purpose | Default |
|---|---|---|
| `MCP_EXEC_TRANSPORT` | `stdio` \| `http` \| `sse` | `stdio` |
| `MCP_EXEC_ADDR` | listen address for http/sse | `:8080` |
| `MCP_EXEC_DEFAULT_TIMEOUT_S` | default wall-clock timeout | `30` |
| `MCP_EXEC_MAX_TIMEOUT_S` | timeout ceiling | `300` |
| `MCP_EXEC_MAX_OUTPUT_BYTES` | combined stdout+stderr cap | `1048576` |
| `MCP_EXEC_MAX_STDIN_BYTES` | stdin size cap | `1048576` |
| `MCP_EXEC_PYTHON` | interpreter path | `python3` |
| `MCP_EXEC_AUTH_TOKEN` | if set, http/sse require `X-MCP-AUTH` header (constant-time); empty = off | `` |

## Not in v1

bash / multi-language, network from the sandbox, proxying other MCP servers into the sandbox.

## License

MIT.

