clawborrator-mcp
Connects Claude Code instances to a clawborrator hub via WebSocket, enabling cross-session communication, file exchange, and agent dispatch.
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.json
If 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.
Install as a Claude Code plugin
clawborrator is an official external Claude Code plugin. This repo
ships .claude-plugin/plugin.json and a root .mcp.json, so once it
is listed in a plugin marketplace it installs with:
/plugin install clawborrator@<marketplace>
The bundled .mcp.json resolves its config from environment
variables instead of a committed token, so it carries no secret.
You still have to supply the channel token yourself — a
committed plugin cannot ship a per-user secret. Before the MCP
server can connect to the hub, set in your environment:
| Env var | Required | Default |
|---|---|---|
CLAWBORRATOR_TOKEN |
yes | none. Mint one with claw token mint --kind=channel. |
CLAWBORRATOR_HUB_URL |
no | wss://next.clawborrator.com. Self-hosters point this at their own hub. |
Without CLAWBORRATOR_TOKEN set, the server starts but cannot
authenticate, and the session never registers with the hub. This is
the one manual step the plugin install cannot do for you.
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/runtime.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 at
.claude/clawborrator/runtime.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 sidecar
When 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-tags
The CLI's claw token mint --mcp-snippet autogenerates an .mcp.json
snippet pointing at the published version.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.