mcpField
V
vllm-ops-mcp

vllm-ops-mcp

本地服务
github.com/jaimenbell云与基础设施011 周前更新

关于 vllm-ops-mcp

vllm-ops-mcp 是面向本地 vLLM 实例的只读运维与健康检查 MCP 服务,针对由 WSL2 和 systemd 管理的环境。它通过 HTTP 探测区分存活与实际生成能力,并提供 GPU、服务状态及启动参数信息。

主要功能

  1. 01分层检查存活与生成能力
  2. 02列出可用模型
  3. 03执行限频的测试生成
  4. 04查看 GPU 显存与利用率
  5. 05查询 systemd 服务状态
  6. 06读取并脱敏启动参数

适用场景

  1. 01确认 vLLM 是否能实际生成
  2. 02检查 GPU 显存和利用率
  3. 03排查服务状态与启动参数

MCP 相关

向 MCP 客户端提供六个只读工具,用于健康探测、模型查询、测试生成和本地运行状态检查。深度健康检查与测试生成会调用真实推理,并受频率限制。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"jaimenbell-vllm-ops": {
"command": "uvx",
"args": [
"vllm-ops-mcp"
]
}
}
}
启动命令uvx vllm-ops-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypivllm-ops-mcp0.1.0

工具

6

收录的工具列表 · 更新于 2 周前

参数类型必填说明
deepboolean否

详细介绍

vllm-ops-mcp

License: MIT tests CI

面向本地、由 WSL2/systemd 管理的 vLLM 服务的只读运维/健康 MCP 服务——提供存活状态与实际完成请求健康等级、GPU/VRAM 状态、systemd 服务状态,以及实时服务启动标志检查。它遵循与 mcp-factory、desktop-mcp 及该运维人员作品集中的其他本地工具相同的标准:独立的 pyproject、独立的 fastmcp 服务、诚实的 README、真实的测试套件,并且只有在确认规格后才编写产品代码。

这不是容器生命周期管理器。它假定 vLLM 已作为裸机 systemd 单元在 WSL2 中运行(这是该运维人员实际使用的配置——见 vllm-autostart),而非运行在 Docker/Podman 中。

快速开始

// ~/.claude.json (or any MCP-host stdio client config)
{
  "mcpServers": {
    "vllm-ops-mcp": {
      "type": "stdio",
      "command": "C:\\Users\\<you>\\projects\\vllm-ops-mcp\\.venv\\Scripts\\python.exe",
      "args": ["C:\\Users\\<you>\\projects\\vllm-ops-mcp\\run_server.py"]
    }
  }
}

工具(阶段 1——全部为只读,除吞吐量上限外无需其他限制)

工具功能无法完成的操作
check_health(deep: bool = False)deep=False:GET /v1/models 存活检查(与 llm_router.LocalLLM.is_healthy() 的信号相同)。deep=True:还会发起一次最小的真实 /v1/chat/completions 调用(与 check-vllm.cmd 的两阶段探测相对应),以确认服务确实会生成内容,而不只是报告已加载模型。无法修复降级的服务——只报告实际状态。deep=True 受到速率限制(默认每分钟 20 次,见下文)。
list_models直接转发 /v1/models。无法提供超出 vLLM API 本身所公开内容的详情。
test_completion(prompt, max_tokens=16)使用调用者提供的提示词,按需进行真实补全,以便手动进行健全性检查。受到速率限制(与 check_health(deep=True) 使用同一个限制桶);如果存活检查未通过,则拒绝执行(服务甚至未在监听时,发起补全毫无意义)。max_tokens 会在服务端限制为 1024(config.MAX_TEST_COMPLETION_TOKENS),提示词上限为 8000 个字符(config.MAX_TEST_COMPLETION_PROMPT_CHARS;超长提示词会被拒绝,而不会截断)——速率限制只限制调用频率,不限制单次调用的成本。
get_gpu_statusnvidia-smi 封装:每个 GPU 的已用/总 VRAM 和利用率%,以及通过 --query-compute-apps 获取的各进程 VRAM。在该运维人员实际使用的 WSL2 配置中,无法按进程归属 VRAM——即使 vLLM 进程占用 13.7GB,实时验证结果仍为空(见“限制”)。processes 仅供尽力而为,且经常为空,不应视为可靠的按 PID 细分结果。
get_service_status通过 Windows 主机上的 wsl -d <distro> 执行 systemctl show <unit> -p ...(返回结构化属性,而非解析自由文本);如果此服务本身运行在 WSL2/Linux 内,则使用原生 systemctl。返回加载/活动/子状态、重启次数、主 PID 和上次活动时间戳。只读——无法启动/停止/重启单元。不计算运行时长(这是有意为之——见“限制”中的时钟同步说明)。
get_serve_config只读的启动标志检查。优先读取运行中进程的实际 argv(systemd 单元 MainPID 对应的 /proc/<pid>/cmdline——这是当前运行状态的真实依据);仅当进程未运行时,才回退到静态执行脚本(通过 VLLM_OPS_MCP_SERVE_CONFIG_PATH 指定的本地镜像,否则实时读取 WSL 侧执行脚本)。vLLM 不会通过 API 公开自身的启动标志,因此此工具不会查询服务本身——它始终通过 shell 命令读取。执行脚本回退解析是尽力而为的 shell 文本解析(精度低于实时 argv 路径)。
未来扩展:restart_service(第 2 阶段,尚未构建)

本版本中特意不实现。根据规范:vLLM 是其他机器人/工具依赖的共享基础设施(options-bot、qwen_cli.py 调用方、DeerFlow 回退机制),因此重启工具需要有自己的门控设计(默认关闭,VLLM_OPS_MCP_ENABLE_RESTART=1,除非 force=True,否则拒绝操作健康实例,并限制调用频率)之后才能发布——而不是事后改造只读 MVP。此功能仅列为 v2 的构想,并非当前能力。如果要构建,应封装 run-vllm.cmd 中的确切方案(仅执行 systemctl start vllm,绝不盲目执行 stop/restart),而非另行发明方案。

差异化优势:探测 HTTP,而非监听器

此服务中的所有健康信号都来自对 OpenAI 兼容 API 的实际 HTTP 请求(使用 urllib.request,而非套接字/连接检查)。这是刻意为之,并非偶然:Get-NetTCPConnection 等基于监听器的检查完全无法发现经 WSL2 镜像网络转发的端口——从 Windows 主机运行监听器探测时,实际健康的 127.0.0.1:8000 可能不可见。check-vllm.cmd 已经体现了这一经验;此服务则将其扩展为两层(存活状态与实际生成),而这两层是该运维人员的工具集里其他 MCP 工具都不具备的。

安全性

注册 vllm-ops-mcp 前请先阅读本节。坦诚说明影响范围正是本节的重点。

  • **此服务会调用 nvidia-smi、systemctl(通过 wsl -d),并读取 /proc/<pid>/cmdline。**全部六个工具均为只读——这里没有任何操作会启动、停止、重启或终止进程,也没有工具会接收未经转义就传入 shell 的参数(单元/发行版名称来自服务端配置,而非调用方输入;shlex.quote 会封装唯一一个与调用方相邻且确实会进入 shell 字符串的路径,即 systemctl show 中的单元名称)。
  • **check_health(deep=True) 和 test_completion 会向共享 GPU 服务发送实际推理请求。**这两项操作受频率限制(默认每分钟 20 次,由 VLLM_OPS_MCP_DEEP_RATE_LIMIT_PER_MIN 配置),尤其因为此 vLLM 实例是其他机器人/工具依赖的共享基础设施——即使每次调用单独来看都是“只读”的,调用方反复请求此 MCP 仍可能耗尽资源或拖慢其他使用方。
  • get_serve_config 的实时进程路径会读取 /proc/<pid>/cmdline,如果曾将机密作为 CLI 标志传入,其中可能包含机密信息(在该运维人员的实际设置中并无此情况——模型路径和标志均非机密;如有身份验证信息,则通过环境变量注入执行脚本,而非作为 argv 标志传入)。作为纵深防御措施:对于前一个标志名称匹配已知敏感模式(token、key、secret、password、passwd、credential——config. SENSITIVE_ARGV_FLAG_PATTERNS)的任何 argv 条目,其值在返回前都会被替换为 [REDACTED],结构化的 argv/flags 字段和 raw_text 中均如此;标志名称本身保持可见,以便仍能诊断参数结构。此规则适用于全部三个来源(live_process、exec_script、local_config_mirror)。
  • **此版本中的工具均不具备写入/修改能力。**没有任何环境变量可以启用此类能力——restart_service 尚不存在于此代码库中(见上文“未来扩展”),因此也就不存在误启用的可能。

能力真实性表

声明实现验证方式
存活健康等级(/v1/models)vllm_ops_mcp/probes.py::_probe_models、check_healthtests/test_probes.py::TestCheckHealthLiveness;实时验证:tests/test_live_smoke.py::test_live_check_health_liveness
深度/真实补全健康等级vllm_ops_mcp/probes.py::_probe_completion、check_health(deep=True)tests/test_probes.py::TestCheckHealthDeep;实时验证:test_live_check_health_deep
模型列表透传probes.py::list_modelstests/test_probes.py::TestListModels;实时验证:test_live_list_models
按需补全健全性检查probes.py::test_completiontests/test_probes.py::TestTestCompletion;实时验证:test_live_test_completion
通过 nvidia-smi 获取 GPU/VRAM 状态probes.py::get_gpu_statustests/test_probes.py::TestGetGpuStatus;实时验证:test_live_get_gpu_status
按进程归属 VRAMprobes.py::get_gpu_status(--query-compute-apps)使用模拟的非空响应进行单元测试;实时验证确认,在此操作员的实际 WSL2 环境中返回 EMPTY——请参阅限制
通过结构化的 systemctl show 获取 systemd 单元状态probes.py::get_service_statustests/test_probes.py::TestGetServiceStatus;实时验证:test_live_get_service_status
通过 /proc/<pid>/cmdline 检查运行中进程的启动标志probes.py::get_serve_config、parse_launch_flagstests/test_probes.py::TestGetServeConfig、TestParseLaunchFlags;实时验证:test_live_get_serve_config——实时确认其能够找回启动标志(--enable-auto-tool-choice --tool-call-parser qwen3_xml),而这些标志未出现在本仓库自身的依据规范中,证明实时 argv 方法优于信任静态文档
单元停止时回退到 Exec 脚本probes.py::get_serve_config、_parse_exec_script_texttests/test_probes.py::TestGetServeConfig::test_falls_back_to_exec_script_when_service_down
本地配置镜像覆盖路径probes.py::get_serve_config + config.serve_config_override_pathtests/test_probes.py::TestGetServeConfig::test_uses_local_override_file、test_override_file_missing_reports_error
在 get_serve_config 中对敏感标志值进行脱敏probes.py::redact_argv、redact_raw_text、config.SENSITIVE_ARGV_FLAG_PATTERNStests/test_probes.py::TestGetServeConfig::test_live_process_redacts_sensitive_flag_values、test_exec_script_raw_text_redacts_sensitive_flag_values、test_local_override_file_redacts_sensitive_flag_values
深度推理速率限制(共享基础设施保护)config.py::TokenBucket、DeepRateLimiter、check_deep_rate_limittests/test_config.py::TestTokenBucket、TestDeepRateLimiter
WSL 与原生 shell-out 抽象probes.py::_shell_args、config.runs_in_wsltests/test_config.py::TestRunsInWsl;tests/test_probes.py::TestGetServiceStatus::test_uses_wsl_prefix_on_windows、test_no_wsl_prefix_when_native
已注册全部 6 个工具,未包含 Phase-2 工具vllm_ops_mcp/server.pytests/test_server.py

局限(依赖此功能前请阅读)

  • 在此运维人员实际使用的 WSL2 GPU 直通配置下,按进程归属的显存数据不可靠。 get_gpu_status 的实时冒烟测试(使用真实的 nvidia-smi.exe 查询真实运行中的 vLLM 进程)返回了一个空的 processes 列表,尽管同一次调用中的 gpus[0].memory_used_mib 正确显示该进程占用了 13.7GB。这是部分 WSL2/直通配置下已记录的 nvidia-smi --query-compute-apps 局限,并非此服务的解析错误——工具如实报告空结果(ok: true, processes: []),而没有伪造归属信息。在此配置下,请勿依赖 processes 来排查显存超额占用的根因;gpus[].memory_used_mib 才是可靠指标。
  • 不计算服务运行时长。 get_service_status 返回 systemctl 中原始的 ActiveEnterTimestamp 字符串(已标注时区,例如 MDT),而不是在服务端计算已过时长——这是刻意设计的,遵循此运维人员自己的时钟纪律规则(绝不根据估算陈述已过时长或预计时间;产物时间戳通常为 UTC,而本地时间为 UTC-6/-7)。如果需要,请在调用处进行计算,并显式转换时区。
  • get_serve_config 的 exec 脚本回退方案采用尽力而为的 shell 文本解析,并非精确的 argv 数组——它通过 shlex.split 处理 \ 行续接和基本引号,但形式足够特殊的 exec 脚本可能会解析错误。实时进程路径(/proc/<pid>/cmdline)不受此局限(这是内核提供的精确 argv,以空字符分隔),并且只要单元处于运行状态,就始终优先使用此路径。
  • 默认针对 WSL2,但相关接口边界明确。 get_service_status 和 get_serve_config 的实时进程路径假定此服务运行在 Windows 主机上,并通过 wsl -d <distro> 在 WSL2 中执行命令。如果此服务进程本身在 WSL2/Linux 中原生运行,请设置 VLLM_OPS_MCP_RUNS_IN_WSL=1(使用原生 systemctl/cat,不经 wsl -d 跳转)——这两种路径均经过单元测试(TestGetServiceStatus::test_uses_wsl_prefix_on_windows / test_no_wsl_prefix_when_native),但只有 Windows 主机路径已在此运维人员的实际配置中进行过实时验证。
  • 适用于此运维人员的单个 vLLM 实例、单个 GPU 配置。 不支持聚合多个实例或多个 GPU;get_gpu_status 会返回 nvidia-smi --query-gpu 枚举到的所有 GPU,也就是进程可见的每个 GPU,而不会在存在多个 GPU 时限定为“vLLM 正在使用的 GPU”。
  • 此版本完全不提供生命周期控制。 请参阅上文“未来扩展”——这是有意为之,并非疏忽。

环境变量

变量作用默认值
VLLM_OPS_MCP_BASE_URLOpenAI 兼容的基础 URLhttp://127.0.0.1:8000/v1(显式使用 127.0.0.1,而非 localhost——请参阅 qwen_cli.py 中关于 IPv6 挂起问题的注意事项)
VLLM_OPS_MCP_MODEL服务模型名称,用于补全请求负载qwen3-14b
VLLM_OPS_MCP_WSL_DISTRO托管 vLLM 的 WSL 发行版Ubuntu-22.04
VLLM_OPS_MCP_SERVICE_UNITsystemd 单元名称vllm
VLLM_OPS_MCP_EXEC_SCRIPT_PATHserve exec 脚本在 WSL 中的路径(回退来源)~/vllm-systemd-exec.sh
VLLM_OPS_MCP_SERVE_CONFIG_PATHexec 脚本的本地文件副本;如果设置,get_serve_config 会直接读取此文件,而不是在回退时进入 WSL 执行命令未设置
VLLM_OPS_MCP_NVIDIA_SMI_PATH覆盖 nvidia-smi 二进制文件路径nvidia-smi(Windows 主机)/ nvidia-smi.exe(原生 WSL2)
VLLM_OPS_MCP_RUNS_IN_WSL若此服务进程本身在 WSL2/Linux 中运行,则设为 1(跳过 wsl -d 跳转)根据 sys.platform 自动检测
VLLM_OPS_MCP_DEEP_RATE_LIMIT_PER_MIN限制每分钟调用 check_health(deep=True) 和 test_completion 的次数20
VLLM_OPS_MCP_LIVE设为 1 以运行真实基础设施冒烟测试(请参阅“测试”)未设置(跳过)

使用示例

// A tool call from the MCP host, illustrative -- not a shell command.
{"tool": "check_health", "arguments": {"deep": true}}
// -> {"ok": true, "status": "up", "tier": "deep", "model_id": "qwen3-14b",
//     "latency_ms": 32.0, "completion_s": 0.218, "error": ""}

{"tool": "get_serve_config", "arguments": {}}
// -> {"ok": true, "source": "live_process", "pid": 5645,
//     "flags": {"model": "Qwen/Qwen3-14B-AWQ", "served_model_name": "qwen3-14b",
//               "port": "8000", "max_model_len": "8192",
//               "gpu_memory_utilization": "0.72", "max_num_seqs": "8",
//               "enable_auto_tool_choice": true, "tool_call_parser": "qwen3_xml", ...}}

// rate limit exceeded (21st deep call within a minute):
{"tool": "test_completion", "arguments": {"prompt": "hi"}}
// -> {"ok": false, "error": {"type": "rate_limited", "group": "deep_inference",
//     "tool": "test_completion", "limit_per_min": 20, "retry_after_s": 4.87}}

测试

CI(.github/workflows/ci.yml)会在每次推送和 PR 时运行此测试套件(ubuntu-latest —— 单元测试套件会模拟 HTTP/子进程,无需运行中的服务/GPU/WSL),并在 Tests 徽章与测试套件 实际报告的结果不一致时使构建失败——参见 scripts/check_readme_counts.py。

# unit suite (mocked HTTP/subprocess, no live server/GPU/WSL required)
.venv\Scripts\python.exe -m pytest -q
# -> 95 passed, 7 skipped

# handshake check -- prints every registered tool name
.venv\Scripts\python.exe scripts\list_tools.py

# real-infra smokes (real vLLM completion, real nvidia-smi, real systemctl
# via WSL, real /proc/<pid>/cmdline read) -- read-only, safe to run anytime
# vLLM is up
VLLM_OPS_MCP_LIVE=1 .venv\Scripts\python.exe -m pytest -v -m live
# -> 7 passed (all live, against the actual running qwen3-14b instance)

安装

python -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt

在 ~/.claude.json 中注册为 vllm-ops-mcp(stdio,使用独立的 .venv,此操作员的默认设置无需环境变量覆盖)。

商业支持

由 Jaimen Bell 维护。如需生产环境 MCP 集成、定制服务或 Agent 可靠性方面的工作,请访问 jaimenbell.dev。

正在构建自己的 MCP 服务?MCP Starter Kit 提供模板、构建指南,以及发布此服务过程中的打包经验分享。

mcp-name: io.github.jaimenbell/vllm-ops-mcp

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。