mcp-exec
by inhuman
README.md
# mcp-exec
**English** | [Русский](README.ru.md)
[](https://github.com/inhuman/mcp-exec/tags)
[](https://registry.modelcontextprotocol.io)
[](https://hub.docker.com/r/idconstruct/mcp-exec)
[](https://hub.docker.com/r/idconstruct/mcp-exec/tags)
[](https://github.com/inhuman/mcp-exec/actions/workflows/docker-publish.yml)
[](https://go.dev/)
[](https://goreportcard.com/report/github.com/inhuman/mcp-exec)
[](LICENSE)
[](https://github.com/inhuman/mcp-exec/issues)
[](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.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues