local-llm-mcp
# local-llm-mcp
本地模型管家 MCP:让任意 MCP 客户端(ZCode / Claude Code / Cursor…)一句话用上
本地 GGUF 模型——列模型、估显存、启停 llama-server、代理对话。
针对 8GB 显存(RTX 4060 Laptop)设计:显存裁判(建议 offload 层数)+
用完即关(闲置自动卸载)是核心能力,不是附属功能。
## MCP 工具(9个)
| Tool | 作用 |
|---|---|
| `ping` | 连通性测试 |
| `runtime_info` | 配置自检(模型目录 / llama-server 路径) |
| `list_models` | 扫描模型目录,返回架构/量化/层数/大小/多模态标志 |
| `estimate_vram` | 估算显存占用(权重+KV+开销),附建议 offload 层数 |
| `suggest_gpu_layers` | 在显存预算内建议最大 offload 层数 |
| `start_server` | 启动 llama-server 并阻塞到健康检查通过 |
| `stop_server` | 停止服务释放显存(幂等;PID 身份校验防误杀) |
| `server_status` | 查询运行状态(进程/健康/闲置计时) |
| `chat` | 对话转发到已加载模型(OpenAI 消息格式),自动剥离思考块 |
典型用法:`estimate_vram` 看放不放得下 → `start_server` 启动(MoE 大模型加
`extra_args=["--cpu-moe"]` 做 CPU+GPU 混合推理,8GB 卡跑 35B-A3B 约 10~15 tok/s)
→ `chat` 对话 → 用完 `stop_server`。忘记停也没关系:默认闲置 10 分钟自动卸载。
状态持久化在磁盘上,MCP 进程重启后 `stop_server` / `server_status` 依然有效。
## 快速开始
```bash
# 1. 安装 uv(Windows)
winget install astral-sh.uv
# 2. 克隆并同步依赖(自动使用 Python 3.12)
git clone https://github.com/Qinlupfu/local-llm-mcp.git
cd local-llm-mcp
uv sync
# 3. 按需设置环境变量(见下表),验证工具链
uv run python scripts/verify_phase0.py
```
llama.cpp 运行时需自备:从 [llama.cpp releases](https://github.com/ggml-org/llama.cpp/releases)
下载对应平台的预编译包(如 `llama-bXXXX-bin-win-cuda-13.3-x64.zip`),把目录设为
`LLM_MCP_LLAMA_DIR`。系统已装 CUDA toolkit(PATH 里有 cudart)时无需额外 cudart 包。
## 测试
```bash
uv run pytest tests/ -v # 单元测试(全部 mock,不碰真实进程/GPU)
uv run python scripts/integration_test.py # 真实集成:Gemma-1B 全生命周期 + 闲置卸载
```
集成测试会真实启动/停止 llama-server 并做一次事实问答,需要本机已配置好模型与运行时。
## ZCode 注册
写入用户级配置 `~/.zcode/cli/config.json` → `mcp.servers`(其他客户端同理):
```json
"local-llm": {
"command": "uv",
"args": ["--directory", "E:\\AI-models\\local-llm-mcp", "run", "local-llm-mcp"]
}
```
## 配置项(环境变量覆盖)
| 变量 | 默认值 | 说明 |
|---|---|---|
| `LLM_MCP_MODELS_ROOT` | `E:\AI-models\LLM` | GGUF 模型根目录 |
| `LLM_MCP_LLAMA_DIR` | `D:\AITools\LLMTools\llama-b10930-bin-win-cuda-13.3-x64` | llama.cpp 目录 |
| `LLM_MCP_PORT` | `18787` | llama-server 端口 |
| `LLM_MCP_CHAT_TIMEOUT` | `300` | chat 超时(秒);35B 混合推理较慢,给足余量 |
| `LLM_MCP_START_TIMEOUT` | `180` | 启动健康等待上限(秒) |
| `LLM_MCP_IDLE_TIMEOUT` | `600` | 闲置自动卸载(秒),0=不自动卸载;应大于 chat 超时 |
| `LLM_MCP_STATE_FILE` | `<项目>/.runtime_state.json` | 运行时状态文件 |
| `LLM_MCP_LOG_DIR` | `<项目>/.runtime_logs` | llama-server 日志目录 |
## 开发约定
- Python 3.12(`.python-version` 已锁定;系统 3.14 太新,部分轮子未编译)。
- 本项目用"任务书工作流"开发:`docs/tasks/` 下每个 Phase 一份任务书
(角色/接口/上下文/验收四段),交给本地 coding 模型写模块代码,
人负责集成层、接口钉死和"咒语级"细节(进程 API、库版本差异)。
- 集成层(`server.py` 的 tool 注册)只做参数透传和 `LocalLlmError` →
`{"ok": false, "error": 中文消息}` 的包装,不写业务逻辑。
TDQS
Scored across 9 tools
Most tools target distinct actions: ping, runtime_info, list_models, start/stop/status, chat. The only notable overlap is between estimate_vram and suggest_gpu_layers, since estimate_vram already returns a suggested_gpu_layers field; an agent could be unsure which to call for layer suggestions. Descriptions help but this pair remains somewhat confused.
All names use snake_case, which is consistent. However, the pattern is mixed: some are verb_noun (list_models, start_server, estimate_vram), while others are noun phrases (runtime_info, server_status) or simple verbs (ping, chat). Minor deviations keep it from a perfect verb_noun pattern.
Nine tools is well-scoped for local LLM server management. The set covers lifecycle, inspection, resource estimation, and inference without obvious bloat. Each tool has a clear role, making the count appropriate.
The surface covers core workflows: start/stop server, status, model listing, VRAM estimation, GPU layer suggestion, and chat. Minor gaps exist, such as no tool to stream or cancel an in-progress chat, no model download, and no configuration update. These are workable around but leave the surface slightly incomplete.