Skip to main content
Glama
flujo-app

mcp-sandbox-computer-vm-for-ai

by flujo-app

MCP Sandbox Computer VM for AI is a lifecycle-focused fork of 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.

  • 🖥️ MCP App dashboard: List computers, run commands, restart, factory reset, and delete from FLUJO or another stable MCP Apps host.

  • 🏷️ Named computers: Reconnect with a stable computer_id, or omit it to receive a readable random slug.

  • 💾 Explicit lifecycle: Temporary computers are removed with their MCP session; permanent computers survive and can be reattached later.

  • 🧰 Multiple backends: Docker/Podman, native Fly Machines, Modal, E2B, and WebAssembly.

  • 🏝️ Isolated per agent: Every agent gets its own dedicated sandbox — no shared state, no cross-contamination.

  • 🔒 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.

  • 🔌 Tool and UI access: terminal_execute stays simple, while optional provider-neutral lifecycle tools power both models and the dashboard.

  • 📈 Scalable: Scale from a few agents on your laptop to thousands running in parallel in the cloud.

Why sandbox computers?

Agents 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.

Related MCP server: open-computer-use

Quick Start

Run the released package directly from PyPI. Docker and stdio are the defaults:

uvx mcp-sandbox-computer-vm-for-ai

Add it to Claude Code:

claude mcp add --scope user sandbox-computer -- uvx mcp-sandbox-computer-vm-for-ai

Or add it to a JSON-based MCP client such as Claude Desktop:

{
  "mcpServers": {
    "sandbox-computer": {
      "command": "uvx",
      "args": ["mcp-sandbox-computer-vm-for-ai"]
    }
  }
}

By 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:

{
  "env": {
    "ENABLE_LIFECYCLE_TOOLS": "true"
  }
}

Then 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.

Named computer lifecycle

terminal_execute accepts two additional optional inputs:

  • 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.

  • 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.

Every execution result includes computer_id and temporary next to stdout, stderr, exit code, and duration:

{
  "computer_id": "steady-otter-a31f",
  "temporary": false,
  "stdout": "persistent\n",
  "stderr": "",
  "exit_code": 0,
  "exec_duration_ms": 84
}

Lifecycle tools are provider-neutral and are disabled unless ENABLE_LIFECYCLE_TOOLS=true:

Tool

Purpose

computer_dashboard

Open the MCP App and return the current inventory

computer_list

List state, backend, image, provider ID, and lifecycle mode

computer_create

Create/attach by ID; omission always generates a new slug

computer_restart

Restart while preserving writable state

computer_factory_reset

Erase writable state and recreate from the base image

computer_delete

Permanently remove the computer

How It Works

┌─────────────┐   MCP   ┌──────────────┐      ┌─────────────────────────┐
│  LLM Agent  │◄───────►│  Sandbox MCP │◄────►│  Sandboxes              │
│  (client)   │         │  MCP Server  │      │  - Docker/Podman        │
│             │         │              │      │  - Cloud VM (Modal,E2B) │
│             │         │              │      │  - WASM Sandbox         │
└─────────────┘         └──────────────┘      └─────────────────────────┘
  1. An MCP client starts MCP Sandbox Computer VM for AI over stdio or connects over HTTP

  2. 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.

  3. Commands run inside the sandbox; stdout, stderr, and exit code are returned

  4. When the session ends, temporary computers are destroyed; permanent computers remain provider-side.

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.

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.

Backend Examples

See the CLI Reference for all arguments.

Docker and Podman (default)

Local containers via Docker or Podman. Any OCI image works.

uvx mcp-sandbox-computer-vm-for-ai                                # Docker + Debian (defaults)
uvx mcp-sandbox-computer-vm-for-ai --image alpine --engine podman # Podman + Alpine
uvx mcp-sandbox-computer-vm-for-ai --image node:22                # Node.js with networking
uvx mcp-sandbox-computer-vm-for-ai --no-network                   # Disable networking

Docker Compose HTTP server

The included image contains the Docker CLI and talks to the host daemon through its socket:

docker compose up --build
# Streamable HTTP MCP endpoint: http://127.0.0.1:8080/mcp

Set ENABLE_LIFECYCLE_TOOLS=true in the Compose service environment when you want the optional dashboard and computer_* tools.

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.

Fly Machines

Fly.io deploys OCI images as VM root filesystems. The fly backend provisions real Fly Machines through flyctl: temporary Machines use disposable root filesystems, while permanent Machines use persist_rootfs=always.

The normal setup is local stdio MCP with remote Fly Machines. There are no required app, region, CPU, or memory choices:

uvx mcp-sandbox-computer-vm-for-ai --backend fly

On first use the backend:

  • uses an existing fly or flyctl, or downloads the current official release to ~/.fly/bin (set AUTO_INSTALL_FLYCTL=false to opt out);

  • uses your cached fly auth login session, FLY_API_TOKEN, or FLY_TOKEN;

  • chooses the personal organization when available, otherwise the first organization on the account;

  • creates a generated Fly App once and remembers it in ~/.mcp-sandbox-computer-vm-for-ai/fly.json;

  • lets Fly choose the region and uses one shared CPU with 512 MB by default.

Authentication 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.

This repository's .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:

{
  "mcpServers": {
    "sandbox-computer-fly": {
      "command": "uvx",
      "args": ["mcp-sandbox-computer-vm-for-ai", "--backend", "fly"],
      "env": {
        "ENABLE_LIFECYCLE_TOOLS": "true",
        "AUTO_INSTALL_FLYCTL": "true"
      }
    }
  }
}

The 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).

Hosted MCP controller (advanced)

The 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:

fly apps create mcp-sandbox-computer-vm-for-ai
fly secrets set -a mcp-sandbox-computer-vm-for-ai \
  FLY_API_TOKEN="$(fly tokens create deploy -a mcp-sandbox-computer-vm-for-ai)" \
  KILNTAINERS_AUTH_TOKEN="$(openssl rand -hex 32)"
fly deploy

The 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.

Cloud Containers & VMs

Modal.com

Hosted containers with sub-second startup via Modal.com. Scales to thousands of parallel sandboxes. Supports GPUs.

uvx mcp-sandbox-computer-vm-for-ai --backend modal
uvx mcp-sandbox-computer-vm-for-ai --backend modal --gpu A10G --region us-east

Authenticate via modal setup CLI or --modal-token-id / --modal-token-secret flags.

E2B

Cloud hosted micro-VM sandboxes from E2B.

uvx mcp-sandbox-computer-vm-for-ai --backend e2b
uvx mcp-sandbox-computer-vm-for-ai --backend e2b --e2b-api-key ABCD --e2b-template my-custom-alpine

Authenticate with --e2b-api-key CLI arg, or E2B_API_KEY environment variable.

WASM Go BusyBox (Experimental)

Runs 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.

uvx --from "mcp-sandbox-computer-vm-for-ai[wasm]" mcp-sandbox-computer-vm-for-ai --backend go_busybox

WASM Runner

Run a custom WASM module as the sandbox backend. Provides agents a set tools compiled to WebAssembly, and an isolated filesystem.

uvx --from "mcp-sandbox-computer-vm-for-ai[wasm]" mcp-sandbox-computer-vm-for-ai --backend wasm --wasm-path ./my_tool.wasm

Installation

uvx mcp-sandbox-computer-vm-for-ai                    # run without installing
uv tool install mcp-sandbox-computer-vm-for-ai        # recommended
uv tool install mcp-sandbox-computer-vm-for-ai[wasm]  # include WASM backends (+15MB)
pip install mcp-sandbox-computer-vm-for-ai            # also works with pip

Requires Python 3.13+. Docker backend requires Docker or Podman. The Modal and E2B backends require accounts to those services.

Releasing

Node is used only as the cross-platform release task runner; the published package remains Python. The release command synchronizes all package and registry metadata.

npm run release:check                 # credential-free command self-check
npm run check                         # lint, types, tests, and package build
npm run release -- --dry-run          # full main-branch preflight, no changes
npm run release                       # patch version; GitHub publishes PyPI via OIDC
npm run release -- minor              # minor version release
npm run release -- 1.0.0              # exact version release

PyPI publication uses Trusted Publishing, 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.

After the PyPI version is visible, validate and publish its immutable metadata to the official MCP Registry:

npm run registry:validate             # downloads pinned publisher; publishes nothing
npm run registry:release              # GitHub login, then publish server.json

The 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.

CLI Reference

usage: mcp-sandbox-computer-vm-for-ai [-h] [--backend {docker,e2b,fly,go_busybox,modal,wasm}] [--transport {stdio,http}] [...]

MCP server providing isolated Linux sandboxes for LLM agent shell execution.

options:
  -h, --help            show this help message and exit

core options:
  --backend {docker,e2b,fly,go_busybox,modal,wasm}
                        Backend to use (default: docker)
  --transport {stdio,http}
                        MCP transport (default: stdio)
  --host HOST           HTTP bind address (default: 127.0.0.1, HTTP mode only)
  --port PORT           HTTP listen port (default: 8435, HTTP mode only)
  --timeout TIMEOUT     Default exec timeout in seconds (default: 120)
  --output-limit OUTPUT_LIMIT
                        Max combined stdout+stderr bytes per exec (default: 2097152 = 2 MiB)
  --session-timeout SESSION_TIMEOUT
                        Idle session timeout in seconds (default: 300, HTTP mode only)
  --auth-token AUTH_TOKEN
                        Bearer token for /mcp (default: KILNTAINERS_AUTH_TOKEN)
  --allow-unauthenticated-http
                        Explicitly allow a non-loopback listener without built-in auth
  --shell SHELL         Shell binary for command mode (e.g., /bin/bash, ash). Default: /bin/bash.
  --network, --no-network
                        Enable network access in sandboxes (default: enabled)

tool description:
  --tool-instruction-override TOOL_INSTRUCTION_OVERRIDE
                        Replace the entire terminal_execute tool description
  --extended-tool-instruction EXTENDED_TOOL_INSTRUCTION
                        Append to the backend's default tool description

docker backend options:
  --engine ENGINE       Container CLI binary (default: docker). Supports podman.
  --docker-host DOCKER_HOST
                        Docker daemon socket/address, passed as -H to the Docker CLI (e.g., "ssh://user@remote-host", "tcp://host:2375")
  --image IMAGE         Docker image (default: debian:bookworm-slim)
  --cpu CPU             Docker CPU limit (e.g., "1.5")
  --memory MEMORY       Docker memory limit (e.g., "512m")
  --docker-run-flag DOCKER_RUN_FLAGS
                        Additional flag passed to docker run. Repeatable. (e.g., --docker-run-flag "--pids-limit=256")

fly backend options:
  --fly-cli FLY_CLI     flyctl/fly executable (default: fly)
  --fly-app FLY_APP     Fly App that owns sandbox Machines (default: FLY_APP_NAME)
  --fly-token FLY_TOKEN Fly API token (default: FLY_API_TOKEN or FLY_TOKEN)
  --fly-image FLY_IMAGE Base OCI image for sandbox Machines
  --fly-region FLY_REGION
                        Region for newly created Machines
  --fly-cpu-kind {shared,performance}
  --fly-cpus FLY_CPUS
  --fly-memory FLY_MEMORY
                        Memory per Machine in MB
  --fly-rootfs-size FLY_ROOTFS_SIZE
                        Optional root filesystem size in GB

e2b backend options:
  --e2b-api-key E2B_API_KEY
                        E2B API key (overrides E2B_API_KEY environment variable)
  --e2b-template E2B_TEMPLATE
                        E2B template name or ID (default: base)
  --e2b-sandbox-timeout E2B_SANDBOX_TIMEOUT
                        Sandbox lifetime timeout in seconds (default: 3600)
  --e2b-metadata E2B_METADATA
                        Metadata key=value pairs (can be used multiple times)
  --e2b-env E2B_ENV     Environment variable key=value pairs (can be used multiple times)

modal backend options:
  --modal-token-id MODAL_TOKEN_ID
                        Modal token ID (overrides environment/default auth)
  --modal-token-secret MODAL_TOKEN_SECRET
                        Modal token secret (overrides environment/default auth)
  --modal-app-name MODAL_APP_NAME
                        Modal app name
  --modal-cpu MODAL_CPU
                        CPU cores (fractional, default: 1.0)
  --modal-memory MODAL_MEMORY
                        Memory in MiB (default: 512)
  --gpu GPU             GPU type (e.g., "A10G", "H100")
  --region REGION       Geographic region (e.g., "us-east")
  --sandbox-timeout SANDBOX_TIMEOUT
                        Sandbox lifetime timeout in seconds (default: 3600, max 86400)

wasm backend options:
  --wasm-path WASM_PATH
                        Path to the .wasm file to execute (required for wasm backend)
  --wasm-max-memory WASM_MAX_MEMORY
                        Max WASM memory in MiB (default: 256)
  --wasm-fuel WASM_FUEL
                        WASM instruction fuel limit (default: unlimited)

Available Tools

1 tool
terminal_executeA

Execute a shell command in an isolated Debian Linux sandbox. Commands run in bash. Each call is independent — no state (shell variables, working directory) persists between calls (however filesystem does persist). Use the working_directory parameter or chain commands with && to control execution context.

To write files or pass data without shell escaping, use the stdin parameter (e.g., command="cat > file.txt" with content in stdin). Commands time out after 120 seconds by default (override with the timeout parameter for long-running operations).

ParametersJSON Schema
NameRequiredDescriptionDefault
argsNoList of arguments for direct execution (mutually exclusive with command).
stdinNoContent to pipe to stdin.
commandNoShell command string (mutually exclusive with args).
timeoutNoTimeout in seconds (defaults to server config).
temporaryNoRemove the computer when its MCP session shuts down. Set false to keep it provider-side and reconnect by computer_id.
computer_idNoStable computer slug. Omit to create and select a readable random ID for this MCP session.
working_directoryNoWorking directory for the command (must be absolute).

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burder. It discloses isolation, lack of state between calls, persistent filesystem, default 120-second timeout, and the stdin overreducing shell escaping issues. This is comprehensive behavioral context beyond just 'execute command'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences with zero waste. The core purpose leads, followed by state semantics, then parameter guidance. Information is front-loaded and each sentence earned its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the major concerns for shell execution: sandbox isolation, state persistence, filesystem persistence, working directory, stdin usage, and timeout. The only notable omission is the return/output format, but the description still gives an agent enough to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already covers all 7 parameters at 100%, but the description adds real context: working_directory for execution control, timeout override for long ops, and an explicit stdin example (cat > file.txt). This goes beyond what the schema fields say.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States clearly that it executes shell commands in an isolated Debian Linux sandbox under bash. The purpose is unambiguous even without sibling tools to differentiate from.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

We no sibling tools to compare, it provides actionable guidance: notes statelessness, suggests using working_directory or chaining with &&, and recommends stdin for passing data without shell escaping. Lacks explicit when-not-to-use scenarios, but that is acceptable given no alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.2.3
    • Removedcomputer_create
    • Removedcomputer_dashboard
    • Removedcomputer_delete
    • Removedcomputer_factory_reset
    • Removedcomputer_list
    • Removedcomputer_restart
    • Removedsandbox_exec
    • Addedterminal_execute
  2. 7 tool updatesv0.2.2
    • First observedcomputer_create
    • First observedcomputer_dashboard
    • First observedcomputer_delete
    • First observedcomputer_factory_reset
    • First observedcomputer_list
    • First observedcomputer_restart
    • First observedsandbox_exec

TDQS

A4.7/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so there is no possibility of confusing it with another tool. Its purpose is clearly defined as executing shell commands in a sandboxed Linux environment.

Naming Consistency5/5

The single tool name terminal_execute follows a clear verb_noun pattern and accurately reflects its function. With only one tool, there are no naming inconsistencies or conflicting conventions.

Tool Count4/5

A one-tool server is minimal, but terminal_execute is a broad and powerful primitive that can handle filesystem operations, package management, script execution, and more. The count feels slightly thin but is justifiable for a sandbox execution server.

Completeness5/5

Arbitrary shell command execution covers the full range of expected sandbox operations, including reading, writing, modifying, and deleting files, as well as running processes and installing software. The stdin and timeout parameters further fill practical gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers