freebuff-bridge
MCP server that bridges agents to Freebuff Desktop sessions, enabling project and thread management, prompt sending, queue control, and wake-on-demand via REST API, SSE, and MCP tools.
README
freebuff-bridge
A communication server for Freebuff Desktop — a bridge between agents/scripts and Desktop sessions.
English · עברית (README.he.md)
Any tool or script (any language, any platform) can open a new session or talk to an existing agent session, watch live activity, and manage work — all over HTTP, MCP, or a Web UI.
┌─────────────────┐ HTTP + SSE ┌────────────────────┐
│ bridge (7777) ├──────────────────►│ orchestrator (dynamic) │ ← Freebuff Desktop
│ bun + Hono │ /api/threads └─────────┬──────────┘
│ reads DB │ /api/thread/:id/message
│ writes via API │ │
│ streams SSE │ ▼
└────────┬────────┘ ┌────────────────────┐
│ reads │ SQLite (.freebuff)│
▼ └────────────────────┘
┌─────────────────┐
│ <project>/ │
│ desktop-v2.db │ ← Freebuff's own DB per project
└─────────────────┘
The bridge talks to both the orchestrator (live) and the SQLite audit log (offline), and keeps working even if one of them is unavailable (falls back to DB-only mode with a fallback flag).
Features
| Area | What you get |
|---|---|
REST API (/v1/*) |
Threads CRUD, send prompts, stop/resume, switch model/harness live, queue control, SSE streams, wake |
| MCP server (stdio) | 14 tools (list_projects, send_prompt, resume_thread, set_agent, wake_freebuff, queue tools…) for Claude Code / Cline / any MCP agent |
| Web UI (port 7778) | RTL Hebrew dashboard — projects, all threads, single-thread view with state + queue + action buttons |
| Wake on demand | POST /v1/wake launches Freebuff.exe if it's down; send_prompt/enqueue_prompt auto-wake the app instead of failing |
| Self-healing | Discovers the orchestrator's dynamic port from its log; re-resolves on port change mid-run; SSE streams reconnect automatically |
| Version compatibility | Reads the installed Freebuff version, checks it against a verified table, warns in banner + /v1/info + UI |
| Shape probe | Validates the live /api/projects schema at startup against the verified contract — catches drift even inside a "verified" version |
| Windows services | Runs 24/7 via nssm (FreebuffBridge on 7777, FreebuffBridgeUi on 7778) |
| Examples | Copy-paste recipes in 4 languages (Python, bash, PowerShell, make) |
Quick install
# Prerequisite: Bun (https://bun.sh)
bun install
bun run init # creates ~/.config/freebuff-bridge/instances.json
bun run serve # listens on 127.0.0.1:7777 (localhost-noauth)
# checks
bun run typecheck # tsc --noEmit
bun run test # 175 tests across 10 files
That's it — the bridge is live. Open the Web UI:
bun run ui # Hono JSX + RTL Hebrew on 127.0.0.1:7778
# → open http://127.0.0.1:7778/
One-liner smoke test
curl -s http://127.0.0.1:7777/v1/info | jq .
curl examples
Reads
# health + self info (includes orchestrator, freebuff version, shape probe)
curl http://127.0.0.1:7777/v1/info
# all configured machines
curl http://127.0.0.1:7777/v1/instances
# all projects the orchestrator sees
curl http://127.0.0.1:7777/v1/projects
# threads of one project
curl "http://127.0.0.1:7777/v1/projects/C:/path/to/project/threads"
# a specific session (from the DB)
curl http://127.0.0.1:7777/v1/threads/<THREAD_ID>
# recent messages of a session
curl "http://127.0.0.1:7777/v1/threads/<THREAD_ID>/messages?limit=20"
Writes (go through the live orchestrator)
# open a new session in a chosen project
curl -X POST http://127.0.0.1:7777/v1/threads \
-H 'content-type: application/json' \
--data-raw '{"title":"[bridge] test","projectPath":"C:/my-project","harnessId":"codebuff","model":"deepseek/deepseek-v4-flash"}'
# send a prompt to a session (endpoint is /message, not /prompt)
curl -X POST http://127.0.0.1:7777/v1/threads/<THREAD_ID>/message \
-H 'content-type: application/json' \
--data-raw '{"text":"Check my email"}'
# stop a running turn
curl -X POST http://127.0.0.1:7777/v1/threads/<THREAD_ID>/stop
Resume a stuck session & switch model in real time
# bring a session back from paused → running
curl -X POST http://127.0.0.1:7777/v1/threads/<THREAD_ID>/resume
# → {"ok":true,"thread":{...}}
# switch only the model (harnessId is auto-filled from current state)
curl -X PATCH http://127.0.0.1:7777/v1/threads/<THREAD_ID> \
-H 'content-type: application/json' \
--data-raw '{"model":"openai/gpt-5.6-luna"}'
# switch model + harness together
curl -X PATCH http://127.0.0.1:7777/v1/threads/<THREAD_ID> \
-H 'content-type: application/json' \
--data-raw '{"harnessId":"codebuff","model":"deepseek/deepseek-v4-flash"}'
# un-pause via PATCH (alias)
curl -X PATCH http://127.0.0.1:7777/v1/threads/<THREAD_ID> \
-H 'content-type: application/json' \
--data-raw '{"queuePaused":false}'
⚠️ PATCH gotchas:
- When changing only
model, the bridge reads current state first to fill inharnessId— the orchestrator requires both together. - If the model is rejected by your tier (
rejected: true), the thread getsmodel: nulland the previous value is lost. Always checkthread.modelin the response. - The orchestrator endpoint is
/api/thread/<id>/agent, not/model(verified against the live bundle).
Wake Freebuff Desktop on demand
curl -X POST http://127.0.0.1:7777/v1/wake
# → {"ok":true,"alreadyRunning":false,"exePath":"C:/.../Freebuff.exe","port":53810,"elapsedMs":4210}
When the orchestrator is down and autoWake is on (default), send_prompt / enqueue_prompt launch Freebuff automatically and retry once instead of returning 502.
Queue control
# list a session's queue (pending + done, sorted by position)
curl http://127.0.0.1:7777/v1/threads/<THREAD_ID>/queue
# → {"thread":{...}, "items":[{id, state, prompt, position, ...}], "pending":N}
# enqueue a prompt (runs when the current turn finishes)
curl -X POST http://127.0.0.1:7777/v1/threads/<THREAD_ID>/queue \
-H 'content-type: application/json' \
--data-raw '{"text":"collect today's PRs","label":"pr-digest"}'
# reorder (lower position = runs earlier)
curl -X POST http://127.0.0.1:7777/v1/threads/<THREAD_ID>/reorder \
-H 'content-type: application/json' \
--data-raw '{"id":"<ITEM_ID>","position":-1}'
# edit a queued item's prompt before it runs
curl -X POST http://127.0.0.1:7777/v1/queue/<ITEM_ID>/edit \
-H 'content-type: application/json' \
--data-raw '{"prompt":"rewritten prompt text"}'
# delete from queue
curl -X POST http://127.0.0.1:7777/v1/queue/<ITEM_ID>/delete
# promote to the front (runs immediately)
curl -X POST http://127.0.0.1:7777/v1/queue/<ITEM_ID>/send-now
⚠️ Queue rules:
- If
queuePaused=true, items accumulate and don't run until you callresume_thread(orPATCH {"queuePaused":false}). - If
queuePaused=false, items run as soon as the current turn finishes (auto-promote to running). reordercan fail with 409 "item is not queued" once the item is already running/done.
Live events (SSE)
# all orchestrator events
curl -N -H 'accept: text/event-stream' http://127.0.0.1:7777/v1/events
# events for one session
curl -N -H 'accept: text/event-stream' http://127.0.0.1:7777/v1/threads/<THREAD_ID>/stream
Running as Windows services (24/7)
The bridge and the Web UI can run as Windows services via nssm — auto-start with the machine, restart-on-crash, logs to .freebuff/, and wake Freebuff automatically when there is work.
# one-time: install nssm
winget install -e --id NSSM.NSSM
# install (elevated)
powershell -ExecutionPolicy Bypass -File .\install-service.ps1 # FreebuffBridge (API, 7777)
powershell -ExecutionPolicy Bypass -File .\install-ui-service.ps1 # FreebuffBridgeUi (UI, 7778)
# uninstall (elevated)
powershell -ExecutionPolicy Bypass -File .\uninstall-service.ps1
powershell -ExecutionPolicy Bypass -File .\uninstall-ui-service.ps1
Why nssm? sc create alone can't work here — bun.exe never registers with the Service Control Manager, so SCM kills the service after 30 seconds (error 1053). nssm is the standard wrapper that manages bun as a child process.
LocalSystem + paths: services run as SYSTEM, so env overrides (FREEBUFF_BRIDGE_APPDATA, FREEBUFF_BRIDGE_LOCALAPPDATA, FREEBUFF_BRIDGE_WAKE_EXE) are written to the service's Environment value (REG_MULTI_SZ — the official SCM mechanism). Note: do not use nssm AppEnvironmentExtra — any nssm set call replaces the whole list.
The tray icon (bun run tray) detects when the services already hold ports 7777/7778 and doesn't start duplicate copies.
MCP server for external agents (Claude Code / Cline)
The bridge exposes an MCP server on stdio that talks directly to Claude Code / Cline / any MCP-aware agent. 14 tools are defined:
Session control (7): list_projects · list_threads · get_thread · send_prompt · stop_thread · resume_thread · set_agent
Wake (1): wake_freebuff
Queue control (6): list_queue · enqueue_prompt · reorder_queue_item · edit_queue_item · delete_queue_item · send_queue_item_now
Use it from Claude Code (~/.claude/mcp.json):
{
"mcpServers": {
"freebuff-bridge": {
"command": "bun",
"args": ["run", "C:/path/to/freebuff-bridge/src/bridge/mcp.ts"]
}
}
}
Make sure the bridge is running first: bun run serve. The MCP server connects automatically to http://127.0.0.1:7777.
Security
- Default bind:
127.0.0.1(loopback only). The bridge does not expose itself to the network. localhost-noauthmode (default): any local process can talk without a token.strictmode: requiresAuthorization: Bearer <token>. Every instance ininstances.jsongets a unique token.- Admin token via env var (
FREEBUFF_BRIDGE_ADMIN_TOKEN) grants access to every instance. - Per-alias env override:
FREEBUFF_BRIDGE_TOKEN_<ALIAS_UPPER>takes priority over the file.
# strict + admin token
FREEBUFF_BRIDGE_HOST=0.0.0.0 FREEBUFF_BRIDGE_BIND_MODE=strict \
FREEBUFF_BRIDGE_ADMIN_TOKEN=$(openssl rand -hex 32) \
bun run serve
Project structure
src/
bridge/
db.ts # SQLite + WAL/NORMAL/busy_timeout + typed reads
instances.ts # config store (load/save/find/env-override)
auth.ts # bearer header regex + decideAuth()
ratelimit.ts # sliding-window in-memory limiter
orchestrator.ts # HTTP client to Freebuff's orchestrator (dynamic port discovery)
projects.ts # multi-project discovery (.../.freebuff scan)
wake.ts # find exe + discover port from log + spawn + poll
compat.ts # installed Freebuff version (asar/exe) + compat table
shape.ts # /api/projects schema probe (validate + HTTP)
server.ts # Hono REST API (/v1/*) — reads DB, writes via orchestrator
mcp.ts # MCP stdio server — 14 tools that proxy /v1/*
web/
ui.tsx # Hono JSX server (7778) — SSR HTML + 9 POST actions + SSE
views/ # layout, projects, threads, thread, queue views
cli/
serve.ts # bun run serve (main entry — bridge on 7777)
ui.ts # bun run ui (Web UI on 7778)
tray.ts # bun run tray (Windows tray icon)
tray/
tray.ps1 # PowerShell NotifyIcon + context menu + health poller
tests/ # 10 files, 175 tests
examples/ # copy-paste integrations in 4 languages
Windows notes
bun:sqliteopens withjournal_mode=WAL,synchronous=NORMAL,busy_timeout=5000ms, andforeign_keys=ONso it never collides with the Desktop running in parallel.- Hebrew/UTF-8 paths are supported.
- The orchestrator port is dynamic in current builds — the bridge reads it from
%APPDATA%\Freebuff\logs\orchestrator-stderr.log(linelistening on http://127.0.0.1:PORT). Manual check:curl http://127.0.0.1:<PORT>/api/projectsshould return JSON, or justGET /v1/infoand look at theorchestratorfield.
Git
bun.lockbis meant to be committed — don't add it to.gitignore.
推荐服务器
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 模型以安全和受控的方式获取实时的网络信息。