模型上下文协议(MCP)正在人工智能领域获得显著关注。该协议得到了大多数大型语言模型(LLM)提供商的支持,它增强了 LLM 的能力,使其能够管理诸如您的笔记本电脑文件系统、AWS 服务,以及本次讨论最重要的容器等资源。

MCP 采用客户端-服务器架构。本地 MCP 客户端将 LLM 提供商连接到一个或多个执行专业任务的 MCP 服务器。MCP 服务器的开发非常简单,这使得可用服务器数量迅速增加。
虽然 MCP 协议非常引人入胜(请参阅此处和此处的介绍性文章),但本文重点演示 LLM 如何使用 MCP 服务器管理容器。具体来说,我们将使用 RamaLama 在本地运行 Qwen 2.1 模型,Goose CLI 作为 MCP 客户端,以及 mcp-server-docker 来执行 Podman 命令。
使用 RamaLama 在本地运行 AI 模型
RamaLama 是一个用于在本地容器中运行 AI 模型的引擎,这使得在个人笔记本电脑上运行模型变得极其简单和安全。RamaLama 分析机器硬件(CPU、GPU、NPU 等),并自动选择最佳容器镜像和推理服务器选项来运行 AI 工作负载。
RamaLama 可以在 macOS、Windows 和 Linux 上运行。我们使用此命令在 macOS 上安装了它(有关不同的安装选项,请参阅文档)
curl -fsSL https://ramalama.ai/install.sh | bash
RamaLama 需要 Podman 或 Docker 才能在容器中运行 AI 模型。在 macOS 和 Windows 上,必须首先创建 Podman 机器。对于 macOS,我们使用以下命令创建 Podman 机器(任何现有的 Podman 机器必须首先停止)
$ CONTAINERS_MACHINE_PROVIDER=libkrun \
podman machine init --memory 4096 --now mcp-test
为了在运行 AI 模型的容器中使 Apple GPU 可用,使用 libkrun
而非默认的 applehv
至关重要。
Podman 配置完成后,RamaLama 的 serve 命令允许我们在容器中运行 Qwen 2.5 模型
$ ramalama --container --runtime=llama.cpp serve \
--ctx-size=32768 \
--port=11434 \
--webui off \
qwen2.5:7b
我们使用 --ctx-size
参数指定了一个大的上下文大小。与默认的 4K 令牌上下文相比,AI 模型在与 MCP 服务器交互时,32K 令牌上下文的性能更好。有关其他选项,请参阅 RamaLama 文档。
安装 MCP 客户端:Goose CLI
本地 MCP Agent 是使用 MCP 服务器的先决条件。有许多选项,例如 Claude Desktop 和 Visual Studio Code。我们将使用 Goose CLI,一个用于 CLI 脚本和自动化的命令行代理。
在 macOS 上,可以通过在终端中运行以下命令来安装 Goose CLI(也有适用于 Linux 和 Windows 的说明)
curl -fsSL \
https://github.com/block/goose/releases/download/stable/download_cli.sh \
| bash
Goose 连接到 LLM 提供商可以通过交互式方式完成,使用命令 goose configure,或者编辑其配置文件(macOS 上为 ~/.config/goose/config.yaml
)
cat << EOF > ~/.config/goose/config.yaml
GOOSE_PROVIDER: ollama
OLLAMA_HOST: localhost
GOOSE_MODEL: qwen2.5
EOF
此配置使 Goose 能够连接到 Ollama,并且至关重要的是 RamaLama。默认使用的模型将是 Qwen 2.5。
让 AI 模型使用 mcp-server-docker
运行容器
为了演示使用 MCP 服务器管理容器,我们将使用 mcp-server-docker。mcp-server-docker
需要正确配置 uv
(安装说明)和 Podman 或 Docker。
尽管名为 mcp-server-docker,如果 Podman 作为服务运行,它也可以使用 Podman。它使用 Python Docker SDK 并连接到默认的 Docker 套接字。$DOCKER_HOST
可用于指定不同的套接字路径。
Goose 的 run
命令,使用 mcp-server-docker
扩展,指示 AI 模型“部署一个 nginx 容器,将 80 端口暴露到 9000 端口”
goose run \
--with-extension "uvx mcp-server-docker" \
-n container-tests \
-t "deploy an nginx container exposing port 80 on port 9000"
上述示例在 macOS 上有效,Podman 机器已配置为监听默认的 Docker 套接字(unix:///var/run/docker.sock
)。在 Linux 上,您可能需要明确指定 Podman 套接字路径
--with-extension \
“DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock \
uvx mcp-server-docker”
结果,MCP 服务器将启动一个 nginx 容器并提供一些有用的信息

请注意,Goose 将会话状态保存在 ~/.local/share/goose/sessions/
文件夹中,并将日志保存在 ~/.local/state/goose/logs/cli
中,这对于调查其操作可能很有帮助。
值得注意的是,尽管 AI 模型在容器中运行,但 Goose 和 MCP 服务器在主机上执行,并拥有对主机资源的完全访问权限。如果这引起安全问题,可以将它们运行在容器中。
附录 1:使用不同的模型提供商
在本博客文章的准备过程中,尝试使用 Anthropic 和 Ollama 很有帮助。Anthropic 是一个更强大、更精细的模型提供商,与本地模型相比,它提供了更快的反馈循环,这有助于理解 MCP 服务器的功能。Ollama 促进了本地模型实验,而无需配置 Podman 或 Docker。一旦设置与这些提供商配合良好,RamaLama 可以很容易地进行调整,以在容器中运行相同的本地模型。
要将 Goose 与 Anthropic(使用模型 Claude Sonet 3.5)配合使用
$ export ANTHROPIC_API_KEY=<your key> # Get Key at https://console.anthropic.com/
$ cat << EOF > ~/.config/goose/config.yaml # Configure Goose
GOOSE_PROVIDER: anthropic
GOOSE_MODEL: claude-3-5-sonnet-latest
ANTHROPIC_HOST: https://api.anthropic.com
EOF
要将 Goose 与 Ollama(使用模型 Qwen 2.5)配合使用
$ cat << EOF > ~/.config/goose/config.yaml # Configure Goose
GOOSE_PROVIDER: ollama
OLLAMA_HOST: localhost
GOOSE_MODEL: qwen2.5
EOF
$ OLLAMA_CONTEXT_LENGTH=32768 ollama server # Start Ollama
$ curl https://:11434 # Check that Ollama is running
$ ollama run qwen2.5 # Pull Qwen 2.5 and run it locally
$ ollama ps # Show the running models details
附录 2:使用 podman-mcp-server 而非 mcp-server-docker
另一个用于 LLM 容器管理的 MCP 服务器是 podman-mcp-server。尽管它的 GitHub 星标少于 `mcp-server-docker`,并且尚未列入官方 MCP 服务器页面,但它不需要 Podman 作为服务运行,并且由 Red Hatter 的同事 Marc Nuri 开发,我决定对其进行测试
goose run \
--with-extension "npx -y podman-mcp-server" \
-n container-tests \
-t "deploy an nginx container exposing port 80 on port 9000"
生成的输出类似,并且容器创建正确。我注意到 `podman-mcp-server` 避免了我在 mcp-server-docker
中观察到的“已启动”和“已创建”之间的一些状态混淆。

附录 3:幻觉
由于 AI 模型的非确定性性质,一致的提示(“部署一个 nginx 容器,将其暴露在 9000 端口”)可能会产生略有不同的答案。有时,模型会遵循错误的路径,并确信错误的事情是真实的(被称为“幻觉”)。以下是一个示例,在本博客文章的准备过程中遇到,其中 AI 模型确信它应该创建一个卷但未能成功

发表评论