Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (clawborrator-channel) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
clawborrator channel
Claude Code side of clawborrator. A stdio MCP server that dials out to a clawborrator hub over WebSocket and relays prompts, replies, and tool-permission verdicts in both directions.
The hub lives at clawborrator/hub.
Claude Code only. This channel uses Claude Code's experimental
<channel>notification protocol (--dangerously-load-development-channels). It does not work with Claude Desktop, the Claude API, or any other client — Claude Desktop'sclaude_desktop_config.jsonMCP slot routes tool calls but doesn't deliver inbound channel notifications, so the remote operator's prompts never reach the model. If you wire the channel intoclaude_desktop_config.jsonyou'll see the MCP server connect but nothing will flow.
Use
No clone, no npm install. Sign in at https://clawborrator.com with GitHub, mint a channel token at /settings, then add this to .mcp.json in your project root (or ~/.claude.json for user-level — note: ~/.claude.json, not ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"clawborrator": {
"command": "npx",
"args": ["-y", "clawborrator-channel"],
"env": {
"CLAWBORRATOR_HUB_URL": "wss://clawborrator.com",
"CLAWBORRATOR_TOKEN": "ck_live_..."
}
}
}
}npx -y clawborrator-channel fetches the latest published version on first run, caches it, and uses the cache on subsequent runs.
Then start Claude Code with custom channels enabled (research-preview flag):
claude --dangerously-load-development-channels server:clawborratorEnv vars
| Var | Default | Purpose |
|---|---|---|
CLAWBORRATOR_HUB_URL |
ws://localhost:8787 |
Hub WebSocket URL. Use wss://clawborrator.com for the hosted hub. |
CLAWBORRATOR_TOKEN |
(required) | Bearer token for WS upgrade. Mint at <hub>/settings. Channel exits on missing. |
CLAWBORRATOR_SESSION_ID |
random UUID | Stable session id (see below). |
CLAWBORRATOR_SOURCE |
clawborrator |
<channel source="…"> attribute Claude sees. |
Durable session IDs
By default each Claude Code restart spawns a fresh session row in the hub dashboard (a new random UUID per process). That's usually what you want — each terminal instance is a real, distinct session.
If you'd rather keep the same dashboard row across restarts (e.g. you
restart Claude Code several times a day on the same project and don't
want a new "session" entry each time), set CLAWBORRATOR_SESSION_ID
to a UUID of your choosing in .mcp.json:
{
"mcpServers": {
"clawborrator": {
"command": "npx",
"args": ["-y", "clawborrator-channel"],
"env": {
"CLAWBORRATOR_HUB_URL": "wss://clawborrator.com",
"CLAWBORRATOR_TOKEN": "ck_live_...",
"CLAWBORRATOR_SESSION_ID": "8b7d2a3a-9c0e-4ff4-9c40-1a2b3c4d5e6f"
}
}
}
}The hub keys session state by this id, so the same channel ID will
re-attach to the same hub-side session on reconnect (chat history,
shares, queue all preserved). One CLAWBORRATOR_SESSION_ID per
project: set it in the project's .mcp.json and don't reuse the
same value across different projects.
Generate a fresh UUID with uuidgen (macOS/Linux) or [guid]::NewGuid()
(PowerShell).
File attachments (v0.9+)
Inbound — operator → Claude
When a remote operator sends a prompt with files attached (paperclip button or pasted images on the dashboard), the channel:
- Downloads each file via a short-lived signed GCS URL the hub mints.
- Writes it to
<cwd>/.clawborrator/attachments/<chatId>/<filename>. - Prepends an
<attachments-from-operator>tag to the prompt content listing the local paths so Claude knows to read them.
Stale staging dirs (older than 1 hour) are reaped on each hub
reconnect. Add .clawborrator/ to .gitignore to keep the staged
files out of any repo this CC is running in.
Outbound — Claude → operator (v0.10+)
Two new MCP tools let Claude attach files to its replies:
attach_file({ path, label? })— Reads a file from inside cwd, uploads to the hub via the channel token, returns afileId.reply({ chat_id, text, attachments? })— The existing reply tool now accepts an optionalattachments: [fileId, ...]array.
Typical agent flow when the operator asks for a file:
operator: "send me oil-spec.md from your data folder"
agent: attach_file({ path: 'data/oil-spec.md' })
→ { fileId: "abc123", filename: "oil-spec.md", ... }
agent: reply({
chat_id: "...",
text: "Here's the file you asked for. ...",
attachments: ["abc123"]
})The operator's dashboard renders a download chip on the reply row; clicking it streams the file from GCS via a freshly-minted signed URL.
Path safety: attach_file rejects any path that resolves outside
process.cwd(). The agent can attach project files but can't walk
out to e.g. ~/.ssh/.
Permanent corpus updates — owner only (v0.11+)
save_to_corpus({ staged_path, target_relative_path }) promotes a
staged attachment into the agent's permanent project tree (e.g.
docs/shop-manuals/1997-gts.pdf). The file becomes part of the
agent's repo and is available on future queries — useful for
RAG-style memory agents that accumulate knowledge over time.
Only the agent owner can use this. The hub stamps a
creator_session="1" attribute on the inbound <channel> tag when
the prompt comes from the session owner's own dashboard (not from
a routed prompt, not from a shared collaborator). The agent's
CLAUDE.md should refuse save_to_corpus calls when this attribute
is absent. The channel-side tool runs the file copy regardless —
the semantic gate lives in the prompt.
Channel-side sanitization rejects:
- Absolute paths
..segments- Dotfile-prefixed segments (no
.env,.git/,.ssh/) node_modules/,dist/,build/as the top segment- Paths deeper than 5 segments
- Source paths outside the project directory
Sample CLAUDE.md snippet for an agent that wants to support corpus extension:
If the inbound <channel> tag has creator_session="1" and the message
asks you to add a file to your knowledge base, call save_to_corpus
with the staged path and a sensible target like docs/<topic>/<file>.
If creator_session is absent, refuse and explain that only the agent
owner can extend the corpus — they should ask via their own session.Transcript-tail hooks (optional)
By default the hub only sees prompts you send and Claude's final replies.
The intermediate work — every Read, Edit, Bash invocation — happens inside
your local Claude Code process and never crosses the channel. Install the
transcript-tail hooks to fan tool calls out to the hub so remote
operators see them inline as ▸ Read foo.js / ▸ Bash npm test (12s, ok)
in the chat log.
Auto-installed by default. When the channel boots as an MCP server it
installs (or refreshes) the hooks idempotently — no command to run, just
add the channel to your .mcp.json. On a fresh project the hooks won't
fire until the next CC restart since Claude Code reads
.claude/settings.json at session start, before MCP servers spawn — so
the very first session has zero ▸ rows; restart and they're live.
To opt out, add "CLAWBORRATOR_DISABLE_HOOK_INSTALL": "true" to your
.mcp.json env block. The channel will then skip the install entirely
and never modify your .claude/ directory.
You can also install manually if you'd rather see the verbose status output:
npx -y clawborrator-channel install-hooksThe install (manual or auto) is idempotent and writes two things:
.claude/hooks/clawborrator-tail.mjs— a copy of the package'shook-template.mjs. Self-contained Node script that POSTs each hook event to the hub..claude/settings.json— adds entries underhooks.PreToolUse,hooks.PostToolUse,hooks.Stop,hooks.SubagentStop, andhooks.Notificationthat point at the script.
Restart Claude Code after installing so the new hook config loads.
To remove the hooks later:
npx -y clawborrator-channel uninstall-hooksThe hook script reads the same CLAWBORRATOR_* env vars from your
.mcp.json — no extra setup. Each event POSTs with a 800 ms / 2 s
timeout (tighter for PreToolUse since that one blocks Claude). Failures
log to stderr and exit 0; the hook never blocks your turn.
A breadcrumb log is written to your tmpdir on every fire as
clawborrator-tail.<sessionId>.log — separate file per Claude Code
session so concurrent projects don't trample each other's debug output.
Use it to diagnose missing tool rows in the hub's chat log.
What flows through:
| Hook event | Renders as |
|---|---|
PreToolUse |
▸ Read foo.js (placeholder while the tool runs) |
PostToolUse |
folds into the matching PreToolUse line, adding (ok, 12s) or (err) |
Stop |
late assistant text — only shows when Claude finished a turn without calling the reply MCP tool |
SubagentStop |
summary text from a Task subagent |
Notification |
idle / waiting / thinking transitions |
Server-side redaction strips common secrets (API keys, GitHub tokens,
AWS keys, KEY=value patterns) from previews, and previews truncate to
2 KB.
Development
If you're hacking on the channel itself, clone the repo and point args at the local file instead:
{
"command": "node",
"args": ["/abs/path/to/clawborrator/channel/channel.js"]
}Files in this package:
| File | Role |
|---|---|
channel.js |
The MCP stdio server. Connects to the hub, routes prompts/replies/permissions, exposes the reply and xroute tools. |
install-hooks.mjs |
Subcommand handler for install-hooks / uninstall-hooks. Also called from channel.js on MCP boot for the auto-install path. |
hook-template.mjs |
Source-of-truth for the per-event hook script. Copied verbatim into <project>/.claude/hooks/clawborrator-tail.mjs on install. Edit this, not the installed copy — install will overwrite the project copy on next channel boot. |