agent-comm-hub 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +472 -445
- package/README.zh.md +327 -319
- package/lib/cli.js +485 -106
- package/lib/index.js +424 -51
- package/lib/setup.js +27 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,445 +1,472 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="assets/agent-hub-banner.png" alt="agent-comm-hub" width="100%" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">agent-comm-hub</h1>
|
|
6
|
-
|
|
7
|
-
<div align="center">
|
|
8
|
-
|
|
9
|
-
**English** | [简体中文](README.zh.md)
|
|
10
|
-
|
|
11
|
-
</div>
|
|
12
|
-
|
|
13
|
-
<div align="center">
|
|
14
|
-
|
|
15
|
-
[](https://www.npmjs.com/package/agent-comm-hub)
|
|
16
|
-
[](LICENSE)
|
|
17
|
-
[](package.json)
|
|
18
|
-
[](package.json)
|
|
19
|
-
[](src)
|
|
20
|
-
[](src/mcp-server.ts)
|
|
21
|
-
[](package.json)
|
|
22
|
-
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
**Generic multi-peer communication hub over MCP.** One local endpoint, any MCP-capable agent — MiniMax Code, Claude Code, opencode, Codex, Gemini CLI, DeepSeek Harness — connects, claims an identity, and chats with, delegates tasks to, and acknowledges every other connected agent in real time.
|
|
26
|
-
|
|
27
|
-
Zero runtime dependencies: the MCP streamable-http server is hand-rolled over `node:http`.
|
|
28
|
-
|
|
29
|
-
```text
|
|
30
|
-
┌────────── agent-comm-hub (127.0.0.1:18764/mcp) ──────────┐
|
|
31
|
-
│ peer registry (bridge_register) · per-peer mailboxes · │
|
|
32
|
-
│ long-poll waiters · broadcast · task/ack routing │
|
|
33
|
-
└───▲──────────▲──────────▲──────────▲──────────▲──────────┘
|
|
34
|
-
│ │ │ │ │
|
|
35
|
-
mcp.json │ .mcp.json │ opencode.json │ config.toml │ settings.json
|
|
36
|
-
┌──────────┴──┐ ┌───────┴───┐ ┌───────┴───┐ ┌──────┴───┐ ┌───────┴───┐
|
|
37
|
-
│ MiniMax Code│ │ Claude Code│ │ opencode │ │ Codex │ │Gemini CLI │
|
|
38
|
-
└─────────────┘ └───────────┘ └───────────┘ └──────────┘ └───────────┘
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Highlights
|
|
42
|
-
|
|
43
|
-
- **Any agent, one config**: every client points at the same `streamable-http` URL — no per-pair wiring.
|
|
44
|
-
- **Reliable identity**: the sender of every message is derived from the connection's session binding, never caller-supplied — peers cannot impersonate each other; duplicate ids are rejected. Connecting the MCP auto-registers your client name — no manual setup.
|
|
45
|
-
- **Real-time by polling**: `bridge_wait` long-polls (default 30 s, server ceiling 60 s); messages queue for offline peers.
|
|
46
|
-
- **Structured conversations**: `chat` / `task` / `notice` / `ack` message kinds, acks auto-routed back to the original sender, `to: "all"` broadcast.
|
|
47
|
-
- **Hard control via herdr** (optional): when the [herdr](https://herdr.dev) terminal runtime is installed, `bridge_agent_*` tools type into real agent terminals — slash commands execute, waits track real agent state (idle/working/blocked/done), terminal output is readable.
|
|
48
|
-
- **Zero dependencies, one process**: `npx agent-comm-hub` — no database, no daemon, no external services.
|
|
49
|
-
|
|
50
|
-
## Quickstart
|
|
51
|
-
|
|
52
|
-
### 1. Install the hub
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# run without installing (fetches from the npm registry each time)
|
|
56
|
-
npx agent-comm-hub
|
|
57
|
-
|
|
58
|
-
# or install globally and run anywhere
|
|
59
|
-
npm install -g agent-comm-hub
|
|
60
|
-
agent-comm-hub
|
|
61
|
-
|
|
62
|
-
# or install into a project
|
|
63
|
-
npm install -D agent-comm-hub
|
|
64
|
-
npx agent-comm-hub
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Update later without a manual reinstall (files are replaced in place, so an
|
|
68
|
-
installed auto-start launcher keeps working; restart the hub afterwards):
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
agent-comm-hub update
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### 2. Start the hub
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
agent-comm-hub
|
|
78
|
-
# → agent-comm-hub listening on http://127.0.0.1:18764/mcp
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
For long-running setups use your preferred supervisor (systemd unit, pm2,
|
|
82
|
-
Task Scheduler on Windows) — or the built-in one-shot auto-start:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
agent-comm-hub service install # Windows: HKCU Run + hidden launcher (no admin)
|
|
86
|
-
# Linux: systemd --user unit, enabled
|
|
87
|
-
# macOS: launchd LaunchAgent
|
|
88
|
-
agent-comm-hub service uninstall # undo
|
|
89
|
-
agent-comm-hub status # is the hub up? who is online?
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
`status` probes the endpoint and prints the hub version plus every registered
|
|
93
|
-
peer with its online state (it registers a throwaway probe and cleans up after
|
|
94
|
-
itself).
|
|
95
|
-
|
|
96
|
-
### 3. Connect your agents (one command)
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
agent-comm-hub setup
|
|
100
|
-
# or: agents/install-all.ps1 (PowerShell equivalent)
|
|
101
|
-
# undo: agent-comm-hub setup --remove
|
|
102
|
-
# list what is installed (no changes): agent-comm-hub discover
|
|
103
|
-
# configure a single agent: agent-comm-hub setup --agent codex
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
`setup` **discovers** which agents are installed on this machine (PATH
|
|
107
|
-
commands, config paths, npm global packages — no shell, cross-platform) and
|
|
108
|
-
merges the `agent-hub` MCP entry into each one's config (mcode, opencode, Kimi
|
|
109
|
-
Code, Gemini CLI, Codex, zcode, DSH, claude-desktop on macOS), plus the English
|
|
110
|
-
skill into `~/.agents/skills/` (the cross-agent standard) and each agent's
|
|
111
|
-
private skills dir. Which agents are supported is declared in
|
|
112
|
-
[`agents/registry.json`](agents/registry.json) — adding a new agent is one
|
|
113
|
-
registry record, no code change. Only the `agent-hub` key is touched, every
|
|
114
|
-
file is backed up first, and re-running is a no-op. Claude Code's MCP config
|
|
115
|
-
stays manual (see below).
|
|
116
|
-
|
|
117
|
-
**Registration is automatic**: once an agent session starts, the MCP handshake
|
|
118
|
-
registers it with the hub (client name becomes the peer id) — no manual step.
|
|
119
|
-
Optional: `bridge_register("tool:project")` for a readable id.
|
|
120
|
-
|
|
121
|
-
### 4. Verify the endpoint
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
curl -X POST http://127.0.0.1:18764/mcp \
|
|
125
|
-
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
|
|
126
|
-
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}'
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Connect your agents
|
|
130
|
-
|
|
131
|
-
Each agent gets **one MCP server entry** pointing at `http://127.0.0.1:18764/mcp`, plus the shared English skill (`agents/SKILL.md`) that teaches it when and how to use the bridge tools. Templates live in [`agents/`](agents/README.md).
|
|
132
|
-
|
|
133
|
-
**One-shot incremental sync** (recommended): `agents/install-all.ps1` merges the
|
|
134
|
-
`agent-hub` entry into every installed agent's MCP config (mcode, opencode,
|
|
135
|
-
Kimi Code, Gemini CLI, Codex, zcode, DSH) and installs the skill — it only
|
|
136
|
-
touches the `agent-hub` key, backs up each file, and is idempotent. Claude Code
|
|
137
|
-
is manual (below).
|
|
138
|
-
|
|
139
|
-
| Agent | Config file | Template | Skill location |
|
|
140
|
-
|---|---|---|---|
|
|
141
|
-
| MiniMax Code (mcode) | `~/.minimax/mcp.json` (+ `~/.minimax/mcp/mcp.json`) | [`agents/minimax-code/`](agents/minimax-code/) | `~/.minimax/skills/agent-comm-hub/SKILL.md` |
|
|
142
|
-
| opencode | `~/.config/opencode/opencode.json` | [`agents/opencode/opencode.json`](agents/opencode/opencode.json) | `~/.config/opencode/skills/agent-comm-hub/SKILL.md` |
|
|
143
|
-
| Kimi Code | `~/.kimi-code/mcp.json` | [`agents/kimi-code/mcp-entry.json`](agents/kimi-code/mcp-entry.json) | `~/.kimi-code/skills/agent-comm-hub/SKILL.md` |
|
|
144
|
-
| Gemini CLI | `~/.gemini/settings.json` | [`agents/gemini-cli/settings.json`](agents/gemini-cli/settings.json) | `~/.gemini/skills/agent-comm-hub/SKILL.md` |
|
|
145
|
-
| Codex | `~/.codex/config.toml` | [`agents/codex/config.toml`](agents/codex/config.toml) | `~/.codex/skills/agent-comm-hub/SKILL.md` |
|
|
146
|
-
| zcode | `~/.zcode/cli/config.json` (`mcp.servers`) | [`agents/zcode/config.json`](agents/zcode/config.json) | `~/.zcode/skills/agent-comm-hub/SKILL.md` |
|
|
147
|
-
| Claude Code | project `.mcp.json` (manual; `~/.claude.json` is never touched) | [`agents/claude-code/.mcp.json`](agents/claude-code/.mcp.json) | `~/.claude/skills/agent-comm-hub/SKILL.md` |
|
|
148
|
-
| DeepSeek Harness (DSH) | `~/.dsh/profiles/*/cordis.patch.yml` (auto by `setup`) | [`agents/dsh/cordis.patch.yml`](agents/dsh/cordis.patch.yml) | `$DSH_HOME/skills/agent-comm-hub/SKILL.md` |
|
|
149
|
-
|
|
150
|
-
> Streamable-http support varies by agent version; the templates use the fields each agent documents. If a client lacks HTTP MCP, wrap the endpoint with a stdio shim.
|
|
151
|
-
|
|
152
|
-
### MiniMax Code (mcode)
|
|
153
|
-
|
|
154
|
-
Run the installer (backs up both config files first, writes UTF-8 without BOM):
|
|
155
|
-
|
|
156
|
-
```powershell
|
|
157
|
-
powershell -ExecutionPolicy Bypass -File agents/minimax-code/install-mcode.ps1
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
It registers `agent-hub` in `~/.minimax/mcp.json` (read by the CLI runtime) and `~/.minimax/mcp/mcp.json` (desktop app), and installs the skill. Restart your mcode session, then ask the agent:
|
|
161
|
-
|
|
162
|
-
```text
|
|
163
|
-
先调用 bridge_register("mavis:myproject"),然后 bridge_peers 看看谁在线
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Claude Code
|
|
167
|
-
|
|
168
|
-
Copy `agents/claude-code/.mcp.json` into your project root (or merge `mcpServers.agent-hub` into `~/.claude.json`):
|
|
169
|
-
|
|
170
|
-
```json
|
|
171
|
-
{
|
|
172
|
-
"mcpServers": {
|
|
173
|
-
"agent-hub": {
|
|
174
|
-
"type": "http",
|
|
175
|
-
"url": "http://127.0.0.1:18764/mcp"
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Copy `agents/SKILL.md` to `~/.claude/skills/agent-comm-hub/SKILL.md`, restart Claude, and have it `bridge_register("claude-code:myproject")`.
|
|
182
|
-
|
|
183
|
-
### opencode
|
|
184
|
-
|
|
185
|
-
Merge into `~/.config/opencode/opencode.json`:
|
|
186
|
-
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"mcp": {
|
|
190
|
-
"agent-hub": {
|
|
191
|
-
"type": "remote",
|
|
192
|
-
"url": "http://127.0.0.1:18764/mcp",
|
|
193
|
-
"enabled": true
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Codex
|
|
200
|
-
|
|
201
|
-
Append to `~/.codex/config.toml`:
|
|
202
|
-
|
|
203
|
-
```toml
|
|
204
|
-
[mcp_servers.agent-hub]
|
|
205
|
-
type = "streamable-http"
|
|
206
|
-
url = "http://127.0.0.1:18764/mcp"
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Gemini CLI
|
|
210
|
-
|
|
211
|
-
Merge into `~/.gemini/settings.json`:
|
|
212
|
-
|
|
213
|
-
```json
|
|
214
|
-
{
|
|
215
|
-
"mcpServers": {
|
|
216
|
-
"agent-hub": {
|
|
217
|
-
"type": "http",
|
|
218
|
-
"url": "http://127.0.0.1:18764/mcp"
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### DeepSeek Harness (DSH)
|
|
225
|
-
|
|
226
|
-
Auto-configured by `agent-comm-hub setup`: it discovers
|
|
227
|
-
`~/.dsh/profiles/*/cordis.patch.yml` and appends the `@deepseek-ai/dsh-mcp-client`
|
|
228
|
-
row, so DSH sessions expose the tools as `mcp__agent-hub__bridge_*` after a dsh
|
|
229
|
-
restart. Manual equivalent (or template for other profiles):
|
|
230
|
-
|
|
231
|
-
```yaml
|
|
232
|
-
- insert:
|
|
233
|
-
- id: agent-comm-hub
|
|
234
|
-
name: '@deepseek-ai/dsh-mcp-client'
|
|
235
|
-
config:
|
|
236
|
-
serverName: agent-hub
|
|
237
|
-
transport: streamable-http
|
|
238
|
-
url: http://127.0.0.1:18764/mcp
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Tools
|
|
242
|
-
|
|
243
|
-
| Tool | Purpose |
|
|
244
|
-
|---|---|
|
|
245
|
-
| `bridge_register(peerId)` | Claim or rename your identity (auto-registered at connect with the client name; optional for a readable id like `opencode:myproject`) |
|
|
246
|
-
| `bridge_unregister()` | Leave the hub (removes peer, queue, and session binding; stays off until an explicit register) |
|
|
247
|
-
| `bridge_chat(to, message)` | Send a chat message; `to: "all"` broadcasts |
|
|
248
|
-
| `bridge_task(to, prompt, context?, deliverable?)` | Delegate a structured task |
|
|
249
|
-
| `bridge_ack(ref, status, note?)` | Acknowledge a task (`accepted`/`rejected`/`done`/`failed`), routed back to the original sender |
|
|
250
|
-
| `bridge_wait(from?, timeoutMs?)` | Long-poll for the next message (default 30 s) |
|
|
251
|
-
| `bridge_poll(from?)` | Non-blocking drain of queued messages |
|
|
252
|
-
| `bridge_status()` | Hub health: peers with connected/queued/waiting state |
|
|
253
|
-
| `bridge_peers()` | Who is online |
|
|
254
|
-
| `bridge_history(peer?, limit?)` | Recent messages (context refresh after reconnect) |
|
|
255
|
-
|
|
256
|
-
### herdr control tools (optional)
|
|
257
|
-
|
|
258
|
-
If the [herdr](https://herdr.dev) terminal runtime is installed, the hub also
|
|
259
|
-
exposes **control tools** that type into real agent terminals — unlike
|
|
260
|
-
`bridge_chat` (a mailbox message the receiving model may ignore), a prompt
|
|
261
|
-
here is physical input: slash commands (`/compact`, `/model`, `/clear`) are
|
|
262
|
-
executed by the target's TUI, and waits block on herdr's real agent state
|
|
263
|
-
(idle/working/blocked/done), not screen activity.
|
|
264
|
-
|
|
265
|
-
| Tool | Purpose |
|
|
266
|
-
|---|---|
|
|
267
|
-
| `bridge_agent_list()` | Agent panes herdr detects (paneId, kind, status, cwd, interactive-ready) |
|
|
268
|
-
| `bridge_agent_status(target)` | Live state of one pane |
|
|
269
|
-
| `bridge_agent_prompt(target, text, wait?, until?, timeoutMs?)` | Submit text / slash command into the target's input line; with `wait`, block until it settles |
|
|
270
|
-
| `bridge_agent_wait(target, until?, timeoutMs?)` | Wait until the agent reaches a state (default idle/done/blocked) |
|
|
271
|
-
| `bridge_agent_read(target, lines?, source?)` | Read the pane's recent terminal output (reply of an agent not on the hub) |
|
|
272
|
-
| `bridge_agent_keys(target, keys)` | Raw key presses (Enter, esc, ctrl-c, arrows…) to dismiss prompts or interrupt |
|
|
273
|
-
|
|
274
|
-
### herdr pane tools (drive ANY pane — no agent detection)
|
|
275
|
-
|
|
276
|
-
`bridge_agent_*` requires herdr to **recognize** the agent (its built-in
|
|
277
|
-
manifest list: claude/codex/opencode/kimi/…). For agents herdr does not know
|
|
278
|
-
(e.g. MiniMax Code), the pane tools drive any pane through the herdr local
|
|
279
|
-
socket — physical input, read output:
|
|
280
|
-
|
|
281
|
-
| Tool | Purpose |
|
|
282
|
-
|---|---|
|
|
283
|
-
| `bridge_pane_list()` | Every pane (ids, titles, agent status) |
|
|
284
|
-
| `bridge_pane_send(target, text, enter?)` | Type text into a pane (slash commands execute; Enter submits by default) |
|
|
285
|
-
| `bridge_pane_keys(target, keys)` | Raw key presses to any pane |
|
|
286
|
-
| `bridge_pane_read(target, lines?, source?)` | Read a pane's recent output |
|
|
287
|
-
|
|
288
|
-
Verified live: a MiniMax Code session was driven end-to-end through the hub —
|
|
289
|
-
prompt injected via `bridge_pane_send`, reply collected via
|
|
290
|
-
`bridge_pane_read`, no agent-side configuration.
|
|
291
|
-
|
|
292
|
-
Control tools are gated: `herdrControlPeers` restricts who may use them
|
|
293
|
-
(default `'all'`, mirroring the hub's loopback-only trust model). They are
|
|
294
|
-
hard control — an injected `/clear` clears the target's context.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/agent-hub-banner.png" alt="agent-comm-hub" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">agent-comm-hub</h1>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
**English** | [简体中文](README.zh.md)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div align="center">
|
|
14
|
+
|
|
15
|
+
[](https://www.npmjs.com/package/agent-comm-hub)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](package.json)
|
|
18
|
+
[](package.json)
|
|
19
|
+
[](src)
|
|
20
|
+
[](src/mcp-server.ts)
|
|
21
|
+
[](package.json)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
**Generic multi-peer communication hub over MCP.** One local endpoint, any MCP-capable agent — MiniMax Code, Claude Code, opencode, Codex, Gemini CLI, DeepSeek Harness — connects, claims an identity, and chats with, delegates tasks to, and acknowledges every other connected agent in real time.
|
|
26
|
+
|
|
27
|
+
Zero runtime dependencies: the MCP streamable-http server is hand-rolled over `node:http`.
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
┌────────── agent-comm-hub (127.0.0.1:18764/mcp) ──────────┐
|
|
31
|
+
│ peer registry (bridge_register) · per-peer mailboxes · │
|
|
32
|
+
│ long-poll waiters · broadcast · task/ack routing │
|
|
33
|
+
└───▲──────────▲──────────▲──────────▲──────────▲──────────┘
|
|
34
|
+
│ │ │ │ │
|
|
35
|
+
mcp.json │ .mcp.json │ opencode.json │ config.toml │ settings.json
|
|
36
|
+
┌──────────┴──┐ ┌───────┴───┐ ┌───────┴───┐ ┌──────┴───┐ ┌───────┴───┐
|
|
37
|
+
│ MiniMax Code│ │ Claude Code│ │ opencode │ │ Codex │ │Gemini CLI │
|
|
38
|
+
└─────────────┘ └───────────┘ └───────────┘ └──────────┘ └───────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Highlights
|
|
42
|
+
|
|
43
|
+
- **Any agent, one config**: every client points at the same `streamable-http` URL — no per-pair wiring.
|
|
44
|
+
- **Reliable identity**: the sender of every message is derived from the connection's session binding, never caller-supplied — peers cannot impersonate each other; duplicate ids are rejected. Connecting the MCP auto-registers your client name — no manual setup. Peers carry a profile (client name/version, display alias) and joins/leaves are pushed over SSE.
|
|
45
|
+
- **Real-time by polling**: `bridge_wait` long-polls (default 30 s, server ceiling 60 s); messages queue for offline peers.
|
|
46
|
+
- **Structured conversations**: `chat` / `task` / `notice` / `ack` message kinds, acks auto-routed back to the original sender, `to: "all"` broadcast.
|
|
47
|
+
- **Hard control via herdr** (optional): when the [herdr](https://herdr.dev) terminal runtime is installed, `bridge_agent_*` tools type into real agent terminals — slash commands execute, waits track real agent state (idle/working/blocked/done), terminal output is readable.
|
|
48
|
+
- **Zero dependencies, one process**: `npx agent-comm-hub` — no database, no daemon, no external services.
|
|
49
|
+
|
|
50
|
+
## Quickstart
|
|
51
|
+
|
|
52
|
+
### 1. Install the hub
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# run without installing (fetches from the npm registry each time)
|
|
56
|
+
npx agent-comm-hub
|
|
57
|
+
|
|
58
|
+
# or install globally and run anywhere
|
|
59
|
+
npm install -g agent-comm-hub
|
|
60
|
+
agent-comm-hub
|
|
61
|
+
|
|
62
|
+
# or install into a project
|
|
63
|
+
npm install -D agent-comm-hub
|
|
64
|
+
npx agent-comm-hub
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Update later without a manual reinstall (files are replaced in place, so an
|
|
68
|
+
installed auto-start launcher keeps working; restart the hub afterwards):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
agent-comm-hub update
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. Start the hub
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
agent-comm-hub
|
|
78
|
+
# → agent-comm-hub listening on http://127.0.0.1:18764/mcp
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For long-running setups use your preferred supervisor (systemd unit, pm2,
|
|
82
|
+
Task Scheduler on Windows) — or the built-in one-shot auto-start:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
agent-comm-hub service install # Windows: HKCU Run + hidden launcher (no admin)
|
|
86
|
+
# Linux: systemd --user unit, enabled
|
|
87
|
+
# macOS: launchd LaunchAgent
|
|
88
|
+
agent-comm-hub service uninstall # undo
|
|
89
|
+
agent-comm-hub status # is the hub up? who is online?
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`status` probes the endpoint and prints the hub version plus every registered
|
|
93
|
+
peer with its online state (it registers a throwaway probe and cleans up after
|
|
94
|
+
itself).
|
|
95
|
+
|
|
96
|
+
### 3. Connect your agents (one command)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
agent-comm-hub setup
|
|
100
|
+
# or: agents/install-all.ps1 (PowerShell equivalent)
|
|
101
|
+
# undo: agent-comm-hub setup --remove
|
|
102
|
+
# list what is installed (no changes): agent-comm-hub discover
|
|
103
|
+
# configure a single agent: agent-comm-hub setup --agent codex
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`setup` **discovers** which agents are installed on this machine (PATH
|
|
107
|
+
commands, config paths, npm global packages — no shell, cross-platform) and
|
|
108
|
+
merges the `agent-hub` MCP entry into each one's config (mcode, opencode, Kimi
|
|
109
|
+
Code, Gemini CLI, Codex, zcode, DSH, claude-desktop on macOS), plus the English
|
|
110
|
+
skill into `~/.agents/skills/` (the cross-agent standard) and each agent's
|
|
111
|
+
private skills dir. Which agents are supported is declared in
|
|
112
|
+
[`agents/registry.json`](agents/registry.json) — adding a new agent is one
|
|
113
|
+
registry record, no code change. Only the `agent-hub` key is touched, every
|
|
114
|
+
file is backed up first, and re-running is a no-op. Claude Code's MCP config
|
|
115
|
+
stays manual (see below).
|
|
116
|
+
|
|
117
|
+
**Registration is automatic**: once an agent session starts, the MCP handshake
|
|
118
|
+
registers it with the hub (client name becomes the peer id) — no manual step.
|
|
119
|
+
Optional: `bridge_register("tool:project")` for a readable id.
|
|
120
|
+
|
|
121
|
+
### 4. Verify the endpoint
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
curl -X POST http://127.0.0.1:18764/mcp \
|
|
125
|
+
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
|
|
126
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Connect your agents
|
|
130
|
+
|
|
131
|
+
Each agent gets **one MCP server entry** pointing at `http://127.0.0.1:18764/mcp`, plus the shared English skill (`agents/SKILL.md`) that teaches it when and how to use the bridge tools. Templates live in [`agents/`](agents/README.md).
|
|
132
|
+
|
|
133
|
+
**One-shot incremental sync** (recommended): `agents/install-all.ps1` merges the
|
|
134
|
+
`agent-hub` entry into every installed agent's MCP config (mcode, opencode,
|
|
135
|
+
Kimi Code, Gemini CLI, Codex, zcode, DSH) and installs the skill — it only
|
|
136
|
+
touches the `agent-hub` key, backs up each file, and is idempotent. Claude Code
|
|
137
|
+
is manual (below).
|
|
138
|
+
|
|
139
|
+
| Agent | Config file | Template | Skill location |
|
|
140
|
+
|---|---|---|---|
|
|
141
|
+
| MiniMax Code (mcode) | `~/.minimax/mcp.json` (+ `~/.minimax/mcp/mcp.json`) | [`agents/minimax-code/`](agents/minimax-code/) | `~/.minimax/skills/agent-comm-hub/SKILL.md` |
|
|
142
|
+
| opencode | `~/.config/opencode/opencode.json` | [`agents/opencode/opencode.json`](agents/opencode/opencode.json) | `~/.config/opencode/skills/agent-comm-hub/SKILL.md` |
|
|
143
|
+
| Kimi Code | `~/.kimi-code/mcp.json` | [`agents/kimi-code/mcp-entry.json`](agents/kimi-code/mcp-entry.json) | `~/.kimi-code/skills/agent-comm-hub/SKILL.md` |
|
|
144
|
+
| Gemini CLI | `~/.gemini/settings.json` | [`agents/gemini-cli/settings.json`](agents/gemini-cli/settings.json) | `~/.gemini/skills/agent-comm-hub/SKILL.md` |
|
|
145
|
+
| Codex | `~/.codex/config.toml` | [`agents/codex/config.toml`](agents/codex/config.toml) | `~/.codex/skills/agent-comm-hub/SKILL.md` |
|
|
146
|
+
| zcode | `~/.zcode/cli/config.json` (`mcp.servers`) | [`agents/zcode/config.json`](agents/zcode/config.json) | `~/.zcode/skills/agent-comm-hub/SKILL.md` |
|
|
147
|
+
| Claude Code | project `.mcp.json` (manual; `~/.claude.json` is never touched) | [`agents/claude-code/.mcp.json`](agents/claude-code/.mcp.json) | `~/.claude/skills/agent-comm-hub/SKILL.md` |
|
|
148
|
+
| DeepSeek Harness (DSH) | `~/.dsh/profiles/*/cordis.patch.yml` (auto by `setup`) | [`agents/dsh/cordis.patch.yml`](agents/dsh/cordis.patch.yml) | `$DSH_HOME/skills/agent-comm-hub/SKILL.md` |
|
|
149
|
+
|
|
150
|
+
> Streamable-http support varies by agent version; the templates use the fields each agent documents. If a client lacks HTTP MCP, wrap the endpoint with a stdio shim.
|
|
151
|
+
|
|
152
|
+
### MiniMax Code (mcode)
|
|
153
|
+
|
|
154
|
+
Run the installer (backs up both config files first, writes UTF-8 without BOM):
|
|
155
|
+
|
|
156
|
+
```powershell
|
|
157
|
+
powershell -ExecutionPolicy Bypass -File agents/minimax-code/install-mcode.ps1
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
It registers `agent-hub` in `~/.minimax/mcp.json` (read by the CLI runtime) and `~/.minimax/mcp/mcp.json` (desktop app), and installs the skill. Restart your mcode session, then ask the agent:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
先调用 bridge_register("mavis:myproject"),然后 bridge_peers 看看谁在线
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Claude Code
|
|
167
|
+
|
|
168
|
+
Copy `agents/claude-code/.mcp.json` into your project root (or merge `mcpServers.agent-hub` into `~/.claude.json`):
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"mcpServers": {
|
|
173
|
+
"agent-hub": {
|
|
174
|
+
"type": "http",
|
|
175
|
+
"url": "http://127.0.0.1:18764/mcp"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Copy `agents/SKILL.md` to `~/.claude/skills/agent-comm-hub/SKILL.md`, restart Claude, and have it `bridge_register("claude-code:myproject")`.
|
|
182
|
+
|
|
183
|
+
### opencode
|
|
184
|
+
|
|
185
|
+
Merge into `~/.config/opencode/opencode.json`:
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"mcp": {
|
|
190
|
+
"agent-hub": {
|
|
191
|
+
"type": "remote",
|
|
192
|
+
"url": "http://127.0.0.1:18764/mcp",
|
|
193
|
+
"enabled": true
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Codex
|
|
200
|
+
|
|
201
|
+
Append to `~/.codex/config.toml`:
|
|
202
|
+
|
|
203
|
+
```toml
|
|
204
|
+
[mcp_servers.agent-hub]
|
|
205
|
+
type = "streamable-http"
|
|
206
|
+
url = "http://127.0.0.1:18764/mcp"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Gemini CLI
|
|
210
|
+
|
|
211
|
+
Merge into `~/.gemini/settings.json`:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"mcpServers": {
|
|
216
|
+
"agent-hub": {
|
|
217
|
+
"type": "http",
|
|
218
|
+
"url": "http://127.0.0.1:18764/mcp"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### DeepSeek Harness (DSH)
|
|
225
|
+
|
|
226
|
+
Auto-configured by `agent-comm-hub setup`: it discovers
|
|
227
|
+
`~/.dsh/profiles/*/cordis.patch.yml` and appends the `@deepseek-ai/dsh-mcp-client`
|
|
228
|
+
row, so DSH sessions expose the tools as `mcp__agent-hub__bridge_*` after a dsh
|
|
229
|
+
restart. Manual equivalent (or template for other profiles):
|
|
230
|
+
|
|
231
|
+
```yaml
|
|
232
|
+
- insert:
|
|
233
|
+
- id: agent-comm-hub
|
|
234
|
+
name: '@deepseek-ai/dsh-mcp-client'
|
|
235
|
+
config:
|
|
236
|
+
serverName: agent-hub
|
|
237
|
+
transport: streamable-http
|
|
238
|
+
url: http://127.0.0.1:18764/mcp
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Tools
|
|
242
|
+
|
|
243
|
+
| Tool | Purpose |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `bridge_register(peerId)` | Claim or rename your identity (auto-registered at connect with the client name; optional for a readable id like `opencode:myproject`) |
|
|
246
|
+
| `bridge_unregister()` | Leave the hub (removes peer, queue, and session binding; stays off until an explicit register) |
|
|
247
|
+
| `bridge_chat(to, message)` | Send a chat message; `to: "all"` broadcasts |
|
|
248
|
+
| `bridge_task(to, prompt, context?, deliverable?)` | Delegate a structured task |
|
|
249
|
+
| `bridge_ack(ref, status, note?)` | Acknowledge a task (`accepted`/`rejected`/`done`/`failed`), routed back to the original sender |
|
|
250
|
+
| `bridge_wait(from?, timeoutMs?)` | Long-poll for the next message (default 30 s) |
|
|
251
|
+
| `bridge_poll(from?)` | Non-blocking drain of queued messages |
|
|
252
|
+
| `bridge_status()` | Hub health: peers with connected/queued/waiting state |
|
|
253
|
+
| `bridge_peers()` | Who is online |
|
|
254
|
+
| `bridge_history(peer?, limit?)` | Recent messages (context refresh after reconnect) |
|
|
255
|
+
|
|
256
|
+
### herdr control tools (optional)
|
|
257
|
+
|
|
258
|
+
If the [herdr](https://herdr.dev) terminal runtime is installed, the hub also
|
|
259
|
+
exposes **control tools** that type into real agent terminals — unlike
|
|
260
|
+
`bridge_chat` (a mailbox message the receiving model may ignore), a prompt
|
|
261
|
+
here is physical input: slash commands (`/compact`, `/model`, `/clear`) are
|
|
262
|
+
executed by the target's TUI, and waits block on herdr's real agent state
|
|
263
|
+
(idle/working/blocked/done), not screen activity.
|
|
264
|
+
|
|
265
|
+
| Tool | Purpose |
|
|
266
|
+
|---|---|
|
|
267
|
+
| `bridge_agent_list()` | Agent panes herdr detects (paneId, kind, status, cwd, interactive-ready) |
|
|
268
|
+
| `bridge_agent_status(target)` | Live state of one pane |
|
|
269
|
+
| `bridge_agent_prompt(target, text, wait?, until?, timeoutMs?)` | Submit text / slash command into the target's input line; with `wait`, block until it settles |
|
|
270
|
+
| `bridge_agent_wait(target, until?, timeoutMs?)` | Wait until the agent reaches a state (default idle/done/blocked) |
|
|
271
|
+
| `bridge_agent_read(target, lines?, source?)` | Read the pane's recent terminal output (reply of an agent not on the hub) |
|
|
272
|
+
| `bridge_agent_keys(target, keys)` | Raw key presses (Enter, esc, ctrl-c, arrows…) to dismiss prompts or interrupt |
|
|
273
|
+
|
|
274
|
+
### herdr pane tools (drive ANY pane — no agent detection)
|
|
275
|
+
|
|
276
|
+
`bridge_agent_*` requires herdr to **recognize** the agent (its built-in
|
|
277
|
+
manifest list: claude/codex/opencode/kimi/…). For agents herdr does not know
|
|
278
|
+
(e.g. MiniMax Code), the pane tools drive any pane through the herdr local
|
|
279
|
+
socket — physical input, read output:
|
|
280
|
+
|
|
281
|
+
| Tool | Purpose |
|
|
282
|
+
|---|---|
|
|
283
|
+
| `bridge_pane_list()` | Every pane (ids, titles, agent status) |
|
|
284
|
+
| `bridge_pane_send(target, text, enter?)` | Type text into a pane (slash commands execute; Enter submits by default) |
|
|
285
|
+
| `bridge_pane_keys(target, keys)` | Raw key presses to any pane |
|
|
286
|
+
| `bridge_pane_read(target, lines?, source?)` | Read a pane's recent output |
|
|
287
|
+
|
|
288
|
+
Verified live: a MiniMax Code session was driven end-to-end through the hub —
|
|
289
|
+
prompt injected via `bridge_pane_send`, reply collected via
|
|
290
|
+
`bridge_pane_read`, no agent-side configuration.
|
|
291
|
+
|
|
292
|
+
Control tools are gated: `herdrControlPeers` restricts who may use them
|
|
293
|
+
(default `'all'`, mirroring the hub's loopback-only trust model). They are
|
|
294
|
+
hard control — an injected `/clear` clears the target's context.
|
|
295
|
+
|
|
296
|
+
### Roster management (aliases, kick)
|
|
297
|
+
|
|
298
|
+
Peers carry a **profile**: the client name/version reported at connect, plus
|
|
299
|
+
an optional **display alias** (`bridge_rename`). The alias is cosmetic — it
|
|
300
|
+
shows up in `bridge_peers` / `bridge_status` and the desktop roster, while
|
|
301
|
+
routing, mailboxes, history, and acks keep using the peer id, so a rename
|
|
302
|
+
never drops messages. A manager can also **truly rename** a registered peer
|
|
303
|
+
(`bridge_rename { peer, peerId }`): mailbox, waiters, session bindings, and
|
|
304
|
+
history attribution move atomically — queued messages and acks stay
|
|
305
|
+
continuous. Renaming yourself is open to everyone; renaming/kicking
|
|
306
|
+
**another** peer (`bridge_unregister { peer }`) or reading another peer's
|
|
307
|
+
history (`bridge_history { peer }` / `peer: "all"`) requires the **manager**
|
|
308
|
+
role (`--manager-peers`, default `agent-hub-cli` — the desktop GUI identity).
|
|
309
|
+
This is a convention on top of the loopback trust model, not authentication.
|
|
310
|
+
|
|
311
|
+
Rosters persist: `--state-file` (default `~/.agent-comm-hub/roster.json`,
|
|
312
|
+
`off` to disable) keeps aliases and client info across hub restarts.
|
|
313
|
+
|
|
314
|
+
Roster changes and queued mail are pushed over the SSE channel as
|
|
315
|
+
`notifications/message` events (`data.event: "peers_changed"` with the full
|
|
316
|
+
roster, `data.event: "message"` hint scoped to the recipient), so GUIs and
|
|
317
|
+
skills can react without polling.
|
|
318
|
+
|
|
319
|
+
Every result is lossless JSON (compatible with DSH's strict tool registry).
|
|
320
|
+
|
|
321
|
+
## CLI reference
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
agent-comm-hub [options] start the hub
|
|
325
|
+
agent-comm-hub setup [options] sync MCP entry + skill to all agents
|
|
326
|
+
agent-comm-hub status [options] hub health + online peers
|
|
327
|
+
agent-comm-hub service install|uninstall [options] one-shot auto-start
|
|
328
|
+
(Windows HKCU Run + hidden launcher,
|
|
329
|
+
no admin; Linux systemd --user)
|
|
330
|
+
|
|
331
|
+
--host <addr> Bind address (default 127.0.0.1)
|
|
332
|
+
--port <n> Listen port (default 18764)
|
|
333
|
+
--path <p> MCP endpoint path (default /mcp)
|
|
334
|
+
--max-queue <n> Queued messages per peer before dropping oldest (default 200)
|
|
335
|
+
--history-limit <n> Retained history messages (default 1000)
|
|
336
|
+
--wait-timeout-ms <n> Long-poll ceiling for bridge_wait (default 60000)
|
|
337
|
+
--default-wait-ms <n> bridge_wait default budget (default 30000)
|
|
338
|
+
--connected-window-ms <n> Peer counts as active within this window (default 30000)
|
|
339
|
+
--peer-idle-timeout-ms <n> Auto-unregister idle peers after this; 0 disables (default 600000)
|
|
340
|
+
--herdr-bin <path> herdr CLI binary for bridge_agent_* control tools
|
|
341
|
+
(default herdr, resolved via PATH)
|
|
342
|
+
--herdr-timeout-ms <n> Default cap for one herdr call in ms (default 30000)
|
|
343
|
+
--manager-peers <ids> Comma-separated roster managers, or "all"
|
|
344
|
+
(default agent-hub-cli — the desktop GUI identity)
|
|
345
|
+
--state-file <path> Roster persistence file
|
|
346
|
+
(default ~/.agent-comm-hub/roster.json; "off" = memory only)
|
|
347
|
+
--url <u> / --server-name <n> / --remove / --dry-run (setup/service/status)
|
|
348
|
+
-h, --help Show help
|
|
349
|
+
-V, --version Show version
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Running & resource usage
|
|
353
|
+
|
|
354
|
+
`agent-comm-hub` is a **foreground process**: it keeps listening once started
|
|
355
|
+
and stops on Ctrl+C. It does NOT auto-start at boot or daemonize — keep it
|
|
356
|
+
alive with your own supervisor:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# pm2 (cross-platform)
|
|
360
|
+
npm i -g pm2
|
|
361
|
+
pm2 start agent-comm-hub --name agent-comm-hub
|
|
362
|
+
pm2 save && pm2 startup # boot persistence
|
|
363
|
+
|
|
364
|
+
# or the built-in one-shot auto-start (no admin needed)
|
|
365
|
+
agent-comm-hub service install # Windows: HKCU Run + hidden VBS launcher
|
|
366
|
+
# Linux: systemd --user unit, enabled
|
|
367
|
+
agent-comm-hub service uninstall
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Measured footprint (Windows / Node 24, idle):**
|
|
371
|
+
|
|
372
|
+
| Metric | Value |
|
|
373
|
+
|---|---|
|
|
374
|
+
| Idle CPU | ≈ 0 (event-driven; the only timer is a once-a-minute idle-GC check) |
|
|
375
|
+
| Memory over an idle Node baseline | **~ +8 MB** WorkingSet (the ~100+ MB baseline is the Node runtime itself) |
|
|
376
|
+
| Disk | None (no database; nothing written besides logs) |
|
|
377
|
+
|
|
378
|
+
Each online agent adds one SSE keep-alive socket; mailboxes/history are
|
|
379
|
+
in-memory with configurable caps. Negligible impact.
|
|
380
|
+
|
|
381
|
+
## Programmatic API
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
import { startHub, DEFAULT_CONFIG } from 'agent-comm-hub'
|
|
385
|
+
|
|
386
|
+
const hub = startHub({ port: 18764 }, console) // returns { hub, registry, server, mcp, close }
|
|
387
|
+
// hub.close() to stop
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
`startHub(config?, logger?)` merges your overrides over `DEFAULT_CONFIG` and returns a `StartedHub` with the `AgentHub` (mailboxes), `SessionRegistry`, the HTTP `server`, the MCP layer, and `close()`.
|
|
391
|
+
|
|
392
|
+
## Message protocol & identity
|
|
393
|
+
|
|
394
|
+
```json
|
|
395
|
+
{ "id": "uuid", "from": "mavis", "to": "claude", "kind": "chat", "content": "..." }
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
- `kind`: `chat` | `task` | `notice` | `ack`. `task` content is `{prompt, context?, deliverable?}`; `ack` content is `{status, note?}` — both JSON-encoded.
|
|
399
|
+
- `from` is **injected by the hub** from the session→peer binding; clients cannot set it.
|
|
400
|
+
- Each connection gets a unique `Mcp-Session-Id`; the binding table maps session → peerId; duplicate peerIds are rejected.
|
|
401
|
+
- **Auto-registration**: connecting the MCP is enough to join — the session
|
|
402
|
+
registers at the handshake (`initialize`) using the `clientInfo` name.
|
|
403
|
+
**Same-name connections share one peer id** (an agent that opens a new
|
|
404
|
+
session per chat keeps a stable identity and its sessions share the
|
|
405
|
+
mailbox). `bridge_register` upgrades the id to something readable;
|
|
406
|
+
`bridge_unregister` detaches (dropping the peer when no other session shares
|
|
407
|
+
it) and suppresses auto-registration until an explicit register.
|
|
408
|
+
- Peers are offline-tolerant: messages queue (max `maxQueue`, oldest dropped) until the peer polls; a peer must re-register after its agent restarts (bindings are per-session and in-memory; restarting the hub clears everything).
|
|
409
|
+
- **Liveness**: `connected` means activity within `connectedWindowMs` (default 30 s) **or** a live SSE channel — an open agent session stays online without heartbeat calls. The idle GC (default 10 min) never evicts a peer with a live SSE channel; only peers whose channel is gone are recycled, freeing their names.
|
|
410
|
+
|
|
411
|
+
## Security
|
|
412
|
+
|
|
413
|
+
- Binds to `127.0.0.1` by default and has **no authentication** — do not expose the port publicly without adding a token/proxy layer.
|
|
414
|
+
- Never put credentials in bridge messages (plaintext on loopback).
|
|
415
|
+
- Peer ids are validated `[A-Za-z0-9._:-]{1,64}`; unregistered callers get a clear error.
|
|
416
|
+
|
|
417
|
+
## Development
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
pnpm install
|
|
421
|
+
pnpm typecheck # tsc --noEmit (strict)
|
|
422
|
+
pnpm test # test suite (181 checks: 80 smoke + 32 setup + 11 ops + 35 herdr + 23 discover)
|
|
423
|
+
pnpm run build # esbuild → lib/{cli,index,setup}.js (zero deps)
|
|
424
|
+
pnpm pack # build + npm pack (publishing artifact)
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Desktop GUI
|
|
428
|
+
|
|
429
|
+
A companion desktop GUI is shipped as a separate npm package: **`agent-comm-hub-app`**. It is a standalone Tauri 2 + React app, lives in `app/`, and depends on the MCP HTTP API rather than on this package's source. It does NOT relax the `dependencies: {}` constraint of the main package — workspace isolation is enforced via `app/pnpm-workspace.yaml`.
|
|
430
|
+
|
|
431
|
+
| English | 简体中文 |
|
|
432
|
+
|---|---|
|
|
433
|
+
|  |  |
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
cd app
|
|
437
|
+
pnpm install
|
|
438
|
+
pnpm tauri:dev # dev with hot reload
|
|
439
|
+
pnpm tauri:build # produces NSIS / MSI / dmg / AppImage / deb installers
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Highlights:
|
|
443
|
+
|
|
444
|
+
- **Hub lifecycle in one window**: auto-spawn on launch (4-tier PATH fallback), start / stop / restart, live log panel with stderr filter + expandable viewer, and an external-hub reuse mode with health probing
|
|
445
|
+
- **Real-time messaging**: `bridge_wait` long-poll keeps the UI live; optimistic send shows your messages instantly; `/history` merges hub memory with the SQLite archive (survives hub restarts)
|
|
446
|
+
- **Peer conversations** (PRD US-2): click any peer to view its full conversation, not just yours; unread badges per peer
|
|
447
|
+
- **Message details**: raw JSON view, task prompt/context/deliverable, ack state-machine timeline
|
|
448
|
+
- **Slash commands**: `/peers /broadcast /history /clear /help` — from the palette or typed directly
|
|
449
|
+
- **Markdown rendering** with rehype-sanitize, multi-peer cc, drag-drop attachments (≤5 MB), virtual scrolling
|
|
450
|
+
- **Theme system**: dark / light / system-follow, brand-blue palette, persisted
|
|
451
|
+
- **Frameless window**: custom titlebar (drag region, double-click maximize), close dialog with minimize-to-tray / quit / cancel
|
|
452
|
+
- **Hub tools in Settings**: install / version / check update / update the hub CLI, one-click `setup` to detect local agents and install the SKILL + MCP config, auto-start service install
|
|
453
|
+
- **System tray** with brand logo and status tooltip; i18n (zh-CN default, en-US)
|
|
454
|
+
|
|
455
|
+
See `app/README.md` for the full feature list and architecture.
|
|
456
|
+
|
|
457
|
+
Tests cover registration, duplicate rejection, chat routing, sender-filtered waits, task+ack routing back to the sender, broadcast, status/peers/history, unregister/re-register, and error paths.
|
|
458
|
+
|
|
459
|
+
## Troubleshooting
|
|
460
|
+
|
|
461
|
+
| Symptom | Cause / fix |
|
|
462
|
+
|---|---|
|
|
463
|
+
| Agent has no `bridge_*` tools | Hub not running — start `agent-comm-hub` and restart the agent session |
|
|
464
|
+
| `unknown recipient: xxx` | The peer hasn't registered (or used a different peerId) — check `bridge_peers()` |
|
|
465
|
+
| `not registered — call bridge_register` | Only appears after an explicit `bridge_unregister` (normal connections auto-register at connect); clients without a client name fall back to `agent` |
|
|
466
|
+
| `peer already registered by another connection` | Another live connection holds the id — pick a unique peerId (e.g. `tool:project`) or restart the hub to clear stale bindings |
|
|
467
|
+
| Port conflict | 18764 is the default; if it is taken, change with `--port` and update every agent config |
|
|
468
|
+
| Chinese garbled in PowerShell clients | Response headers carry `charset=utf-8`; send request bodies as UTF-8 bytes (`[System.Text.Encoding]::UTF8.GetBytes(...)`) |
|
|
469
|
+
|
|
470
|
+
## License
|
|
471
|
+
|
|
472
|
+
MIT — see [LICENSE](LICENSE). Contributions welcome: keep the 64-check suite green (`pnpm test`) and zero runtime dependencies. Architecture: [ARCHITECTURE.md](ARCHITECTURE.md).
|