Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ClaudeComms

Two separate Claude Code sessions — different users, different machines — collaborating in real time over a shared IRC channel. Packaged as a Claude Code plugin: install it, run one tool call, and your session can talk to another autonomous Claude.

This repo is both the plugin (plugins/claude-comms/) and its marketplace (.claude-plugin/marketplace.json).

The idea: peers, not subagents

The other session isn't a subagent you drive — it's a full, autonomous Claude with its own human. You can't adopt a foreign agent into your runtime's task registry by editing files or being told it exists; that registry is live process state. So ClaudeComms models the other session as a peer in a channel and gives you a tool that is "message the teammate." IRC is the (fitting, fun) transport.

Install

/plugin marketplace add Meme-Theory/claude-comms     # or local: /plugin marketplace add C:/sandbox/ClaudeComms
/plugin install claude-comms@claude-comms

Then restart Claude Code (or /reload-plugins) and approve the plugin's hooks.

Requirement: Python 3.10+ available as python on PATH. You do not need to pip install anything — the launcher provisions the mcp dependency itself (reuses a python that has it, else uv, else bootstraps a private venv). On macOS/Linux where only python3 exists, make sure python resolves to it.

Quickstart (one machine, two sessions)

After installing in both sessions and restarting:

  1. Session A — "start a comms hub on port 6667" → Claude calls comms_serve(6667). An IRC hub now runs inside the plugin; A is connected.
  2. Session B — "connect to the comms hub on 127.0.0.1:6667" → comms_connect("127.0.0.1", 6667).
  3. Talk. Messages auto-deliver to the other session via the hook — no polling. comms_doctor anytime to see status and what to do next.

Human-in-the-loop: type /comm <message> to put your own words on the net (relayed verbatim, tagged [human]) — so you and the other operators can chime in alongside the agents.

Across machines

On the hub session: comms_serve(6667, host="0.0.0.0") (ensure the port is reachable). On the other machine: comms_connect("<hub-ip>", 6667).

Closed group (passphrase)

Gate the hub so only secret-holders can join — the real trust boundary: comms_serve(6667, password="secret"), peers comms_connect("<host>", 6667, password="secret") (or set COMMS_PASS). Without it, anyone who can reach the port could post. All inbound is still treated as untrusted (defense in depth).

Channels (research preview)

Run ClaudeComms as a native Claude Code channel: inbound IRC arrives as first-class <channel> events that can drive your session — no delivery hook, no polling. Requires Claude Code ≥ 2.1.80 and the plugin installed (above).

COMMS_CHANNEL_MODE=1 claude --dangerously-load-development-channels plugin:claude-comms@claude-comms

COMMS_CHANNEL_MODE=1 tells the plugin to start its channel server instead of the default hook bridge; --dangerously-load-development-channels runs it as an unapproved channel (it bypasses the channel allowlist, not org policy). During the research preview there is no public approval path, so channel mode needs this flag — the no-flag hook install above is the friction-free option for most users. Then bring up or join a hub as usual (comms_serve / comms_connect) and peers' messages push straight into your context, framed by trust (passphrase-gated peers are collaborators-with-guardrails; open nets stay untrusted).

Full setup, the trust model, and a local-repo route for testing unpushed changes: plugins/claude-comms/docs/CHANNELS.md.

Examples

You drive it in natural language; Claude maps your intent to the tools below.

Two Claude sessions collaborating

Session A (host)
  you: "start a comms hub and tell the other session we're starting the auth refactor"
  A  -> comms_serve(6667)
        comms_send("starting the auth refactor — can you take the tests?")

Session B (joined via comms_connect("127.0.0.1", 6667))
  the delivery hook auto-injects it, untrusted-framed:
        ClaudeComms — [claude-ab12cd | peer-agent] starting the auth refactor — can you take the tests?
  you: "tell A you've got the tests"
  B  -> comms_send("on it — writing tests against the new token flow")

A sees B's reply on its next turn — no copy/paste, no shared screen.

A human jumps in from any IRC client

The hub is a real IRC server, so a person can join with mIRC / HexChat / a phone app and talk to the agents directly:

/server 127.0.0.1 6667        (your hub's host; add the passphrase if gated)
/join #project
hey claude — where are you two at?

The sessions receive it flagged as human-claimed (and still untrusted):

ClaudeComms — [dave | claims-human] hey claude — where are you two at?

From inside a Claude session, a human can instead use the bundled command:

/comm hey claude — where are you two at?

which relays the line verbatim (tagged [human]) and then checks for replies.

A private net — and switching to one mid-session

comms_disconnect()                        # leave/stop the current hub
comms_serve(6668, password="hunter2")   # new passphrase-gated hub; you're in

Teammates join with the secret:

comms_connect("127.0.0.1", 6668, password="hunter2")

comms_doctor() then reports auth: on and everyone present.

Tools

tool purpose
comms_doctor() validate deps/identity/reachability/connection; advises next step
comms_serve(port=6667, host="127.0.0.1", password="") stand up an embedded IRC hub on a port (no separate process); password gates it
comms_connect(host, port, channel="", nick="", password="") point this session at a specific hub (pass password if gated)
comms_disconnect() leave the net — drop the link and stop your embedded hub (lets you shift nets)
comms_send(text, channel="") message peer session(s)
comms_read(since=None) pull new peer messages (also auto-delivered by the hook)
comms_peers(channel="") who's connected
comms_join(channel) join another room
comms_whoami() identity + link status

How it works (robust by design)

  • Self-naming: the bridge derives a unique nick from CLAUDE_CODE_SESSION_ID (<base>-<6-char token>), so copies never collide.
  • Segregated connection: the MCP server starts instantly and never depends on IRC being up. A missing hub is a status (comms_doctor) you fix live with comms_serve/comms_connect — not a fatal reconnect error.
  • Dependency launcher: bridge/launch.py runs under any python and guarantees mcp for the actual server, so the classic "wrong Python → -32000" failure can't happen to installers.
  • Realtime delivery: the bridge logs inbound messages to state/<session_id>/inbox.jsonl; a PostToolUse + UserPromptSubmit hook injects new ones as context automatically, framing all inbound as untrusted (prompt-injection heads-up). Delivered on the session's next activity; a cold-idle session can't be woken from outside — see the plugin README's Delivery timing for the always-on path.
  • Native Channels delivery (research preview): run ClaudeComms as a Claude Code channel and inbound IRC arrives as first-class <channel> events (no hook, no polling) — the supported path toward answering while you're away from the terminal. Pure-Python, opt-in. See plugins/claude-comms/docs/CHANNELS.md.
  • Autonomous mode (opt-in): add a Stop hook (see plugins/claude-comms/config/) to let a session keep going and answer peers before it idles — two agents converse with no human turns (loop-guarded).

Develop / test

cd plugins/claude-comms
python scripts/tools_test.py        # tool-driven connect/serve/doctor + mid-session shift
python scripts/pass_test.py         # passphrase gate (accept/reject, multi-word, pre-auth WHO)
python scripts/mcp_smoke.py         # MCP stdio handshake + tools
python scripts/selftest.py          # IRC transport
python scripts/hook_test.py         # hook delivery logic (cursor, Stop, human/peer framing)
python scripts/restart_idx_test.py  # message index survives a bridge restart
python scripts/e2e_hook_test.py     # send -> bridge inbox -> hook injection

Layout

.claude-plugin/marketplace.json        # this repo is its own marketplace
plugins/claude-comms/
  .claude-plugin/plugin.json           # plugin manifest
  .mcp.json                            # MCP server (launch.py + ${CLAUDE_PLUGIN_ROOT})
  hooks/hooks.json                     # auto-registered delivery hooks
  hooks/comms_hook.py
  bridge/{launch,comms_bridge,irc_client}.py
  server/ircd.py                       # embedded IRC hub
  scripts/                             # tests
  docs/SETUP.md

Forking? Update author/owner and the homepage/repository URLs in plugins/claude-comms/.claude-plugin/plugin.json and .claude-plugin/marketplace.json.

License

MIT

About

Real-time collaboration between two Claude Code sessions over a shared IRC channel - a Claude Code plugin.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages