Skip to main content

🐋 Docker MCP server

An MCP server for managing Docker with natural language!

This is the dboeckli fork of ckreiling/mcp-server-docker. Credit for the original server belongs to Christian Kreiling and the upstream contributors. This fork adds the Buildx tools and related maintenance.

🪩 What can it do?

  • 🚀 Compose containers with natural language
  • 🔍 Introspect & debug running containers
  • 📀 Manage persistent data with Docker volumes

❓ Who is this for?

  • Server administrators: connect to remote Docker engines for e.g. managing a public-facing website.
  • Tinkerers: run containers locally and experiment with open-source apps supporting Docker.
  • AI enthusiasts: push the limits of what an LLM is capable of!
  • Docker sandbox users: expose the host Docker daemon and Buildx to a sandbox through an MCP gateway without mounting the Docker socket.

🍴 What this fork adds

  • Buildx tools: buildx_list, buildx_history, and buildx_logs
  • Clear tool error messages, including Docker and Buildx failures
  • A published container image: ghcr.io/dboeckli/mcp-server-docker
  • A published PyPI package: mcp-server-docker-dboeckli
  • Docker/Buildx integration tests and coverage in CI
  • Automated dependency updates (Dependabot and Renovate)

🧱 Use case: Docker sandbox

This server was originally designed for direct Docker management from an MCP client. It can also serve as the host-side bridge for a Docker sandbox (for example opencode-sandbox-kit):

  • The sandbox keeps its own isolated Docker daemon; the host Docker socket is not mounted into it and port 2375 is not exposed.
  • This server runs on the host and is registered with an MCP gateway (for example the sbx MCP gateway).
  • The sandbox reaches the gateway over MCP and only sees the tools the gateway allows.
  • Read-only tools (list_*, fetch_container_logs, buildx_*) can be allow-listed; write tools should stay behind ask or be denied.
  • The Buildx tools added by this fork are meant for this setup: inspecting builders, build history and build logs from inside the sandbox.

This is not a sandbox boundary by itself: the host-side server still has access to the host Docker daemon. Use the gateway's permission rules and review them.

🏎️ Quickstart

Install

Claude Desktop

On MacOS: ~/Library/Application\ Support/Claude/claude_desktop_config.json

On Windows: %APPDATA%/Claude/claude_desktop_config.json

Install from PyPI with uv (recommended)

The package is published to PyPI as mcp-server-docker-dboeckli. That is fast to start (a wheel download, no clone and no build) and needs no Git.

The PyPI name mcp-server-docker belongs to the upstream project and stops at 0.3.0. It does not contain the Buildx tools of this fork.

If you don't have uv installed, follow the installation instructions for your system: link

Then add the following to your MCP servers file:

"mcpServers": {
  "mcp-server-docker": {
    "command": "uvx",
    "args": [
      "--from",
      "mcp-server-docker-dboeckli==0.7.0",
      "mcp-server-docker"
    ]
  }
}
Install from a GitHub release wheel

Every release attaches the built wheel and sdist. This works without PyPI and without cloning the repository:

uvx --from https://github.com/dboeckli/mcp-server-docker/releases/download/v0.7.0/mcp_server_docker_dboeckli-0.7.0-py3-none-any.whl \
  mcp-server-docker
Install from GitHub source with uv

Pins the Git tag and builds from source on first start. Use this only when you want to run unreleased commits; it needs Git and is slower to start than the PyPI or wheel install.

"mcpServers": {
  "mcp-server-docker": {
    "command": "uvx",
    "args": [
      "--from",
      "git+https://github.com/dboeckli/mcp-server-docker@v0.7.0",
      "mcp-server-docker"
    ]
  }
}
Install with Docker

Purely for convenience, the server can run in a Docker container. A prebuilt image is published to GHCR:

docker run -i --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/dboeckli/mcp-server-docker:0.7.0

Alternatively, build the image locally:

docker build -t mcp-server-docker:0.7.0 .

And then add the following to your MCP servers file:

"mcpServers": {
  "mcp-server-docker": {
    "command": "docker",
    "args": [
      "run",
      "-i",
      "--rm",
      "-v",
      "/var/run/docker.sock:/var/run/docker.sock",
      "ghcr.io/dboeckli/mcp-server-docker:0.7.0"
    ]
  }
}

Note that we mount the Docker socket as a volume; this ensures the MCP server can connect to and control the local Docker daemon. The image does not include the Docker CLI, so the Buildx tools only work when the server runs where the CLI is installed.

📔 Resources

The server exposes resource templates rather than enumerating currently-running containers:

  • docker://containers/{container_id}/logs (text/plain)
  • docker://containers/{container_id}/stats (application/json)

Read either URI with a Docker container ID or name.

🔨 Tools

Containers

  • list_containers
  • create_container
  • run_container
  • recreate_container
  • start_container
  • fetch_container_logs
  • stop_container
  • remove_container
  • container_inspect
  • container_health
  • container_processes
  • container_stats

container_inspect redacts environment values like image_inspect. container_health returns a compact summary instead of the full inspect payload: state, health status with the last health log entry, restart count, exit code, OOMKilled, start/finish timestamps, image and command. It builds a fresh response, so no environment value is included. container_processes is the equivalent of docker top. container_stats returns a one-shot CPU, memory, network and block-IO snapshot (stream=false), so it never blocks a tool call; the docker://containers/{container_id}/stats resource stays available for clients that read resources.

Images

  • list_images
  • pull_image
  • push_image
  • build_image
  • remove_image
  • image_inspect
  • image_history

image_inspect replaces environment values with <redacted>. image_history is not redacted: layer CreatedBy commands can contain secrets baked into the image.

Buildx

  • buildx_list
  • buildx_du
  • buildx_inspect
  • buildx_history
  • buildx_logs

These tools invoke the docker CLI, so the docker binary (with the Buildx plugin) must be available on PATH. The container image built from this repository does not include the Docker CLI, so the Buildx tools are only usable when the server runs where the CLI is installed.

CLI output is decoded as UTF-8 with malformed bytes replaced by � (U+FFFD), independent of the host code page, so build logs with non-UTF-8 bytes cannot crash a tool on Windows.

buildx_logs accepts progress="plain" and progress="rawjson". The tty mode needs a terminal, which a stdio MCP server never has, so the tool rejects it with an explanatory error instead of calling the CLI.

System

  • system_df
  • version
  • system_info

system_df uses the docker CLI and reports the same summary as docker system df, including reclaimable space. Pass verbose=true for the per-image, per-container, per-volume, and build-cache detail.

Events

  • events_list

events_list reports recent Docker events (die, oom, unhealthy, restart loops) for a window that always ends now, so a call can never wait for future events:

  • window_seconds (default 900, clamped to 1..86400) is how far back to look. There is no until parameter on purpose. The window end is rounded up to the next full second, so events from the current second are included.
  • limit (default 100, clamped to 1..1000) keeps the newest events and sets truncated=true when the window holds more.
  • filters accepts type, event, container, image and label, each a list, and maps them to repeated --filter key=value arguments.
  • The CLI call itself is bounded too: if docker events does not return in time, the events collected so far are returned with truncated=true and truncated_reason="timeout" instead of a generic timeout error.

Like the Buildx tools, events_list invokes the docker CLI and needs it on PATH.

Networks

  • list_networks
  • network_inspect
  • create_network
  • remove_network

network_inspect returns the full network attributes, including driver, IPAM configuration and connected containers.

Volumes

  • list_volumes
  • volume_inspect
  • create_volume
  • remove_volume

volume_inspect returns the full volume attributes, including driver, mountpoint, labels and options.

Both inspect tools apply the same environment redaction as container_inspect (<redacted>), so the reading posture stays uniform even if the daemon adds a Config.Env section.

📝 Prompts

🎻 docker_compose

Optional: turns a project name and a container description into a plan+apply loop for containers, volumes, and networks. Reusing an existing project name lets the LLM see the current state, which is useful for cleanup.

This prompt is not required to use the server; the tools work directly without it.

🔒 Read-only mode

Start the server with --read-only, or set MCP_SERVER_DOCKER_READ_ONLY=1, to expose only tools annotated with readOnlyHint=true. Write and destructive tools are not registered at all: they are absent from tools/list and calls to them return Unknown tool.

  • Default: all 36 tools.
  • Read-only: the 22 read-only tools, including all list_*, log, stats, inspect, container_health, events_list, disk-usage, and Buildx inspection tools.
  • The container log/stats resources and the docker_compose prompt remain available.

Example with uvx:

"args": [
  "--from",
  "git+https://github.com/dboeckli/mcp-server-docker@v0.7.0",
  "mcp-server-docker",
  "--read-only"
]

Or with the environment variable:

"env": {
  "MCP_SERVER_DOCKER_READ_ONLY": "1"
}

For the sbx MCP gateway, append --read-only to the comma-separated --args list, e.g. sbx mcp add docker --args "--from,...,mcp-server-docker,--read-only".

Read-only mode is a best-effort guardrail, not a sandbox boundary. The process still has host Docker access; keep gateway policy and sandbox isolation in place.

🚧 Disclaimers

Sensitive Data

DO NOT CONFIGURE CONTAINERS WITH SENSITIVE DATA. This includes API keys, database passwords, etc.

Any sensitive data exchanged with the LLM is inherently compromised, unless the LLM is running on your local machine.

If you are interested in securely passing secrets to containers, file an issue on this repository with your use-case.

Reviewing Created Containers

Be careful to review the containers that the LLM creates. Docker is not a secure sandbox, and therefore the MCP server can potentially impact the host machine through Docker.

For safety reasons, this MCP server doesn't support sensitive Docker options like --privileged or --cap-add/--cap-drop. If these features are of interest to you, file an issue on this repository with your use-case.

🛠️ Configuration

This server uses the Python Docker SDK's from_env method. For configuration details, see the documentation.

Connect to Docker over SSH

This MCP server can connect to a remote Docker daemon over SSH.

Simply set a ssh:// host URL in the MCP server definition:

"mcpServers": {
  "mcp-server-docker": {
    "command": "uvx",
    "args": [
      "--from",
      "git+https://github.com/dboeckli/mcp-server-docker@v0.7.0",
      "mcp-server-docker"
    ],
    "env": {
      "DOCKER_HOST": "ssh://myusername@myhost.example.com"
    }
  }
}

💻 Development

Prefer using Devbox to configure your development environment. The server uses MCP Python SDK v2's high-level MCPServer API and can be inspected directly:

uv sync --all-groups
uv run mcp dev src/mcp_server_docker/server.py:app
# or: npx @modelcontextprotocol/inspector uv run mcp-server-docker

Run the hermetic test and lint suite without a Docker daemon:

uv run pytest
uv run pytest --cov=mcp_server_docker --cov-report=term-missing
uv run ruff format --check src tests
uv run ruff check src tests

Run the Docker integration tests (requires Docker and Buildx):

uv run pytest -o addopts= -m integration

See the devbox.json for helpful development commands.

After setting up devbox you can configure your Claude MCP config to use it:

{
  "mcpServers": {
    "docker": {
      "command": "/path/to/repo/.devbox/nix/profile/default/bin/uv",
      "args": [
        "--directory",
        "/path/to/repo/",
        "run",
        "mcp-server-docker"
      ]
    }
  }
}

Metadata

Release files for mcp-server-docker-dboeckli 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-server-docker-dboeckli 0.7.0
File Size Uploaded Provenance Actions
mcp_server_docker_dboeckli-0.7.0.tar.gz 140.1 kB With provenance Details for mcp_server_docker_dboeckli-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mcp-server-docker-dboeckli 0.7.0
File Interpreter ABI Platform Actions
mcp_server_docker_dboeckli-0.7.0-py3-none-any.whl Python 3 none any Details for mcp_server_docker_dboeckli-0.7.0-py3-none-any.whl

Total release size: 182.7 kB

Release files / mcp_server_docker_dboeckli-0.7.0.tar.gz

Download URL mcp_server_docker_dboeckli-0.7.0.tar.gz
Size 140.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0d3186f1515b5f71ec815d2a59f78c441d8e0b5bf9498953cb0a59ac15f5c8b8
BLAKE2b-256 checksum
How to use checksums
bce824a23808d69cc8bf4728d9520b7f155041f0166111af8b4ccd6e07a47395
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

Release files / mcp_server_docker_dboeckli-0.7.0-py3-none-any.whl

Download URL mcp_server_docker_dboeckli-0.7.0-py3-none-any.whl
Size 42.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
687551413041e91943e90a8b17fd1d4340b3f39ec8b28d9c233a37c06515057e
BLAKE2b-256 checksum
How to use checksums
890b88b66b1987e3309e74c9323e6b64abd812a6c4581ea27a766ce51a21b4b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

Security for mcp-server-docker-dboeckli 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mcp_server_docker_dboeckli-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page