clawborrator-mcp 0.0.25 → 0.0.26

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 CHANGED
@@ -2,14 +2,15 @@
2
2
 
3
3
  MCP server that connects each running Claude Code instance to a
4
4
  [`hub_v1`](https://github.com/clawborrator/hub_v1) over WebSocket.
5
- Companion to the hub. Designed to be invoked by Claude Code via
6
- `.mcp.json`; runs as both a long-lived stdio MCP server AND a
7
- short-lived hook spawn (selected by the `--hook=<HookName>` CLI flag).
5
+ Designed to be invoked by Claude Code via `.mcp.json`; runs as both
6
+ a long-lived stdio MCP server AND a short-lived hook spawn (selected
7
+ by the `--hook=<HookName>` CLI flag).
8
8
 
9
- > **Status: dev-mode-only.** Connect to a local hub at `ws://localhost:8787`.
10
- > Production deployment is a future concern.
11
- >
12
- > Design context: [`hub/design/IMPL-PLAN-1-CHANNEL-V1-FRESH-START.md`](https://github.com/clawborrator/hub/blob/main/design/IMPL-PLAN-1-CHANNEL-V1-FRESH-START.md).
9
+ Published as [`clawborrator-mcp`](https://www.npmjs.com/package/clawborrator-mcp)
10
+ on npm.
11
+
12
+ > **Status: production hub at [`next.clawborrator.com`](https://next.clawborrator.com).**
13
+ > Local dev uses `ws://localhost:8787`. Both supported.
13
14
 
14
15
  ---
15
16
 
@@ -24,7 +25,7 @@ Set in your project's `.mcp.json`:
24
25
  "command": "npx",
25
26
  "args": ["-y", "clawborrator-mcp"],
26
27
  "env": {
27
- "CLAWBORRATOR_HUB_URL": "ws://localhost:8787",
28
+ "CLAWBORRATOR_HUB_URL": "wss://next.clawborrator.com",
28
29
  "CLAWBORRATOR_TOKEN": "ck_live_…"
29
30
  }
30
31
  }
@@ -56,7 +57,8 @@ claw token mint --kind=channel --name=mbp --mcp-snippet
56
57
  4. Writes `<cwd>/.claude/clawborrator.session.json` (mode 0600) so per-event hook spawns can find the active session.
57
58
  5. Maintains the WS with heartbeat ping/pong; reconnects with exponential backoff (1s/2s/5s/15s/30s/60s).
58
59
  6. Listens for hub-side messages: `prompt` (cross-session route), `permission_response`, `peers_update`, `bye`, `error`.
59
- 7. On clean shutdown (SIGINT/SIGTERM/exit), deletes the sidecar.
60
+ 7. Dispatches MCP tool calls (see below) over the same WS.
61
+ 8. On clean shutdown (SIGINT/SIGTERM/exit), deletes the sidecar.
60
62
 
61
63
  **Short-lived hook path** (`--hook=<HookName>` flag):
62
64
  1. Reads JSON payload from stdin (Claude Code's hook protocol).
@@ -70,29 +72,79 @@ Hooks are installed with `claw session init` from inside a project — see hub_v
70
72
 
71
73
  ---
72
74
 
73
- ## Tools exposed to Claude
75
+ ## MCP tools exposed to Claude
76
+
77
+ Routed: targets a peer (your own session or another operator's session you have a share on) by routingName.
78
+
79
+ | Tool | Purpose |
80
+ |---|---|
81
+ | `reply({ chat_id, text })` | Post a tagged final reply for a routed prompt (closes the round-trip when the source session is blocking on a reply). |
82
+ | `reply_chunk({ chat_id, text, done })` | Stream a reply progressively — the operator sees text growing live; close with `done:true`. Same correlation as `reply`. |
83
+ | `list_peers()` | Discover other CC sessions the operator has access to (own sessions + shared ones). Refused on agents published as `isolated`. |
84
+ | `route_to_peer({ peer, prompt, mode })` | Send one prompt to one peer. `mode: 'ask'` blocks for the reply; `mode: 'tell'` is fire-and-forget. |
85
+ | `probe_peers({ prompt, peers? })` | Fan out the same short question to many peers in parallel for discovery. |
86
+ | `await_routed_prompt({ maxWaitMs })` | Dequeue an inbound routed prompt for THIS session — used by agents that service requests from other sessions. |
87
+
88
+ Cross-tenant — public agents owned by other operators:
89
+
90
+ | Tool | Purpose |
91
+ |---|---|
92
+ | `list_agents()` | Discover public agents on the hub. Returns handle, name, tagline, online, mine, isolated flags. |
93
+ | `dispatch_to_agent({ handle, prompt, mode })` | Invoke a published agent by `<owner>/<slug>` handle. `ask` mode waits up to 15 min for the reply; `tell` mode is fire-and-forget. |
74
94
 
75
- v1 ships an empty MCP tool list. The hooks-based event firehose
76
- covers chat + tail event capture without any Claude-side tool calls.
95
+ File exchange:
77
96
 
78
- Phase D adds these:
79
- - `reply({ chat_id, text })` — Claude posts a tagged final reply
80
- - `list_peers()` Claude discovers other operator sessions
81
- - `route_to_peer({ peer, prompt, mode })` Claude routes a question
82
- - `probe_peers({ prompt, peers? })` Claude fan-out probes
97
+ | Tool | Purpose |
98
+ |---|---|
99
+ | `attach_file({ path, targetSessionId? })` | Upload a file from disk to the session (or to a peer's session you have a share on). Returns `fileId`. |
100
+ | `read_file({ fileId })` | Fetch a session-attached file inline (text-mime; under 1 MB). Reply-clone makes peer-uploaded files visible to the recipient. |
101
+ | `download_to_path({ fileId, path })` | Fetch a larger or binary file to disk. Returns the absolute path written. |
83
102
 
84
- For now, operators initiate routing via `claw route` / `claw probe`.
103
+ The hub correlates `reply` / `reply_chunk` to their originating
104
+ `route_to_peer` / `dispatch_to_agent` by chatId; the source session's
105
+ CC unblocks when the matching reply lands. 15-minute timeout caps —
106
+ see `hub_v1/server/src/services/agents.ts` and `services/op-routes.ts`.
107
+
108
+ For `await_routed_prompt` to actually fire — i.e., for an agent to
109
+ service incoming requests — its CLAUDE.md needs a line telling Claude
110
+ to call it at the start of each turn. Without that note, Claude
111
+ won't know to consult the inbox. See
112
+ [`hub_v1/docs/3-AGENT-SETUP.md`](https://github.com/clawborrator/hub_v1/blob/main/docs/3-AGENT-SETUP.md)
113
+ for the dispatcher-pattern setup.
85
114
 
86
115
  ---
87
116
 
88
- ## Phases
117
+ ## Hook coverage
118
+
119
+ Maps each Claude Code hook to a hub event. The hook script is
120
+ `dist-hook/clawborrator-tail.mjs`; install via `claw session init`.
89
121
 
90
- - **Phase A** (✓): connect / register / heartbeat / reconnect
91
- - **Phase B** (✓): hooks + event forwarding via sidecar
92
- - **Phase C** (): bidirectional permission relay protocol (channel
93
- hub operator back). Hook IPC for actually delivering decisions
94
- into a blocked PreToolUse hook is upcoming.
95
- - **Phase D**: MCP tools (above)
122
+ | Hook | Hub event | Notes |
123
+ |---|---|---|
124
+ | `UserPromptSubmit` | `chat/prompt` (source='cli') | Operator typing into the local CC terminal. |
125
+ | `PreToolUse` | `tail/PreToolUse` (+ `chat/assistant_text` per text block from the transcript) | The tail captures pre-reply narration too. |
126
+ | `PostToolUse` | `tail/PostToolUse` | |
127
+ | `PostToolUseFailure` | `tail/PostToolUseFailure` | |
128
+ | `Stop` | `tail/Stop` (+ `chat/reply` if assistant_text present) | Turn-end signal. |
129
+ | `Notification` | `tail/Notification` | CC user notifications (idle / permission). |
130
+ | `SessionStart` / `SessionEnd` | `tail/SessionStart` / `tail/SessionEnd` | |
131
+ | `TaskCreated` / `TaskCompleted` | `tail/TaskCreated` / `tail/TaskCompleted` | Carries `task_id`, `task_subject`, `task_description`. |
132
+ | `SubagentStart` / `SubagentStop` | `tail/SubagentStart` / `tail/SubagentStop` | SubagentStop carries `last_assistant_message` recap. |
133
+
134
+ The tail reads the CC transcript file directly to enrich `PreToolUse`
135
+ with the assistant's pre-reply text (which CC doesn't put on the
136
+ hook payload directly). See `transcript.ts` for the walker.
137
+
138
+ ---
139
+
140
+ ## Phases (all shipped)
141
+
142
+ - **Phase A** ✓ — connect / register / heartbeat / reconnect
143
+ - **Phase B** ✓ — hooks + event forwarding via sidecar
144
+ - **Phase C** ✓ — bidirectional permission relay (channel → hub → operator → back)
145
+ - **Phase D** ✓ — MCP tools (above)
146
+ - **Phase E** ✓ — public-agent dispatch (`dispatch_to_agent`, `list_agents`); 15-min timeouts; cyclomatic-complexity refactor
147
+ - **Phase F** ✓ — streaming `reply_chunk` (incremental output), `read_file` / `download_to_path` for cross-session file exchange
96
148
 
97
149
  ---
98
150
 
@@ -107,4 +159,16 @@ npm link
107
159
  clawborrator-mcp --hook=PreToolUse < /dev/null # exits cleanly with no sidecar
108
160
  ```
109
161
 
110
- When `claude` runs in a folder whose `.mcp.json` references `clawborrator-mcp`, npm/npx resolves it to your linked build.
162
+ When `claude` runs in a folder whose `.mcp.json` references
163
+ `clawborrator-mcp`, npm/npx resolves it to your linked build.
164
+
165
+ To publish a new release:
166
+
167
+ ```bash
168
+ npm version patch # bumps package.json + creates git tag
169
+ npm publish
170
+ git push --follow-tags
171
+ ```
172
+
173
+ The CLI's `claw token mint --mcp-snippet` autogenerates an `.mcp.json`
174
+ snippet pointing at the published version.
package/dist/sidecar.js CHANGED
@@ -49,19 +49,17 @@ export function readSidecar(cwd) {
49
49
  return null;
50
50
  }
51
51
  }
52
- // Walk upward from `start` looking for a sidecar. Hooks may run from
53
- // a deeper subdirectory than where the channel registered.
52
+ // Read the sidecar at `start` ONLY. The earlier walk-up was a
53
+ // misfeature: when a clawborrator-less CC ran inside a parent
54
+ // project that DID have a sidecar (e.g. an orchard subagent under
55
+ // a clauderemote checkout), its hooks attributed every event to
56
+ // the parent's sessionId. The fix: if there's no sidecar at the
57
+ // hook's exact cwd, drop the event silently. Hooks fired from
58
+ // nested subdirectories of an actual clawborrator project should
59
+ // be the rare case; if it surfaces in practice, re-add a bounded
60
+ // walk anchored on a clawborrator-specific marker file (NOT a
61
+ // generic .claude/ presence).
54
62
  export function findSidecar(start) {
55
- let dir = resolve(start);
56
- for (let i = 0; i < 32; i++) {
57
- const found = readSidecar(dir);
58
- if (found)
59
- return found;
60
- const parent = resolve(dir, '..');
61
- if (parent === dir)
62
- break;
63
- dir = parent;
64
- }
65
- return null;
63
+ return readSidecar(start);
66
64
  }
67
65
  //# sourceMappingURL=sidecar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,kEAAkE;AAClE,8DAA8D;AAC9D,qDAAqD;AACrD,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,mEAAmE;AACnE,+DAA+D;AAE/D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAY/B,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAuB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC;YAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,qEAAqE;AACrE,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,kEAAkE;AAClE,8DAA8D;AAC9D,qDAAqD;AACrD,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,mEAAmE;AACnE,+DAA+D;AAE/D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAY/B,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAuB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC;YAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,8DAA8D;AAC9D,kEAAkE;AAClE,gEAAgE;AAChE,gEAAgE;AAChE,8DAA8D;AAC9D,iEAAiE;AACjE,iEAAiE;AACjE,8DAA8D;AAC9D,8BAA8B;AAC9B,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
@@ -37,15 +37,7 @@ function readSidecar(cwd) {
37
37
  }
38
38
  }
39
39
  function findSidecar(start) {
40
- let dir = resolve(start);
41
- for (let i = 0; i < 32; i++) {
42
- const found = readSidecar(dir);
43
- if (found) return found;
44
- const parent = resolve(dir, "..");
45
- if (parent === dir) break;
46
- dir = parent;
47
- }
48
- return null;
40
+ return readSidecar(start);
49
41
  }
50
42
 
51
43
  // src/transcript.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-mcp",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "type": "module",
5
5
  "description": "clawborrator channel for hub_v1 — MCP server that connects Claude Code to a hub over WebSocket, with hooks for activity capture and tools for cross-session routing.",
6
6
  "license": "MIT",