subhive

subhive

A shared context and coordination layer for multiple AI agents over MCP, featuring semantic memory, dependency-aware task DAGs, auto-scheduling, role-based access, real-time push, and a live dashboard.

Category
访问服务器

README

<div align="center">

🐝 subhive

One live, shared brain for every AI agent your tools spawn.

Semantic memory · dependency-aware task DAG · auto-scheduler · roles · real-time push · live dashboard — all over MCP.

MCP Node SQLite WAL Tools Tests License

</div>


Point Claude Code, Hermes, Cursor, Codex — or any MCP client — at the same hive and they share one brain instead of stepping on each other. Most "shared context" MCP servers are a JSON file behind a lock. subhive is a concurrent SQLite (WAL) store with a real event log, live WebSocket push, and the things multi-agent work actually needs and JSON bridges lack.

        Claude ┐
        Codex  ┤          ┌─────────────────────────────┐
        Cursor ┼─ MCP ──▶ │  🐝 subhive                 │ ──▶ live dashboard
        Hermes ┤          │  memory · tasks · artifacts │ ──▶ WebSocket push
         …any  ┘          │  scheduler · roles · events │
                          └─────────────────────────────┘

Table of contents


Why

Spin up three agents on one job and they immediately collide: no shared memory, no idea who's doing what, no handoff. subhive gives them a single context to coordinate through, with the same 24 tools regardless of which tool launched them.

Problem with JSON context-bridges subhive
Rewrite-the-whole-file, lock contention Concurrent SQLite WAL, atomic writes
No handoff — agents duplicate work Dependency DAG — tasks unblock automatically
Hand-assign every task Auto-scheduler load-balances across idle agents
Exact-key lookup only Semantic memory search by meaning
Poll a file for changes Event log + live WebSocket push
No access control Reader/writer/admin roles, tokens, rate limit, audit
Corrupts on crash Crash recovery requeues orphaned in-flight tasks

Features

  • 🧠 Semantic memory — memory_search("how do we auth") finds the auth-strategy entry by meaning. Fully local embedder (trigram hashing + cosine). No API, no downloads.
  • 🔗 Dependency-aware task DAG — a task stays blocked and hidden from workers until the tasks it needs are done, then unblocks automatically and fires an event. Cycle detection prevents deadlock.
  • ⚖️ Auto-scheduler — task_claim_next hands each agent the highest-priority ready task race-safely; auto_assign load-balances across the least-busy online agents.
  • 📇 Late-join digest — a new agent calls digest and gets a human-readable briefing of the whole context: roster, memory, task board, recent activity.
  • ♻️ Crash recovery — on restart, ghost agents are dropped and orphaned in-flight tasks are requeued so nothing gets stuck.
  • 🔐 Roles + rate limiting + audit — readers can't write, admins administer, runaway agents get throttled, every denial is logged. Admin is token-granted, not claimable.
  • 📡 Real-time — every write emits an event; agents poll get_events or subscribe over WebSocket for live push.
  • 📊 Live dashboard — open http://host:port/ for a real-time roster, task board, shared memory, and event stream. Single HTML file, no build step.

🚀 Quick start

npm install
npm start          # → subhive serve on http://127.0.0.1:8787
npm run demo       # self-contained 3-agent showcase (temp DB, no setup)
npm test           # 5 suites: store · features · security · integration ×2

Or, once published:

npx subhive serve --port 8787

Create an isolated, token-protected context:

subhive context create myproject --token s3cret --desc "auth refactor"
subhive context list

🔌 Connect an MCP client

Point any MCP client at the HTTP endpoint and have it identify via headers:

URL:     http://127.0.0.1:8787/mcp
Headers:
  x-subhive-context: myproject     # which hive (default: "default")
  x-subhive-token:   s3cret        # required if the context has a token
  x-subhive-agent:   planner       # this agent's display name (make it unique!)
  x-subhive-tool:    claude        # claude / codex / cursor / hermes / …
  x-subhive-role:    reader         # optional; reader/writer (admin needs the token)

The whole trick: give each agent a different x-subhive-agent and the same x-subhive-context.

Claude Code / Claude Desktop (.mcp.json)

{
  "mcpServers": {
    "subhive": {
      "type": "http",
      "url": "http://127.0.0.1:8787/mcp",
      "headers": {
        "x-subhive-context": "myproject",
        "x-subhive-token": "s3cret",
        "x-subhive-agent": "claude-planner",
        "x-subhive-tool": "claude"
      }
    }
  }
}

Zero-config: generate the client block for you

subhive connect claude --agent planner  --context myproject --token s3cret
subhive connect cursor --agent coder
subhive connect codex  --agent reviewer --role reader

Prints a ready-to-paste config for Claude, Cursor, VS Code, Codex, or generic JSON — and tells you exactly which file it belongs in.

Or let it write the file for you — --write merges the entry straight into the client's config file, keeping any other MCP servers already there:

subhive connect claude --agent planner --context myproject --token s3cret --write
#  ✓ created .mcp.json (under "mcpServers") — agent "planner", context "myproject"

subhive connect vscode --agent coder --write            # → .vscode/mcp.json
subhive connect claude --agent x --write --out ~/.claude/mcp.json   # custom path

It refuses to clobber an existing subhive entry (re-run with --force) and never overwrites a malformed file. --write works for claude, cursor, and vscode; codex/json stay copy-paste.


📡 Live push & dashboard

WebSocket — first frame is a full {type:'snapshot'}, then {type:'event', event} per change:

ws://127.0.0.1:8787/ws?context=myproject&token=s3cret

Dashboard — open http://127.0.0.1:8787/ in a browser for a real-time roster (online status + task load), a four-column task board, shared memory, and a live event stream — all driven by the same feed the agents use.


🧰 Tools

24 MCP tools, grouped by concern. Every call is role-checked, rate-limited, and audited.

Tool Purpose
whoami · roster your identity + role · who else is connected (with load)
digest human-readable briefing of the whole context for late joiners
memory_set · memory_get · memory_list · memory_delete shared tagged key/value memory
memory_search semantic search over memory by meaning, not exact key
task_create create work; needs:[ids] for deps, priority high/normal/low
task_list filter by status / assignee; shows blocked state
task_next only unblocked pending tasks, priority-ordered
task_claim_next atomically claim the top ready task (race-safe scheduler)
task_claim · task_update claim a specific task · set status/result; done auto-unblocks dependents
auto_assign (admin) load-balance ready work across idle agents
artifact_put · artifact_get · artifact_list shared blobs (code/plan/json/md/sql)
send_message · inbox direct or broadcast messaging
get_events event log since id N (poll to catch up)
snapshot whole context in one call (agents, memory, tasks, ready, artifacts)
set_role · reap (admin) manage roles · evict stale agents

Roles: readers get read-only tools; writers get everything except admin ops; admins get everything. Every denied call is written to the audit log.


The dependency handoff + scheduler (the point)

planner: task_create "design schema"  priority:high         → t1
planner: task_create "build api"  needs:[t1]                → t2 (blocked)

worker:  task_claim_next   → t1        # highest-priority READY task, race-safe
worker:  task_update t1 done           # emits task.unblocked
worker:  task_claim_next   → t2        # now unblocked, claimed cleanly

auto_assign can instead fan all ready work out across the least-busy online agents automatically. No polling races, no "is it my turn yet", no duplicated work. Circular dependencies are rejected at creation time, so the scheduler can never deadlock.


Semantic memory

memory_set  "auth-strategy" = "JWT with 15 minute expiry and refresh tokens"
memory_search "how do we authenticate users"
  → auth-strategy (score 0.33)   # found by meaning, not the key

Embeddings are computed locally with a dependency-free hashing embedder (trigrams + stopword removal, cosine similarity). No external API, no model downloads, no config.


🏗 Architecture

src/
  core/db.js               SQLite (WAL) schema + additive migrations
  core/store.js            API over the DB; events, scheduler, search, digest, recovery
  core/embed.js            local hashing embedder for semantic memory search
  core/guard.js            role checks + per-session token-bucket rate limiter
  tools/register.js        24 MCP tools, each guarded by role + rate limit + audit
  tools/connect.js         client-config generator (claude/cursor/vscode/codex/json)
  transport/httpServer.js  Streamable-HTTP MCP + WebSocket push + dashboard + REST
  transport/dashboard.html live web dashboard (single file, no build)
  server.js                wires store + transport; runs crash recovery + reaper
  cli.js                   serve / connect / context
test/
  store.test.js            unit: store + dependency logic
  features.test.js         unit: search, scheduler, digest, recovery, roles, rate limit
  security.test.js         auth-bypass, DM-leak, cycle, and privilege-escalation regressions
  integration.test.js      e2e: 2 MCP clients + WS listener over HTTP
  integration_v2.test.js   e2e: semantic search, scheduler, roles+audit, digest

Data model: contexts (auth boundary) → agents (with role), memory (with embeddings), tasks + task_deps (dependency edges), artifacts, messages, and an append-only events log that powers get_events, WebSocket push, and the audit trail.

Concurrency: better-sqlite3 is synchronous, so all writes serialize within the process; the scheduler's atomic UPDATE … WHERE status='pending' guard makes task_claim_next race-safe against simultaneous claimers.

Durability: SQLite WAL keeps committed writes safe across crashes. On startup recover() drops ghost agent rows and requeues orphaned in-flight tasks; a periodic reaper evicts agents whose heartbeat went stale.


🔒 Security

subhive shipped after a two-track audit — a manual sweep plus an independent auditor agent running against a live server. 12 issues were found and fixed, each with a regression test in security.test.js / features.test.js.

Severity Issue Fix
🔴 Critical Self-declared admin via x-subhive-role: admin header Admin is token-granted; tokenless contexts cap at writer
🔴 Critical Direct messages fanned out to every WS subscriber DM content redacted in broadcast; recipients read via inbox
🟠 High Circular dependency → permanent scheduler deadlock BFS cycle detection rejects cycles + self-deps at creation
🟠 High Cross-context dependency edges broke isolation same-context validation in task_create and addDep
🟠 High Crash-recovery events lost (event hook wired too late) onEvent wired before recover()
🟠 High Context token leaked plaintext in snapshot / WS / REST publicContext() redacts token, exposes hasToken flag
🟠 High Dangling needs:[fake-id] blocked a task forever validates referenced task IDs exist
🟡 Med task_update accepted arbitrary status strings status/priority enum validation
🟡 Med Rate-limiter clock skew → negative tokens → lockout clamp elapsed ≥ 0, guard zero refill
🟡 Med Token compared with === (timing-observable) crypto.timingSafeEqual
🟢 Low Stale tool count + dead listMessages paging corrected count; since implemented via created_at

Security model: named contexts are the auth boundary; optional per-context tokens gate access; roles are server-enforced (never client-asserted); every denied call is audited.

Known limitations

Called out honestly rather than hidden:

  • Single-process deployment. The scheduler is race-safe within one process (synchronous SQLite). Running multiple server processes against one DB file is not yet safe — auto_assign uses read-then-write without cross-process locking. Run one subhive serve per DB.
  • WS DM filtering is coarse. WebSocket connections aren't yet bound to an agent identity, so DM content is redacted from the broadcast entirely; recipients read private messages via inbox. Per-recipient WS delivery needs identity binding (planned).
  • Local embedder trades recall quality for zero-config/zero-dependency operation. It's great for "find the decision," not a replacement for a real vector DB at scale.

✅ Testing

npm test    # runs all 5 suites

# or individually:
node test/store.test.js           # STORE OK
node test/features.test.js        # ALL FEATURE TESTS OK
node test/security.test.js        # SECURITY OK
node test/integration.test.js     # INTEGRATION OK — tools=24
node test/integration_v2.test.js  # INTEGRATION v2 OK

Integration tests start a real server, connect real MCP clients plus a WebSocket listener, and verify auth, shared memory, semantic search, the full dependency handoff, the scheduler, role enforcement + audit, artifacts, messaging, the event log, and live push end-to-end. security.test.js reproduces every audited vulnerability over the real MCP transport and asserts it's closed.


License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选