内容
# llama-mcp
MCP 服务器,用于与本地的 **llama.cpp**(`llama-server`)或 **LM Studio** 实例进行通信,该实例在工作站上运行,可远程安全访问 **无需打开任何公共端口**。
> **状态**:v1 已完成并经过端到端验证(服务器、启动脚本、独立发布、快速隧道、OAuth),针对真实的 LM Studio 实例。有关所有架构决策,请参见 [`CLAUDE.md`](./CLAUDE.md)。
## 用途
如果您已经支付 Claude 订阅费用,那么仅当它实际上节省令牌时,启用一个或多个本地代理才有意义:将基本、重复或可委托的工作(数据提取、分类、简单草稿、文档/图像分析...)卸载到运行在您自己的硬件上的较小/更便宜的模型,而不是在 Sonnet/Opus 令牌上花费。如果任务需要真正的推理,您最好直接使用 Sonnet — 这是用于评估此处每个新功能的过滤器。
## 架构
```
MCP 客户端(远程) --HTTP/SSE via tunnel--> Cloudflare Tunnel --> MCP 服务器(在工作站上) --localhost--> llama.cpp / LM Studio
```
- MCP 服务器在与 llama.cpp/LM Studio **相同的工作站**上运行,并通过 `localhost` 访问它。
- 远程访问通过 **Cloudflare 快速隧道**:无需公开端口,无需配置动态 DNS,无需 Cloudflare 帐户。
- 身份验证通过 **API 密钥 / 承载令牌**(Claude Code、脚本/CLI)或通过 **OAuth 2.1** 与 PKCE(claude.ai,ChatGPT — 网页客户端需要 OAuth,静态标头不够)。两者都由 MCP 服务器直接处理,无需委托给隧道。
- 目标:`llama-server` 和 LM Studio 暴露的 **OpenAI 兼容** API。
## MCP 工具暴露(v1)
- **`chat`** — 代理 `/v1/chat/completions`。接受 OpenAI 样式的 `messages` 数组(系统/用户/助手),可选生成参数(`temperature`,`max_tokens`,`top_p`,...)传递给后端,以及可选的 `model`(否则默认为服务器配置)。无流式传输:单个调用中的完整响应。
- **`list_models`** — 代理 `/v1/models`,列出后端可用的模型。
## 先决条件
- [.NET 10 SDK](https://dotnet.microsoft.com/)(仅用于构建/发布,不用于运行已发布的二进制文件)。
- [`cloudflared`](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) 在您的 `PATH` 中。
- `llama-server` 或 LM Studio 在工作站上运行,加载模型并激活 API 服务器(LM Studio 的默认端口 `1234`)。
## 快速启动(服务器 + 隧道)
```bash
# Linux/macOS
./start.sh
# Windows: 双击 start.bat,或
powershell -File start.ps1
```
脚本:
1. 生成一个随机承载令牌(或使用 `LLAMA_MCP_TOKEN` 中设置的令牌);
2. 启动 MCP 服务器(如果存在,使用 `publish/<rid>/` 中的发布二进制文件,否则回退到开发模式下的 `dotnet run`);
3. 启动 `cloudflared tunnel --url http://localhost:5181`;
4. 打印公用 URL (`https://xxxx.trycloudflare.com`) 和 MCP 客户端中使用的令牌。
URL 是短暂的:每次脚本重启时都会更改。
## 发布独立二进制文件
为了避免在工作站上需要 .NET 运行时:
```bash
# Linux
dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o publish/linux-x64
# Windows
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o publish\win-x64
```
`start.sh`/`start.ps1` 在这些确切的路径中查找二进制文件。
## 连接 MCP 客户端
使用 `start.sh`/`start.ps1` 打印的 URL 和令牌:
**Claude Code**(CLI):
```bash
claude mcp add --transport http llama-mcp https://xxxx.trycloudflare.com/ --header "Authorization: Bearer <token>"
```
**Claude Desktop**(`claude_desktop_config.json`):
```json
{
"mcpServers": {
"llama-mcp": {
"url": "https://xxxx.trycloudflare.com/",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
```
**claude.ai / ChatGPT(网页)** — 这些需要 OAuth,不接受静态标头:
1. 设置 → 连接器 → “添加自定义连接器” → 粘贴 URL (`https://xxxx.trycloudflare.com/`)。
2. 客户端自行发现 OAuth 端点并自动注册(动态客户端注册)— 如果它改为要求您手动输入“客户端 ID”,则自动注册未生效;请检查 URL 是否与脚本打印的 URL 完全匹配。
3. 服务器打开同意屏幕:输入 `start.sh`/`start.ps1` 打印的相同承载令牌(它充当批准密码,并且从未与网页客户端共享)。
4. 完成 — 网页客户端现在持有自己的访问/刷新令牌,与主承载令牌分开。
OAuth 状态(已注册客户端、颁发令牌、签名密钥)保存在 `~/.config/llama-mcp/`(Windows 上为 `%APPDATA%\llama-mcp\`)并在服务器重启后存活 — 无需在每次重启时重新授权每个客户端。
## 本地开发(无隧道)
```bash
Auth__BearerToken=<any-token-you-choose> dotnet run
```
服务器监听 `http://localhost:5181/`。每个 MCP 请求都需要 `Authorization: Bearer <token>` 标头(无它则为 401)。`Backend:BaseUrl` 默认值为 `http://localhost:1234`(LM Studio 的默认端口)— 可在 `appsettings.json` 中或通过 `Backend__BaseUrl` 环境变量配置。
## 技术栈
优先级:**.NET 10** → Python → Node.js。
## 许可证
请参阅 [LICENSE](./LICENSE)。