关于 Docker MCP Server
Docker MCP Server 为 AI Agent 提供管理和监控本地或远程 Docker 守护进程的类型化工具,并通过只读与破坏性操作限制、输出截断及日志和统计资源辅助控制。
主要功能
- 01管理容器、镜像、网络和卷
- 02管理 Swarm 服务等 Docker 域
- 03标记只读及破坏性操作
- 04通过全局模式限制写入
- 05以资源形式读取日志和统计
适用场景
- 01排查容器故障和资源使用情况
- 02管理本地及远程 Docker 环境
- 03比较测试与生产守护进程状态
MCP 相关
这是一个 MCP 服务,向 MCP 客户端提供类型化的 Docker 操作工具,以及日志、统计、SDK 文档和实时工具目录。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
162收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| annotations | array | 否 | |
| attest | array | 否 | |
| build_args | object | 否 | |
| build_contexts | object | 否 | |
| builder | string | 否 | |
| cache_from | array | 否 | |
| cache_to | array | 否 | |
| context | string | 是 | |
| file | string | 否 | |
| labels | object | 否 | |
| load | boolean | 否 | |
| no_cache | boolean | 否 | |
| no_cache_filter | array | 否 | |
| output | array | 否 | |
| platforms | array | 否 | |
| provenance | string | 否 | |
| pull | boolean | 否 | |
| push | boolean | 否 | |
| sbom | string | 否 | |
| secret | array | 否 | |
| ssh | array | 否 | |
| tags | array | 否 | |
| target | string | 否 | |
| timeout_seconds | number | 否 |
详细介绍
docker-mcp-server
它不仅仅是一个功能齐全的 MCP 服务,可让 AI Agent 管理 Docker(容器、镜像、网络、卷、swarm 服务、密钥、配置、节点、插件等),还可以帮助你创建工作流,轻松管理 Docker 环境。
它比直接调用 Docker CLI 提供更强的控制力和灵活性:每项操作都作为独立的类型化工具提供,并标明是否为只读操作,同时单独标记具有破坏性的操作。这意味着客户端可以自动批准读取操作,同时始终要求确认任何破坏性操作;整个服务也可以切换为只读或禁止破坏性操作模式,作为全面的安全防护。输出长度受到限制,不会无限增长——达到上限时会设置 truncated 标志,而不是悄然超出 Agent 的上下文容量。
对于简单场景,你只需安装即可使用,无需任何配置——加载后,它会自动发现本地 Docker 套接字,并向 AI Agent 提供完整的命令接口。对于高级用户,它可以管理多个 Docker 守护进程,例如在同一会话中同时管理本地开发环境和通过 TCP、TLS 或 SSH 连接的远程生产环境。你还可以将某些守护进程设为只读,从而监控它们而无需担心意外更改。
它甚至可以在未安装 Docker 的机器上运行,并通过 SSH、TLS 或 TCP 管理远程守护进程(某些功能需要 SSH)。AI 本身无需 shell 或 SSH 访问权限。
MCP 服务还会将日志和统计信息等内容作为资源提供,便于监控和排查问题,让你能够解答问题,例如“我的容器为什么崩溃了?”、“我的 swarm 状态如何?”、“我是否遇到了内存压力?”、“我的卷占用了多少磁盘空间?”、“我的测试环境和生产环境有哪些差异?”,等等……
文档是为 Agent 编写的,而不仅仅是为配置服务的人准备的:MCP 资源会在会话中提供 Docker SDK 参考文档(对于无法读取资源的客户端,也提供可通过工具调用的备用方式),实时工具目录资源则会准确报告当前配置下已注册的工具。每个工具的说明都会列出最相近的同类工具以及各自的适用场景,用通俗的语言说明前置条件和副作用,并如实说明可能导致失败的情况——因此,Agent 可以从 150 多种选项中一次就选对工具,而不必猜测。
docker-mcp-server 已针对支持延迟加载工具的新一代 MCP 客户端进行了优化。对于仍会立即加载所有工具的客户端,可以选择配置服务,排除部分领域中的工具(例如排除 swarm 和 scout 工具),以缩减工具列表。还可以将 MCP 服务设为“只读”或“禁止破坏性操作”模式,使任何具有写入或破坏性能力的工具都不会被注册,从而进一步减小占用。
此服务完全在你的机器上运行,可以选择原生运行、作为 mcpb bundle、作为 Claude 插件,或容器化运行,并且不会发送任何遥测数据。你完全掌控一切——请参阅隐私政策。
要求
注意:如果使用容器化的 MCP 服务或 MCPB 捆绑包,Python 和 uv 的要求已为你处理好。
- 运行中的 Docker 守护进程,可供运行服务的主机访问(遵循标准的
DOCKER_HOST/ Unix 套接字约定) - Python ≥ 3.14
- 用于依赖管理的 uv
- 仅限 Intel (x86_64) macOS: 原生安装(通过
uvx/pip、Claude 插件或.mcpb捆绑包;这些方式都会在本地解析依赖)需要 Rust 和 OpenSSL 3.x,因为cryptography(通过mcp->pyjwt[crypto]引入的传递依赖)自版本 49.0.0 起不再提供 x86_64 macOS wheel,因此必须在此平台上从源代码构建。如果不想安装构建工具链,可以改用容器镜像——它会运行相同的预构建 Linux 二进制文件,不受 Mac CPU 架构影响,因此不受此要求限制。更多信息请参阅安全注意事项。
使用服务
该服务已发布到 PyPI,名称为 docker-mcp-server。在 AI 工具的 MCP 配置中(通常是 mcp.json 或客户端中的等效配置)添加一条指向它的条目,让 uvx 运行它——uv 会在首次使用时获取并缓存该软件包:
{
"mcpServers": {
"docker-mcp-server": {
"command": "uvx",
"args": ["docker-mcp-server"],
"env": {}
}
}
}
若要固定特定版本,请在软件包名称后附加 ==<version>(例如 docker-mcp-server==1.5.0)。若想将其安装到 PATH,运行 pipx install docker-mcp-server 即可获得 docker-mcp-server 控制台脚本(同时也会安装 docker-mcp 别名)。
改为从 git 安装。 若要直接运行此仓库中的未发布修订版本:
{
"mcpServers": {
"docker-mcp-server": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/L337-org/docker-mcp.git",
"docker-mcp-server"
],
"env": {}
}
}
}
若要固定特定修订版本,请在 git URL 后附加 @<tag-or-commit>。
安装为桌面扩展(.mcpb)
对于 Claude Desktop,每个 GitHub Release 都附有一键安装捆绑包 docker-mcp-server-<version>.mcpb(以及匹配的 .sha256 文件)。下载后将其拖入设置 > 扩展,或使用设置 > 扩展 > 高级设置 > 安装扩展...并选择该文件。安装对话框会显示Docker 主机字段,以及只读/禁止破坏性操作/禁用域名开关,无需手动编辑 JSON。
这是一个 uv 类型捆绑包:Claude Desktop 托管的 uv 会解析依赖并运行服务,因此主机只需具备 Docker,无需单独安装 Python、uv 或 git。将Docker 主机字段留空即可使用默认 Docker context;设置一个端点(ssh://user@host)以连接远程守护进程,或列出多个端点(参见管理多个守护进程)。
安装为 Claude 插件
claude-plugin/ 文件夹将此服务打包为 Claude Code 和 Cowork 的插件,供 Anthropic 插件目录使用。它会运行 uvx docker-mcp-server==<version>,并固定到构建该插件时使用的发布版本,因此主机上需要安装 uv。它附带一个锁文件,按哈希固定所有依赖;该目录说明其锁定启动方式会精确安装这些依赖。通过其他方式加载时,uvx 会在安装时解析依赖。它提供与 .mcpb 安装对话框相同的设置(Docker 主机、只读、禁止破坏性操作和禁用域名),可在 Claude Code 的插件设置(/plugin)中配置。发布流水线只有在版本发布到 PyPI,且插件已从 PyPI 安装并测试后,才会更新该目录提供的插件。
作为容器运行
以容器方式运行服务,即可完全免除 Python / uv / git 前置条件——主机只需要 Docker,而你已经安装了。每次发布时都会在 Docker Hub(gavinlucas/docker-mcp-server)和 GHCR(ghcr.io/l337-org/docker-mcp-server)发布预构建的多架构镜像(linux/amd64 + linux/arm64)——两者完全相同。将 MCP 客户端指向 docker run:
{
"mcpServers": {
"docker-mcp-server": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"gavinlucas/docker-mcp-server:latest"
],
"env": {}
}
}
}
-i 是必需的(服务通过 stdio 使用 MCP 通信);客户端断开连接时,--rm 会清理容器。要固定版本,请将 :latest 替换为发布标签(例如 :1.5.1)。要改为从 GHCR 拉取,请使用 ghcr.io/l337-org/docker-mcp-server:latest。
镜像已重命名。 自 1.5.0 起,镜像以
docker-mcp-server发布(与 PyPI 名称一致)。旧版ghcr.io/gavinlucas/docker-mcp镜像停留在 1.4.0,不再更新——后续拉取请使用ghcr.io/l337-org/docker-mcp-server。
镜像变体。 两种变体均在两个注册表(Docker Hub 上的 gavinlucas/docker-mcp-server 和 GHCR 上的 ghcr.io/l337-org/docker-mcp-server)发布,且都由同一个 Dockerfile 构建。基于 CLI 的领域(Compose、Stack、Buildx、Scout、Context)会调用 docker CLI 及其插件;在 Stack 中,只有 stack_deploy 会这样做。
| 变体 | 标签 | 约略大小 | 包含内容 |
|---|---|---|---|
full (默认) | :latest、:<version> | ~510 MB | docker CLI + compose + buildx + scout |
no-scout | :no-scout、:<version>-no-scout | ~315 MB | docker CLI + compose + buildx |
Scout 的插件二进制文件本身就使 full 比 no-scout 大约多出 ~195 MB。no-scout 镜像还会将 DOCKER_MCP_SERVER_DISABLE=scout 设为默认值,因此不会注册 scout 工具——Agent 不会收到其 CLI 插件缺失的工具(它看到的是更精简、完全可用的工具列表,而不是每次调用都会报错的 scout 工具)。如需更改禁用项,可在运行时通过 -e DOCKER_MCP_SERVER_DISABLE=... 覆盖(注意,这会替换而不是追加)。
自行构建。 所有变体都通过构建参数使用仓库的 Dockerfile 构建:
docker build -t docker-mcp-server:full . # full (default)
docker build --build-arg INSTALL_SCOUT=0 --build-arg DISABLE_DOMAINS=scout \
-t docker-mcp-server:no-scout . # no-scout
docker build --build-arg INSTALL_CLI=0 -t docker-mcp-server:lite . # lite (SDK-only, ~165 MB)
lite 镜像(仅含 docker-py SDK 工具——Compose/Buildx/Scout/Context 会降级为“插件不可用”)可以构建,但不会发布。
从容器内部连接守护进程。 镜像默认将 DOCKER_HOST 设为 unix:///var/run/docker.sock,因此只需将主机的套接字挂载到该路径即可。不过,主机套接字的位置各不相同——如果启动时无法连接,服务会在 stderr 中打印适用于当前平台的提示:
- Linux:
-v /var/run/docker.sock:/var/run/docker.sock(无根模式:-v $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock)。 - macOS(Docker Desktop): 实际套接字通常位于
~/.docker/run/docker.sock——将其挂载到容器内的路径:-v $HOME/.docker/run/docker.sock:/var/run/docker.sock(或者启用 Settings > Advanced > Allow the default Docker socket,并使用/var/run/docker.sock)。 - Windows(Docker Desktop / WSL2): 引擎使用命名管道,而非 Unix 套接字——建议使用
-e DOCKER_HOST=tcp://host.docker.internal:2375(在 Docker Desktop 中启用 TCP 端点)。该端点未经身份验证且未加密——请确保其仅绑定到本地主机,不使用时将其禁用;对于任何远程守护进程,请使用 TLS 或DOCKER_HOST=ssh://...。 - 远程 / TLS / SSH 守护进程: 跳过套接字挂载,改为传入
-e DOCKER_HOST=...(以及下方的 TLS 变量)——请参阅连接远程守护进程。 访问宿主机文件系统。 在容器内,文件路径工具(image_save/container_export中的dest_path、image_load/container_archive_put中的from_file、container_archive_get_to_file, 以及 compose 的project_dir/files)解析的路径位于容器内, 而非宿主机上。请绑定挂载要用于交换文件的目录——使用内外相同的 路径,可使宿主机和容器中的路径保持一致:
-v $HOME/docker-work:$HOME/docker-work
如果使用这些工具之一时指定的路径不在绑定挂载中,服务会立即拒绝操作,并告知你需要添加哪个 -v——否则,写入未映射路径的内容会在容器退出时被静默丢弃。(上限为 32 MiB 的带内字节工具无需挂载。)配置环境变量(DOCKER_MCP_SERVER_READONLY、DOCKER_HOST 等)应像 uvx 安装时一样,放在客户端的 env
块中。
连接远程守护进程
设置 DOCKER_HOST 后,服务会直接使用它(通过 docker.from_env(),因此也会遵循 DOCKER_TLS_VERIFY / DOCKER_CERT_PATH)。通过 env 设置常见覆盖项:
"env": {
"DOCKER_HOST": "tcp://remote-host:2375",
"DOCKER_TLS_VERIFY": "1",
"DOCKER_CERT_PATH": "/path/to/certs"
}
默认守护进程(未设置 DOCKER_HOST)。 未设置 DOCKER_HOST 时,服务会像 docker CLI 一样解析守护进程,而不是假定其位于 /var/run/docker.sock:它会遵循当前启用的 Docker 上下文(DOCKER_CONTEXT,否则读取 ~/.docker/config.json 中的 currentContext,并从该上下文的 meta.json 中读取端点);如果没有解析到端点,则会探测常见的套接字位置(Docker Desktop 4.13+ 的 ~/.docker/run/docker.sock、无根模式的 $XDG_RUNTIME_DIR/docker.sock,然后是 /var/run/docker.sock)。这很重要,因为单独使用 docker.from_env() 会忽略上下文并回退到 /var/run/docker.sock——而 Docker Desktop 4.13+ 默认不再创建该套接字(它使用 desktop-linux 上下文,除非你启用 Settings > Advanced > Allow the default Docker socket),因此,通过 CLI 可访问的标准 Desktop 安装在此处会失败。优先级如下:非空的 DOCKER_HOST 始终优先,并直接交由 docker.from_env() 处理(该函数会忽略上下文);仅当未设置 DOCKER_HOST 时才会查询 DOCKER_CONTEXT / currentContext;只有两者都未解析到端点时才会探测套接字。远程上下文附带的 TLS 材料不会自动应用——tcp:// + TLS 上下文仍需设置 DOCKER_HOST / DOCKER_CERT_PATH。
通过 SSH
通过纯 Python 传输方式支持 DOCKER_HOST=ssh://user@remote-host(paramiko 由 docker[ssh] 依赖引入)——不需要系统级的 ssh 二进制文件,因此在主机上安装和在容器镜像中运行时效果相同。它使用你常规的 SSH 配置进行身份验证:
- 密钥/代理。 使用基于密钥的身份验证;将密钥加载到代理中(
ssh-add),并确保服务器环境中已设置SSH_AUTH_SOCK(或将密钥放在默认的~/.ssh/id_*路径下)。 - 已知主机。
paramiko会根据~/.ssh/known_hosts验证主机密钥,并拒绝未知主机。只有在通过可信渠道验证主机密钥指纹后,才添加该密钥——可以先用ssh user@remote-host进行一次交互式连接并确认提示,也可以将ssh-keyscan remote-host | ssh-keygen -lf -的结果与可信指纹进行比对后再追加。避免直接将ssh-keyscan的输出管道传入known_hosts,因为这会信任返回的任何密钥(包括中间人攻击者提供的密钥)。 - 在容器中。 以只读方式挂载 SSH 文件——
-v $HOME/.ssh:/root/.ssh:ro(密钥 +known_hosts)——或转发代理套接字;无需挂载套接字,也无需安装ssh软件包。
由 CLI 驱动的工具(Compose、Stack、Buildx、Scout、Context)会调用 docker CLI,而在 ssh:// 端点上,这通常会使用系统级 ssh 二进制文件。为避免这种情况,run_docker() 会检测 DOCKER_HOST=ssh://...,并透明地启动一个仅供单次调用使用的本地 TCP 代理(docker_mcp/tools/_ssh_proxy.py);该代理会打开与 docker-py 相同的 paramiko 连接,通过此连接运行 docker system dial-stdio,并在这次调用期间将 CLI 子进程指向 tcp://127.0.0.1:<ephemeral port>。因此,由 CLI 驱动的工具会使用与上述由 docker-py 驱动的工具完全相同的凭据和主机密钥策略进行身份验证——直接连接无需系统级的 ssh 二进制文件,在主机上安装和在容器镜像中运行时效果也完全相同。唯一例外是 ~/.ssh/config 中的 ProxyCommand(堡垒机/跳板机场景):paramiko 会按原样执行该命令,而该命令通常是 ssh -W %h:%p ...,因此跳板机连接仍会调用系统的 ssh 客户端,尽管直接连接不会。
这个临时的 127.0.0.1 监听器会在单次 CLI 调用期间,使用你的 SSH 凭据连接到远程(等同于 root 权限的)守护进程,因此在这段短暂的时间内,任何共享同一环回接口的进程都可以访问它。暴露范围有限——仅限本地主机,调用返回后即会关闭——而在容器中范围更小,只能由该容器网络命名空间内的进程访问。无论哪种情况,信任边界仍然是守护进程(请参阅安全注意事项)。
未安装本地 Docker
如果本地未安装 Docker,或者缺少调用所需的插件,大多数工具仍会像以前一样在远程主机上运行。少数工具系列(Compose、Buildx、Scout 和 stack_deploy)会通过 SSH 直接在目标主机上运行。如果本地未安装 Docker,这些命令无法通过 TCP 和 TLS 连接运行。
值得注意:
- 这是备用方案,而非首选方案。 只要本地 CLI 能处理该调用——包括二进制文件和调用所需的插件——就始终会使用本地 CLI,因此正常安装不会有任何变化。
- 命令读取的本地文件会先复制到远程主机——包括 Compose 项目目录、bake 文件和构建上下文(遵循
.dockerignore)——放入私有的0700临时目录中,并在调用返回时删除。但这只是尽力而为,因为 SSH 连接中断后,便无人能执行清理。未清理的目录名为docker-mcp-server.stage.*,并会记录相关故障。 - 使用远程主机的凭据。 注册表登录信息来自远程主机的
~/.docker/config.json,因此,访问私有注册表的compose_pull、stack deploy --with-registry-auth或大多数 Scout 操作可能需要先在远程主机上运行docker login。system_login会与守护进程通信,不会写入远程 CLI 的配置。 - 整个工作目录都会被复制,因为无法确定 Compose 文件引用了哪些文件(
build:、env_file:、include:都可以指向任意路径)。请将工具指向项目目录,而不是较大的父目录;否则调用会因大小限制而被拒绝(200 MiB / 50 000 个条目)。 compose_cp会通过同一 SSH 连接中转位于本地一侧的复制对象:主机上的源文件会像其他输入一样先暂存到远程主机;容器中的结果则会在复制成功后取回真实目标位置。实际复制仍会通过远程主机上的真实docker compose cp执行,因此所有参数的行为与本地执行时相同。唯一的区别是:如果本地目标已存在,容器到主机的复制会被拒绝,因为只有本地主机知道这一点。- 少数情况会直接拒绝执行,而不会只完成一部分:对于
buildx_build,如果output/cache_to中包含文件系统dest=、cache_from中包含本地src=,或包含任何ssh=,调用都会被拒绝——这些内容会在远程机器上解析。 - 远程主机必须提供 POSIX shell。 任何 Linux/macOS/BSD 主机都符合要求,在 WSL 发行版内运行的 sshd 也受支持(它是 Linux 目标主机;并且使用 Docker Desktop 的 WSL2 后端时,守护进程本来就在其中)。如果 sshd 运行在 Windows 侧的
cmd/PowerShell 中,则会附带说明性错误并拒绝执行;来自 MSYS/MinGW/Cygwin 的uname也会被拒绝。Windows 方言虽已纳入架构设计,但尚未实现。若 Windows sshd 的 shell 是wsl.exe,命令会在 WSL 中运行,但其 SFTP 子系统仍在 Windows 侧运行,因此文件复制工具会被拒绝;仅运行命令的工具仍可使用。 context_*工具绝不会回退到远程执行。 它们管理的是此主机的 CLI 上下文注册表,远程主机对此一无所知。
管理多个守护进程
以上内容都针对单个守护进程。要在单个会话中管理多个守护进程——例如本地开发环境和远程生产环境——请将 DOCKER_MCP_SERVER_HOSTS 设置为以逗号分隔的 name=endpoint 列表:
"env": {
"DOCKER_MCP_SERVER_HOSTS": "local=auto, prod=ssh://[email protected](ro)"
}
endpoint可以是auto(如上文所述,使用默认上下文/套接字)、local(使用平台本地套接字,忽略上下文),也可以是unix://、tcp://、ssh://或npipe://URL。推荐使用ssh://作为远程传输方式(每台主机通过 SSH 密钥进行身份验证,无需配置 TLS 证书)。通过 TLS 连接的tcp://守护进程需要使用(tls=<dir>)标记指定证书目录,例如prod=tcp://prod:2376(tls=/etc/docker/prod)。该目录必须包含ca.pem(始终使用它验证守护进程,因此自签名守护进程也能正常工作,只需在此固定其证书);仅当守护进程要求客户端证书(双向 TLS)时,才添加cert.pem和key.pem。不支持未经验证的 TLS 模式——TLS 连接始终会对守护进程进行身份验证,因此加密始终伴随验证。- 在端点后添加
(ro)可将该主机标记为只读:更改类和破坏性工具会拒绝对其执行操作。这项逐主机保护在调用时强制执行,独立于服务器级DOCKER_MCP_SERVER_READONLY开关——将生产环境标记为(ro)后,Agent 可以随时检查它,但无法更改它,而本地环境仍可读写。 (nd)会将主机标记为非破坏性:只有破坏性工具(删除、清理、终止)会拒绝对其执行操作——读取和常规更改(启动/停止/创建)仍可执行。这与服务器级DOCKER_MCP_SERVER_NO_DESTRUCTIVE开关作用相同,但按主机生效。(ro)已包含此限制,因此(ro)(nd)可以组合使用,不会报错,但属于冗余设置。- 单个守护进程的简写。 不含
name=的纯值表示单个主机——DOCKER_MCP_SERVER_HOSTS=ssh://ops@prod(也可以是auto或留空)。因此,这个字段也适用于单个远程主机的情况。未设置DOCKER_MCP_SERVER_HOSTS时,DOCKER_HOST仍然有效;但设置DOCKER_MCP_SERVER_HOSTS后,它将接管配置(此时会忽略DOCKER_HOST,并向 stderr 输出一次提示)。
Agent 如何使用它。 配置两个或更多主机后,每个面向守护进程的工具都会增加可选的 host 参数,其值限定为已配置的名称:省略该参数时,只读工具默认使用第一个主机,而更改类和破坏性工具则必须显式指定 host(以免 Agent 意外更改错误的守护进程)。host_list(以及 docker-mcp://hosts 资源)会报告已配置的主机及默认主机;容器/服务可观测性资源也会支持指定主机——默认主机的日志尾流 URI 为 docker-logs:///{id}(注意 authority 为空),命名主机的 URI 为 docker-logs://{host}/{id};docker-stats://、service-logs:// 和 service-tasks:// 也遵循相同模式;配置多个主机后,不再注册单主机的简写形式(docker-logs://{id} 等)。survey_hosts 提示词会以只读方式遍历所有主机。auto/local 端点会解析为具体 URL,并在启动时固定,因此 SDK 和 CLI 始终会将名称解析到同一个守护进程——更改 Docker 上下文后,请重启以重新解析。
Agent 可以做什么
加载后,Agent 会获得按 Docker 领域分组的 MCP 工具。以下是几个示例:
- 容器 -
container_run、container_list(设置managed_only=True只列出由此服务创建的容器 - 请参阅来源标签)、container_exec、container_logs、container_stop、container_commit、container_export/container_archive_get_to_file/container_archive_put(在主机路径与容器之间流式传输 tar 归档) - 镜像 -
image_build、image_pull、image_push、image_tag、image_prune(设置build_cache=True,也会清理守护进程的构建缓存 - 这是独立于悬空镜像的资源)、image_save/image_load(通过dest_path/from_file在主机路径与镜像之间流式传输镜像 tar 包)、image_import(从扁平 rootfs tar 包、URL 或现有镜像构建单层镜像 - 即docker import,不要与image_load混淆) - 插件 -
plugin_install(从注册表拉取;安装前设置dry_run=True可查看插件要求的主机访问权限 ,守护进程会以非交互方式授予这些权限)、plugin_enable/plugin_disable、plugin_configure、plugin_upgrade(同样支持dry_run)、plugin_list/plugin_inspect、plugin_remove(管理引擎插件 - 卷、网络、日志驱动程序 - 而非用于扩展docker命令本身的 CLI 插件) - 网络 / 卷 -
network_create、network_connect、volume_create、volume_prune - Swarm -
swarm_init、swarm_join_tokens(完成从初始化到加入集群的流程)、swarm_update(轮换加入令牌 / 解锁密钥)、service_create、service_scale、service_rollback(重新应用上一个服务规范)、service_ps(查看单个服务的任务;不指定服务则查看集群中的所有任务,可按节点或期望状态筛选 - 没有任何单条 CLI 命令能做到这一点)、service_logs(查看服务的日志,或单个任务的日志)、node_list、node_remove、secret_create、config_create - 系统 -
system_wait(统一的等待工具:等待容器退出、变为健康状态或输出某行日志;等待服务或堆栈收敛、堆栈移除、节点就绪、Compose 项目运行、变为健康状态或退出,或等待标签推送到注册表 - 每次等待都有超时,默认 600 s;超时会返回结果而非抛出异常)、system_ping、system_info、system_version、system_df、system_events、host_list(列出已配置的守护进程以及默认守护进程 - 请参阅管理多个守护进程)、system_login/system_logout(缓存或清除注册表凭据)、system_reconnect(重建主机的 SDK 客户端,以恢复卡住的连接) - Compose -
compose_up、compose_down、compose_stop、compose_start、compose_restart、compose_pause/compose_unpause、compose_kill、compose_ps、compose_list、compose_images、compose_top、compose_port、compose_logs、compose_config、compose_build、compose_pull、compose_run、compose_exec、compose_cp(封装docker composeCLI 插件) - 堆栈 -
stack_deploy、stack_list、stack_ps、stack_services、stack_remove(将 Compose 文件部署到 Swarm 中作为堆栈 -stack_deploy封装docker stack deploy,该命令会转换 Compose 文件;其余工具使用 Engine API - 需要 Swarm 管理器) - 上下文 -
context_list、context_inspect、context_create、context_use、context_remove(封装docker contextCLI) - 注册表 / Hub -
registry_tags、registry_manifest、registry_image_config(读取镜像的 env / entrypoint / labels,无需拉取镜像)、hub_tags、hub_repo_info、hub_rate_limit(剩余拉取额度)(通过 HTTPS 访问 OCI v2 注册表和 Docker Hub API - 无需守护进程;遇到短暂的 429 错误时会自动重试) - Buildx -
buildx_build、buildx_bake、buildx_imagetools_inspect、buildx_imagetools_create、buildx_list、buildx_inspect、buildx_du、buildx_history_list/buildx_history_inspect(深入查看过去的构建记录)、buildx_prune、buildx_create、buildx_use、buildx_remove(封装docker buildxCLI 插件)。请使用buildx_imagetools_*代替docker manifest- 后者处于维护模式,且不支持 OCI 镜像索引和证明。 - Scout -
scout_cves、scout_quickview、scout_recommendations、scout_compare、scout_sbom(封装docker scoutCLI 插件;除scout_sbom外,使用其他工具都需要在运行 CLI 的主机上执行docker login)。 基于 SDK 的功能表面与 Docker SDK 参考保持一致——其中记录的内容在这里都可用。Compose 和 Context 功能表面遵循 Compose CLI 和 docker context 参考文档。
该服务还会将 Docker SDK for Python 参考文档以及精选的 Docker CLI / registry 参考文档发布为 MCP 资源,供 Agent 在运行时查阅:读取 docker-docs://contents 获取章节索引,然后读取 docker-docs://<section>(例如 docker-docs://containers、docker-docs://compose、docker-docs://oci-distribution-spec、docker-docs://dockerfile、docker-docs://build-best-practices、docker-docs://engine-security、docker-docs://engine-api)获取渲染后的页面。对于无法读取资源的 MCP 客户端(例如 Claude Desktop、Cursor),docs_lookup 工具提供相同内容——不带参数调用可获取章节索引,或使用 docs_lookup(section=...) 获取页面;无论 DOCKER_MCP_SERVER_DISABLE 的值如何,该工具始终可用。另一个资源 docker-mcp://tool-catalog 列出该服务了解的所有工具,包括其所属领域、变更类别以及是否由当前配置注册,可用于确认某个工具的影响范围,或了解该工具为何未出现在当前列表中。无法读取资源的客户端可使用 tool_list 工具获取相同内容,该工具还支持筛选:使用 tool_list(domain="buildx") 获取某个领域中每个工具占一行的简介,使用 tool_list(category="destructive") 查看可能破坏数据的工具,或使用 tool_list(keyword="logs one task") 搜索名称、摘要和参数名称——所有匹配任意关键词的工具都会返回,匹配词最多的排在前面。该工具仅列出当前配置注册的工具;如果没有匹配项,则会明确返回空结果。与 docs_lookup 一样,无论 DOCKER_MCP_SERVER_DISABLE 的值如何,该工具始终可用。
容器和服务的可观测性也以资源形式提供,因此客户端无需调用工具即可附加实时状态作为上下文:docker-logs://<id-or-name> 用于获取容器日志的有限尾部(容器退出后仍可读取,便于诊断原因),docker-stats://<id-or-name> 用于获取运行中容器的资源使用情况汇总(CPU 百分比、内存、网络和块 I/O)。Swarm 服务也采用相同模式——service-logs://<id-or-name> 用于获取有限的日志尾部,service-tasks://<id-or-name> 用于获取计算得出的任务 / 滚动更新摘要(运行中与期望的任务数量、失败任务以及当前滚动更新状态)。使用 container_list / service_list 查找要填入的 ID 或名称。这些资源与对应工具(container_logs/container_stats、service_logs)互为补充;禁用 services 时,服务相关资源会隐藏(containers 则不会)。
示例提示词
许多 AI 客户端允许你直接调用已注册的 MCP 提示词(在 Claude Code 中,输入 / 即可查看)。该服务在 docker_mcp/tools/prompts.py 中提供了一小套模板,用于搭建多步骤工作流——模板会生成结构化计划,然后由 Agent 使用 Docker 工具执行。
查阅 SDK 文档
/lookup_docker_docs section=services
/verify_docker_method method=containers.run section=containers
……或者直接用日常语言提问:
阅读
docker-docs://networks,告诉我create和connect有什么区别。 在更改任何代码之前,先检查docker-docs://containers,确认run是否接受restart_policy参数。
创建和管理容器
/deploy_container image=nginx:1.27 name=web
/monitor_container_fleet
/triage_incident window_minutes=30
/troubleshoot_container container=api-1
/migrate_container container=api-1 new_image=myorg/api:v2
/inspect_stack label=com.example.app=web
/clean_environment scope=stopped
/plan_compose_stack description="wordpress + mysql sharing a named volume"
Compose、上下文和注册表
/deploy_compose_project project_dir=/srv/myapp
/troubleshoot_compose_project project_dir=/srv/myapp
/deploy_swarm_stack stack_name=web compose_file=/srv/myapp/docker-stack.yml
/audit_docker_contexts
/find_latest_image_tag image=ghcr.io/org/repo
审计、安全和主机操作
/review_dockerfile dockerfile_path=/srv/myapp/Dockerfile
/audit_container_security
/debug_container_networking source=web target=db
/investigate_disk_usage
/backup_volume volume=pgdata dest_path=/backups/pgdata.tar
/restore_volume volume=pgdata source_path=/backups/pgdata.tar
/audit_swarm_health
Buildx、Scout 和多架构清单
/plan_multiarch_build image=ghcr.io/org/app:v1 platforms=linux/amd64,linux/arm64
/audit_image_cves image=alpine:3.19
/compare_image_versions old_image=org/app:v1 new_image=org/app:v2
/recommend_base_image image=org/app:v1
/inspect_multiarch_manifest image=alpine:3.19
/create_multiarch_manifest target_tag=org/app:v1 source_tags=org/app:v1-amd64,org/app:v1-arm64
/migrate_from_docker_manifest
……或者直接用日常语言提问:
拉取
redis:7-alpine,并将其作为名为cache的容器运行在新建的app-net网络上,仅在该网络内公开端口 6379。 容器api-1一直在重启——获取最近 200 行日志,检查其状态和退出代码,并在更改任何内容之前告诉我问题所在。 将正在运行的web容器替换为nginx:1.27,同时保留其当前端口、挂载和重启策略。 规划一个位于私有网络上的 wordpress + mysql 堆栈,并为数据库使用命名卷。在创建任何内容之前,先向我展示计划。 将标记为com.example.app=web的所有容器、网络和卷汇总为一张表。不要进行任何更改。 磁盘空间紧张——显示system_df,清理已停止的容器和悬空镜像,然后再次显示system_df。跳过卷。 在/srv/myapp中启动 Compose 项目,但在启动任何内容之前,先向我展示渲染后的配置并拉取镜像。 列出我的 Docker 上下文,并告诉我此 MCP 服务当前连接的是哪个守护进程。 不拉取镜像,找出ghcr.io/org/repo最新的稳定标签,并告诉我它支持哪些平台。
配置
环境变量命名。 服务的环境变量使用
DOCKER_MCP_SERVER_*命名空间,与已发布的软件包名称保持一致。此前 2.0 版本之前的DOCKER_MCP_*别名拼写现已不再受支持。
若要选择服务连接的守护进程,请参阅连接远程守护进程和管理多个守护进程(DOCKER_MCP_SERVER_HOSTS / DOCKER_HOST)。以下变量用于限制注册的工具。
服务启动时,三个环境变量会限制注册的工具。由于这些变量会在注册时移除工具,被禁用的工具绝不会出现在客户端的工具列表中——这是服务端的保证,而不是客户端提示词。将两个布尔开关设为 1 / true / yes / on:
DOCKER_MCP_SERVER_READONLY- 仅注册只读工具(查询、日志/数据读取、扫描)。所有会更改状态的工具都会被省略。适用于不得修改任何内容的监控或检查 Agent。DOCKER_MCP_SERVER_NO_DESTRUCTIVE- 注册除破坏性工具(remove_*、prune_*、container_kill、compose_down、swarm_leave、context_remove、buildx_prune、buildx_remove)之外的所有工具。这是一种“不会丢失数据”模式,同时仍允许创建和启动资源。如果两者都已设置,则限制更严格的DOCKER_MCP_SERVER_READONLY优先。DOCKER_MCP_SERVER_DISABLE- 以逗号分隔、要整体禁用的领域(功能区域)列表,无论类别如何:例如,DOCKER_MCP_SERVER_DISABLE=swarm,services,nodes,configs,secrets会从单主机服务中移除整个 swarm 功能,而DOCKER_MCP_SERVER_DISABLE=scout,buildx会精简 Agent 永远不会用到的构建/扫描工具。领域是工具模块的名称:images、networks、volumes、compose、stack、context、buildx、scout、registry、swarm、services、nodes、plugins、configs、secrets。不能禁用system和containers,因此指定任一名称都会被忽略:system包含 Agent 用于了解当前状态和恢复所需的内容,以及唯一的等待工具;containers则是 Docker 服务的核心,compose、stack 和 service 工具启动的容器只能通过它来等待、读取和移除。禁用containers并不能阻止 Agent 运行代码,因为 compose、stack、service_create和image_build都能运行代码;真正能做到这一点的是DOCKER_MCP_SERVER_READONLY,而且它还会阻止 Agent 登录注册表。禁用某个领域也会将其中的目标从system_wait中移除。名称不区分大小写;无法识别的名称不会禁用任何内容。两种错误都会通过三种方式报告,因为 MCP 客户端很少会向任何人显示服务的 stderr:启动时在 stderr 中输出一行WARNING,在tool_list的结果中添加configuration_warnings条目(并在工具目录中添加unknown_disabled_domains/ignored_disabled_domains),以及在服务说明顶部添加一行,告知 Agent 检查tool_list并告知用户。此设置可与类别开关叠加:只有类别未被禁用且所属领域已启用的工具才会注册。禁用某个领域移除的不仅是其工具:对应的工作流提示词也会跳过(这样 Agent 就不会收到驱动服务器已不再提供的功能区域的提示词——例如,禁用scout会移除audit_image_cves提示词,否则该提示词会指示 Agent 调用一个未注册的工具),对应的文档资源也会从docker-docs://contents中隐藏(例如scout/scout-cli章节)。工具目录中的prompts列表和disabled_doc_sections字段可用于审计这两项变更。精简 Agent 不需要的领域,也能缩小客户端需要处理的工具列表;对于这么大规模的服务来说,这一点很重要。 这三项都不是网络控制措施。DOCKER_MCP_SERVER_READONLY限制的是 Agent 能更改什么,而不是服务能访问什么:注册表和 Hub 工具是只读的,因此即使是只读服务,也仍会向工具参数指定的注册表主机发起出站 HTTPS 请求——请求从服务运行所在的位置发出,而该位置的网络访问范围可能比它所管理的守护进程更广。除非注册表返回令牌质询,否则这些请求不会携带凭据;含凭据的令牌端点会先经过验证(方案、不得向公共主机发送明文,以及公共注册表不得将其 realm 指向私有地址或环回地址),但请求仍会发出,响应也会返回给 Agent。docs_lookup和docker-docs://资源同样会从固定列表中的文档主机获取内容。如果你需要阻止出站请求,DOCKER_MCP_SERVER_DISABLE=registry会彻底移除该域;对于其余请求,则应通过主机上的网络策略进行控制——完整的服务访问目标列表见PRIVACY.md。
此外,每个已注册工具都带有 MCP ToolAnnotations——查询工具带有 readOnlyHint,破坏性操作带有 destructiveHint(prune 系列还带有 idempotentHint)——因此,Claude Code 这类客户端可以自动允许安全的读取操作,并对破坏性调用进行限制。分类信息位于 docker_mcp/server.py 中的 TOOL_CATEGORIES。如需在运行时查看完整信息——包括每个工具所属的域、类别,以及当前启用的开关是否注册了该工具——请读取 docker-mcp://tool-catalog MCP 资源。
对于私有注册表,如果没有传入显式的 username/password 参数,基于 HTTPS 的 registry_* 工具会回退到服务环境中的 DOCKER_MCP_SERVER_REGISTRY_USERNAME / DOCKER_MCP_SERVER_REGISTRY_PASSWORD(显式参数优先;只有两个参数都未设置时才会使用环境变量)。在环境中设置凭据可避免它们出现在工具参数中,因为许多 MCP 客户端会原样记录这些参数——密码可以是个人访问令牌。
来源标签
Agent 通过此服务创建的每个 Docker 对象——容器、网络、卷、swarm 服务、配置和密钥——都会带上一组 docker-mcp-server.* 标签,记录该对象由此服务创建(docker-mcp-server.managed=true)、服务版本、来源工具和创建时间戳。这样,你(或清理任务)之后就能通过单条命令 docker ... --filter label=docker-mcp-server.managed=true,准确列出 Agent 创建的所有对象;container_list、network_list、volume_list 和 service_list 中的 managed_only=True 参数提供了工具内的快捷方式(它会与传入的其他 filters 组合使用)。标签只会附加,不会覆盖:如果发生键冲突,你自行传入的标签始终优先;标签使用独立命名空间,因此默认情况下是安全的;DOCKER_MCP_SERVER_NO_LABELS=1 可彻底关闭标签功能。镜像构建不会添加标签,这是有意为之,因为构建标签会改变生成镜像的摘要。
若要仅清理此服务创建的内容——而不触及其他内容——请使用 prune_managed 工作流提示词;它会将每个移除步骤限定为 docker-mcp-server.managed=true 标签对应的对象(只有传入 include_volumes=True 时才会清理卷,并且仅在确认后进行)。
示例:只读监控服务
这些内容都应放在 MCP 客户端配置中该服务条目的 env 块内(与上文的 DOCKER_HOST 位于同一位置)。例如,针对远程守护进程的只读检查服务:
{
"mcpServers": {
"docker-mcp-server-readonly": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/L337-org/docker-mcp.git",
"docker-mcp-server"
],
"env": {
"DOCKER_HOST": "tcp://staging-host:2376",
"DOCKER_TLS_VERIFY": "1",
"DOCKER_MCP_SERVER_READONLY": "1"
}
}
}
}
将 DOCKER_MCP_SERVER_READONLY 替换为 DOCKER_MCP_SERVER_NO_DESTRUCTIVE,即可允许创建、启动和部署,同时仍禁止 remove_* / prune_* / container_kill。你也可以用不同名称注册同一服务两次:一个需要时启用的完全访问条目,以及一个日常使用的只读条目。使用 claude mcp(Claude Code)时,对应配置如下:
claude mcp add docker-mcp-server-readonly \
--env DOCKER_MCP_SERVER_READONLY=1 \
-- uvx --from git+https://github.com/L337-org/docker-mcp.git docker-mcp-server
或者完全不用服务:l337-docker Agent 技能
关于任何 MCP 服务,一个合理的问题是:它是否有必要存在。本仓库公开给出了答案:skills/l337-docker/ 是一项 Claude Code Agent 技能,仅通过 docker CLI 操作 Docker——无需服务进程、无需 Python,除了 docker 二进制文件外什么都不需要(少数注册表操作示例还需要 jq 和 curl)。
这项技能的存在,是为了如实展示技能方案的能力上限,让你自行权衡取舍,而不是听信我们的一面之词。它力求将这种方案做到最好:由路由器和各领域的参考资料及工作流组成,每条命令都经过真实守护进程验证,Shell 片段也由 CI 执行,确保不会偏离实际情况。对于单个本地守护进程和日常工作,它很可能已足够——如果是这样,就用它。
它的局限不在覆盖范围,而在于强制执行。技能的安全规则只是提示词中的指示;服务的安全规则则是代码中的拒绝机制:
| MCP 服务 | l337-docker 技能 | |
|---|---|---|
| 只读/禁止破坏性操作模式 | 强制执行——永远不会注册这些工具 | 写明规则,要求 Agent 遵守 |
按守护进程设置写入保护((ro)/(nd)) | 在调用边界强制执行 | 不支持 |
| 自终止防护 | 强制执行 | 写明规则 |
| 输出长度限制 | 强制执行,并带有 truncated 标记 | 写明规则(--tail、--no-stream) |
| 多守护进程定向 | 启动时解析并固定目标 | 使用可能在会话中途改变的环境 Docker 上下文 |
| 要求 | Python ≥3.14,或容器 | docker 二进制文件 |
这种差异在最容易被忽视的地方最为重要:提示词中的规则可能在压力下被跳过,也可能被 Agent 刚读过的容器日志中的提示注入绕过。未注册的工具根本无法调用。因此,对于任何面向生产环境的操作,或任何需要保证而非指示的场景,都应优先选择服务;而在风险较低、简单性更重要时,则优先选择技能。
MCP_VS_SKILLS.md 提供了完整、坦诚的对比:两者经过测量的令牌开销——对于积极加载的客户端,技能便宜得多,尤其是在空闲时;而对于按需加载的客户端,服务的单项任务开销更低——此外还介绍了各自真正擅长的方面,以及涵盖每项工具、提示词和资源的逐工具对照表。
要安装,请从某个发布版本下载归档文件,并解压到技能目录中。归档以 l337-docker/ 为根目录,因此无需调整即可正确放置:
# personal (all projects)
tar -xzf l337-docker-skill-<version>.tar.gz -C ~/.claude/skills
# or per-project, checked into version control
tar -xzf l337-docker-skill-<version>.tar.gz -C .claude/skills
使用随附的校验和验证(sha256sum -c l337-docker-skill-<version>.tar.gz.sha256);该归档可逐字节重现,因此从标签重新构建会得到相同的哈希值。技能和服务可以共存——它们为自己创建的资源使用不同标签,彼此也不会读取对方的资源。
安全注意事项
将此服务连接到 AI Agent,相当于授予它对已配置守护进程与本地 Docker CLI 会话相同级别的访问权限。这种权限范围很广:守护进程的套接字实际上等同于运行它的主机上的 root 权限。请将 Agent 视为特权用户,并在启用服务前权衡以下风险。
- 使用受限范围的守护进程。 优先将
DOCKER_HOST指向专供 Agent 操作其获准管理工作负载的守护进程(开发 VM、远程沙箱、Docker Desktop、无 root 安装),而不是生产环境的套接字。守护进程就是信任边界——没有针对单个工具的授权层。 - 以容器方式运行。 将
/var/run/docker.sock挂载到容器中,赋予它与 uvx 安装相同的、相当于 root 的守护进程访问权限——不多也不少,只是现在在docker run命令中明确写出。同样适用受限守护进程的建议:优先挂载获准由 Agent 控制的守护进程套接字,或将DOCKER_HOST指向该守护进程。请注意,容器化后,文件路径工具读写的是容器自身的文件系统,因此只能访问通过绑定挂载提供的主机目录(参见以容器方式运行)。作为防误操作措施,具有破坏性的容器生命周期工具(container_remove、container_kill、container_stop、container_restart、container_pause)拒绝操作服务自身所在的容器,避免 Agent 在调用过程中结束自己的会话;这只是便利措施,不是安全边界(可通过DOCKER_MCP_SERVER_ALLOW_SELF_TERMINATE=1绕过,而且人类始终可以从主机 shell 恢复该容器),也不会限制拥有守护进程权限的 Agent 以其他许多方式影响主机。 - 特权容器和主机挂载。
container_run接受privileged=True和任意volumes。特权容器,或绑定挂载主机/的容器,都能轻易逃逸到主机文件系统。除非已审查请求,否则不要允许 Agent 设置这些选项。Compose 文件也可以声明相同设置——在陌生项目上批准compose_up前,请先审查渲染后的compose_config输出。 - 透传的
extra_kwargs/updates会绕过可见架构。container_run、container_create、service_create(extra_kwargs)以及container_update、service_update(updates)会将任意字典直接传给 Docker SDK。即便客户端依据工具声明参数中的privileged=False等设置进行限制,仍可通过extra_kwargs={"privileged": True, "pid_mode": "host"}绕过。这些后门符合“守护进程是信任边界”的模型,但你在 MCP 客户端层构建的任何允许/拒绝策略都必须考虑到它们,而不能只信任具名参数。 - 注册表凭据。 许多 MCP 客户端会原样记录工具调用,因此应将通过工具传递的任何密码或
auth_config视为已暴露。- 基于 SDK 的工具(
system_login、image_push、image_registry_data)既可直接接收凭据,也可复用docker login缓存在~/.docker/config.json中的凭据。建议在运行此 MCP 服务的主机上执行一次docker login,并将凭据参数留空。(注意:这里指运行服务的主机,而非守护进程——当DOCKER_HOST指向远程守护进程时尤为重要。)传给system_login的凭据会缓存在服务内存中,直至客户端生命周期结束;system_logout会清除此内存缓存(所有注册表或指定注册表),但不会修改~/.docker/config.json;system_close/system_reconnect则会丢弃客户端并清除缓存。守护进程端没有可结束的会话——Engine 的/auth端点只负责验证。 - 基于 HTTPS 的注册表工具(
registry_tags、registry_manifest、registry_image_config、hub_tags、hub_repo_info、hub_rate_limit,以及用于注册表标签的system_wait)会直接通过 HTTPS 与注册表通信,不会读取~/.docker/config.json。registry_*工具可通过username/password访问私有注册表;更好的做法是从服务的环境中读取DOCKER_MCP_SERVER_REGISTRY_USERNAME/DOCKER_MCP_SERVER_REGISTRY_PASSWORD,这样凭据就不会经过工具参数(参见配置);hub_*工具仅支持公开的 Hub 仓库。如果要通过参数传递凭据,请使用每次调用专用且权限范围最小的令牌,而不是长期有效的密码。注册表返回Bearer身份验证质询时,服务会在发送任何内容前验证其指向的令牌realm:协议必须为 http/https,拒绝向非本地主机使用明文 http;公开注册表也不得将带凭据的令牌请求重定向到私有/环回地址(防止 SSRF)。真正的本地开发注册表(例如localhost:5000)仍可使用本地 realm。分页也采用相同限制:Docker Hub 的nextURL 必须保持在 Hub 自身的源站上;OCILink标头中的主机名会被丢弃,改用当前查询的注册表,因此响应正文绝不可能将此服务重定向到任意主机。重定向本身允许跨主机跟随——注册表通常会将 blob 获取请求重定向到其他主机上的 CDN——但 HTTP 客户端会在任何跨源重定向时剥除Authorization标头,因此凭据不会随之传递。
- 基于 SDK 的工具(
- Swarm 秘密信息也会经由工具调用传递。 除注册表凭据外,若干 Swarm 工具会通过参数或返回值传递秘密信息,MCP 客户端可能会记录这些内容:
secret_create(data=...)和config_create(data=...)将负载作为参数接收;secret_inspect/config_inspect会返回已存储的对象;swarm_join(join_token=...)和swarm_unlock(key=...)会接收集群加入/解锁密钥;swarm_unlock_key和swarm_join_tokens会返回集群凭据(通过swarm_update轮换后,旧令牌会失效)。管理器加入令牌的持有者可以作为管理器加入 Swarm(在集群中拥有相当于 root 的权限)。对于任何会记录工具流量的客户端,都应将这些内容视为已暴露;最好在主机上以带外方式配置 Swarm 秘密信息并读取加入令牌,而不要经由 Agent。如果 Agent 无需接纳节点,可通过DOCKER_MCP_SERVER_DISABLE=swarm禁用整个功能范围(参见配置)。 container_exec、compose_exec和compose_run会运行任意命令。 如果命令的任何部分来自 Agent 控制的输入,请使用不会调用 shell 的 exec 形式 argv 列表(例如["python", "-V"])。像["sh", "-c", template]这样的列表会调用 shell,从而解释不可信子字符串中的 shell 元字符。- 容器归档路径。
container_archive_get和container_archive_put会将提供的路径原样转发给守护进程。容器就是信任边界——如果不信任其文件系统,不要假定..路径遍历会被拒绝。 - 文件路径负载工具会读写服务主机的文件系统。
image_save、container_export(使用dest_path时)和container_archive_get_to_file会在运行此 MCP 服务的主机上写入dest_path(除非overwrite=True,否则拒绝覆盖现有文件);image_load、image_import和container_archive_put(使用from_file时)会读取主机路径;compose_cp会在服务容器与主机路径之间双向复制。image_import(from_url=...)是唯一完全不经过主机的工具:守护进程会在其自身网络命名空间中获取调用方指定的 URL,因此可以访问该守护进程可访问的任何内容(与image_pull的注册表参数一样,由调用方指定目标)。这些工具以服务运行用户的身份执行,因此 Agent 可以写入该用户可写的任何文件,也可以读取该用户可读的任何文件。如果不信任 Agent 访问主机文件系统,优先使用带内字节工具(上限为 32 MiB)。DOCKER_MCP_SERVER_READONLY也会移除主机写入工具——但请注意,它并非专门针对这些工具:它只注册只读工具,因此image_load和container_archive_put(以及其他所有会修改或造成破坏的工具)也会一并移除。没有只移除文件写入工具的开关。 - 破坏性操作没有内置确认机制。
prune_*、remove_*、container_kill、swarm_leave、compose_down(volumes=True)、compose_kill、stack_remove(会拆除堆栈中的所有服务)、buildx_prune(始终带--force执行)和buildx_remove都会立即执行。这些工具带有destructiveHint注释,因此 Claude Code 之类的客户端可以对它们进行拦截;随附的clean_environment提示词也会要求 Agent 在清理卷前进行确认——但服务本身不会拦截工具调用。要实现强制保证,请使用DOCKER_MCP_SERVER_NO_DESTRUCTIVE=1(完全移除这些工具)或DOCKER_MCP_SERVER_READONLY=1(参见配置);如需审批步骤,请在 MCP 客户端中配置。 - CLI shell 调用攻击面。 Compose、Stack、Buildx、Scout 和 Context 工具会在运行此 MCP 服务的主机上启动
docker子进程。每次调用都将参数作为列表传递(不使用 shell,也不解释元字符),通过shutil.which查找可执行文件,并在经过清理的环境中运行(仅保留 DOCKER_HOST 及相关变量)。位置参数(镜像引用、服务 / context / builder 名称、构建上下文、bake 目标)还会在以-开头时被拒绝,以免将参数伪装成 CLI 标志(例如将服务命名为--output=...);唯一的特意例外是compose_exec/compose_run中尾随的命令,它本就用于传入任意 argv。提供给compose_*的文件系统路径(project_dir、files)会由服务主机上的 docker CLI 读取——传入陌生路径可能暴露服务用户可读取的任何 Compose 文件。如果主机上没有本地 docker CLI,且目标为ssh://,这些子进程会改在远程主机上运行(见上文),这会带来两项变化:命令以远程 SSH 用户的身份及其注册表凭据执行;命令要读取的文件会先复制到该主机的临时目录中——因此,buildx_build的--secret src=文件或暂存目录中的任何其他内容都会短暂存于远程磁盘上(权限模式为0700,调用返回时删除;只有连接中断才可能使文件残留)。对于依赖暂存的工具,请仅指定你愿意复制的目录。 - 守护进程集合在启动时固定;请谨慎选择。 未设置
DOCKER_HOST/DOCKER_MCP_SERVER_HOSTS时,服务的初始 SDK 连接会跟随当前 Docker context(DOCKER_CONTEXT/currentContext)——也就是 docker CLI 使用的同一守护进程。因此,如果该 context 指向远程或生产环境的守护进程,Agent 也会连接到那里。请在启动服务前设置DOCKER_MCP_SERVER_HOSTS(或DOCKER_HOST,或选择受限 context),以明确固定目标;使用DOCKER_MCP_SERVER_HOSTS时,auto/local端点会在启动时固定,之后即使 context 发生变化也不会漂移。启动后,context_use只会更改后续基于 CLI 的工具所用的 CLI 默认值;基于 SDK 的工具仍会使用其连接池客户端已连接的守护进程。运行时无法向任意端点引入或重新指定守护进程——system_reconnect只能重建已配置主机的客户端(用于恢复失效连接),不能将其指向其他位置;要添加或更改守护进程,请编辑DOCKER_MCP_SERVER_HOSTS并重启。这一设计有意封闭了扩大信任范围的途径(Agent 无法在会话中途将相当于 root 的边界转移到未经审查的端点)。context_create(skip_tls_verify=True)会禁用该 context 的 TLS 验证;仅用于可信的本地守护进程。 - 每主机只读是防误操作措施,不是安全边界。 在
DOCKER_MCP_SERVER_HOSTS中标记为(ro)的主机会在调用时拒绝执行会修改或造成破坏的工具(多个主机时,写操作还必须明确指定目标主机——避免 Agent 因遗漏指定目标而修改错误的守护进程)。与guard_not_self一样,这是进程内的便利措施:它会限制 Agent 通过此服务执行操作,但守护进程本身仍是信任边界。因此,对于 Agent 绝不能修改的主机,应优先将其指向真正只读或受限的守护进程,而不要只依赖该标记。 - 每主机的非破坏性限制也是防误操作措施,作用范围更窄。 标记为
(nd)的主机只会拒绝破坏性工具调用(终止、移除、清理),读取和常规修改仍会执行。与(ro)一样,这是由本服务防护机制在进程内执行的便利措施,并非守护进程层面的边界。 cryptography(通过mcp->pyjwt[crypto]引入的传递依赖)自 49.0.0 起就不再提供 x86_64/universal2 macOS wheel——已确认是永久变化,并非暂时问题——因此在该平台上原生安装(使用uvx、pip或.mcpb包)会解析到当前版本并从源代码构建,需要安装 Rust 和 OpenSSL 3.x。 本项目曾短暂尝试使用仅针对 Intel macOS 的cryptography<49限制来避免构建步骤;后来发现该限制会影响所有平台,而不只是它指定的平台(仅设置平台范围的版本上限不会让uv lock分叉解析),因此所有人都被悄然固定在某个版本上,而该版本落入了后来出现的高危 CVE 影响范围(PKCS#7 EnvelopedData 解密 Bleichenbacher oracle)。项目最终移除了这一限制,而没有用其他方案替代:本项目本身不会解密 PKCS#7 信封,但明知某个依赖含有可利用的缺陷,就不应仅为了让一个平台只安装 wheel 而继续发布该依赖。如果不想安装构建工具链,请改用容器镜像(集中在 Linux 上构建,因此不会遇到此问题)。
软件包和列表
| 渠道 | 链接 |
|---|---|
| PyPI | docker-mcp-server |
| GHCR(容器) | ghcr.io/l337-org/docker-mcp-server |
| Docker Hub(容器) | gavinlucas/docker-mcp-server |
| 桌面扩展(.mcpb) | GitHub Releases |
l337-docker Agent 技能(.tar.gz) | GitHub Releases |
| 官方 MCP 注册表 | io.github.L337-org/docker-mcp-server |
| Glama | docker-mcp-server |
| mcp.so | docker-mcp-server |
| awesome-mcp-servers | punkpeye/awesome-mcp-servers |
隐私政策
docker-mcp-server 不收集数据、不发送遥测信息,也没有由作者运营的后端。它在本地运行,只与你指定的 Docker 守护进程和容器注册表通信,以执行你请求的操作。完整声明请参阅 PRIVACY.md。
贡献
欢迎贡献。本项目重视 Docker SDK 公共接口与我们公开的 MCP 工具之间的紧密映射。有关项目结构、工具约定、添加新工具模块的检查清单以及本地开发设置,请参阅 CONTRIBUTING.md。
商标
docker-mcp-server 是一个独立的开源项目。它与 Docker, Inc. 无关联,未获其认可,也未受其赞助。Docker 是 Docker, Inc. 的商标或注册商标。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。