{"id":"34996c07-c92e-4c03-943f-c8ee74f62f76","slug":"mcp-exec","kind":"mcp","name":"mcp-exec","summary":"MCP server for executing any commands inside it","owner":"inhuman","repoUrl":"https://github.com/inhuman/mcp-exec","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-06-02T13:55:04.000Z","addedAt":"2026-10-14T05:39:09.493Z","logoUrl":"https://avatars.githubusercontent.com/u/2518263?u=a0870032e2f791e1a302013bd0c77b1a00f62ff3&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra"],"tags":[],"runtime":"docker","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-17T16:09:50.774Z","sample":false,"url":"https://conduits.dev/tools/mcp-exec","language":"Go","transports":["stdio"],"install":{"docker":"docker.io/idconstruct/mcp-exec:v0.5.4"},"requirements":{"env":[{"name":"MCP_EXEC_TRANSPORT","secret":false,"required":false,"description":"MCP transport. Must be 'stdio' for direct docker/stdio use."},{"name":"MCP_EXEC_DEFAULT_TIMEOUT_S","secret":false,"required":false,"description":"Default wall-clock timeout per exec, seconds."},{"name":"MCP_EXEC_MAX_TIMEOUT_S","secret":false,"required":false,"description":"Maximum wall-clock timeout a caller may request, seconds."},{"name":"MCP_EXEC_MAX_OUTPUT_BYTES","secret":false,"required":false,"description":"Cap on combined stdout/stderr before truncation."},{"name":"MCP_EXEC_MAX_STDIN_BYTES","secret":false,"required":false,"description":"Cap on stdin passed to the sandboxed code."},{"name":"MCP_EXEC_AUTH_TOKEN","secret":true,"required":false,"description":"Optional X-MCP-AUTH token (http/sse transports only)."}],"upstreamMayCharge":false},"tools":null,"readme":"# mcp-exec\n\n**English** | [Русский](README.ru.md)\n\n[![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)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.inhuman%2Fmcp--exec-blue?style=flat-square)](https://registry.modelcontextprotocol.io)\n[![Docker Pulls](https://img.shields.io/docker/pulls/idconstruct/mcp-exec?style=flat-square&logo=docker)](https://hub.docker.com/r/idconstruct/mcp-exec)\n[![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)\n[![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)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/inhuman/mcp-exec?style=flat-square&logo=go)](https://go.dev/)\n[![Go Report Card](https://goreportcard.com/badge/github.com/inhuman/mcp-exec?style=flat-square)](https://goreportcard.com/report/github.com/inhuman/mcp-exec)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE)\n[![Issues](https://img.shields.io/github/issues/inhuman/mcp-exec?style=flat-square)](https://github.com/inhuman/mcp-exec/issues)\n[![Last Commit](https://img.shields.io/github/last-commit/inhuman/mcp-exec?style=flat-square)](https://github.com/inhuman/mcp-exec/commits/main)\n\nPublic OSS MCP server (Go, MIT) exposing a single powerful tool — **`exec`** — that runs\ncaller-supplied **Python** code in a **network-isolated, locked-down sandbox** and returns\n`stdout` / `stderr` / `exit_code`. It is the \"code-execution mode\" building block: instead of\nflooding an agent's context with hundreds of tool schemas, the agent writes code that orchestrates\nthe work.\n\nWorks over three transports — **stdio / HTTP / SSE** — with an identical tool set everywhere\n(official [`modelcontextprotocol/go-sdk`](https://github.com/modelcontextprotocol/go-sdk)).\n\n## The `exec` tool\n\n**Input**: `{ code: string (required), timeout_s?: int, stdin?: string }`\n**Output**: `{ stdout, stderr, exit_code, duration_ms, truncated, timed_out }`\n\n- A non-zero `exit_code` or `timed_out=true` is a **normal result**, not a tool error. Only invalid\n  input (empty `code`, oversized `stdin`) is a tool-call error.\n- Sandbox v1: Python 3 with stdlib + **PyYAML**, **Jinja2**, **Pillow**, **numpy**, **pandas**, **matplotlib**.\n\n## Security model (invariants)\n\nPer execution: **no network**, non-root, `cap-drop=ALL`, `no-new-privileges`, read-only rootfs,\n**no CAP_SYS_ADMIN**, ephemeral tmpdir (cleaned up), wall-clock timeout (kills the whole\nprocess-group), memory/PID/CPU limits, capped output (1 MiB → `truncated`). Runs are **serialized**\nwithin an instance; scale out with replicas. Caller data (`code`/`stdin`/output) is never persisted\nand never logged in full — only metadata.\n\n> `exec` is the most powerful surface there is. When embedding it in an agent, gate it behind that\n> agent's tool-policy (trusted roles only).\n\n**Network note:** `--network none` only applies to **stdio**. In **HTTP/SSE** the container needs\nnetworking to serve its port, so sandboxed code would inherit egress — deny it at the orchestrator.\nIn k8s, a `NetworkPolicy` that allows ingress to the port and denies all egress:\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata: { name: mcp-exec-lockdown }\nspec:\n  podSelector: { matchLabels: { app: mcp-exec } }\n  policyTypes: [Ingress, Egress]\n  ingress: [{ ports: [{ port: 8080 }] }]\n  egress: []   # deny all egress → sandbox has no network\n```\n\n## Run\n\n```bash\ngo build -o mcp-exec ./cmd/mcp-exec\nMCP_EXEC_TRANSPORT=stdio ./mcp-exec\n```\n\nDocker (recommended production posture):\n\n```bash\ndocker run --rm -i --network none --read-only --cap-drop ALL \\\n  --security-opt no-new-privileges --user 65532:65532 \\\n  --tmpfs /tmp:rw,noexec,nosuid,size=64m \\\n  --memory 256m --pids-limit 128 --cpus 1 \\\n  idconstruct/mcp-exec\n```\n\n`--tmpfs /tmp` is required: the rootfs is read-only, and each run needs a writable\nephemeral workspace (cleaned up after).\n\n### Optional auth (HTTP/SSE)\n\nSet `MCP_EXEC_AUTH_TOKEN` to require every HTTP/SSE request to carry a matching `X-MCP-AUTH` header\n(constant-time compare; `401` otherwise). Empty token disables it. Not applicable to stdio.\n\n## Configuration\n\n| Env var | Purpose | Default |\n|---|---|---|\n| `MCP_EXEC_TRANSPORT` | `stdio` \\| `http` \\| `sse` | `stdio` |\n| `MCP_EXEC_ADDR` | listen address for http/sse | `:8080` |\n| `MCP_EXEC_DEFAULT_TIMEOUT_S` | default wall-clock timeout | `30` |\n| `MCP_EXEC_MAX_TIMEOUT_S` | timeout ceiling | `300` |\n| `MCP_EXEC_MAX_OUTPUT_BYTES` | combined stdout+stderr cap | `1048576` |\n| `MCP_EXEC_MAX_STDIN_BYTES` | stdin size cap | `1048576` |\n| `MCP_EXEC_PYTHON` | interpreter path | `python3` |\n| `MCP_EXEC_AUTH_TOKEN` | if set, http/sse require `X-MCP-AUTH` header (constant-time); empty = off | `` |\n\n## Not in v1\n\nbash / multi-language, network from the sandbox, proxying other MCP servers into the sandbox.\n\n## License\n\nMIT.\n"}