bearier-mcp
Bearier MCP lets two desktop AI agents collaborate asynchronously through a shared local task queue — no API keys, no IDE, no cloud. Just one SQLite file bridging agents that otherwise can't talk to each other.
README
🐻 Bearier MCP
Multi-Agent Desktop Toolkit for Everyone
Bearier MCP lets two desktop AI agents collaborate asynchronously through a shared local task queue — no API keys, no IDE, no cloud. Just one SQLite file bridging agents that otherwise can't talk to each other.
Pair a brain agent (plans, dispatches, reviews) with a hands agent (executes, reports). They coordinate through Bearier without either one needing an open API, an SDK, or a single line of glue code.
Brain agent Hands agent
(plans, dispatches, (claims, executes,
reviews results) reports back)
│ │
│ MCP stdio │ MCP stdio
▼ ▼
┌─────────────────────────────────────────┐
│ Bearier MCP server (stdio) │
│ │
│ shared SQLite (local) │
└─────────────────────────────────────────┘
Why
Most multi-agent tooling assumes you're a developer who lives in an IDE, configures API keys, and wires up coding agents inside VS Code. Bearier is built for everyone else — people who use desktop AI apps that have no open API, no SDK, and no extension surface beyond an MCP config file and natural-language conversation.
If your agent can load an MCP server over stdio, it can join Bearier. That's the only requirement.
Bearier itself is just a task post office: it reliably relays tasks, persists state and result pointers, and gets out of the way. It never reasons, never executes commands, and never bypasses either agent's own permissions.
Features
- 6-state machine with terminal-state protection — a finished task can never be re-claimed by another worker
- Atomic task claiming —
UPDATE ... WHERE status='pending'inside a transaction; the database guarantees a single winner even under concurrentfetch_pending_tasks - Heartbeat lease renewal + dual-layer timeout — pending tasks that nobody claims expire to
failed; running tasks whose lease lapses are reaped tofailed/TIMEOUT - Approval gating — tasks flagged
approval_requiredordestructiveare reported asneeds_approvaland never auto-executed - Path safety —
working_directory,context_path,result_pathare validated by realpath against an allowlist; symlink traversal is rejected - Zero heavy dependencies — Python stdlib
sqlite3+mcp; no Node, no Rust, no Docker - Cross-platform — runs on macOS, Windows, and Linux; paths adapt via
os.pathsep
Quick start
1. Install Python dependencies
Bearier needs Python 3.13+. Create a venv and install:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
macOS note (no Rust):
mcp==1.28.1pullspyjwt[crypto]→cryptography, which needs Rust to build. Since stdio never uses RS256 JWT, install in two steps to skip it: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
Verify: python -c "from mcp.server.fastmcp import FastMCP; print('ok')"
2. Configure both agents
Both agents must point at the same BRIDGE_DB_PATH — that's how they see each other's writes.
WorkBuddy — ~/.workbuddy/mcp.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 desktop — ~/.codex/config.toml (TOML, not JSON):
[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"
Restart both apps after writing. In WorkBuddy, also click Trust on the connector management page.
3. Verify connectivity
Ask each agent to call ping(caller="codex" / "workbuddy"), then list_ping_log(limit=5). If you see both pings, the bridge is live.
Tools (7)
| Tool | Called by | Purpose |
|---|---|---|
ping(caller, note) |
both | connectivity check, writes ping_log |
list_ping_log(limit) |
both | view ping history |
db_info() |
both | database path + stats (debugging) |
assign_task(...) |
brain | dispatch a self-contained task |
fetch_pending_tasks(worker_id, limit, claim) |
hands | pull work; claim=true atomically transitions pending→running |
report_result(task_id, worker_id, status, ...) |
hands | report done / failed / needs_approval / cancelled / running (heartbeat) |
get_task_result(task_id) |
brain | fetch result + full event timeline |
State machine
pending → running claim
pending → failed claim timeout (no worker)
running → running heartbeat / lease renewal
running → done success
running → failed failure / lease timeout (TIMEOUT)
running → needs_approval requests human approval
running → cancelled cancelled
done / failed / needs_approval / cancelled are terminal — re-submitting the same terminal state is idempotent and returns the stored result. Only pending→running and running→running change task ownership; all other transitions are reported by the holding worker.
Automation (hands agent auto-pull)
Schedule the hands agent to periodically call fetch_pending_tasks so dispatched work gets picked up without human prompting. Suggested automation prompt:
Call
fetch_pending_tasks(worker_id="workbuddy-default", limit=1, claim=true). Ifcount=0, return silently. If a task is claimed: execute perinstructioninsideworking_directory. On success callreport_result(status="done", task_id=..., worker_id="workbuddy-default", summary="..."). On failure callreport_result(status="failed", task_id=..., worker_id="workbuddy-default", error_code="EXEC_ERROR", error_message="..."). Tasks markeddestructiveorapproval_required=trueare reported asneeds_approvaland not executed.
For real-time collaboration, just tell the hands agent "pull pending tasks" — it responds in seconds. Automation is the offline backstop.
Dashboard
Visualize the full collaboration timeline in a browser:
PYTHONPATH=src python src/dashboard.py
Open http://127.0.0.1:8765. Bound to loopback only — never exposed publicly. Each task card shows title, status badge, worker, timestamps, error (if any), and the event timeline (created → claimed → completed).
Security
- stdio only — no network ports (dashboard binds
127.0.0.1exclusively) - Never expose the database or dashboard to the public internet
- Database lives on the local system disk — not on ExFAT/removable drives (multi-process SQLite locking is unreliable there)
working_directorymust fall insideALLOWED_WORKSPACEScontext_path/result_pathmust fall insideworking_directoryorSHARED_DIR(realpath-validated, anti-traversal)summary≤ 4 KB,metadata≤ 16 KB — larger payloads are forced to disk viaresult_pathdestructive/approval_requiredtasks are never auto-executed by automation
Error codes
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
Uniform response shape: {ok: bool, data: dict|null, error: {code, message, retryable}|null}
How it compares
Bearier occupies a lane most multi-agent tools don't:
| Bearier MCP | agent-orchestration | beads-village | |
|---|---|---|---|
| Target user | everyone (non-coders) | developers in IDEs | developers in IDEs |
| Target agent | desktop apps, no API needed | IDE coding agents (Cursor, Copilot) | IDE coding agents |
| Agent discovery | by worker_id, no shared cwd |
requires same cwd |
team-based, same project |
| Transport | stdio | stdio | stdio |
| Task timeout | dual-layer (pending + lease) | agent-level only | none |
| Approval gating | yes | research gate | no |
| Dependencies | Python stdlib only | Node 18+ | Node + Python + optional Go |
If you live in an IDE and want rich in-editor coordination, those projects fit better. If you have two desktop AI apps that only speak MCP and want them to hand off tasks — Bearier is the bridge.
Project structure
bearier-mcp/
├── README.md this file (English)
├── README.zh-CN.md 中文版
├── requirements.txt pinned dependencies
├── src/
│ ├── server.py MCP server (7 tools)
│ ├── config.py config loading + path boundary checks
│ ├── errors.py 12 error codes + uniform response
│ ├── models.py 6-state machine + Task data structure
│ ├── db.py SQLite connection + schema init
│ ├── repository.py task repo (CRUD + atomic claim + timeout sweep + path validation)
│ └── dashboard.py collaboration timeline HTTP server (127.0.0.1:8765)
├── tests/
│ ├── test_ping_client.py connectivity test
│ ├── test_repository.py data layer (29 cases)
│ └── test_mcp_tools.py MCP tool end-to-end (22 cases)
└── config-examples/
├── workbuddy.mcp.json WorkBuddy config example
└── codex-desktop.config.toml Codex desktop config example
Testing
PYTHONPATH=src python tests/test_repository.py # 29 cases
PYTHONPATH=src python tests/test_mcp_tools.py # 22 cases
PYTHONPATH=src python tests/test_ping_client.py # connectivity
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。