{
  "markdown": "# devcontainer-mcp\n\n[![CI](https://github.com/aniongithub/devcontainer-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/aniongithub/devcontainer-mcp/actions/workflows/ci.yml)\n[![Website](https://img.shields.io/badge/website-devcontainer--mcp-blue)](https://www.anionline.me/devcontainer-mcp)\n\n**Give your AI agent its own dev environment — not yours.**\n\n`devcontainer-mcp` is an MCP server that lets AI coding agents create, manage, and work inside [dev containers](https://containers.dev/) across three backends: local Docker, [DevPod](https://devpod.sh/), and [GitHub Codespaces](https://github.com/features/codespaces). The agent builds, tests, and ships code in an isolated container — your laptop stays clean.\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/aniongithub/devcontainer-mcp/gh-pages/screengrabs/devcontainer-mcp-local-docker.gif\" alt=\"devcontainer-mcp local Docker demo\" width=\"720\">\n</p>\n\n> Works with **GitHub Copilot**, **Claude**, **Cursor**, **opencode**, and any MCP-compatible client.\n\n## The Problem\n\nWhen AI agents write code, they need to run it somewhere. Today that means your host machine:\n\n- 🔴 **Host contamination** — agents install packages, modify PATH, leave behind build artifacts\n- 🔴 **\"Works on my machine\"** — agents assume your local toolchain matches production\n- 🔴 **No isolation** — one project's dependencies break another\n- 🔴 **Security risk** — agents run arbitrary commands with your user privileges\n- 🔴 **Hardware constraints** — you're limited to your local machine's resources\n\n## The Solution\n\nThe [devcontainer spec](https://containers.dev/) already defines reproducible, container-based dev environments. Every major project ships a `.devcontainer/devcontainer.json`. But AI agents can't use them — until now.\n\n`devcontainer-mcp` exposes **45 MCP tools** that let any AI agent:\n\n1. **Spin up** a dev container from any repo — locally, on a cloud VM, or in Codespaces\n2. **Run commands** inside the container — builds, tests, linting, anything\n3. **Manage the lifecycle** — stop, restart, delete when done\n4. **Authenticate** against cloud providers — GitHub, AWS, Azure, GCP — without ever seeing a raw token\n\n```\nAgent: \"Let me build this project...\"\n  → auth_status(\"github\") → picks account\n  → codespaces_create(auth: \"github-you\", repo: \"your/repo\")\n  → codespaces_ssh(auth: \"github-you\", codespace: \"...\", command: \"cargo build\")\n  → ✅ Built in the cloud. Your laptop did nothing.\n```\n\n## Quick Install\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/aniongithub/devcontainer-mcp/gh-pages/screengrabs/devcontainer-mcp-install.gif\" alt=\"devcontainer-mcp install demo\" width=\"720\">\n</p>\n\n### Linux / macOS\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aniongithub/devcontainer-mcp/main/install.sh | bash\n```\n\n### Windows (via WSL)\n\n```powershell\nInvoke-RestMethod https://github.com/aniongithub/devcontainer-mcp/releases/latest/download/install.ps1 | Invoke-Expression\n```\n\n> **How it works:** The binary runs inside WSL; MCP clients on Windows launch it via `wsl ~/.local/bin/devcontainer-mcp serve`. The stdio transport works transparently across the WSL boundary. WSL 2 is required — install it with `wsl --install` if you haven't already.\n\nBackend CLIs (`devpod`, `devcontainer`, `gh`) are detected at runtime — if one is missing, the MCP server returns a helpful error with install instructions.\n\nBinaries available for **linux-x64**, **linux-arm64**, **darwin-x64**, and **darwin-arm64**.\n\n## Host Protection & Opt-Out\n\nThe installer configures two agent hooks (Claude Code & GitHub Copilot CLI) that activate **only** in a directory containing `.devcontainer/devcontainer.json`:\n\n- **`devcontainer-guard`** (PreToolUse) — blocks shell/command execution on the host so the agent routes builds, tests, and runs through the MCP tools instead. Host-safe commands (`git`, `gh`) are allowlisted, and both hooks *fail open* — if `jq` is missing or a payload can't be parsed, commands are allowed rather than blocked.\n- **`devcontainer-skill-loader`** (SessionStart) — injects the `SKILL.md` usage guide as context.\n\n### Turning it off for a repo\n\nSometimes a project ships a stale or unmaintained `.devcontainer` that you don't actually want to route work through. To disable both hooks for that repo, drop a marker file at the repo root:\n\n```bash\ntouch .devcontainer-mcp-disable\n```\n\nWhen `.devcontainer-mcp-disable` is present, the guard allows host commands through and the skill-loader skips context injection — the agent works locally as if no devcontainer were declared. Commit it (or add it to `.gitignore` for a local-only opt-out).\n\n**One-off bypass:** to run a single host command without disabling the guard, include `USER_CONFIRMED_HOST_OPERATION=1` anywhere in the command.\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[AI Agent / MCP Client] -->|stdio JSON-RPC| B[devcontainer-mcp]\n    \n    subgraph \"devcontainer-mcp\"\n        B --> C[33 MCP Tools]\n        C --> D[Auth Broker]\n        C --> E[devcontainer-mcp-core]\n    end\n    \n    D -->|opaque handles| C\n    E -->|subprocess| F[DevPod CLI]\n    E -->|subprocess| G[devcontainer CLI]\n    E -->|subprocess| H[gh CLI]\n    E -->|bollard API| I[Docker Engine]\n    \n    F --> J[Docker / K8s / Cloud VMs]\n    G --> K[Local Docker]\n    H --> L[GitHub Codespaces]\n```\n\n## Three Backends, One Interface\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/aniongithub/devcontainer-mcp/gh-pages/screengrabs/devcontainer-mcp-codespaces.gif\" alt=\"devcontainer-mcp Codespaces demo\" width=\"720\">\n</p>\n\n| Backend | Best for | Requires | Auth needed? |\n|---------|----------|----------|:---:|\n| **devcontainer CLI** (`devcontainer_*`) | Local Docker — fast, simple | [@devcontainers/cli](https://github.com/devcontainers/cli) + Docker | No |\n| **DevPod** (`devpod_*`) | Multi-cloud: Docker, K8s, AWS, Azure, GCP | [DevPod CLI](https://devpod.sh) | Optional (cloud providers) |\n| **Codespaces** (`codespaces_*`) | GitHub-hosted cloud environments | [gh CLI](https://cli.github.com/) | Yes (`auth` handle) |\n\n## Auth Broker\n\nThe agent never sees raw tokens. Instead:\n\n1. **`auth_status(provider)`** — list available accounts and scopes\n2. **`auth_login(provider, scopes?)`** — initiate login, opens browser, handles device codes\n3. **`auth_select(id)`** — switch the active account\n4. **`auth_logout(id)`** — revoke credentials\n\nCodespaces tools require an auth handle (e.g. `\"github-aniongithub\"`). The MCP server resolves it to the real token on each call via the CLI's native keyring.\n\nSupported providers: **GitHub**, **AWS**, **Azure**, **GCP**, **Kubernetes**\n\n## MCP Tools (46 total)\n\n### Auth (4 tools)\n\n| Tool | Description |\n|------|-------------|\n| `auth_status` | Check auth for a provider — returns handles, accounts, scopes |\n| `auth_login` | Initiate login or refresh scopes — browser + device code flow |\n| `auth_select` | Switch the active account for a provider |\n| `auth_logout` | Revoke credentials for an account |\n\n### DevPod (19 tools)\n\n| Tool | Description |\n|------|-------------|\n| `devpod_up` | Create and start a workspace from a git URL, local path, or image |\n| `devpod_stop` | Stop a running workspace |\n| `devpod_delete` | Delete a workspace and its resources |\n| `devpod_build` | Build a workspace image without starting it |\n| `devpod_status` | Get workspace state (`Running`, `Stopped`, `Busy`, `NotFound`) |\n| `devpod_list` | List all workspaces with IDs, sources, providers, and status |\n| `devpod_ssh` | Execute a command inside a workspace via SSH |\n| `devpod_logs` | Get workspace logs |\n| `devpod_provider_list` | List all configured providers |\n| `devpod_provider_add` | Add a new provider |\n| `devpod_provider_delete` | Remove a provider |\n| `devpod_context_list` | List all contexts |\n| `devpod_context_use` | Switch to a different context |\n| `devpod_container_inspect` | Docker inspect — labels, ports, mounts, state |\n| `devpod_container_logs` | Stream container logs via Docker API |\n| `devpod_file_read` | Read file content with optional line range |\n| `devpod_file_write` | Create or overwrite a file (auto-creates parent dirs) |\n| `devpod_file_edit` | Surgical string replacement — old_str → new_str |\n| `devpod_file_list` | List directory contents (non-hidden, 2 levels deep) |\n\n### devcontainer CLI (12 tools)\n\n| Tool | Description |\n|------|-------------|\n| `devcontainer_up` | Create and start a local dev container |\n| `devcontainer_exec` | Execute a command inside a running dev container |\n| `devcontainer_build` | Build a dev container image |\n| `devcontainer_read_config` | Read merged devcontainer configuration as JSON |\n| `devcontainer_list_configs` | Discover all devcontainer.json files in a workspace (single + multi-container) |\n| `devcontainer_stop` | Stop a dev container (via Docker API) |\n| `devcontainer_remove` | Remove a dev container and its resources |\n| `devcontainer_status` | Get dev container state by workspace folder |\n| `devcontainer_file_read` | Read file content with optional line range |\n| `devcontainer_file_write` | Create or overwrite a file (auto-creates parent dirs) |\n| `devcontainer_file_edit` | Surgical string replacement — old_str → new_str |\n| `devcontainer_file_list` | List directory contents (non-hidden, 2 levels deep) |\n\n### GitHub Codespaces (11 tools) — require `auth` handle\n\n| Tool | Description |\n|------|-------------|\n| `codespaces_create` | Create a new codespace for a repository |\n| `codespaces_list` | List your codespaces with state and machine info |\n| `codespaces_ssh` | Execute a command inside a codespace via SSH |\n| `codespaces_stop` | Stop a running codespace |\n| `codespaces_delete` | Delete a codespace |\n| `codespaces_view` | View detailed codespace info (state, machine, config) |\n| `codespaces_ports` | List forwarded ports with visibility and URLs |\n| `codespaces_file_read` | Read file content with optional line range |\n| `codespaces_file_write` | Create or overwrite a file (auto-creates parent dirs) |\n| `codespaces_file_edit` | Surgical string replacement — old_str → new_str |\n| `codespaces_file_list` | List directory contents (non-hidden, 2 levels deep) |\n\n## MCP Server Configuration\n\n### Linux / macOS\n\n```json\n{\n  \"mcpServers\": {\n    \"devcontainer-mcp\": {\n      \"command\": \"devcontainer-mcp\",\n      \"args\": [\"serve\"]\n    }\n  }\n}\n```\n\n### Windows (WSL bridge)\n\n```json\n{\n  \"mcpServers\": {\n    \"devcontainer-mcp\": {\n      \"command\": \"wsl\",\n      \"args\": [\"~/.local/bin/devcontainer-mcp\", \"serve\"]\n    }\n  }\n}\n```\n\n## Prerequisites\n\nInstall backend CLIs as needed — the MCP server detects them at runtime and returns helpful errors if missing:\n\n- **devcontainer CLI**: `npm install -g @devcontainers/cli` + [Docker](https://docs.docker.com/get-docker/)\n- **DevPod**: [DevPod CLI](https://devpod.sh/docs/getting-started/install) + Docker (or another provider)\n- **Codespaces**: [GitHub CLI](https://cli.github.com/) — auth is handled by the `auth_login` tool\n\n## Self-Healing\n\nWhen `devcontainer_up`, `devpod_up`, or `codespaces_create` fails, the full build output (including errors) is returned to the agent. The agent can read the error, fix the `Dockerfile` or `devcontainer.json`, and retry — making the dev environment a **dynamic, agent-managed asset** rather than a static prerequisite.\n\n## Multi-container workspaces\n\nThe devcontainer spec supports [connecting to multiple containers](https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers) in one workspace by placing per-service configs at `.devcontainer/<name>/devcontainer.json`, each pointing at a shared `docker-compose.yml`. `devcontainer-mcp` supports this pattern end-to-end:\n\n- **Discovery** — `devcontainer_list_configs` returns every config it finds (root `.devcontainer.json`, `.devcontainer/devcontainer.json`, and each `.devcontainer/*/devcontainer.json`) with its kind (`image` / `dockerfile` / `compose`), service name, and absolute path.\n- **Targeting** — Every devcontainer tool (`up`, `exec`, `build`, `stop`, `remove`, `status`, `read_config`, `file_*`) accepts an optional `config` parameter pointing at a specific `devcontainer.json`. Single-container workflows continue to work unchanged — `config` defaults to whatever the devcontainer CLI auto-detects.\n- **Ambiguity handling** — When a workspace has multiple configs and no `config` is provided, lookup-style tools (`status`, `exec`, `stop`, `remove`, `file_*`) return a structured `Ambiguous` result listing every matching container so the agent can pick the right one. `status` reports this as `{\"state\":\"Ambiguous\",\"candidates\":[...],\"hint\":\"...\"}`.\n- **Robust container matching** — Sibling compose containers are identified via `com.docker.compose.service` + `com.docker.compose.project.config_files` (not the unreliable `devcontainer.local_folder` label, which is only stamped on the first container).\n\n## Development\n\nThis project eats its own dogfood — development happens inside its own devcontainer.\n\n```bash\n# Using the devcontainer CLI\ndevcontainer up --workspace-folder .\ndevcontainer exec --workspace-folder . cargo build --workspace\ndevcontainer exec --workspace-folder . cargo test --workspace\ndevcontainer exec --workspace-folder . cargo build --release -p devcontainer-mcp\n\n# Or using DevPod\ndevpod up . --id devcontainer-mcp --provider docker --open-ide=false\ndevpod ssh devcontainer-mcp --command \"cd /workspaces/devcontainer-mcp && cargo build --workspace\"\n```\n\n### CI/CD\n\n- **Pull Requests** — `cargo check`, `cargo test`, `cargo clippy`, `cargo fmt` run automatically\n- **Releases** — Creating a GitHub release builds binaries for all 4 platforms\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 13675,
  "sha": "e52d0dbc84bf0a1764c0bfe849d4060e95c2deed274cf140b1a7b5156ea95668",
  "repo_slug": "aniongithub/devcontainer-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_aniongithub_devcontainer_mcp_c10c2490/readme"
}