docker-mcp
Allows pulling Docker images and creating Docker containers via the Docker Engine API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@docker-mcppull nginx:latest and create a container named web with port 80"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
docker-mcp
An MCP (Model Context Protocol) server that creates Docker containers by
talking directly to the Docker Engine API over /var/run/docker.sock.
Why this exists
It's the sibling project to unraid-mcp, which wraps
Unraid's official GraphQL API. That API has no container-creation mutation —
Unraid's own "Add Container" feature is a separate webGUI/dockerMan
subsystem, not part of the official API. docker-mcp fills that one gap by
talking to the Docker Engine directly, using the official docker Python SDK
(never shelling out to docker run — every parameter is a typed field in a
structured API payload, not a shell string).
It is deliberately not a fork or subfolder of unraid-mcp, and
deliberately narrow in scope: exactly two tools, pull_image and
create_container. Once a container exists — regardless of how it was
created — unraid-mcp's existing docker/start, stop, remove_container,
etc. already manage it by ID against the same Docker daemon. This project
does not duplicate that lifecycle surface.
Related MCP server: Docker MCP Server
Why a separate server instead of adding this to unraid-mcp
Controlling the Docker Engine is root-equivalent access to the host. Bolting
that onto unraid-mcp (which is a large, LLM-driven tool surface across 19
domains) would mean every one of those 178 operations shares a blast radius
with "can create arbitrary containers." Splitting it out means only this
small, narrowly-scoped server gets the Docker socket mount — unraid-mcp
stays exactly as sensitive as its GraphQL API and nothing more.
Security posture — read this
privilegedand host PID-namespace sharing are not supported at all — there is no parameter for them anywhere, on any code path.network="host"and bind-mounting the Docker socket, host root (/),/etc,/proc,/sys,/var/lib/docker,/root, or/bootare rejected before any Docker Engine call is made (seedocker_mcp/core/validation.py).This validation is a guardrail against mistakes, not a security boundary. Anyone who can call
create_containeralready has root-equivalent control of the host via the Docker Engine — the same daemon would happily do any of the above if asked directly with the Docker CLI. Don't expose this server to anyone/anything you wouldn't hand a root shell.create_containerrequiresconfirm=True(or interactive elicitation) — same pattern asunraid-mcp's destructive-action gating.HTTP transport requires a bearer token by default (auto-generated into
~/.docker-mcp/.envon first startup) and refuses to bind an unauthenticated endpoint to a non-loopback address unless you explicitly setDOCKER_MCP_TRUST_PROXY=truebehind a gateway that enforces auth itself.The
entrypoint.shdocker.sock GID-matching trick (joining a group that matches the socket's GID instead of running fully as root) is best-effort hardening that mostly helps on Debian-styleroot:dockerhosts. On Unraid the socket is commonlyroot:root, in which case there's no non-root group to join and the entrypoint falls back to running as root with a printed warning — Docker Engine access is root-equivalent either way, so this is not pretending to be a real isolation boundary.
Tools
pull_image(image, tag="latest", platform=None)
Pulls an image onto the Docker host. Not gated — download-only, no host mutation.
create_container(image, name=None, environment=None, ports=None, volumes=None, network=None, restart_policy=None, labels=None, command=None, working_dir=None, cap_add=None, mem_limit=None, start=True, confirm=False)
Creates (and by default starts) a container. Requires the image to already
be present locally — call pull_image first if needed.
create_container(
image="lscr.io/linuxserver/plex:latest",
name="plex",
environment={"PUID": "1000", "PGID": "1000", "TZ": "America/New_York"},
ports={"32400/tcp": 32400},
volumes={"/mnt/user/appdata/plex": {"bind": "/config", "mode": "rw"},
"/mnt/user/media": {"bind": "/media", "mode": "ro"}},
restart_policy={"Name": "unless-stopped"},
confirm=True,
)Running it
cp .env.example ~/.docker-mcp/.env # edit as needed
docker compose up -ddocker-compose.yaml pulls the prebuilt image from
ghcr.io/zshureih/docker-mcp, published by .github/workflows/docker-publish.yml
on every push to main. To build locally instead (e.g. while developing),
replace the image: line with build: ..
The bearer token is auto-generated into ~/.docker-mcp/.env on first HTTP
startup if not already set — check the container logs for it.
Making it reachable from other devices on your LAN
By default the published port is bound to 127.0.0.1 on the Docker host —
nothing else on your network can reach it, even with the token. To expose it
to other LAN devices, set DOCKER_MCP_BIND_HOST in a project-root .env
file (Docker Compose's own dotenv mechanism, which it reads when parsing
docker-compose.yaml — this is a different file from
~/.docker-mcp/.env, which is the app's own credentials file loaded inside
the container and has no effect on Compose's port-mapping substitution):
echo "DOCKER_MCP_BIND_HOST=192.168.0.174" >> .env # your Unraid host's LAN IP
docker compose up -dKeep bearer-token auth enabled (DOCKER_MCP_DISABLE_HTTP_AUTH=false, the
default) when doing this — otherwise every device on your LAN could create
and control containers on your Unraid box with no authentication at all.
Only set DOCKER_MCP_DISABLE_HTTP_AUTH=true if a reverse proxy genuinely
sits in front of this port and enforces auth itself (in which case also set
DOCKER_MCP_TRUST_PROXY=true); the server refuses to start otherwise once
it detects a non-loopback bind with auth disabled.
Development
uv sync --group dev
uv run pytest
uv run ruff check docker_mcp/
uv run ty check docker_mcp/This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/zshureih/docker-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server