agent-chat
Skill0 starsChanged 3 months agoMITView on GitHub
Set up a shared chat room in a temp directory so multiple agents running at the same time (subagents, or separate Claude Code sessions in different terminals) can send each other messages, ask questions, and coordinate work while they run. Use this whenever the user wants agents to talk to each other, message or ping each other, hand off work between agents, run a debate or review between two agents, share findings live instead of only at the end, or coordinate parallel workers - and also when they describe the mechanism rather than naming it, e.g. "have the agents communicate through a folder", "a shared inbox/mailbox/scratch dir for agents", "let session A tell session B what it found", or "a message bus for my agents". Reach for it even if the user does not say "chat".
4 other projects use a version of this.
Adopted by
Most recently taken up by
- ZwaarContrast/skillstheir own version, first seen Nov 1, 2026
- vicnaum/vics-agent-skillstheir own version, first seen Oct 25, 2026
- profbernardoj/everclawtheir own version, first seen Oct 8, 2026
- merijnvanes/agent-chattheir own version, first seen Apr 27, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- profbernardoj/everclaw★ 112same name
- vicnaum/vics-agent-skills★ 53same name
- merijnvanes/agent-chat★ 1same name
- ZwaarContrast/skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
3 rules. 0 are common, 2 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 17
All of it goes through one script — don't hand-roll file writes into the room, because the cursor and ordering invariants are easy to break …
- Distinctive: line 125
Expect your opening messages to cross, and don't re-answer: If two agents both open with a broadcast, each one composes before the other's …
- Very specific: line 166
Don't chain
sayandleavein one shell command: If the say goes out mangled you've already left and can't post a correction.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Agent Chat
A chat room is a directory under $TMPDIR/agent-chat/<room>/. Every message is
one immutable JSON file named with a nanosecond timestamp, so listing the
directory in sorted order is the conversation. Nobody locks anything; writes
land via os.rename(), which is atomic, so a reader never sees half a message.
Each agent has its own cursor file, which is what lets read return "what's new
for me" without disturbing what anyone else has seen. 120 concurrent writers were
verified to produce 120 correctly ordered messages with none lost.
All of it goes through one script — don't hand-roll file writes into the room, because the cursor and ordering invariants are easy to break by accident:
python3 ~/.claude/skills/agent-chat/scripts/chat.py <command> ...Setting up a conversation
Two things every participant needs: a name and the room name. Export them once per agent so no later command has to repeat them:
export AGENT_CHAT_NAME=reviewer # who you are; must be unique in the room
export CHAT="python3 $HOME/.claude/skills/agent-chat/scripts/chat.py"
$CHAT join design-review --role "reviews the API surface for breaking changes"--role is worth filling in. It shows up in who, and it's how a peer decides
whether you're the right agent to ask something.
By default a joiner's cursor starts at the end of the room, so arriving late
doesn't bury you in backlog. Pass --history to replay everything instead.
Launching the participants
Subagents in one session — spawn them in a single message so they run concurrently, and give each one its name, the room, and the exact command:
You are
builderin the agent-chat roomrefactor. Start with:export AGENT_CHAT_NAME=builder; export CHAT="python3 $HOME/.claude/skills/agent-chat/scripts/chat.py"; $CHAT join refactor --role "applies the edits"Then$CHAT wait refactor --timeout 240for instructions fromplanner. When your work is finished,$CHAT say refactor --type done -m "<summary>".
Separate terminals / sessions — they share /tmp, so the same room name is
all they need. Tell the user to run the join line in each session. If the
sessions run as different users, set AGENT_CHAT_DIR to a path both can write.
Commands
| Command | What it's for |
join <room> --role "..." | register, announce yourself, see who's already here |
say <room> -m "text" | post to everyone |
say <room> --to bob -m "text" | direct message — only bob and you can see it |
say <room> --reply-to 7 -m "text" | thread a reply onto message #7 |
say <room> --type done -m "..." | tag a message: question, answer, status, done |
read <room> | messages new to you since last read; advances your cursor |
read <room> --peek | same, but don't advance the cursor |
read <room> --all | everything visible to you, from the top |
wait <room> --timeout 300 | block until something new arrives, print it, return |
wait <room> --from alice | block until alice specifically says something |
who <room> | roster with roles and how long since each was last active |
log <room> --tail 20 | full transcript, for a final summary |
leave <room> -m "..." | announce departure and deregister |
rooms / clean [<room>] | list rooms / delete one (or all) |
read and wait skip your own messages, since echoing your own words back at
you wastes context; pass --mine if you want them, or use log for the raw
transcript. Add --json to read, wait, who, and log when you want to
parse rather than read. Omit -m on say to take the message from stdin — better for
multi-line payloads like code or log excerpts than fighting shell quoting.
wait exits 0 when it delivers messages and 2 on timeout, so a timeout is
detectable in a shell conditional. Use --timeout-exit 0 if you'd rather treat
"nobody answered" as normal.
Making the conversation actually work
The hard part of multi-agent chat isn't transport, it's that agents talk past each other or wait forever. A few habits prevent nearly all of it.
Compose messages on stdin whenever they contain code. Your shell expands
$VAR, $(...) and backticks inside a double-quoted -m before chat.py ever
runs, so a message quoting a Makefile recipe or a shell snippet arrives with
those tokens silently blanked — and the send still reports success. Pipe or
heredoc instead, which passes the bytes through untouched:
python3 <SKILL_DIR>/scripts/chat.py say "$CHAT" --to runner <<'EOF'
The rule is: $(CXX) $(CXXFLAGS) $< -o $@
EOFsay echoes back the text it actually stored — read that echo. It is there so
you can catch mangling at send time, while you can still correct it. Nothing is
treated as a format string, so % needs no escaping; write 60%, not 60%%.
Block with wait, never poll with read in a loop. A read loop burns a
tool call and a slice of context every few seconds and adds latency besides.
wait sleeps in one process and returns the instant a message lands.
Always bound the wait, and decide in advance what a timeout means. A peer
can crash, finish early, or never have been started. Pick a timeout that fits
the work you're waiting on, and on expiry do something definite — proceed with
your best assumption, who to see if they're still around, or report the stall
to the user. Silently waiting again is how a room deadlocks.
Announce that you're done. Send --type done with a one-line summary before
you stop. Peers waiting on you have no other way to learn you're finished, and
done is the difference between them continuing and them burning their full
timeout.
Say what you need, not that you have a need. "Blocked" tells a peer nothing.
--to builder -m "parse_config() drops the trailing newline — line 88 of
config.py. Can you take it, or should I?" is answerable in one message. Long
round-trips are the main cost here, so front-load the context.
Expect your opening messages to cross, and don't re-answer. If two agents
both open with a broadcast, each one composes before the other's lands, so both
arrive asking questions the other has already answered. This is the normal case,
not bad luck. Two habits fix it: read once immediately before composing any
long reply, and when you find your question already answered, say so in one line
and move on rather than restating everything. Better still, have one side open
and the other wait first — see the two-agent pattern below.
Send paths, not payloads. Room messages are for coordination. Write real artifacts to a normal file and send the path — a 500-line diff in a chat message costs every reader their context window.
Address your messages. Broadcast for anything the room should know; --to
for anything only one agent needs. In a busy room, unaddressed chatter forces
everyone to read everything.
One agent decides. With three or more participants, name a coordinator up front — it assigns work, resolves disagreements, and declares the end. Peer-to-peer negotiation between equals tends to converge slowly or not at all.
Patterns
Coordinator and workers. The coordinator joins, spawns workers, DMs each an
assignment, then waits in a loop consuming done messages until all workers
have reported or the deadline passes. Workers wait for their assignment, do the
job, post done, and leave.
Two-agent debate or review. Decide up front which side opens; the other
waits first. If both open at once their messages cross and you burn an
exchange re-answering each other. After the opener lands, alternate
wait --from <peer> and say --reply-to <n>. Agree in advance on how
it ends — usually a fixed number of exchanges, or either side posting done —
otherwise two agents will happily agree with each other forever.
Live findings channel. Parallel explorers each join and post --type status
as they discover things. The reader doesn't need to wait for anyone to finish;
read picks up whatever has landed. Cheap, and it lets one agent's discovery
redirect another mid-run.
When something looks wrong
Don't chain say and leave in one shell command. If the say goes out
mangled you've already left and can't post a correction. Send, look at the
echo, then leave.
wait --from <peer> returns on their join too, since joins are ordinary
messages. That's useful — a bare wait right after joining is how you learn a
peer has actually started, which join itself won't tell you. But it means a
--from wait can return something that isn't the reply you wanted; check the
message before assuming your question was answered, and wait again if not.
log <room> --tail 30 shows the whole conversation including join/leave
events and is almost always enough to see what happened: who never joined, who
never answered, who left early. who <room> shows last-seen ages — an agent that
hasn't been seen in minutes is finished or dead, not thinking.
The room lives in /tmp, so it does not survive a reboot and holds nothing you'd
want to keep. Copy anything worth retaining out with log --json before running
clean.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

