{
  "markdown": "<h1 align=\"center\">MCP Sandbox Computer VM for AI</h1>\n<h3 align=\"center\">\n  Named, manageable Linux computers for AI agents — via MCP\n</h3>\n\n<p align=\"center\">\n  <a href=\"https://github.com/flujo-app/mcp-sandbox-computer-vm-for-ai/actions/workflows/build_and_test.yml\"><img src=\"https://github.com/flujo-app/mcp-sandbox-computer-vm-for-ai/actions/workflows/build_and_test.yml/badge.svg\" alt=\"Build and Test\"></a>\n  <a href=\"https://pypi.org/project/mcp-sandbox-computer-vm-for-ai/\"><img src=\"https://img.shields.io/pypi/v/mcp-sandbox-computer-vm-for-ai.svg?logo=pypi&label=PyPI&logoColor=gold\" alt=\"PyPI\"></a>\n</p>\n\nMCP Sandbox Computer VM for AI is a lifecycle-focused fork of [Kilntainers](https://github.com/Kiln-AI/Kilntainers). It gives agents isolated Linux computers, stable IDs, temporary or persistent lifecycles, an interactive MCP App dashboard, and first-class Docker and Fly Machines backends.\n\n<!-- mcp-name: io.github.flujo-app/mcp-sandbox-computer-vm-for-ai -->\n\n- 🖥️ **MCP App dashboard:** List computers, run commands, restart, factory reset, and delete from FLUJO or another stable MCP Apps host.\n- 🏷️ **Named computers:** Reconnect with a stable `computer_id`, or omit it to receive a readable random slug.\n- 💾 **Explicit lifecycle:** Temporary computers are removed with their MCP session; permanent computers survive and can be reattached later.\n- 🧰 **Multiple backends:** Docker/Podman, native Fly Machines, [Modal](https://modal.com), [E2B](https://e2b.dev), and WebAssembly.\n- 🏝️ **Isolated per agent:** Every agent gets its own dedicated sandbox — no shared state, no cross-contamination.\n- 🔒 **Secure by design:** The agent communicates *with* the sandbox over MCP — it doesn’t run *inside* it. No agent API keys, code, or prompts are exposed to the sandbox.\n- 🔌 **Tool and UI access:** `terminal_execute` stays simple, while optional provider-neutral lifecycle tools power both models and the dashboard.\n- 📈 **Scalable:** Scale from a few agents on your laptop to thousands running in parallel in the cloud.\n\n## Why sandbox computers?\n\nAgents are already excellent at using terminals and can save thousands of tokens with common Linux utilities like `grep`, `find`, `jq`, and `awk`. Giving an agent access to the host OS is dangerous, while provisioning large numbers of isolated environments is operationally painful. MCP Sandbox Computer VM for AI gives every agent a dedicated sandbox with an explicit lifecycle.\n\n## Quick Start\n\nRun the released package directly from PyPI. Docker and stdio are the defaults:\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai\n```\n\nAdd it to Claude Code:\n\n```bash\nclaude mcp add --scope user sandbox-computer -- uvx mcp-sandbox-computer-vm-for-ai\n```\n\nOr add it to a JSON-based MCP client such as Claude Desktop:\n\n```json\n{\n  \"mcpServers\": {\n    \"sandbox-computer\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mcp-sandbox-computer-vm-for-ai\"]\n    }\n  }\n}\n```\n\nBy default, the server exposes only `terminal_execute`. Set `ENABLE_LIFECYCLE_TOOLS=true` before starting the server to expose the `computer_*` tools and MCP App dashboard. For a JSON-based stdio client, add it to the server configuration:\n\n```json\n{\n  \"env\": {\n    \"ENABLE_LIFECYCLE_TOOLS\": \"true\"\n  }\n}\n```\n\nThen call `computer_dashboard` to open the App. The dashboard has no external browser dependencies. Its internal resource URI remains `ui://kilntainers/computers` for compatibility with the upstream implementation.\n\n## Named computer lifecycle\n\n`terminal_execute` accepts two additional optional inputs:\n\n- `computer_id`: a 1–63 character lowercase slug. The first call without one creates a readable random ID and reuses it as that MCP session's default.\n- `temporary`: defaults to `true`. Temporary computers are removed when the owning MCP session closes. Set it to `false` for a computer that survives server/session shutdown and can be reattached later by ID.\n\nEvery execution result includes `computer_id` and `temporary` next to stdout, stderr, exit code, and duration:\n\n```json\n{\n  \"computer_id\": \"steady-otter-a31f\",\n  \"temporary\": false,\n  \"stdout\": \"persistent\\n\",\n  \"stderr\": \"\",\n  \"exit_code\": 0,\n  \"exec_duration_ms\": 84\n}\n```\n\nLifecycle tools are provider-neutral and are disabled unless `ENABLE_LIFECYCLE_TOOLS=true`:\n\n| Tool | Purpose |\n|---|---|\n| `computer_dashboard` | Open the MCP App and return the current inventory |\n| `computer_list` | List state, backend, image, provider ID, and lifecycle mode |\n| `computer_create` | Create/attach by ID; omission always generates a new slug |\n| `computer_restart` | Restart while preserving writable state |\n| `computer_factory_reset` | Erase writable state and recreate from the base image |\n| `computer_delete` | Permanently remove the computer |\n\n## How It Works\n\n```\n┌─────────────┐   MCP   ┌──────────────┐      ┌─────────────────────────┐\n│  LLM Agent  │◄───────►│  Sandbox MCP │◄────►│  Sandboxes              │\n│  (client)   │         │  MCP Server  │      │  - Docker/Podman        │\n│             │         │              │      │  - Cloud VM (Modal,E2B) │\n│             │         │              │      │  - WASM Sandbox         │\n└─────────────┘         └──────────────┘      └─────────────────────────┘\n```\n\n1. An MCP client starts MCP Sandbox Computer VM for AI over stdio or connects over HTTP\n2. On the first `terminal_execute` call, the server creates a named isolated computer. Each connection gets its own random default unless it explicitly attaches by ID.\n3. Commands run inside the sandbox; stdout, stderr, and exit code are returned\n4. When the session ends, temporary computers are destroyed; permanent computers remain provider-side.\n\n**Security:** The agent communicates *with* the sandbox over MCP — it doesn't run *inside* it. This is intentional: agents often need secrets (API keys, system prompts, code), and those should never be exposed inside a sandbox where a prompt injection could exfiltrate them.\n\n**Agent Isolation & Sandbox Lifecycle:** An omitted ID gives each MCP connection an isolated default computer. Explicit IDs make reconnection intentional. Docker labels and Fly Machine metadata make permanent computers discoverable after the MCP server itself restarts.\n\n## Backend Examples\n\nSee the [CLI Reference](#cli-reference) for all arguments.\n\n### Docker and Podman (default)\n\nLocal containers via Docker or Podman. Any OCI image works.\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai                                # Docker + Debian (defaults)\nuvx mcp-sandbox-computer-vm-for-ai --image alpine --engine podman # Podman + Alpine\nuvx mcp-sandbox-computer-vm-for-ai --image node:22                # Node.js with networking\nuvx mcp-sandbox-computer-vm-for-ai --no-network                   # Disable networking\n```\n\n### Docker Compose HTTP server\n\nThe included image contains the Docker CLI and talks to the host daemon through its socket:\n\n```bash\ndocker compose up --build\n# Streamable HTTP MCP endpoint: http://127.0.0.1:8080/mcp\n```\n\nSet `ENABLE_LIFECYCLE_TOOLS=true` in the Compose service environment when you want the optional dashboard and `computer_*` tools.\n\n`compose.yaml` binds only to loopback. For a remote listener, set `KILNTAINERS_AUTH_TOKEN` and send it as an `Authorization: Bearer …` header. Mounting the Docker socket grants the service control of the host Docker daemon; use a dedicated host or a restricted remote daemon in production.\n\n### Fly Machines\n\nFly.io deploys OCI images as VM root filesystems. The `fly` backend provisions real [Fly Machines](https://fly.io/docs/machines/) through `flyctl`: temporary Machines use disposable root filesystems, while permanent Machines use `persist_rootfs=always`.\n\nThe normal setup is local stdio MCP with remote Fly Machines. There are no required app, region, CPU, or memory choices:\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai --backend fly\n```\n\nOn first use the backend:\n\n- uses an existing `fly` or `flyctl`, or downloads the current official release to `~/.fly/bin` (set `AUTO_INSTALL_FLYCTL=false` to opt out);\n- uses your cached `fly auth login` session, `FLY_API_TOKEN`, or `FLY_TOKEN`;\n- chooses the `personal` organization when available, otherwise the first organization on the account;\n- creates a generated Fly App once and remembers it in `~/.mcp-sandbox-computer-vm-for-ai/fly.json`;\n- lets Fly choose the region and uses one shared CPU with 512 MB by default.\n\nAuthentication is the only unavoidable account step. On a genuinely fresh machine, start the MCP once so it installs flyctl, then run the exact `flyctl auth login` command shown by its error and restart the MCP client. CI can set `FLY_API_TOKEN` instead. `FLY_ORG`, `FLY_APP_NAME`, `FLY_REGION`, and the `--fly-*` flags remain optional overrides.\n\nThis repository's [`.mcp.json`](.mcp.json) is ready for Fly mode and runs the local checkout with lifecycle tools enabled. For a client outside the checkout, use this equivalent configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"sandbox-computer-fly\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mcp-sandbox-computer-vm-for-ai\", \"--backend\", \"fly\"],\n      \"env\": {\n        \"ENABLE_LIFECYCLE_TOOLS\": \"true\",\n        \"AUTO_INSTALL_FLYCTL\": \"true\"\n      }\n    }\n  }\n}\n```\n\nThe first `terminal_execute` call creates a temporary Machine. To keep its root filesystem, pass a stable `computer_id` and `temporary=false` (or create a permanent computer in the dashboard).\n\n#### Hosted MCP controller (advanced)\n\nThe included `fly.toml` can still host the MCP HTTP controller itself. This requires an app-scoped deploy token inside that controller because a Fly Machine cannot use your laptop's cached login:\n\n```bash\nfly apps create mcp-sandbox-computer-vm-for-ai\nfly secrets set -a mcp-sandbox-computer-vm-for-ai \\\n  FLY_API_TOKEN=\"$(fly tokens create deploy -a mcp-sandbox-computer-vm-for-ai)\" \\\n  KILNTAINERS_AUTH_TOKEN=\"$(openssl rand -hex 32)\"\nfly deploy\n```\n\nThe remote MCP endpoint is `https://mcp-sandbox-computer-vm-for-ai.fly.dev/mcp`; send `KILNTAINERS_AUTH_TOKEN` as a bearer token. The checked-in controller config uses `gru`, but local stdio mode does not choose a region unless you explicitly set one.\n\n### Cloud Containers & VMs\n\n#### Modal.com\n\nHosted containers with sub-second startup via [Modal.com](https://modal.com). Scales to thousands of parallel sandboxes. Supports GPUs.\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai --backend modal\nuvx mcp-sandbox-computer-vm-for-ai --backend modal --gpu A10G --region us-east\n```\n\nAuthenticate via `modal setup` CLI or `--modal-token-id` / `--modal-token-secret` flags.\n\n#### E2B\n\nCloud hosted micro-VM sandboxes from [E2B](https://e2b.dev).\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai --backend e2b\nuvx mcp-sandbox-computer-vm-for-ai --backend e2b --e2b-api-key ABCD --e2b-template my-custom-alpine\n```\n\nAuthenticate with `--e2b-api-key` CLI arg, or `E2B_API_KEY` environment variable.\n\n### WASM Go BusyBox (Experimental)\n\nRuns [go-busybox](https://github.com/rcarmo/go-busybox) in a WebAssembly sandbox. Not a full Linux environment, but provides common utilities (`grep`, `awk`, `sed`, `ls`, `wc`, `sort`, etc.) in a very lightweight and secure sandbox.\n\n```bash\nuvx --from \"mcp-sandbox-computer-vm-for-ai[wasm]\" mcp-sandbox-computer-vm-for-ai --backend go_busybox\n```\n\n### WASM Runner\n\nRun a custom WASM module as the sandbox backend. Provides agents a set tools compiled to WebAssembly, and an isolated filesystem.\n\n```bash\nuvx --from \"mcp-sandbox-computer-vm-for-ai[wasm]\" mcp-sandbox-computer-vm-for-ai --backend wasm --wasm-path ./my_tool.wasm\n```\n\n## Installation\n\n```bash\nuvx mcp-sandbox-computer-vm-for-ai                    # run without installing\nuv tool install mcp-sandbox-computer-vm-for-ai        # recommended\nuv tool install mcp-sandbox-computer-vm-for-ai[wasm]  # include WASM backends (+15MB)\npip install mcp-sandbox-computer-vm-for-ai            # also works with pip\n```\n\nRequires Python 3.13+. Docker backend requires Docker or Podman. The Modal and E2B backends require accounts to those services.\n\n## Releasing\n\nNode is used only as the cross-platform release task runner; the published package remains Python. The release command synchronizes all package and registry metadata.\n\n```bash\nnpm run release:check                 # credential-free command self-check\nnpm run check                         # lint, types, tests, and package build\nnpm run release -- --dry-run          # full main-branch preflight, no changes\nnpm run release                       # patch version; GitHub publishes PyPI via OIDC\nnpm run release -- minor              # minor version release\nnpm run release -- 1.0.0              # exact version release\n```\n\nPyPI publication uses [Trusted Publishing](https://docs.pypi.org/trusted-publishers/), so no PyPI token is stored locally or in GitHub. Configure the PyPI publisher once with owner `flujo-app`, repository `mcp-sandbox-computer-vm-for-ai`, workflow `release.yml`, and environment `pypi`. The release command pushes the version commit and tag, dispatches `.github/workflows/release.yml`, and waits for PyPI and the GitHub Release.\n\nAfter the PyPI version is visible, validate and publish its immutable metadata to the official MCP Registry:\n\n```bash\nnpm run registry:validate             # downloads pinned publisher; publishes nothing\nnpm run registry:release              # GitHub login, then publish server.json\n```\n\nThe registry command verifies the published PyPI README ownership marker before authenticating. `mcp:validate` and `mcp:publish` are retained as aliases matching the sibling MCP App repositories.\n\n## CLI Reference\n\n```\nusage: mcp-sandbox-computer-vm-for-ai [-h] [--backend {docker,e2b,fly,go_busybox,modal,wasm}] [--transport {stdio,http}] [...]\n\nMCP server providing isolated Linux sandboxes for LLM agent shell execution.\n\noptions:\n  -h, --help            show this help message and exit\n\ncore options:\n  --backend {docker,e2b,fly,go_busybox,modal,wasm}\n                        Backend to use (default: docker)\n  --transport {stdio,http}\n                        MCP transport (default: stdio)\n  --host HOST           HTTP bind address (default: 127.0.0.1, HTTP mode only)\n  --port PORT           HTTP listen port (default: 8435, HTTP mode only)\n  --timeout TIMEOUT     Default exec timeout in seconds (default: 120)\n  --output-limit OUTPUT_LIMIT\n                        Max combined stdout+stderr bytes per exec (default: 2097152 = 2 MiB)\n  --session-timeout SESSION_TIMEOUT\n                        Idle session timeout in seconds (default: 300, HTTP mode only)\n  --auth-token AUTH_TOKEN\n                        Bearer token for /mcp (default: KILNTAINERS_AUTH_TOKEN)\n  --allow-unauthenticated-http\n                        Explicitly allow a non-loopback listener without built-in auth\n  --shell SHELL         Shell binary for command mode (e.g., /bin/bash, ash). Default: /bin/bash.\n  --network, --no-network\n                        Enable network access in sandboxes (default: enabled)\n\ntool description:\n  --tool-instruction-override TOOL_INSTRUCTION_OVERRIDE\n                        Replace the entire terminal_execute tool description\n  --extended-tool-instruction EXTENDED_TOOL_INSTRUCTION\n                        Append to the backend's default tool description\n\ndocker backend options:\n  --engine ENGINE       Container CLI binary (default: docker). Supports podman.\n  --docker-host DOCKER_HOST\n                        Docker daemon socket/address, passed as -H to the Docker CLI (e.g., \"ssh://user@remote-host\", \"tcp://host:2375\")\n  --image IMAGE         Docker image (default: debian:bookworm-slim)\n  --cpu CPU             Docker CPU limit (e.g., \"1.5\")\n  --memory MEMORY       Docker memory limit (e.g., \"512m\")\n  --docker-run-flag DOCKER_RUN_FLAGS\n                        Additional flag passed to docker run. Repeatable. (e.g., --docker-run-flag \"--pids-limit=256\")\n\nfly backend options:\n  --fly-cli FLY_CLI     flyctl/fly executable (default: fly)\n  --fly-app FLY_APP     Fly App that owns sandbox Machines (default: FLY_APP_NAME)\n  --fly-token FLY_TOKEN Fly API token (default: FLY_API_TOKEN or FLY_TOKEN)\n  --fly-image FLY_IMAGE Base OCI image for sandbox Machines\n  --fly-region FLY_REGION\n                        Region for newly created Machines\n  --fly-cpu-kind {shared,performance}\n  --fly-cpus FLY_CPUS\n  --fly-memory FLY_MEMORY\n                        Memory per Machine in MB\n  --fly-rootfs-size FLY_ROOTFS_SIZE\n                        Optional root filesystem size in GB\n\ne2b backend options:\n  --e2b-api-key E2B_API_KEY\n                        E2B API key (overrides E2B_API_KEY environment variable)\n  --e2b-template E2B_TEMPLATE\n                        E2B template name or ID (default: base)\n  --e2b-sandbox-timeout E2B_SANDBOX_TIMEOUT\n                        Sandbox lifetime timeout in seconds (default: 3600)\n  --e2b-metadata E2B_METADATA\n                        Metadata key=value pairs (can be used multiple times)\n  --e2b-env E2B_ENV     Environment variable key=value pairs (can be used multiple times)\n\nmodal backend options:\n  --modal-token-id MODAL_TOKEN_ID\n                        Modal token ID (overrides environment/default auth)\n  --modal-token-secret MODAL_TOKEN_SECRET\n                        Modal token secret (overrides environment/default auth)\n  --modal-app-name MODAL_APP_NAME\n                        Modal app name\n  --modal-cpu MODAL_CPU\n                        CPU cores (fractional, default: 1.0)\n  --modal-memory MODAL_MEMORY\n                        Memory in MiB (default: 512)\n  --gpu GPU             GPU type (e.g., \"A10G\", \"H100\")\n  --region REGION       Geographic region (e.g., \"us-east\")\n  --sandbox-timeout SANDBOX_TIMEOUT\n                        Sandbox lifetime timeout in seconds (default: 3600, max 86400)\n\nwasm backend options:\n  --wasm-path WASM_PATH\n                        Path to the .wasm file to execute (required for wasm backend)\n  --wasm-max-memory WASM_MAX_MEMORY\n                        Max WASM memory in MiB (default: 256)\n  --wasm-fuel WASM_FUEL\n                        WASM instruction fuel limit (default: unlimited)\n```\n",
  "bytes": 18064,
  "sha": "ac68b01779f6af58009fb73c97048a0d6329f4bfa92cbcf4ebc77d446ed2ef28",
  "repo_slug": "flujo-app/mcp-sandbox-computer-vm-for-ai",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_flujo_app_mcp_sandbox_computer_973dda76/readme"
}