内容
# 🐻 Bearier MCP
> **适用于所有人的多智能体桌面工具包**
[English](README.md) | [简体中文](README.zh-CN.md)
Bearier MCP 让两个桌面 AI 代理通过共享的本地任务队列异步协作 —— **无需 API 密钥、无需 IDE、无需云服务**。只需一个 SQLite 文件即可连接原本无法通信的代理。
将一个 **大脑** 代理(计划、调度、审查)与一个 **手** 代理(执行、报告)配对。它们通过 Bearier 协调,无需任一代理开放 API、SDK 或任何一行胶水代码。
```
大脑代理 手代理
(计划、调度、 (认领、执行、
审查结果) 回报)
│ │
│ MCP 标准输入输出 │ MCP 标准输入输出
▼ ▼
┌─────────────────────────────────────────┐
│ Bearier MCP 服务器 (标准输入输出) │
│ │
│ 共享 SQLite (本地) │
└─────────────────────────────────────────┘
```
## 为什么
大多数多智能体工具假设您是开发者,居住在 IDE 中,配置 API 密钥,并在 VS Code 中编写代理代码。**Bearier 是为其他人构建的** —— 使用桌面 AI 应用的人,他们没有开放的 API、SDK 和扩展接口,只有 MCP 配置文件和自然语言对话。
如果您的代理可以加载 MCP 服务器通过标准输入输出,Bearier 就可以连接它。这就是唯一的条件。
Bearier 本身只是一个 **任务邮局**:它可靠地中转任务,持久化状态和结果指针,并不干涉代理。它从不推理,从不执行命令,从不绕过任一代理的权限。
## 功能
- **6 状态机,终端状态保护** —— 已完成的任务永远不会被另一个工作者重新认领
- **原子任务认领** —— `UPDATE ... WHERE status='pending'` 在事务内部;数据库保证单个获胜者,即使在并发 `fetch_pending_tasks` 下
- **心跳租期续期 + 双层超时** —— 待处理任务若无人认领则过期为 `failed`;运行任务若租期到期,则被回收为 `failed/TIMEOUT`
- **审批门控** —— 标记为 `approval_required` 或 `destructive` 的任务被报告为 `needs_approval`,永远不会自动执行
- **路径安全** —— `working_directory`、`context_path`、`result_path` 通过 realpath 验证为允许列表;拒绝符号链接遍历
- **零重依赖** —— Python 标准库 `sqlite3` + `mcp`;无需 Node、Rust 或 Docker
- **跨平台** —— 在 macOS、Windows 和 Linux 上运行;路径适配通过 `os.pathsep`
## 快速开始
### 1. 安装 Python 依赖
Bearier 需要 Python 3.13+。创建虚拟环境并安装:
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
> **macOS 注意(无 Rust):** `mcp==1.28.1` 引入 `pyjwt[crypto]` → `cryptography`,需要 Rust 构建。由于标准输入输出从未使用 RS256 JWT,请分两步安装以跳过它:
> ```bash
> pip install --no-deps mcp==1.28.1
> pip install --only-binary :all httpx-sse==0.4.3 jsonschema==4.26.0 \
> python-multipart==0.0.32 sse-starlette==3.4.6 starlette \
> typing-inspection uvicorn pyjwt==2.13.0
> ```
验证:`python -c "from mcp.server.fastmcp import FastMCP; print('ok')"`
### 2. 配置两个代理
两个代理必须指向 **相同的 `BRIDGE_DB_PATH`** —— 这是它们看到对方写入的方式。
**WorkBuddy** —— `~/.workbuddy/mcp.json`:
```json
{
"mcpServers": {
"bearier": {
"command": "/path/to/python",
"args": ["/path/to/bearier-mcp/src/server.py"],
"env": {
"PYTHONPATH": "/path/to/bearier-mcp/src",
"BRIDGE_DB_PATH": "/path/to/bridge.db",
"ALLOWED_WORKSPACES": "/path/to/your/workspace",
"SHARED_DIR": "/path/to/your/shared"
}
}
}
}
```
**Codex 桌面版** —— `~/.codex/config.toml`(TOML,不是 JSON):
```toml
[mcp_servers.bearier]
type = "stdio"
command = "/path/to/python"
args = ["/path/to/bearier-mcp/src/server.py"]
startup_timeout_sec = 30
[mcp_servers.bearier.env]
PYTHONPATH = "/path/to/bearier-mcp/src"
BRIDGE_DB_PATH = "/path/to/bridge.db"
ALLOWED_WORKSPACES = "/path/to/your/workspace"
SHARED_DIR = "/path/to/your/shared"
```
重启两个应用程序后编写。在 WorkBuddy 中,还要在连接器管理页面上点击 **信任**。
### 3. 验证连接
要求每个代理调用 `ping(caller="codex" / "workbuddy")`,然后 `list_ping_log(limit=5)`。如果您看到两个 ping 消息,则桥接已激活。
## 工具(7)
| 工具 | 调用者 | 目的 |
|---|---|---|
| `ping(caller, note)` | 两个代理 | 连接性检查,写入 `ping_log` |
| `list_ping_log(limit)` | 两个代理 | 查看 ping 历史 |
| `db_info()` | 两个代理 | 数据库路径 + 统计信息(调试) |
| `assign_task(...)` | 大脑 | 调度自包含任务 |
| `fetch_pending_tasks(worker_id, limit, claim)` | 手 | 拉取工作;`claim=true` 原子转换为 `pending→running` |
| `report_result(task_id, worker_id, status, ...)` | 手 | 报告 `done` / `failed` / `needs_approval` / `cancelled` / `running`(心跳) |
| `get_task_result(task_id)` | 大脑 | 获取结果 + 完整事件时间线 |
## 状态机
```
pending → running 认领
pending → failed 认领超时(无工作者)
running → running 心跳 / 租期续期
running → done 成功
running → failed 失败 / 租期超时(TIMEOUT)
running → needs_approval 请求人工审批
running → cancelled 取消
```
`done` / `failed` / `needs_approval` / `cancelled` 是 **终端状态** —— 重新提交相同的终端状态是幂等的,并返回存储的结果。只有 `pending→running` 和 `running→running` 更改任务所有权;所有其他转换均由持有者报告。
## 自动化(手代理自动拉取)
安排手代理定期调用 `fetch_pending_tasks`,以便调度的工作在无人提示的情况下被拾取。建议的自动化提示:
> 调用 `fetch_pending_tasks(worker_id="workbuddy-default", limit=1, claim=true)`。如果 `count=0`,则静默返回。如果认领任务:根据 `instruction` 在 `working_directory` 中执行。在成功时调用 `report_result(status="done", task_id=..., worker_id="workbuddy-default", summary="...")`。在失败时调用 `report_result(status="failed", task_id=..., worker_id="workbuddy-default", error_code="EXEC_ERROR", error_message="...")`。标记为 `destructive` 或 `approval_required=true` 的任务被报告为 `needs_approval`,不会被执行。
对于实时协作,只需告诉手代理“拉取待处理任务” —— 它几秒钟内就会响应。自动化是离线备份。
## 仪表盘
在浏览器中可视化完整的协作时间线:
```bash
PYTHONPATH=src python src/dashboard.py
```
打开 `http://127.0.0.1:8765`。仅绑定到环回地址 —— 永远不会公开暴露。每个任务卡片显示标题、状态徽章、工作者、时间戳、错误(如果有)和事件时间线 (`created → claimed → completed`)。
## 安全
- **仅限标准输入输出** —— 无网络端口(仪表盘仅绑定到 `127.0.0.1`)
- **永远不要将数据库或仪表盘暴露给公共互联网**
- 数据库存储在本地系统磁盘上 —— **不在 ExFAT/可移动驱动器上**(多进程 SQLite 锁定在那里不可靠)
- `working_directory` 必须位于 `ALLOWED_WORKSPACES` 内
- `context_path` / `result_path` 必须位于 `working_directory` 或 `SHARED_DIR` 内(通过 realpath 验证,防遍历)
- `summary` ≤ 4 KB,`metadata` ≤ 16 KB;较大的负载通过 `result_path` 强制到磁盘
- `destructive` / `approval_required` 任务永远不会被自动化执行
## 错误代码
`VALIDATION_ERROR` / `TASK_NOT_FOUND` / `INVALID_STATE` / `TASK_ALREADY_CLAIMED` / `WORKER_MISMATCH` / `TIMEOUT` / `PERMISSION_DENIED` / `PATH_VIOLATION` / `RESULT_TOO_LARGE` / `EXEC_ERROR` / `DATABASE_BUSY` / `UNKNOWN`
统一响应形状: `{ok: bool, data: dict|null, error: {code, message, retryable}|null}`
## 比较
Bearier 占据了大多数多智能体工具不涉及的领域:
| | Bearier MCP | 智能体编排 | beads-village |
|---|---|---|---|
| 目标用户 | 所有人(非编码人员) | IDE 中的开发者 | IDE 中的开发者 |
| 目标智能体 | 桌面应用,无需 API | IDE 编码智能体(Cursor、Copilot) | IDE 编码智能体 |
| 智能体发现 | 通过 `worker_id`,无需共享 `cwd` | 需要相同的 `cwd` | 基于团队,相同项目 |
| 传输 | 标准输入输出 | 标准输入输出 | 标准输入输出 |
| 任务超时 | 双层(待处理 + 租期) | 仅限智能体级别 | 无 |
| 审批门控 | 是 | 研究门控 | 否 |
| 依赖 | 仅限 Python 标准库 | Node 18+ | Node + Python + 可选 Go |
如果您居住在 IDE 中,并希望在编辑器中实现丰富的协调,这些项目更合适。如果您有两个桌面 AI 应用,它们只会说 MCP,并希望它们可以相互传递任务 —— Bearier 就是桥梁。
## 项目结构
```
bearier-mcp/
├── README.md 本文件(英文)
├── README.zh-CN.md 中文版
├── requirements.txt 固定的依赖项
├── src/
│ ├── server.py MCP 服务器(7 个工具)
│ ├── config.py 配置加载 + 路径边界检查
│ ├── errors.py 12 个错误代码 + 统一响应
│ ├── models.py 6 状态机 + 任务数据结构
│ ├── db.py SQLite 连接 + 模式初始化
│ ├── repository.py 任务仓库(CRUD + 原子认领 + 超时扫描 + 路径验证)
│ └── dashboard.py 协作时间线 HTTP 服务器(127.0.0.1:8765)
├── tests/
│ ├── test_ping_client.py 连接性测试
│ ├── test_repository.py 数据层(29 个用例)
│ └── test_mcp_tools.py MCP 工具端到端(22 个用例)
└── config-examples/
├── workbuddy.mcp.json WorkBuddy 配置示例
└── codex-desktop.config.toml Codex 桌面版配置示例
```
## 测试
```bash
PYTHONPATH=src python tests/test_repository.py # 29 个用例
PYTHONPATH=src python tests/test_mcp_tools.py # 22 个用例
PYTHONPATH=src python tests/test_ping_client.py # 连接性
```
## 许可证
MIT