Docker MCP Gateway 配置指南:Profile、客户端连接与密钥管理
一步步配置 Docker MCP Gateway:运行 docker mcp gateway run、从 Catalog 创建 Profile、连接 Claude Code、Cursor 和 VS Code,并安全管理密钥。
Docker MCP Gateway 是一个开源代理:它把每个 MCP Server 放进隔离的 Docker 容器中运行,再通过同一个 MCP 端点统一暴露给你的 AI 客户端。你只需把 Server 加进一个 Profile,用 docker mcp gateway run --profile <name> 启动网关,然后让 Claude Code、Cursor、VS Code 或任何 MCP 客户端连接这一个网关,而不必逐个配置每个 Server。
本文完整覆盖当前(基于 Profile 的)工作流:安装、Catalog、Profile、客户端连接、密钥、默认开启的安全机制,以及用 Docker Compose 无界面运行网关。下面每条命令都已对照 Docker 官方 MCP Toolkit 文档 和 docker/mcp-gateway README(截至 2026 年 10 月)核实。
MCP Toolkit、MCP Gateway 和 MCP Catalog 的区别
这三个名字描述的是同一套技术栈:
| 组成部分 | 是什么 | 在哪里看到 |
|---|---|---|
| MCP Catalog | 一份精选的容器化 MCP Server 列表,以 OCI 镜像 mcp/docker-mcp-catalog 发布 | hub.docker.com/mcp、Docker Desktop 的 Catalog 标签页 |
| MCP Gateway | 负责启动 Server 容器、注入凭据、执行策略并路由调用的代理 | docker mcp gateway run |
| MCP Toolkit | 构建在两者之上的 Docker Desktop 界面 | Docker Desktop 侧边栏中的 MCP Toolkit |
docker mcp CLI | 驱动以上一切的 CLI 插件,脱离 Docker Desktop 也能用 | docker mcp --help |
架构很简单:AI 客户端 → MCP Gateway → MCP Server(容器)。由于客户端只和网关通信,一个 Server 配置一次,所有已连接的客户端都能看到。
前置条件
- Docker Desktop 4.62 或更高版本。 Docker 的 CLI 参考文档 明确说明当前的
docker mcp命令需要 4.62+;更早的版本 Toolkit 界面不同。该插件随 Docker Desktop 一起发布,所以docker mcp --help应该已经可以直接运行。 - 用的是 Docker CE、WSL2 或容器环境而不是 Desktop? CLI 依然可用。如果守护进程在运行却提示 "Docker Desktop is not running",设置
DOCKER_MCP_IN_CONTAINER=1,并显式启用 Profile 功能:
export DOCKER_MCP_IN_CONTAINER=1
docker mcp feature enable profiles
docker mcp feature list
第 1 步:浏览 Catalog
默认 Catalog 是 mcp/docker-mcp-catalog。拉取它并列出其中的 Server:
docker mcp catalog pull mcp/docker-mcp-catalog
docker mcp catalog ls
docker mcp catalog server ls mcp/docker-mcp-catalog
在 Docker Desktop 中,同样的列表位于 MCP Toolkit → Catalog。每个条目都有一个 Server 名,例如 github-official、duckduckgo 或 playwright,下一步会以 catalog://mcp/docker-mcp-catalog/<server> 的形式引用它们。
第 2 步:创建 Profile
Profile 是一组具名的 Server(连同它们的配置和工具白名单),客户端连接的就是它。Profile 取代了旧版的全局"已启用 Server"列表;早期 Toolkit 版本的配置会被自动迁移到名为 default 的 Profile 中。
# Create a profile with two catalog servers
docker mcp profile create --name dev-tools \
--server catalog://mcp/docker-mcp-catalog/github-official+duckduckgo
# Add another server later
docker mcp profile server add dev-tools \
--server catalog://mcp/docker-mcp-catalog/playwright
# Inspect what you have
docker mcp profile list
docker mcp profile show dev-tools
docker mcp profile server ls --filter profile=dev-tools
Server 引用并不局限于 Catalog。一个 Profile 可以混合使用 catalog:// 条目、你自己的镜像(docker://my-server:latest)、本地定义文件(file://./my-server.yaml)以及 MCP Registry URL(https://registry.modelcontextprotocol.io/v0/servers/<id>)。仓库的 Profile 文档 指出 Registry 引用尚未完全实现,所以目前优先使用 Catalog 或镜像引用。
有两个 Profile 功能值得从第一天就用起来:
# Per-server configuration (keys differ per server)
docker mcp profile config dev-tools --set github-official.<key>=<value>
docker mcp profile config dev-tools --get-all
# Tool allowlists: expose only what the agent needs
docker mcp profile tools dev-tools --disable-all github-official
docker mcp profile tools dev-tools --enable github-official.list_issues
精简工具比看上去更重要。每个暴露出来的工具都会占用上下文 token,工具越少,选错工具的情况也越少(参见我们的 MCP 工具发现指南)。
如果你更喜欢图形界面:MCP Toolkit → Profiles → Create profile,然后在 Catalog 标签页通过 Profile 下拉框添加 Server。Profile 的 Tools 标签页可以逐个开关工具。
第 3 步:运行网关
# stdio, using the "default" profile
docker mcp gateway run
# stdio, a specific profile
docker mcp gateway run --profile dev-tools
# Debug: show config, images and servers, then exit without listening
docker mcp gateway run --profile dev-tools --verbose --dry-run
不传 --profile 时,网关使用名为 default 的 Profile;如果它不存在,则使用空配置。大多数情况下你不需要自己以 stdio 模式启动网关:MCP 客户端会像启动其他 stdio Server 一样,把 docker mcp gateway run 作为子进程拉起。
第 4 步:连接客户端
最快的方式是 docker mcp client connect,它会为对应客户端写好配置文件。支持的客户端名称(来自 自动生成的 CLI 参考)包括 claude-code、claude-desktop、cursor、vscode、codex、gemini、zed、cline、continue、goose、kiro、lmstudio 和 opencode。
docker mcp client ls
docker mcp client connect <client> --profile dev-tools
docker mcp client disconnect <client>
Claude Code
docker mcp client connect claude-code --profile dev-tools --global
也可以用标准的 claude mcp add 语法手动添加(-- 之后的内容就是 Server 命令):
claude mcp add --scope user MCP_DOCKER -- docker mcp gateway run --profile dev-tools
在 Claude Code 里运行 /mcp 确认网关已连接。如果你设置了 CLAUDE_CONFIG_DIR,client connect 会写入该目录下的 .claude.json,而不是 ~/.claude.json。更多 Claude Code 配置见我们的 Claude Code MCP 指南。
Cursor
docker mcp client connect cursor --profile dev-tools
手动配置写在 ~/.cursor/mcp.json(全局)或 .cursor/mcp.json(项目级)中:
{
"mcpServers": {
"MCP_DOCKER": {
"command": "docker",
"args": ["mcp", "gateway", "run", "--profile", "dev-tools"]
}
}
}
VS Code(GitHub Copilot)
在项目目录中运行下面的命令。它会生成 .vscode/mcp.json,该文件是用户专属的,所以不要提交到 git:
docker mcp client connect vscode --profile dev-tools
echo ".vscode/mcp.json" >> .gitignore
手动配置使用 VS Code 的 servers 键:
{
"servers": {
"MCP_DOCKER": {
"type": "stdio",
"command": "docker",
"args": ["mcp", "gateway", "run", "--profile", "dev-tools"]
}
}
}
Claude Desktop 只需点一下:MCP Toolkit → Clients,点击 Claude Desktop 旁边的 Connect,然后重启它。其他客户端可以浏览 MCP 客户端目录。
第 5 步:密钥与 OAuth
需要 API Key 的 Server 从网关获取密钥,而不是从客户端配置里的环境变量获取。默认情况下,网关从 Docker Desktop 的密钥存储读取(--secrets=docker-desktop),其底层是操作系统的钥匙串。
# Pipe the value in via stdin so it never lands in shell history
echo "$GITHUB_TOKEN" | docker mcp secret set github.personal_access_token
docker mcp secret ls
docker mcp secret rm github.personal_access_token
密钥名称因 Server 而异(在 Docker Desktop 中查看该 Server 的 Configuration 标签页,或使用 docker mcp catalog server inspect)。密钥只对声明它的 Server 可见,一个 Server 读不到另一个 Server 的密钥。
对于基于 OAuth 的 Server,在 Docker Desktop 中打开该 Server 的 Configuration 标签页,选择 OAuth 并完成浏览器授权流程;之后可在 OAuth 标签页撤销授权。对应的 CLI 命令见 docker mcp oauth --help。Docker 的 Profile 文档 有两点提醒:OAuth 凭据在所有 Profile 之间共享;推送到镜像仓库的 Profile 从不包含凭据,因此团队成员需要在自己的机器上重新授权。协议层面的细节可以阅读 MCP 认证与 OAuth。
网关默认提供的安全机制
这正是把 Server 放到网关后面、而不是直接运行 npx some-server 的主要原因。根据仓库的 安全模型文档:
| 防护 | 默认 | 参数 / 设置 |
|---|---|---|
容器隔离、no-new-privileges、不传入宿主机环境变量 | 开启 | — |
| 每个 Server 的 CPU / 内存上限 | 1 CPU、2 GB | --cpus、--memory |
校验 mcp/ Catalog 镜像签名 | 开启 | --verify-signatures |
| 扫描工具参数和响应中疑似密钥的值 | 开启 | --block-secrets |
| 调用日志(只记录工具名和参数结构,不记录原始值) | 开启 | --log-calls |
| 限制出站网络 | 关闭 | --block-network |
| HTTP 传输要求 Bearer Token | 开启 | MCP_GATEWAY_AUTH_TOKEN,用 --allow-unauthenticated 关闭 |
| 拒绝不同 Server 之间的工具 / Prompt / Resource 重名 | 开启 | — |
宿主机目录挂载默认只读,且只允许白名单路径。远程 MCP URL 必须是公网 HTTPS。但这些都无法阻止工具返回内容中的提示词注入,所以仍要配合 MCP 安全最佳实践 中的做法。
通过 HTTP 为多个客户端提供服务
stdio 模式下每个客户端都有自己的网关进程。要共享一个网关,切换到 Streamable HTTP 传输:
export MCP_GATEWAY_AUTH_TOKEN="$(openssl rand -hex 32)"
docker mcp gateway run --profile dev-tools --transport streaming --port 8080
客户端连接 http://localhost:8080/mcp,并且必须携带 Authorization: Bearer <token> 请求头。在 Claude Code 中:
claude mcp add --transport http docker-gateway http://localhost:8080/mcp \
--header "Authorization: Bearer $MCP_GATEWAY_AUTH_TOKEN"
浏览器请求只接受来自 localhost 的 Origin,/health 端点不需要认证,方便做健康检查。
用 Docker Compose 运行网关
网关也以镜像 docker/mcp-gateway 发布,因此 Agent 和 CI 可以在没有 Docker Desktop 的情况下使用它。它需要挂载 Docker socket 来启动 Server 容器。这种模式下用 --servers(Catalog 名称)而不是 Profile 来列出 Server,密钥可以来自文件:
services:
gateway:
image: docker/mcp-gateway
command:
- --transport=streaming
- --port=8811
- --servers=github-official,duckduckgo
- --secrets=docker-desktop:/run/secrets/mcp_secret
environment:
- MCP_GATEWAY_AUTH_TOKEN=${MCP_GATEWAY_AUTH_TOKEN}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets:
- mcp_secret
secrets:
mcp_secret:
file: .env
.env 文件中写的是类似 github.personal_access_token=... 的行。你的 Agent 服务随后连接 http://gateway:8811/mcp。仓库的 examples 目录 还提供了 Python 客户端、PostgreSQL、拦截器(interceptors)、健康检查和远程 Server 等变体。--secrets 接受以冒号分隔的查找链:先查 Docker Desktop,再查挂载的文件。
Dynamic MCP:让 Agent 自己添加 Server
启用 Toolkit 后,网关还会暴露一些管理工具,例如 mcp-find(搜索 Catalog)、mcp-add 和 mcp-remove(为当前会话添加或移除 Server)以及 mcp-config-set。通过这种方式添加的 Server 只在当前会话有效,不会保存到 Profile。Docker 将此功能标记为实验性;如果你想要固定的工具列表,可以用 docker mcp feature disable dynamic-tools 关闭它(文档)。
故障排查
- 客户端看不到任何工具。 运行
docker mcp gateway run --profile dev-tools --verbose --dry-run。它会打印启用了哪些 Server、拉取了哪些镜像、加载了多少工具,能发现拼写错误、缺失的密钥和缺失的镜像。 - 单独排查某个工具调用。 先
docker mcp tools ls,再docker mcp tools call <tool> key=value。加上--verbose可以看到网关内部在做什么。 - Linux / WSL2 上提示 "Docker Desktop is not running"。 导出
DOCKER_MCP_IN_CONTAINER=1。 - 出现 "unsupported dialect" schema 错误。 升级网关;当前版本会自动把 draft-07 工具 schema 转换为 JSON Schema 2020-12。
- 你看的教程用的是
docker mcp server enable。 那是 Profile 之前的旧工作流。在 4.62+ 上,请改用docker mcp profile server add把 Server 加入 Profile。 - HTTP 传输返回 401。 带上
MCP_GATEWAY_AUTH_TOKEN中的 Bearer Token。可以用 MCP Inspector 在客户端之外测试这个端点。
下一步
先建一个只含两三个你信任的 Server 的小 Profile,把每个 Server 精简到你真正会调用的工具,然后只连接一个客户端。不错的起点包括 GitHub MCP Server、用于浏览器自动化的 Playwright MCP(参见 Playwright 配置指南),以及提供最新文档的 Context7。准备好扩展时,去 MCP.so Server 目录 找适合你技术栈的 Server。
常见问题
什么是 Docker MCP Gateway?
- 它是一个开源代理,以 docker mcp CLI 插件的形式发布,把 MCP Server 放在隔离的容器中运行,并通过单一 MCP 端点暴露给 AI 客户端。Docker Desktop 的 MCP Toolkit 是构建在它之上的图形界面。
Docker MCP Gateway 免费吗?
- 免费。网关是 GitHub 上以 MIT 协议开源的项目,MCP Toolkit 随 Docker Desktop 一起提供。Docker Desktop 本身仍遵循其常规许可条款。
不装 Docker Desktop 能用 Docker MCP Gateway 吗?
- 可以。你可以用 Docker Compose 运行 docker/mcp-gateway 镜像,或在 Docker CE 上直接使用 CLI。如果要在 Desktop 之外使用 Profile,先设置 DOCKER_MCP_IN_CONTAINER=1 并运行「docker mcp feature enable profiles」。
如何把 Claude Code 连接到 Docker MCP Gateway?
- 运行「docker mcp client connect claude-code --profile 你的Profile --global」,或用「claude mcp add MCP_DOCKER -- docker mcp gateway run --profile 你的Profile」手动添加。然后在 Claude Code 中运行 /mcp 确认已连接。