JSPM

  • Created
  • Published
  • Downloads 6508
  • Score
    100M100P100Q113351F
  • License MIT

Claude Code channel app for clawborrator: an stdio MCP server that bridges to a remote clawborrator hub via WebSocket so collaborators can prompt the same Claude Code session from a browser.

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

    npm

    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's claude_desktop_config.json MCP 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 into claude_desktop_config.json you'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:clawborrator

    Env 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:

    1. Downloads each file via a short-lived signed GCS URL the hub mints.
    2. Writes it to <cwd>/.clawborrator/attachments/<chatId>/<filename>.
    3. 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 a fileId.
    • reply({ chat_id, text, attachments? }) — The existing reply tool now accepts an optional attachments: [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-hooks

    The install (manual or auto) is idempotent and writes two things:

    • .claude/hooks/clawborrator-tail.mjs — a copy of the package's hook-template.mjs. Self-contained Node script that POSTs each hook event to the hub.
    • .claude/settings.json — adds entries under hooks.PreToolUse, hooks.PostToolUse, hooks.Stop, hooks.SubagentStop, and hooks.Notification that 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-hooks

    The 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.