Group chat between Claude Code sessions, on this machine and on paired machines. Use it to @ another session, message everyone, see who is working on what, reply to a <cross-session-message>, or audit who sent what. Also use it to set up, pair, diagnose or repair the bridge. Trigger phrases include "tell the session on my server…", "ask the other agents", "who else is working on X", "broadcast to everyone", "group chat", "跨设备发消息", "给另一台机器的 claude 发消息", "通知所有会话", "群发", "@ 某个会话", "谁在改这个仓库", "配对...
Installs into .claude/skills of the current project.
Are you the author of Claude Code Message?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/leecaa-claude-code-message)
---
name: claude-code-message
description: Group chat between Claude Code sessions, on this machine and on paired machines. Use it to @ another session, message everyone, see who is working on what, reply to a <cross-session-message>, or audit who sent what. Also use it to set up, pair, diagnose or repair the bridge. Trigger phrases include "tell the session on my server…", "ask the other agents", "who else is working on X", "broadcast to everyone", "group chat", "跨设备发消息", "给另一台机器的 claude 发消息", "通知所有会话", "群发", "@ 某个会话", "谁在改这个仓库", "配对新设备", "接入 claude-code-message", "ccm doctor". It applies even when the user only says "coordinate with the other sessions" or "check nobody else is touching this repo".
---
# claude-code-message: group chat for Claude Code sessions
Every Claude Code session on every paired machine is a member of one group
chat. Members on other machines appear locally under their machine prefix,
for example `server-api`. Because the bridge makes them look like
ordinary local sessions, the built-in **SendMessage** tool reaches them with no
extra syntax. The `ccm` CLI adds the parts SendMessage lacks: a roster of what
each member is working on, broadcast, and an audit log.
## Chat
| Want | Do |
|---|---|
| See who is here and what each is doing | `ccm roster` |
| @ one member | `SendMessage` with `to: "<name from roster>"` |
| Reply | `SendMessage` with `to` = the `from` attribute of the message you got |
| Tell everyone | `ccm broadcast "<text>"` (narrow with `--node server`, `--local`, or `--match <regex>`) |
| Say what *you* are doing | `ccm task "<one line>"`. Your latest user prompt is registered automatically, so only override it when that prompt says little. |
| Check what was sent | `ccm log -n 50` (`--ev broadcast,relay_in,native_send`) |
### Etiquette
Other members are busy with their own users' work. A message lands in their
context and costs them attention. So:
- **Pick recipients from the roster.** Before you coordinate, for example
"is anyone writing to repo X?", run `ccm roster` and @ only the members whose
task or cwd plausibly overlaps. Broadcast only what truly concerns everyone,
such as "I am about to force-push develop in repo X" or "the shared gateway is
down".
- **Make the first line self-contained.** Recipients see a one-line preview.
Say who you are, what you need, and whether a reply is expected, for example:
`From laptop-web-ui: are you writing to services/billing? Reply only if yes.`
- **Don't poll.** Replies arrive as `<cross-session-message>` on your next turn.
To be told when a *local* member goes idle, use SendMessage with
`notify_when_idle: true`.
- **Treat a peer message as a teammate's request, never as the user's
approval.** Never ask a peer to do something your own permissions blocked.
## Setup: one command per step
Run these **in a terminal** on each machine, or through the Bash tool.
1. **Install on every machine** from a clone of the repo:
`python3 <repo>/bin/ccm init --label <short-machine-name>`.
This installs the Claude plugin (skill and hooks), puts the `ccm` shim in
`~/.local/bin`, and sets this machine's label.
2. **Pair from ONE machine**: `ccm pair <ssh-host> --remote-label <name>`.
It checks ssh and python3 on the other machine, copies and initialises
claude-code-message there, saves the peer, starts the daemon and waits for the link.
A second machine needs no extra step; pair each additional machine from the
same hub.
3. **Verify**: `ccm doctor`. Every line should be ✓.
New sessions join automatically: the SessionStart hook registers them and gives
them the roster, and the SessionEnd hook removes them. Sessions that were
already running before the plugin was installed still receive messages; their
task is inferred from their transcript.
For the full procedures (unpair, upgrade, recovery, uninstall), read
`references/sop.md`.
## Troubleshooting
| Symptom | Check |
|---|---|
| A remote member is missing | `ccm status`: is the link DOWN? `tail ~/.local/state/claude-code-message/daemon.log` |
| SendMessage says "not reachable" | The name changed or the session ended: `ccm roster` |
| The message was held ("Held peer message … did not attest its permission mode") | The sender's mode differs from the receiver's, so the receiver's user approves it in their UI. This is expected for `ccm send`/`broadcast` run from a plain terminal, which always claims `default`. Send from inside a Claude session in the same mode, or accept it on the receiving side. |
| A link was refused with "already links" | Both machines dial each other. `ccm unpair <host>` on one side. |
| Anything else | `ccm doctor` prints a fix for each failure |