clawborrator-mcp
v0.0.32
Published
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.
Maintainers
Readme
clawborrator-mcp (channel_v1)
MCP server that connects each running Claude Code instance to a
clawborrator hub over
WebSocket. Designed to be invoked by Claude Code via .mcp.json;
runs as both a long-lived stdio MCP server AND a short-lived hook
spawn (selected by the --hook=<HookName> CLI flag).
Published as clawborrator-mcp
on npm.
Status: production hub at
next.clawborrator.com. Local dev usesws://localhost:8787. Both supported.
Configuration
Set in your project's .mcp.json:
{
"mcpServers": {
"clawborrator": {
"command": "npx",
"args": ["-y", "clawborrator-mcp"],
"env": {
"CLAWBORRATOR_HUB_URL": "wss://next.clawborrator.com",
"CLAWBORRATOR_TOKEN": "ck_live_…"
}
}
}
}| Env var | Required | Notes |
|---|---|---|
| CLAWBORRATOR_HUB_URL | yes | ws://… or wss://…; no trailing slash |
| CLAWBORRATOR_TOKEN | yes | Channel token (ck_live_…) minted via claw token mint --kind=channel |
| CLAWBORRATOR_REUSE_SESSION_ID | no | Opt-in: reconnect rebinds to a known session id rather than creating a fresh one |
| CLAWBORRATOR_LOG_LEVEL | no | debug, info, warn, error; default info |
Get the snippet pre-filled with the right URL + token via the
clawborrator-cli:
npx clawborrator-cli token mint --kind=channel --name=mbp --mcp-snippet --out .mcp.jsonIf you're running the desktop daemon
(clawborrator-supervisor), it mints channel tokens server-side
when it spawns managed Claude Code sessions for you — the .mcp.json
ends up in the spawned project automatically.
What it does
Long-lived MCP path (default invocation):
- Reads env config; loads channel token.
- Opens WSS to
<HUB_URL>/channelwithAuthorization: Bearer <CHANNEL_TOKEN>. - Sends
registerwith host / cwd / pid / version; receiveswelcomewith sessionId + routingName. - Writes
<cwd>/.claude/clawborrator.session.json(mode 0600) so per-event hook spawns can find the active session. - Maintains the WS with heartbeat ping/pong; reconnects with exponential backoff (1s/2s/5s/15s/30s/60s).
- Listens for hub-side messages:
prompt(cross-session route),permission_response,peers_update,bye,error. - Dispatches MCP tool calls (see below) over the same WS.
- On clean shutdown (SIGINT/SIGTERM/exit), deletes the sidecar.
Short-lived hook path (--hook=<HookName> flag):
- Reads JSON payload from stdin (Claude Code's hook protocol).
- Locates the active sidecar (walks up from cwd looking for
.claude/clawborrator.session.json). - Maps the hook name to a clawborrator event (e.g.
PreToolUse→tail/PreToolUse,UserPromptSubmit→chat/prompt). - POSTs to
<HUB_URL>/api/channel/eventwith the channel token from the sidecar. - Echoes stdin to stdout so Claude's hook chain stays intact.
- Exits cleanly even if the hub is unreachable — never breaks the operator's actual Claude flow.
Hooks are auto-installed on first MCP startup: clawborrator-mcp reconciles
.claude/settings.json to add (or refresh) the entries that point at
dist-hook/clawborrator-tail.mjs. No separate install step.
MCP tools exposed to Claude
Routed: targets a peer (your own session or another operator's session you have a share on) by routingName.
| Tool | Purpose |
|---|---|
| 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). |
| reply_chunk({ chat_id, text, done }) | Stream a reply progressively — the operator sees text growing live; close with done:true. Same correlation as reply. |
| list_peers() | Discover other CC sessions the operator has access to (own sessions + shared ones). Refused on agents published as isolated. |
| route_to_peer({ peer, prompt, mode }) | Send one prompt to one peer. mode: 'ask' blocks for the reply; mode: 'tell' is fire-and-forget. |
| probe_peers({ prompt, peers? }) | Fan out the same short question to many peers in parallel for discovery. |
| await_routed_prompt({ maxWaitMs }) | Dequeue an inbound routed prompt for THIS session — used by agents that service requests from other sessions. |
Cross-tenant — public agents owned by other operators:
| Tool | Purpose |
|---|---|
| list_agents() | Discover public agents on the hub. Returns handle, name, tagline, online, mine, isolated flags. |
| 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. |
File exchange:
| Tool | Purpose |
|---|---|
| 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. |
| read_file({ fileId }) | Fetch a session-attached file inline (text-mime; under 1 MB). Reply-clone makes peer-uploaded files visible to the recipient. |
| download_to_path({ fileId, path }) | Fetch a larger or binary file to disk. Returns the absolute path written. |
The hub correlates reply / reply_chunk to their originating
route_to_peer / dispatch_to_agent by chatId; the source session's
CC unblocks when the matching reply lands. 15-minute timeout caps —
see hub_v1/server/src/services/agents.ts and services/op-routes.ts.
For await_routed_prompt to actually fire — i.e., for an agent to
service incoming requests — its CLAUDE.md needs a line telling Claude
to call it at the start of each turn. Without that note, Claude
won't know to consult the inbox. See
hub_v1/docs/3-AGENT-SETUP.md
for the dispatcher-pattern setup.
Hook coverage
Maps each Claude Code hook to a hub event. The hook script is
dist-hook/clawborrator-tail.mjs; auto-installed on first MCP
startup (no separate install step).
| Hook | Hub event | Notes |
|---|---|---|
| UserPromptSubmit | chat/prompt (source='cli') | Operator typing into the local CC terminal. |
| PreToolUse | tail/PreToolUse (+ chat/assistant_text per text block from the transcript) | The tail captures pre-reply narration too. |
| PostToolUse | tail/PostToolUse | |
| PostToolUseFailure | tail/PostToolUseFailure | |
| Stop | tail/Stop (+ chat/reply if assistant_text present) | Turn-end signal. |
| Notification | tail/Notification | CC user notifications (idle / permission). |
| TaskCreated / TaskCompleted | tail/TaskCreated / tail/TaskCompleted | Carries task_id, task_subject, task_description. |
| SubagentStart / SubagentStop | tail/SubagentStart / tail/SubagentStop | SubagentStop carries last_assistant_message recap. |
SessionStart / SessionEnd are intentionally not hooked by
this MCP. The hook spawn had a fundamental race — the sidecar
isn't written yet at SessionStart, and is already gone by SessionEnd
— so lifecycle is now emitted server-side from the /channel WS
welcome / close transitions (hub_v1/server/src/ws/channel.ts).
Hub-authoritative, captures actual channel liveness, no hook timing
involved.
The tail reads the CC transcript file directly to enrich PreToolUse
with the assistant's pre-reply text (which CC doesn't put on the
hook payload directly). See transcript.ts for the walker.
Local dev (linked to a sibling hub_v1 checkout)
npm install
npm run build
npm link
# verify the binary is on PATH
clawborrator-mcp --hook=PreToolUse < /dev/null # exits cleanly with no sidecarWhen claude runs in a folder whose .mcp.json references
clawborrator-mcp, npm/npx resolves it to your linked build.
To publish a new release:
npm version patch # bumps package.json + creates git tag
npm publish
git push --follow-tagsThe CLI's claw token mint --mcp-snippet autogenerates an .mcp.json
snippet pointing at the published version.
