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 +90 -26
- package/dist/sidecar.js +11 -13
- package/dist/sidecar.js.map +1 -1
- package/dist-hook/clawborrator-tail.mjs +1 -9
- package/package.json +1 -1
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
>
|
|
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": "
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
|
|
76
|
-
covers chat + tail event capture without any Claude-side tool calls.
|
|
95
|
+
File exchange:
|
|
77
96
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
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
|
-
//
|
|
53
|
-
// a
|
|
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
|
-
|
|
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
|
package/dist/sidecar.js.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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.
|
|
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",
|