内容
# 🐝 local-swarm-mcp
<p align="center">
<a href="https://github.com/jhonsferg/local-swarm-mcp/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/jhonsferg/local-swarm-mcp/actions/workflows/ci.yml/badge.svg"></a>
<a href="https://github.com/jhonsferg/local-swarm-mcp/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
<img alt="Go" src="https://img.shields.io/badge/go-1.26%2B-00ADD8?logo=go&logoColor=white">
<img alt="MCP" src="https://img.shields.io/badge/MCP-compatible-6f42c1">
<img alt="Status" src="https://img.shields.io/badge/status-v0.5-orange">
</p>
<p align="center">
<img alt="Ollama" src="https://img.shields.io/badge/Ollama-supported-000000?logo=ollama&logoColor=white">
<img alt="llama.cpp" src="https://img.shields.io/badge/llama.cpp-supported-333333">
<img alt="vLLM" src="https://img.shields.io/badge/vLLM-supported-4B8BBE">
<img alt="OpenAI API" src="https://img.shields.io/badge/API-OpenAI--compatible-412991?logo=openai&logoColor=white">
</p>
<p align="center">
<img alt="Vue" src="https://img.shields.io/badge/Vue-3-4FC08D?logo=vuedotjs&logoColor=white">
<img alt="Tailwind CSS" src="https://img.shields.io/badge/Tailwind-CSS-06B6D4?logo=tailwindcss&logoColor=white">
<img alt="Vite" src="https://img.shields.io/badge/Vite-built-646CFF?logo=vite&logoColor=white">
</p>
MCP 服务器将机械性、低判断力任务委托给本地或远程 OpenAI 兼容的推理后端(llama.cpp 的 `llama-server`,Ollama,vLLM 或任何托管提供商,暴露相同的 API 形状),并为 MCP 客户端提供对该委托工作的完全控制:即时背景任务,多轮会话,持久性临时存储和上下文预算助手 - 与其自己的子代理类似的底层实现,由运行在您自己的硬件上的模型支持。 🖥️⚡
## 🧠 为什么
判断力高的工作(架构决策,判断发现是否为误报,编写有意义的测试)需要强大的模型。机械性工作(生成样板,日志摘要,格式化,重复转换)则不需要。本服务器允许 MCP 客户端将后者卸载到您已经运行的本地模型的硬件上,保持其自身的令牌预算用于前者 - 并像对待其自己的后台代理一样对待卸载的工作,而不是单个阻塞请求/响应调用。 💸
## 🗺️ 架构
```mermaid
flowchart LR
subgraph Client["🤖 MCP Client"]
A["AI Agent<br/>(e.g. Claude Code)"]
end
subgraph Server["🐝 local-swarm-mcp"]
direction TB
B["MCP Tools<br/>(stdio / HTTP)"]
C["Backend Registry"]
D["Task Registry<br/>(async + agent loop)"]
E["Session Registry<br/>(multi-turn)"]
F["Scratch Store<br/>(bbolt)"]
M["Downstream MCP<br/>client manager"]
B --> C
B --> D
B --> E
B --> F
D --> M
end
subgraph Backends["⚙️ Inference Backends"]
G["llama.cpp<br/>llama-server"]
H["Ollama"]
I["vLLM /<br/>remote provider"]
end
subgraph Downstream["🧩 Downstream MCP servers"]
J["codebase-memory-mcp"]
K["...other configured servers"]
end
A <-->|"MCP protocol"| B
C -->|"OpenAI-compatible API"| G
C -->|"OpenAI-compatible API"| H
C -->|"OpenAI-compatible API"| I
M <-->|"stdio MCP client"| J
M <-->|"stdio MCP client"| K
```
每个后端仅支持 OpenAI `/v1/chat/completions` + `/v1/models` 接口,因此服务器从不硬编码 vLLM/llama.cpp/Ollama 特定的逻辑。添加新提供商只需修改配置文件,不需要代码更改。下游 MCP 客户端管理器允许 `spawn_agent_task` 代理调用其他 MCP 服务器的工具,自主地,以循环方式,就像主机应用程序调用其自己的工具一样 - 请参阅 [工具使用代理](#-tool-using-agents-autonomous-like-a-host-applications-own-agents)。
## 🤝 预期客户端行为:检查可用性,然后优先使用此服务器而非原生代理
本服务器旨在与 MCP 客户端的原生代理/子代理功能并存,而不是取代它们。
```mermaid
sequenceDiagram
participant Agent as 🤖 AI Agent
participant MCP as 🐝 local-swarm-mcp
participant LLM as 🧩 Local Model
Agent->>MCP: health_check()
alt backend healthy
Agent->>MCP: classify_task_risk(description)
MCP-->>Agent: risk = low
Agent->>MCP: spawn_task(prompt)
MCP-->>Agent: task_id
MCP->>LLM: POST /v1/chat/completions
LLM-->>MCP: completion
Agent->>MCP: wait_task(task_id)
MCP-->>Agent: result ✅
else backend unreachable
Agent->>Agent: fall back to native agent 🔁
end
```
1. **在可能委托的任务开始时**,调用 `list_backends` 和/或 `health_check` 以确认至少有一个后端当前可达 - 配置的后端如果 `llama-server`/Ollama 进程未运行或远程 HTTP 传输实例离线,不应默默阻止工作。
2. **如果后端健康**,优先使用 `spawn_task`/`create_session` 而非客户端自己的原生子代理机制,用于机械性、低判断力工作(如果不确定任务是否符合条件,请先使用 `classify_task_risk`)- 这实际上节省了令牌/成本,因为工作在您已拥有的硬件上运行,而不是客户端自己的付费模型上。
3. **如果没有后端健康**,则回落到客户端的原生代理执行该工作,而不是使任务失败 - 本服务器是一种成本节约优化,而不是硬依赖。
服务器中没有任何内容强制执行此操作 - 这是一个客户端策略,本项目旨在支持。有关客户端如何应用它的具体配置,请参见客户端自己的配置文件(规则文件,内存,系统提示等)。
## ⚙️ 先决条件
**1. OpenAI 兼容的推理后端,在某个可达位置运行。**
local-swarm-mcp 本身不嵌入或捆绑推理引擎 - 它是推理引擎的前端客户端。可以选择适合您硬件的任意引擎;两者都在开发过程中针对此服务器进行了端到端验证。
### 🦙 Ollama(最简单 - 推荐如果您只想要一个可用的)
Ollama 捆绑了模型管理和 OpenAI 兼容的 API,并自动检测您的 GPU 后端(CUDA/ROCm/Metal/CPU),无需手动选择后端。
**Windows:**
```powershell
winget install --id Ollama.Ollama -e
```
**macOS:** 从 [ollama.com/download](https://ollama.com/download) 下载,或使用 `brew install ollama`。
**Linux:**
```bash
curl -fsSL https://ollama.com/install.sh | sh
```
然后拉取一个小模型并启动服务(Ollama 还会在 Windows/macOS 上自动启动为后台服务 - 如果它已经运行,则只需 `ollama serve`):
```bash
ollama pull qwen2.5-coder:1.5b # ~1GB, 适合 4-6GB VRAM 笔记本电脑
ollama serve # 如果不是已经作为服务运行
```
验证它是否启动:
```bash
curl http://localhost:11434/v1/models
```
Ollama 的 OpenAI 兼容端点是 `http://localhost:11434/v1`。
### 🔧 llama.cpp(更适合混合 NVIDIA/AMD 硬件)
更手动,但其 Vulkan 后端在 NVIDIA 和 AMD GPU 上运行,无需依赖 ROCm 的成熟度 - 如果您有例如 NVIDIA 笔记本电脑和 AMD 台式机,并且希望一个构建在两者上都起作用,则非常有用。
```bash
# 从源代码构建(https://github.com/ggml-org/llama.cpp),或为您的平台获取发布二进制文件,然后:
llama-server -m /path/to/model.gguf --host 0.0.0.0 --port 8080
```
其 OpenAI 兼容端点是 `http://<host>:8080/v1`。
### 🌐 其他
**vLLM** 或任何具有 OpenAI 兼容 `/v1/chat/completions` 端点的托管提供商也起作用 - 只需将后端条目指向它。
**2. local-swarm-mcp 本身** - 要么获取发布二进制文件,要么从源代码构建。参见下面的 [安装](#-installing)。
## 📦 安装
### Linux / macOS
```sh
curl -fsSL https://raw.githubusercontent.com/jhonsferg/local-swarm-mcp/main/install/install.sh | sh
```
### Windows
```powershell
irm https://raw.githubusercontent.com/jhonsferg/local-swarm-mcp/main/install/install.ps1 | iex
```
两个脚本都检测您的操作系统/架构,下载匹配的发布存档及其 `checksums.txt`,验证 SHA-256 校验和,并将 `local-swarm-mcp`(Windows 上为 `.exe`)安装到 `~/.local/bin`(Linux/macOS)或 `%USERPROFILE%\.local\bin`(Windows)。在覆盖安装位置或固定特定版本之前,请设置 `LSM_INSTALL_DIR`/`LSM_VERSION`(Windows 上为 `$env:LSM_INSTALL_DIR`/`$env:LSM_VERSION`)。
发布版本由 [goreleaser](https://goreleaser.com) 为 `linux,darwin,windows} x {amd64,arm64}` 构建,并在 `main` 的每次合并中自动发布,提交自上一个标签以来保证版本号的变更(Conventional Commits:`feat:` -> 次要版本,`fix:`/`perf:`/`refactor:` -> 补丁版本,`feat!:`/`BREAKING CHANGE` -> 主版本号)。参见 [发布版本](https://github.com/jhonsferg/local-swarm-mcp/releases)。
### 从源代码
```sh
go build -o local-swarm-mcp ./cmd/local-swarm-mcp
```
需要 Go 1.26 或更新版本。
## 🛠️ 配置后端
没有配置文件需要维护:以守护进程方式运行并通过 CLI 或 Web UI 添加后端,两种方式立即生效,无需重启。
```sh
# 启动一次守护进程,并启用仪表盘
local-swarm-mcp -transport http -insecure-no-auth -ui
# 然后,从 CLI(单独的终端,或脚本)或仪表盘的“注册主机”表单:
local-swarm-mcp -register-host -name local-llama -host-base-url http://localhost:11434
```
`-register-host` 要么与您刚刚启动的守护进程(如果已经在 `-http-addr` 处运行)通信,要么如果尚未运行,则成为守护进程本身 - 参见下面的 [主机发现](#-host-discovery---add-inference-hardware-without-editing-config-or-restarting) 以了解完整的机制。单个临时后端仅凭标志仍然有效,例如用于快速一次性 `-transport stdio` 运行:
```bash
local-swarm-mcp -backend-name local-llama -backend-url http://localhost:8080/v1 -backend-model qwen2.5-coder
```
### 最重要的标志
| 标志 | 默认值 | 目的 |
|---|---|---|
| `-transport` | `stdio` | `"stdio"`(作为本地子进程生成)或 `"http"`(持久守护进程) |
| `-ui` | `false` | 为 `/` 提供嵌入式仪表盘 - 仅适用于 `-transport=http` |
| `-http-addr` | `:8090` | `-transport=http` 时的监听地址,例如 `:8090` 或 `0.0.0.0:8090` |
| `-api-key` | *(无)* | `-transport=http` 时,HTTP 客户端必须提供的 Bearer 令牌;除非设置 `-insecure-no-auth`,否则需要 |
| `-insecure-no-auth` | `false` | 允许 `-transport=http` 无需 `-api-key` - 仅在受信任的隔离网络上 |
| `-register-host` | `false` | 注册推理主机以进行后台发现 - 参见 `-name`/`-host-base-url`/`-host-api-key` |
| `-backend-name`/`-backend-url`/`-backend-model`/`-backend-key` | *(无)* | 单个临时后端,用于快速运行,无需守护进程,无需注册 |
| `-store-path` | `<user cache dir>/local-swarm-mcp/scratch.db` | 覆盖临时存储文件位置 |
运行 `local-swarm-mcp -h` 以获取完整的分组标志引用(主机发现、下游 MCP 服务器、存储位置等)。
<details>
<summary>遗留:YAML/JSON 配置文件</summary>
`-config path/to/config.yaml`(或 `.json`)文件包含 `backends:` 和 `mcp_servers:` 列表,仍然有效,仍然在 `<user config dir>/local-swarm-mcp/config.yaml` 处自动检测(如果存在)- 这早于主机发现和动态下游 MCP 服务器注册,并且不再是推荐的配置任何涵盖这些功能的方法。它仅适用于一件事:一个固定的、版本可控的启动点,一次加载,然后永远不会改变,因为静态条目永远不会被发现者管理程序触及(它不是管理程序要管理的)。如果您已迁移到主机发现并且仍然看到不再存在的旧模型,此文件 - 而不是发现中的错误 - 几乎肯定是原因:要么删除它,要么清空其 `backends:` 列表,然后重启守护进程。
```yaml
backends:
- name: local-llama
base_url: http://localhost:8080/v1
model: qwen2.5-coder
mcp_servers:
- name: codebase-memory-mcp
command: /path/to/codebase-memory-mcp
store_path: C:\Users\you\.cache\local-swarm-mcp\scratch.db
```
⚠️ **此文件即使您从不传递 `-config`** 也会自动加载 - 默认值为相同的 `<user config dir>` 路径,因此如果它存在于早期设置中,其 `backends:` 列表每次都会被加载,并且会与动态注册的内容一起存在,因为静态条目永远不会被发现循环器管理(它不是循环器管理的)。如果您已迁移到主机发现并且仍然看到旧模型,则此文件 - 而不是发现中的错误 - 几乎肯定是原因:要么删除它,要么清空其 `backends:` 列表,然后重启守护进程。
</details>
## 🔌 注册 MCP 客户端
### 💻 本地(stdio)- 常见情况
将您的客户端的 MCP 配置(例如 Claude Code 的 `.mcp.json`)中的 `command` 指向构建的二进制文件:```json
{
"mcpServers": {
"local-swarm-mcp": {
"command": "/path/to/local-swarm-mcp"
}
}
}
```
保持此路径 **未版本化**(`local-swarm-mcp`,而不是 `local-swarm-mcp-v2`):重建到相同的固定路径意味着您的客户端配置永远不需要更改,您也不需要重启它 仅需拾取新版本。Windows 不允许覆盖正在运行的进程打开的 `.exe` 文件,但它 **允许** 重命名一个文件,然后重建并覆盖它:
```powershell
Rename-Item local-swarm-mcp.exe local-swarm-mcp.exe.old -ErrorAction SilentlyContinue
go build -o local-swarm-mcp.exe ./cmd/local-swarm-mcp
```
已经运行的进程在重命名文件后仍然可以正常工作,直到下次重启,此时它将使用来自相同稳定路径的新版本,而无需进行配置编辑。
### 🌍 远程(HTTP)- 在单独的 GPU 机器上运行
如果您的推理硬件位于与您的 MCP 客户端不同的机器上(例如 DGX Spark 或您网络上的其他具有 GPU 的 PC),请在那里运行 `local-swarm-mcp`,然后从另一个机器或从仪表盘注册该机器的本地推理服务器作为主机:
```bash
local-swarm-mcp -transport http -http-addr 0.0.0.0:8090 -api-key <a-strong-random-token> -ui
```
然后通过 HTTP 将您的 MCP 客户端指向它(确切的配置语法取决于您的客户端 - 请检查它是否支持 `url` + `headers` 样式的 MCP 条目,例如):
```json
{
"mcpServers": {
"local-swarm-mcp": {
"url": "http://gpu-host:8090/mcp",
"headers": { "Authorization": "Bearer <a-strong-random-token>" }
}
}
}
```
🔒 `-api-key` 是必需的,除非您传递 `-insecure-no-auth`,否则任何人都可以访问该端口,因此请像对待任何其他网络暴露的服务一样对待它。 `-insecure-no-auth` 仅在您完全信任并隔离的网络上是合理的(例如家庭 LAN 上没有其他不受信任的设备)。
### 🛰️ 主机发现 - 无需编辑配置或重启即可添加推理硬件
一旦运行 `-transport http`,local-swarm-mcp 就变成了一个小型服务发现守护进程,用于您的推理主机:注册一个主机(桌面 GPU,DGX Spark,AMD AI 盒 - 任何支持 Ollama API 的主机),它在后台永久轮询。主机上拉取的新模型自动显示为 `<host>/<model>` 后端 - 无需 YAML/JSON 编辑,无需客户端重启。
```bash
local-swarm-mcp -register-host -name rx9070 -host-base-url http://192.168.18.29:11434
```
- 如果已经有一个守护进程在默认地址运行,这是一个薄客户端:它会转发注册并退出。
- 如果还没有守护进程运行,则此调用 **变为** 守护进程(相同的进程,相同的领导者选举机制 `-transport http` 通常遵循)并保留注册。
恰好一个进程获胜:每个调用都会探测 `-http-addr`,如果没有人响应,则会回落到一个 PID 锁文件(`<user cache dir>/local-swarm-mcp/daemon.lock`)以及一个健康检查作为第二个独立确认 - 僵尸进程的过时锁将被自动回收,但一个仍然有效的 PID 但实际上并没有响应作为真正的 local-swarm-mcp 守护进程运行的 PID 将被报告为真正的冲突而不是被静默覆盖。
相同的操作也作为 MCP 工具可用(`register_backend_host`,`unregister_backend_host`,`list_backend_hosts`),因此代理 - 或您,通过您的 MCP 客户端 - 可以直接通过现有连接管理主机。`list_backend_hosts` 报告每个主机当前是否可达(`up`),因此您可以(或编排工作的代理)告诉一个主机在断电之前实际上可用,而不是仅仅注册但实际上不可达,然后再调度任务到它。
### 🔌 下游 MCP 服务器,动态
`mcp_servers:` 配置文件列表仍然像以前一样工作,但现在它是遗留的:`register_downstream_mcp_server`(及其 `unregister_downstream_mcp_server` / `list_downstream_mcp_servers` 对应项)允许在运行时注册服务器,如 `codebase-memory-mcp` - 立即生成并连接,持久化,以便在守护进程重启时自动重新连接,无需配置文件或重启。相同的三个操作也通过嵌入式仪表盘和 HTTP 管理界面公开(`POST /admin/register-mcp-server`,`POST /admin/unregister-mcp-server`,`GET /admin/mcp-servers`)。
</div>
## 📊 仪表盘
```
local-swarm-mcp -transport http -insecure-no-auth -ui
```
`-ui` 在 `/` 处提供一个嵌入式仪表盘(一个小型 Vue 应用 - 参见 [`ui/`](ui/)),显示已配置的后端、已注册的推理主机,带有实时上下线状态和已发现的模型,已注册的下游 MCP 服务器,带有实时连接/断开状态,以及实时日志流。页面上的所有内容都是同一个 `/admin/*` 端点的薄客户端 - 您可以在不触摸配置文件或终端的情况下注册或编辑主机,注册下游 MCP 服务器,或实时查看守护进程正在执行的操作。
## 🧰 工具
### 🔗 后端
| 工具 | 用途 |
|---|---|
| `list_backends` | 列出已配置的后端(名称,基准 URL,模型) |
| `health_check` | 探测一个后端的可达性,或省略所有后端 |
### 🛰️ 主机发现(仅在运行 `-transport http` 时)
| 工具 | 用途 |
|---|---|
| `register_backend_host` | 注册一个新的推理主机用于后台模型发现 |
| `unregister_backend_host` | 删除已注册的主机并停止轮询它 |
| `list_backend_hosts` | 列出已注册的主机,主机当前是否可达,以及在其上发现的模型 |
### 🔌 下游 MCP 服务器(仅在运行 `-transport http` 时)
| 工具 | 用途 |
|---|---|
| `register_downstream_mcp_server` | 在运行时注册和连接下游 MCP 服务器(例如 codebase-memory-mcp) |
| `unregister_downstream_mcp_server` | 断开并删除已注册的下游 MCP 服务器 |
| `list_downstream_mcp_servers` | 列出已注册的下游服务器以及它们当前是否连接 |
### ⚡ 一次性委托
| 工具 | 用途 |
|---|---|
| `delegate_task` | 向后端发送任务并阻塞以等待完成 - 简单同步路径 |
| `compact_context` | 通过后端将文本块压缩到目标大小,以免在客户端自己的上下文中占用过多空间 |
`delegate_task`、`spawn_task`、`send_message` 和 `spawn_agent_task` 都采用相同的三个采样参数:`max_tokens`、`temperature`、`top_p`。故意仅使用这三个参数 - 它们是 OpenAI 聊天完成规范实际定义的,因此无论后端是 llama.cpp、Ollama、vLLM 还是托管提供商,都能一致地受到尊重。Ollama 特有的参数,如 `num_ctx`(上下文窗口大小)或 `top_k`,不是该规范的一部分:经过验证,Ollama 的 OpenAI 兼容端点接受它们在一个 `options` 对象中,但不会报错,而是会静默忽略它们,因此这里不提供它们 - 一个看起来有效但实际上无效的参数可能会比没有该参数更糟糕。目前,调整这些参数的实际方法要么是使用 `ollama create` 构建派生模型并在其内部嵌入 `PARAMETER num_ctx ...`,要么直接调用后端的原生 API 而不是通过 local-swarm-mcp。
### 🎯 后台任务(fire-and-forget,如生成子代理)
| 工具 | 用途 |
|---|---|
| `spawn_task` | 在后台启动任务,立即返回任务 ID |
| `task_status` | 任务状态的非阻塞快照(待处理/运行/完成/失败/取消) |
| `wait_task` | 阻塞直到任务完成或超时,然后返回其最终快照 |
| `list_tasks` | 列出此服务器运行期间启动的所有任务 |
| `cancel_task` | 取消正在运行的任务 |
### 🧑🔧 使用工具的代理(自主,如主机应用程序的代理)
| 工具 | 用途 |
|---|---|
| `spawn_agent_task` | 启动一个后台代理,可以从配置的下游 MCP 服务器(配置中的 `mcp_servers`)循环调用工具,然后回答,跟踪使用 `task_status`/`wait_task`/`list_tasks`/`cancel_task` 工具。结果包括每次工具调用的完整记录,用于审计。 |
| `list_available_agent_tools` | 列出从配置的下游 MCP 服务器发现的所有工具(命名空间 `<server>__<tool>`),代理可以调用 |
⚠️ **需要支持调用工具的模型。** 并非所有声称支持“工具”的模型实际上都会产生真正的结构化 `tool_calls` 响应。在此项目中验证:
| 模型 | 真实的 `tool_calls`? |
|---|---|
| `llama3.1:8b`(Ollama) | ✅ 是 |
| `qwen2.5-coder:7b`(Ollama) | ❌ 否 - 打印 tool-call-shaped JSON 作为纯文本 |
| `qwen2.5-coder:1.5b`(Ollama) | ❌ 否 - 相同的失败模式 |
在依赖 `spawn_agent_task` 之前,请使用简单的工具架构测试新模型 - 失败的模型会静默打印其“调用”为文本,循环只是将其视为(可能错误)的最终输出。
示例配置将 `codebase-memory-mcp`(先前安装,参见其自己的文档)作为下游服务器:
```yaml
backends:
- name: agent-model
base_url: http://localhost:11434/v1
model: llama3.1:8b
mcp_servers:
- name: codebase-memory-mcp
command: /path/to/codebase-memory-mcp
```
🔒 下游工具访问是按需配置的,每个服务器配置;`codebase-memory-mcp` 是一个很好的参考集成,因为其工具是只读的(索引和查询,无写入)。在将代理任务指向具有写入/破坏性工具的下游服务器之前,请仔细考虑 - 驱动它的模型可能比配置它的客户端可靠性要低得多。
### 💬 会话(持久多轮对话,如恢复命名代理)
| 工具 | 用途 |
|---|---|
| `create_session` | 使用可选系统提示打开与后端的会话 |
| `send_message` | 在会话中发送消息,携带其完整的历史记录,并获取回复 |
| `session_history` | 返回会话的完整消息历史记录 |
| `close_session` | 丢弃会话 |
| `list_sessions` | 列出每个打开会话的后端和消息计数 |
### 🗄️ 临时存储(客户端上下文之外的持久键值空间)
| 工具 | 用途 |
|---|---|
| `scratch_set` | 存储键下的值 |
| `scratch_get` | 通过键检索值 |
| `scratch_list` | 列出所有存储的键 |
| `scratch_delete` | 删除键 |
### 📊 上下文预算
| 工具 | 用途 |
|---|---|
| `estimate_tokens` | 粗略的启发式标记计数,用于块状文本,以确定是否值得调用 `compact_context` |
| `classify_task_risk` | 快速基于规则的检查(无模型调用),标记任务描述是否看起来不安全以委托(破坏性 git/DB 操作、秘密、架构决策)- 不权威,只是快速第一步 |
## 🧪 开发
```
go build ./...
go vet ./...
go test ./... -race -covermode=atomic
```
`-race` 需要 cgo(`CGO_ENABLED=1`);在没有 C 工具链的机器上,本地运行时请删除 `-race` - CI 仍会在所有三个操作系统上运行它。
### 构建仪表盘(`ui/`)
嵌入式仪表盘是一个单独的 Vue 3 + TypeScript + Tailwind 项目,位于 [`ui/`](ui/),与 Go 服务器保持独立,以便每个端都有自己的快速测试循环(UI 组件的 `vitest`,服务器的 `go test`),而不是一个缓慢、纠缠不清的测试循环。
```
cd ui
npm install
npm run test # vitest,组件级
npm run build # 类型检查(vue-tsc)然后直接构建到 ../internal/webui/dist,cmd/local-swarm-mcp 通过 go:embed 嵌入
```
`internal/webui/dist` 处提交了一个最小占位符,以便在没有 Node 安装的情况下,裸 `go build ./...` 永远不会中断 - CI 和 goreleaser 始终会先运行真正的 `npm run build`(参见 `.github/workflows/ci.yml` 中的 `ui` 作业和 `.goreleaser.yml` 中的 `before.hooks`),因此发布和 CI 测试的二进制文件始终会提供实际的仪表盘,而不是占位符。如果您编辑了 `ui/src` 下的任何内容,请运行 `npm run build` 并将生成的更改提交到 `internal/webui/dist`,以便占位符保持对每个人来说合理的新鲜度。
对于针对正在运行的守护进程的前端开发,`npm run dev` 启动 Vite 的开发服务器,将 `/admin` 代理到 `http://localhost:8090`(参见 `ui/vite.config.ts`)- 通过编辑该代理目标,将其指向不同的 `-http-addr`。
## 📌 状态
v0.5 - 核心委托、任务编排、会话、上下文工具、使用工具的代理、发布管道、多主机推理发现、动态下游 MCP 服务器注册、结构化日志记录和嵌入式仪表盘全部到位。针对两个真实 Ollama 后端和两台机器(6GB-VRAM 笔记本电脑 GPU 和 16GB-VRAM 台式机 GPU 在同一 LAN 上)进行了端到端验证:
- v0.1:所有 20 个工具已注册并针对 `qwen2.5-coder:1.5b` 正确响应,包括完整的 spawn/wait 任务往返和多轮会话。
- v0.2:针对 `llama3.1:8b` 运行 `spawn_agent_task`,并将 `codebase-memory-mcp` 作为下游服务器连接,正确调用 `index_repository` 在此仓库上并报告真实结果(288 个节点,937 个边)而不是幻觉结果,并在任务记录中记录工具调用。
- v0.3:自动发布管道(Conventional Commits 增量检测,goreleaser)和 Linux/macOS 和 Windows 的一键安装脚本,均针对 goreleaser 生成的真实存档和校验和进行验证。
- v0.4:针对真实远程 Ollama 实例的 `-register-host` - 客户端路径(现有守护进程转发注册)和守护进程选举路径(尚未运行守护进程,调用成为一个)均已验证;后台轮询器正确发现了一个新拉取的模型(`gemma4:12b`)并使其在主机上可调用,命名为 `rx9070/gemma4:12b`,无需任何配置编辑或重启。
- v0.5:`-ui` 在真实守护进程和真实远程主机上验证 - 从仪表盘注册、编辑和删除主机和下游 MCP 服务器均通过 `/admin/*` 端点成功完成,实时日志流(SSE)显示每个操作的发生,并且 `goreleaser build --snapshot` 生成的发布二进制文件提供真实的(非占位符)仪表盘,确认整个 `ui/` → `internal/webui/dist` → `go:embed` 管道在 CI 之外也有效。
## 📄 许可证
MIT - 参见 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器