关于 Docker MCP Server
Docker MCP Server 为 AI Agent 提供面向 Docker 和 Compose 的结构化工具,供开发与运维人员检查容器、日志、健康状态及数据库,也可按配置通过 SSH 操作远程主机。
主要功能
- 01检查容器状态、健康状况和资源
- 02读取有界日志窗口
- 03查询数据库并生成转储
- 04管理 Compose 项目和服务
- 05通过 SSH 配置远程 Docker 主机
适用场景
- 01排查 Compose 服务健康问题
- 02调查容器错误日志
- 03检查服务资源使用情况
- 04在本地与远程主机间管理部署
MCP 相关
这是基于官方 MCP SDK 的原生 MCP 服务,向 MCP 客户端提供结构化 Docker 工具。客户端可连接本机 Docker,也可通过 SSH 配置文件选择远程主机。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @hypnosis/docker-mcp-serverDOCKER_MCP_PROFILES_FILEAbsolute path to the JSON file describing the Docker hosts this agent may reach. Without it the server answers about the Docker on this machine.DOCKER_PROFILESThe same profiles JSON inline, used when no profiles file is set.DOCKER_MCP_ALLOW_SSH_FALLBACKKeep going when a profile's SSH key is missing, instead of refusing the profile. Defaults to false.LOG_LEVELLog verbosity: error, warn, info or debug. Defaults to info.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
10收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | enum | 是 | list:项目的所有容器及其状态和运行状况。stats:某个服务此刻的 CPU、内存、网络和磁盘用量。list | stats |
| profile | string | 否 | 按配置名称指定 Docker 主机。默认值:标记为默认的配置。 |
| project | string | 否 | 指定 compose 项目。默认值:工作目录所属的项目。名称不匹配时会报错,不会回退为主机上的所有容器。action 为 list 且未指定时:列出主机通过 compose 运行的所有容器。 |
| service | string | 否 | compose 文件中写明的服务名称。action 为 stats 时必填。 |
| compose_path | string | 否 | compose 文件所在位置:文件本身或其所在目录。仅当主机上没有容器带有该项目标签时才需要,即该项目从未在此主机上启动过。若目录中有多个 compose 文件,则会列出文件名并拒绝操作,而不会猜测使用哪个文件。 |
详细介绍
Docker MCP Server — 面向 AI Agent 的 Docker 工具
一个 Docker MCP 服务,让 AI Agent 能够通过结构化、原生 Docker 工具操作 Compose 堆栈,而不是依赖脆弱的 shell 命令和终端格式的输出。
检查容器、读取日志、检查健康状态、查询数据库、导出转储,以及启动或停止堆栈——无论是在你的笔记本电脑上,还是通过指定配置文件名称连接到世界另一端的服务器。
它使用你熟悉的方式与 Docker 交互:你的 compose 文件、项目名称和服务名称。返回的结果会包含命名字段和足够的上下文,供 Agent 据此采取行动,而不是让它解析 ASCII 表格并猜测。
适用于 Claude Code、Codex CLI、Cursor、opencode、Gemini CLI、Qwen Code 和其他 MCP 客户端。
30 秒内完成安装
无需全局安装。首次使用时,npx 会下载此软件包:
npx -y @hypnosis/docker-mcp-server
将它添加到你的 MCP 客户端——例如 Claude Code——即可用于每个项目:
claude mcp add docker -s user -- npx -y @hypnosis/docker-mcp-server
这就是在本机使用 Docker 的全部配置。无需配置文件,也无需环境变量:该服务使用本地 Docker 套接字,并将当前工作目录对应的 compose 项目作为它要处理的项目。
如果要连接另一台机器上的 Docker 主机,只需添加一个文件,列出通过 SSH 连接的服务:
claude mcp add docker -s user \
-e DOCKER_MCP_PROFILES_FILE="$HOME/.claude/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
{
"default": "local",
"profiles": {
"local": { "mode": "local" },
"production": {
"host": "prod.example.com",
"username": "deployer",
"privateKeyPath": "~/.ssh/id_ed25519"
}
}
}
现在,每个工具都接受一个 profile 参数,docker_health({ action: "profiles" }) 会列出提供给该服务的配置文件。
Codex、Cursor、opencode 和其他客户端的配置方法,请参阅配置 Docker MCP 服务。
作为插件安装
有些客户端——例如 Claude Code——可以直接将整个服务作为插件使用:
/plugin marketplace add hypnosis/docker-mcp-server
/plugin install docker-mcp-server@docker-mcp-server
该插件会连接到本机的 Docker,无需任何配置即可启动服务。要连接其他主机,可像上文一样通过 DOCKER_MCP_PROFILES_FILE 配置。
要求
Node.js 18+,以及一个你已经可以访问的 Docker 守护进程——可以是本地套接字,也可以是通过 SSH 和密钥访问的远程主机。
无论 Docker 是否已启动,服务都会启动。在守护进程关闭时发起调用,会得到“启动 Docker”的提示;下次重试即可正常工作,无需重启 MCP 客户端。
如果你更倾向于固定版本、离线工作,或者希望每次启动时少进行一次注册表检查:
运行 npm install -g @hypnosis/docker-mcp-server,然后使用 docker-mcp-server 作为命令,而不是 npx。
这款 Docker MCP 服务适合谁
- 使用 AI 辅助开发的开发者:借助 Docker Compose 构建、运行和调试应用。
- 后端和全栈开发者:需要编码 Agent 在解决问题时检查容器、日志、健康检查、数据库和 Compose 服务。
- 独立开发者和小型产品团队:将 Docker 应用部署到自己的服务器,并希望用同一套 Agent 工作流进行本地开发和生产环境运维。
- 平台工程师:维护开发、预发布和生产主机上的 Docker 环境。
- 使用 AI 编码 Agent 的 DevOps 工程师和 SRE:进行事故检查、日常容器工作,并更快地排查基于 Compose 的服务。
- 维护客户应用的代理机构和技术团队:Agent 需要先了解陌生的 Compose 堆栈,才能进行更改。
- QA 和发布工程师:发布前需要反复查看测试堆栈、服务健康状况、日志和数据库。
为什么使用 Docker MCP 服务,而不是直接使用 Docker CLI?
Docker CLI 非常适合在终端前工作的人员。AI Agent 需要的则有所不同:可直接查询的 Docker 和 Compose 概念、便于推理的结果,以及清晰的边界,能区分发生了什么、未找到什么,以及无法检查什么。
减少上下文,降低 AI 成本
docker ps、docker stats 和 docker logs 是为在屏幕上阅读而设计的。它们的输出将标签、值、单位和格式混在一起,Agent 必须先解析才能使用。
Docker MCP 工具会返回任务所需的字段:服务、项目、状态、健康状况、端口、时间戳、字节数、退出代码和日志流。Agent 接收到的终端噪音更少,解析结果时消耗的 token 更少,也能为正在解决的问题保留更多上下文。
将 Docker Compose 作为一个系统进行调试
Docker 应用不只是一个容器列表。它是一个由服务、依赖项、健康检查、日志、数据库和相互影响的资源组成的 Compose 项目。
该服务让 Agent 能够使用你日常采用的名称来询问这个系统:项目、服务和 Compose 文件。一次调用即可显示堆栈的状态和健康状况;另一次调用则可以检查限定范围内的日志窗口、测量服务,或查询旁边已在运行的数据库。Agent 可以把精力放在查找原因上,而不是拼装和解读 shell 命令。
根据明确结果做出决策
Shell 命令可能返回空表、截断的输出,或在普通文本旁打印错误。对 Agent 来说,这些情况各不相同——把它们混为一谈就会导致猜测。
Docker MCP 结果会说明找到了什么、没有找到什么、什么被截断了,以及某项操作为何没有运行。缺少健康检查不等于健康检查失败;空列表不等于读取失败;没有退出代码的命令说明它根本没有启动。这能为 Agent 的后续步骤提供可靠依据,也能减少那些看似自信、实则错误的修复。
通过 SSH 管理本地和远程 Docker 主机
在你身边的 Docker 守护进程和远程服务上,使用相同的 Docker MCP 工具。远程 Docker 主机由一个配置档案表示,其中包含稳定的名称、SSH 连接,以及所需的身份验证信息。Agent 会在工具调用中指定该配置档案:
docker_container({ "action": "list", "profile": "production" })
省略 profile,默认 Docker 主机就会响应,让本地开发保持顺畅。如果指定了服务不认识的配置档案,响应会列出它认识的配置档案,而不是悄悄把请求发到另一台机器。
远程 Docker Compose 项目会根据容器已有的标签来解析。无论项目位于该主机的何处,都可以按名称请求项目——无需维护远程工作目录或固定的 Compose 路径。对于尚未在该主机上运行过的项目,可通过 compose_path 显式传入其文件。
专为 Model Context Protocol 打造
基于官方 MCP SDK 构建的原生 Docker MCP 服务,提供专为 AI Agent 设计的结构化工具,而非终端自动化工具。
其行为由单元测试和端到端测试覆盖,测试会针对真实 Docker 容器运行,而不只是使用模拟对象。
Docker MCP 与 Docker CLI:实用示例
当由人来操作终端时,Docker CLI 是合适的接口。这些示例展示了当 AI Agent 需要检查 Docker Compose 应用、理解结果并选择下一步安全操作时,有哪些不同。
每组对比都采用相同的实际任务:先展示 Agent 必须处理的命令和输出,再展示它可以直接使用的结构化 Docker MCP 结果。
诊断 Docker Compose 堆栈的健康状况
情况: 刚刚完成一次部署。网站运行缓慢,而你不知道是容器已停止、健康检查失败,还是某个进程正在消耗内存。
问题:“这个堆栈健康吗?”
原始 docker CLI
$ docker compose ps
NAME IMAGE STATUS PORTS
shop-api-1 shop-api:latest Up 4 minutes (healthy) 0.0.0.0:8080->8080/tcp
shop-postgres-1 postgres:16 Up 4 minutes (unhealthy) 5432/tcp
shop-worker-1 shop-worker:latest Exited (1) 2 minutes ago
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
1f2c4d5e6a7b shop-api-1 3.10% 214.8MiB / 7.66GiB 2.74% 12.4MB / 8.9MB 0B / 4.1MB
9a8b7c6d5e4f shop-postgres-1 0.42% 1.204GiB / 7.66GiB 15.7% 3.2MB / 44MB 112MB / 890MB
$ docker inspect --format '{{.State.Health.Status}}' shop-postgres-1
unhealthy
$ docker inspect --format '{{.State.Health.Status}}' shop-worker-1
Template parsing error: executing "" at <.State.Health.Status>: nil pointer evaluating *types.Health.Status
三条命令,三种输出格式;最后一条还会失败,因为 worker 镜像根本没有声明健康检查。一切都没有损坏——只是没有可读取的内容——但 Agent 现在必须区分“没有健康检查”和“健康检查失败”,而表格对此毫无帮助。
结构化 MCP 结果
docker_container({ "action": "list", "project": "shop" })
{
"action": "list",
"project": "shop",
"containers": [
{ "name": "shop-api-1", "service": "api", "project": "shop", "state": "running",
"health": "healthy", "image": "shop-api:latest",
"ports": ["0.0.0.0:8080->8080/tcp"], "created": "2026-08-24T09:14:02Z" },
{ "name": "shop-postgres-1", "service": "postgres", "project": "shop", "state": "running",
"health": "unhealthy", "image": "postgres:16",
"ports": ["5432/tcp"], "created": "2026-08-24T09:14:01Z" },
{ "name": "shop-worker-1", "service": "worker", "project": "shop", "state": "exited",
"health": null, "image": "shop-worker:latest",
"ports": [], "created": "2026-08-24T09:14:01Z" }
],
"reason": null,
"legend": {
"containers[].state=running": "Running now.",
"containers[].state=exited": "Stopped. Its logs survive, its processes do not.",
"containers[].health=healthy": "Its own healthcheck passed last run.",
"containers[].health=unhealthy": "Its own healthcheck failed enough times in a row to give up on it.",
"containers[].health=null": "The image declares no healthcheck, so nothing is measured. Not the same as failing."
}
}
对 Agent 有何改变
| 原始 docker CLI | 结构化 MCP | 带来的好处 |
|---|---|---|
| 三条命令,三种输出格式 | 一次调用,返回每项服务的状态、健康状况和端口 | 减少往返调用 |
| 缺少健康检查时会报错或显示为失败 | 答案本身会说明 health: null 的含义 | 不会把没有人编写的检查归咎于容器 |
| 必须将容器名称映射回服务 | 每一行都包含 service、project 和 name | Agent 使用 Compose 术语,而非容器 ID |
图例只解释此答案中实际用到的词,并紧邻使用这些词的字段——这样,unhealthy 的含义就不会藏在几百条消息之前的工具描述里。
需要具体数值而非状态? docker_container({ action: "stats", service: "postgres" }) 会以数值形式返回 CPU、相对于限制值的内存、网络和磁盘数据,并明确说明这只是某一时刻的读数,不是平均值。
需要查看健康检查本身? docker_health({ action: "services" }) 会报告每项服务自身的判定结果,统计其检查次数和失败次数;对于没有健康检查的服务,会标记为 none,而不是将其计为异常。
调查容器日志,同时保留上下文
情况: 大约十分钟前,API 开始返回 502。容器已运行一周,并写入了数十万行日志。
问题:“出故障时,它打印了什么?”
原始 docker CLI
$ docker compose logs api --tail 200
api-1 | 2026-08-24T10:31:07.104Z INFO request GET /health 200 3ms
api-1 | 2026-08-24T10:31:07.882Z INFO request GET /health 200 2ms
... 196 more lines of the same ...
api-1 | 2026-08-24T10:39:14.522Z ERROR database connection timed out after 30000ms
$ docker compose logs api --since 10m | grep -i error
api-1 | 2026-08-24T10:39:14.522Z ERROR database connection timed out after 30000ms
第一次调用耗费了两百行上下文来显示健康检查噪声。第二次找到了错误,却丢弃了它周围的行;而且两次输出都没有说明数据流是 stdout 还是 stderr,也没有说明过程中是否丢失了内容。
结构化 MCP 结果
docker_logs({ "service": "api", "project": "shop", "since": "10m", "lines": 50 })
{
"service": "api",
"project": "shop",
"date": "2026-08-24",
"lines": [
{ "stream": "stdout", "time": "10:39:14.518",
"text": "INFO pool exhausted, waiting for a free connection" },
{ "stream": "stderr", "time": "10:39:14.522",
"text": "ERROR database connection timed out after 30000ms" },
{ "stream": "stderr", "time": "10:39:14.530",
"text": "ERROR upstream 502 while proxying GET /api/orders" }
],
"returned_lines": 3,
"since": "10m",
"until": null,
"truncated": false,
"truncated_reason": null,
"clipped_lines": 0,
"follow": false,
"reason": null,
"legend": {
"lines[].stream=stderr": "the stream the container wrote to; many programs write their ordinary progress there, so a line is not an error for being here"
}
}
对 Agent 的改变
| 原始 docker CLI | 结构化 MCP | 你的收益 |
|---|---|---|
| 截取行数只能靠猜:太少会漏掉目标,太多又会淹没它 | 先用 since 和 until 按时间限定范围,再用 lines 计数 | 减少噪声占用的 token |
| 一大段文本;数据流和时间戳都粘在里面 | 每一行都带有自己的 stream、time 和 text | 按字段查找错误,而不是用 grep |
| 中间部分被丢弃,和日志安静无声看起来一模一样 | truncated、truncated_reason 和 clipped_lines 会注明每处截断 | 不会根据部分读取得出“日志很干净”的结论 |
这些行所属的日期只在顶部说明一次,之后每行只带时间——每行重复相同的时间戳,只会让你白白付出代价。跨越多天的行会保留完整时间戳,并说明原因。
since 也接受日期或 UNIX 时间戳;follow: true 会等待后续日志行到达,并在自身的时间和大小上限内返回已收到的内容,而不是一直挂在打开的数据流上。
查询 Docker 中运行的数据库
情况: 订单不再显示在仪表板上。你想查看数据库——它运行在容器中,里面有客户端,且没有向你的机器发布端口。
问题:“表里实际存了什么?”
原始 docker CLI
$ docker compose exec -T postgres psql -U app -d shop -c "select status, count(*) from orders group by status"
status | count
-----------+-------
paid | 1284
pending | 17
(2 rows)
$ docker compose exec -T redis redis-cli info keyspace
db0:keys=41822,expires=41822,avg_ttl=3600000
每种数据库引擎都需要自己的客户端、标志,以及指定用户和数据库的方式。只要有一个标志写错,Shell 就会打印错误,Agent 还得把它当作文本来读——这次调用本身却“成功了”。
结构化 MCP 结果
docker_db({ "action": "query", "service": "postgres", "project": "shop",
"query": "select status, count(*) from orders group by status" })
{
"action": "query",
"service": "postgres",
"project": "shop",
"engine": "postgresql",
"query": "select status, count(*) from orders group by status",
"output": " status | count\n-----------+-------\n paid | 1284\n pending | 17\n(2 rows)",
"stderr": "",
"exit_code": 0,
"clipped_bytes": 0,
"warnings": [],
"reason": null,
"legend": {}
}
对 Agent 的改变
| 原始 docker CLI | 结构化 MCP | 你的收益 |
|---|---|---|
| 每种数据库引擎都需要不同的客户端、标志集和用户 | 一个工具支持 PostgreSQL、MySQL/MariaDB、Redis、MongoDB 和 SQLite | 学会一套工具,查询五种数据库 |
| 被拒绝的语句看起来仍像是成功的命令 | exit_code 和 stderr 与 output 分开呈现 | 失败会明确显示为失败 |
| 凭据需要重新输入到命令行中 | 默认使用容器自身的用户和数据库 | 对话记录中包含的密钥更少 |
status 会改为向数据库查询自身信息——版本、大小、运行时长、连接数;而 format: "csv" 会将 PostgreSQL 结果行排布为便于解析的格式。可能销毁数据库或整个键空间的语句,只有带有确认标记时才会运行;请参阅面向 AI Agent 的破坏性命令保护。
在执行有风险的迁移前备份数据库
情况: 即将执行一项会重写表的迁移。你想先导出备份——并确认备份确实有效,再让迁移动手。
问题:“我真的有备份吗?”
原始 docker CLI
$ docker compose exec -T postgres pg_dump -U app shop | gzip > backup.sql.gz
$ echo $?
0
$ ls -lh backup.sql.gz
-rw-r--r-- 1 you staff 20B 24 Aug 11:02 backup.sql.gz
退出码为零是由管道中的最后一个命令 gzip 返回的,而不是 pg_dump。二十字节只是一个空归档:导出因用户错误而失败,错误被发送到了终端,Shell 却报告成功。现在,迁移要基于一份并不存在的备份来运行。
结构化 MCP 结果
docker_db_admin({ "action": "backup", "service": "postgres", "project": "shop" })
{
"action": "backup",
"service": "postgres",
"project": "shop",
"engine": "postgresql",
"file": "/backups/shop-2026-08-24T11-02-17.dump.gz",
"bytes": 48219553,
"verified": true,
"message": null,
"confirmed": false,
"restarted": false,
"reason": null,
"legend": {
"verified": "The file was read back around the call, and bytes is its size on disk. This is the difference between a dump that exists and a command that did not fail."
}
}
对 Agent 有何影响
| 原始 Docker CLI | 结构化 MCP | 带来的好处 |
|---|---|---|
| 管道会报告最后一条命令的退出代码 | 转储会被读回,并报告其大小 | 空备份不会被误认为有效备份 |
| 每种引擎都需要各自的转储命令和标志 | 一个调用即可处理 PostgreSQL、MySQL、MongoDB、SQLite 和 Redis | 无论技术栈如何,都能使用同一工作流 |
| “完成”只是一个词 | verified 是一个字段,bytes: null 则说明大小未知的原因 | Agent 知道自己不知道什么 |
如果文件无法读回,结果会如实说明,而不会声称已知大小:verified
保持为 false,bytes 为 null,message 会说明是什么阻止了读取——不会把未知大小
报告为空文件。
将数据库填回去也使用同一工具:action: "restore"。它会覆盖现有内容,
因此在调用的 confirm 字段中携带确认标记之前,操作会被拒绝——
拒绝信息会提示你先在此处创建备份。
清理前先了解 Docker 磁盘用量
场景: 服务器磁盘使用率达到 90%。Docker 显然是怀疑对象,但你不知道 占用空间的是镜像、卷、已停止的容器还是构建缓存——清理错了就会 破坏数据库。
问题:“哪些内容可以安全回收?”
原始 Docker CLI
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 48 9 31.2GB 22.4GB (71%)
Containers 21 7 1.8GB 412MB (22%)
Local Volumes 19 6 64.9GB 38.1GB (58%)
Build Cache 264 0 9.7GB 9.7GB
$ docker system df -v | head -40
... several screens of per-image, per-container and per-volume tables ...
摘要便于人阅读,却会让 Agent 付出较高成本:百分比放在括号中,
大小以混合单位显示为文本,而详细视图长达数屏。要比较
“可回收卷”和“可回收镜像”,Agent 必须把 64.9GB 和
38.1GB (58%) 重新解析为数字。
结构化 MCP 结果
docker_resource({ "action": "disk" })
{
"action": "disk",
"count": 4,
"total_bytes": 115534368358,
"disk": [
{ "group": "images", "count": 48, "active": 9,
"size_bytes": 33500985344, "unused_bytes": 24051816448 },
{ "group": "containers", "count": 21, "active": 7,
"size_bytes": 1932735283, "unused_bytes": 431994470 },
{ "group": "volumes", "count": 19, "active": 6,
"size_bytes": 69686362112, "unused_bytes": 40908324864 },
{ "group": "build_cache", "count": 264, "active": 0,
"size_bytes": 10414285619, "unused_bytes": 10414285619 }
],
"reason": null,
"legend": {
"disk[].active": "How many of them something uses right now: a running container, or an image behind one.",
"disk[].unused_bytes": "Size of what nothing uses at the moment. Removing it frees less than this: what is shared stays until its last holder is gone.",
"disk[].group=images": "Images are counted by their layers on disk, so this is what they really take; the sizes of separate images add up to more, because a shared layer belongs to each of them.",
"disk[].group=containers": "Only what a container wrote on top of its image. What the image itself takes is counted with the images."
}
}
对 Agent 有何影响
| 原始 Docker CLI | 结构化 MCP | 带来的好处 |
|---|---|---|
| 大小以混合单位和百分比显示为文本 | 以数字形式表示字节,分为四个具名组 | Agent 直接比较,而不必解析 |
| 详细视图长达数屏 | 一次调用,每组一个数字 | 用更少的令牌获得相同答案 |
| “可回收”没有说明是什么在占用卷 | active 统计正在使用的内容,unused_bytes 统计未使用的内容 | 构建缓存可以清除,数据库卷则能保留 |
images、volumes 和 networks 会列出主机上持有的内容——卷还会显示其大小以及
有多少容器持有它们。空列表表示已查询但没有找到内容,这与从未查询
并不相同。
为 AI Agent 内置的破坏性命令防护
AI Agent 可能会生成有效但仍不该执行的命令。此服务会在任何内容传递给 Docker 或数据库客户端之前 添加本地防护,因此不可逆操作必须在发起请求的调用中明确确认。
该防护会区分两类操作:删除承载数据的对象——数据库、卷或 顶层目录——以及更改或删除其中的数据。第一类操作在确认前会被拒绝。 第二类操作可以执行,但会返回一条说明所做更改的警告。
阻止不可逆的数据丢失,警告破坏性变更
| 拒绝执行 — 目标本身 | 仅发出警告 — 目标内容 |
|---|---|
DROP DATABASE、DROP SCHEMA、dropdb | DROP TABLE、TRUNCATE |
FLUSHALL、FLUSHDB(Redis) | 不带 WHERE 的 DELETE FROM |
db.dropDatabase()(MongoDB) | 使用空筛选条件的 deleteMany({})、updateMany({}) |
docker volume rm、docker volume prune | docker image prune、docker container prune |
docker system prune | docker network prune |
rm -rf /、rm -rf ~、rm -rf /srv | rm -rf /srv/app/cache |
mkfs、dd of=/dev/... |
警告不等于拒绝:操作会执行,并会在答案的 warnings 中如实说明其销毁的内容。带有 WHERE 的 DELETE FROM orders 不会收到任何提示——这是一条普通语句。
删除操作要看目标位置。直接位于根目录下的目录包含某种整体内容——应用、数据或系统——因此会拒绝 rm -rf /srv,而 rm -rf /srv/app/cache 才是删除文件的正常用途。若命令封装在 sh -c 中,系统会将其解开,并逐层读取其中嵌套的 Shell。命令会作为一个 argv 运行,因此顶层分隔符会成为参数:echo "hi"; rm -rf /data 会打印一行内容,不会删除任何内容。
确认有意执行的破坏性操作
没有任何操作会被永久禁止。三个工具都支持确认机制,各自在危险所在之处生效:
docker_exec({ "service": "api",
"command": "rm -rf /srv/legacy # CONFIRMED-DESTRUCTIVE" })
docker_db({ "action": "query", "service": "redis",
"query": "FLUSHDB # CONFIRMED-DESTRUCTIVE" })
docker_compose_control({ "action": "down", "volumes": true,
"confirm": "# CONFIRMED-DESTRUCTIVE" })
标记会随调用一同传递,因此只会解除该次调用的拒绝,不影响其他调用。标记本身永远不会传到数据库或 Shell——语句执行前会将其移除。
每次拒绝都会说明将要删除的内容,因此可以在重试调用前先行查看,而不是直接跳过:DROP DATABASE shop destroys the database itself. Add # CONFIRMED-DESTRUCTIVE to the command to run it.
防护机制会逐次检查调用。它无法将一次调用中的删除操作与下一次调用中的读取操作关联起来,而且它只认识已知的工具——它无法识别会清空目录的自定义二进制程序。它是安全带,不是策略引擎:可恢复的操作仍由你决定。
用于容器、Compose 和数据库的 Docker MCP 工具
这是一套专注于 Docker 的 MCP 工具集,适用于 AI Agent 最常执行的工作:检查 Compose 堆栈、诊断服务、控制其生命周期、操作其数据库,以及了解主机资源。完整参数和示例请参阅 docs/tools.md。
所有工具都使用相同的 Docker Compose 术语。profile 用于选择 Docker 主机;project 用于选择 Compose 项目;service 用于从 Compose 文件中选择服务,而不是生成的容器名称。省略 profile 时,默认主机会响应。省略 project 时,将使用工作目录中的项目。仅当 Docker 尚未在该主机上运行过、因而无法解析项目时,才使用 compose_path。
检查 Docker Compose 堆栈
| 工具 | 功能 |
|---|---|
docker_container | 列出项目及其状态、健康状况和端口,或测量单个服务的资源消耗 |
docker_logs | 按行读取容器输出,并可按时间范围限定 |
docker_compose | 读取项目声明的内容:解析后的 compose 文件或其变量 |
docker_health | 查看服务的健康检查、此服务的健康状况,以及提供给它的主机 |
docker_resource | 查看主机的镜像、卷和网络,以及磁盘空间的去向 |
控制服务和堆栈生命周期
| 工具 | 功能 |
|---|---|
docker_container_control | 启动、停止或重启单个服务,并报告其操作前的状态 |
docker_compose_control | 启动整个堆栈,或将其关闭 |
使用在 Docker 中运行的数据库
| 工具 | 功能 |
|---|---|
docker_db | 执行语句,或询问数据库自身的信息 |
docker_db_admin | 导出数据库,或从转储文件填充数据库 |
PostgreSQL、MySQL/MariaDB、Redis、MongoDB 和 SQLite 都通过镜像中已有的客户端进行操作——无需在容器中安装任何内容。
默认隐藏密钥
使用 docker_compose 读取项目变量时,会隐藏键名中包含密钥的变量值——也就是名称中包含 PASSWORD、TOKEN、KEY、SECRET、PRIVATE 或 CREDENTIALS 的变量。每个变量都会注明是否已隐藏,因此不会把掩码值误当成真实值;确实需要时,设置 mask: false 即可返回原值。
没有合适的专用工具时运行命令
| 工具 | 功能 |
|---|---|
docker_exec | 在服务容器内运行命令,并分别输出 stdout 和 stderr |
MCP 客户端中的安全默认设置
标准 MCP 注解会告知客户端哪些工具可以安全地在无需询问的情况下运行。五个读取工具声明了 readOnlyHint。两个控制工具声明了 destructiveHint 和 idempotentHint——同一调用执行两次会留下相同状态。docker_db、docker_db_admin 和 docker_exec 只声明了 destructiveHint:它们处理的内容并非由服务写入,因此结果取决于你提供的内容。
设置 Docker MCP 服务
对于本地 Docker,将服务添加到 MCP 客户端即可开始使用。无需配置文件或 Docker 端点配置:服务会使用此机器上的 Docker 套接字。
只有当 AI Agent 需要通过 SSH 连接远程 Docker 主机时,才需要配置配置文件。
配置远程 Docker 主机
将配置文件存放在 MCP 客户端保存其配置的位置。每个配置文件都会为 Agent 提供一个 Docker 主机名称及所需的 SSH 连接详情:
{
"default": "local",
"profiles": {
"local": { "mode": "local" },
"production": {
"host": "prod.example.com",
"username": "deployer",
"port": 22,
"privateKeyPath": "~/.ssh/id_ed25519"
},
"staging": {
"host": "staging.example.com",
"username": "deployer",
"port": 2222,
"privateKeyPath": "~/.ssh/id_ed25519_staging"
}
}
}
mode: "local" 的配置文件表示此机器上的 Docker。远程配置文件需要 host 和 username;port 默认为 22。无需指定该服务器上 compose 项目的位置:系统会根据容器携带的标签查找项目。default 指定调用未提供 profile 时使用的配置文件。
优先使用密钥。不带 privateKeyPath 的配置文件会使用 SSH Agent;如果密钥经过加密,这是更好的选择。
系统会检查主机密钥:首次连接时,会将密钥保存到 ~/.ssh/known_hosts;如果之后主机返回不同的密钥,系统会拒绝连接,而不会继续通信。如果你将这些密钥单独存放,可在配置文件中使用 knownHostsPath 指定另一个文件。
配置 Claude Code、Codex、Cursor 和其他 MCP 客户端
Claude Code — 只需一条命令;-s user 会让服务在每个项目中都可用:
claude mcp add docker -s user \
-e DOCKER_MCP_PROFILES_FILE="$HOME/.claude/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
Codex CLI
codex mcp add docker \
--env DOCKER_MCP_PROFILES_FILE="$HOME/.codex/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
Cursor — 在 ~/.cursor/mcp.json 中:
{
"mcpServers": {
"docker": {
"command": "npx",
"args": ["-y", "@hypnosis/docker-mcp-server"],
"env": {
"DOCKER_MCP_PROFILES_FILE": "~/.cursor/docker-profiles.json"
}
}
}
}
opencode — 在 ~/.config/opencode/opencode.json 中:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"docker": {
"type": "local",
"command": ["npx", "-y", "@hypnosis/docker-mcp-server"],
"enabled": true,
"environment": {
"DOCKER_MCP_PROFILES_FILE": "~/.config/opencode/docker-profiles.json"
}
}
}
}
其他 MCP 客户端 — Gemini CLI、Qwen Code、Cline、编辑器插件或你自己的 Agent,配置方式都相同。它们只需要一条可运行的命令;对于远程主机,还需要一个环境变量。
验证连接
重启 MCP 客户端,然后运行 docker_health({ action: "profiles" })。它会列出服务从配置中读取到的 Docker 主机,并指出无法读取的配置文件以及需要处理的字段。
Docker MCP 服务配置
| 变量 | 作用 | 默认值 |
|---|---|---|
DOCKER_MCP_PROFILES_FILE | profiles JSON 文件的路径。未设置时,仅使用本地 Docker | — |
DOCKER_PROFILES | 内联的相同 JSON,在未设置 profiles 文件时使用 | — |
DOCKER_MCP_ALLOW_SSH_FALLBACK | 配置文件缺少密钥时继续运行,而不是拒绝 | false |
LOG_LEVEL | debug、info、warn、error | info |
DOCKER_PROFILES_FILE 是第一个变量已弃用的写法。它仍然有效,并会记录一条提示,要求你将其重命名。
默认情况下,如果配置文件指向不存在的密钥,系统会拒绝该配置,并说明路径和可采取的解决方式——否则,缺少密钥会导致连接尝试失败,而且要到很久之后、在不那么明显的地方才会发现。
Docker MCP 服务的限制
该服务更倾向于有明确边界的显式工具调用,而不是开放式或隐式行为。请注意以下当前限制:
- 日志跟踪有边界。
follow: true会返回 10 秒内或 1 MB 以内到达的内容,以先达到者为准。这是查看实时流的方式,不是订阅。 - 防护机制一次只读取一次调用。 它无法将一次调用中的删除操作与下一次调用中的读取操作关联起来,而且只能识别已知工具——会清空目录的自定义二进制文件不在其中。
- 主机资源按主机划分,而非按项目划分。
docker_resource会回答有关守护进程持有的所有资源的问题;若要缩小到单个项目的范围,请使用docker_container。 - 未经 Windows 验证。 服务中的内容并非针对某个平台编写,但尚未在 Windows 上完成端到端运行。
开发和测试 Docker MCP 服务
npm install
npm run build # tsc
npx tsc --noEmit # types
npm run test:unit # unit tests
npm run docker:test:up # start the test containers
npm run test:e2e # end-to-end suite against those containers
端到端测试套件使用真实的 PostgreSQL、MySQL、MariaDB、MongoDB、Redis 和 Web 服务容器运行。它会验证仅靠单元测试和模拟无法证明的 Docker 集成行为。项目布局请参见 docs/architecture.md。
支持 Docker MCP Server
如果这个工具对你的团队有所帮助,请在 GitHub 上为项目点星。这也能帮助其他开发者找到它。
为 Docker MCP 服务做贡献
欢迎在 github.com/hypnosis/docker-mcp-server提交问题和拉取请求。
许可证
MIT——请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。