Simple agent room
Two reusable agent skills (simple-agent-comms, simple-agent-room) + Python CLI tools for inter-agent messaging on disk. JSON-Lines rooms, inotify-driven monitors, no broker dependency. Agent never needs to know the file paths.
npx -y skills add clankercode/agent-file-chat --skill simple-agent-roomAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
One-file-per-room chat log for many-to-many inter-agent messaging. The room is a JSON-Lines append-only file under ~/.cache/simple-agent-room/, and three CLI tools (simple-room-send, simple-room-monitor, simple-room-scan) on $PATH are all an agent needs to know. The monitor filters out the local agent's own messages by default and uses inotify (no polling), so it slots directly into a `Monitor(...)` tool as the command. Use when several agents need to discover each other, exchange mid-task findings, or coordinate without depending on c2c / SendMessage brokers.
The file declares its own license as Unlicense + CC0-1.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
13.2 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it
Simple agent room
When to use
A room is a many-to-many chat log. Any number of agents can post to a
room, and any agent can Monitor it. Typical uses:
- Several sub-agents working on related tasks and needing to share intermediate findings (a coder reporting a parser bug, a researcher reporting a URL, a tester reporting a failing assertion).
- A long-running agent that needs to be discoverable by other agents that may spawn later.
- A coordination channel for an "agent team" doing a multi-step plan.
For one-to-one comms with a single long-running subagent, the
sister skill simple-agent-comms (two files + a monitor) is lighter.
This skill is the specialized N:N broadcast variant of the general
subagent-protocols pattern: it commits you to one shared log that
every agent in the room writes to and watches. The general pattern
(subagent-protocols) lets you decide per subagent whether to
broadcast, append on demand, or stay one-way — which is the right pick
when each subagent's traffic should stay private or when the set of
agents is uneven. Use this skill when you have many agents that
need to discover each other and can tolerate the shared-log volume
(self-filter cuts local noise; global volume still grows with each
poster).
What you (the agent) need to know
Three commands, all on $PATH. You do not need to know any file
paths. The room name is the only thing you pass around.
simple-room-send <room> [args] # post a message
simple-room-monitor <room> [args] # stream new messages (Monitor-friendly)
simple-room-scan <room> <subcmd> # count / tail / active / grep / ids / path
That's it. You pick a room name (alphanumerics, dot, underscore, dash; max 64 chars), you pick an agent id for yourself, and you send / read.
If the rest of the system needs to know where the room is stored, the
single canonical location is ~/.cache/simple-agent-room/<room>.log,
overridable via $SIMPLE_AGENT_ROOM_DIR (rare — only for testing or
multi-tenant layouts).
Quickstart (one agent, one line)
simple-room-send kitchen "stove is on" # you posted a message
simple-room-scan kitchen tail -n 5 # you read the last 5
simple-room-scan kitchen active --window 60 # who is in here
Quickstart (two agents coordinating)
# agent A # agent B
simple-room-send tasks -m "I'm starting" \
simple-room-monitor tasks # in a Monitor:
▲ # new lines arrive,
│ # self-msgs filtered
# --- later, in another terminal/turn --- simple-room-send tasks -m "ack"
The right pattern: spawn the monitor as a persistent background
command in a Monitor(...) tool call, then send / scan / talk in the
foreground.
ASCII flowcharts
Posting a message
agent simple-room-send on disk
───── ──────────────── ───────
$ simple-room-send kitchen \ │
-a alice -m "hi" │ format_record
│ → JSON line + '\n'
│ → os.open(O_APPEND|O_CREAT, 0o644)
│ → os.write(fd, line)
▼
~/.cache/simple-agent-room/kitchen.log
─────────────────────────────────────────
{"id":"…","ts":"…","agent":"alice", … }
{"id":"…","ts":"…","agent":"bob", … }
…
Concurrent posters do not tear each other's records: O_APPEND writes are atomic on POSIX for buffers ≤ PIPE_BUF (4096 B), and the JSON record is always < 1 KiB in practice.
Monitoring (the Monitor(...) shape)
simple-room-monitor Monitor tool
─────────────────── ───────────
backfill: tail the last N records stdout
(or 0 for "live only") │
parse JSON, drop self ──────►│ each line is a
│ background event,
live: pyinotify.watch on the file │ not a user reply
IN_MODIFY ─► read new bytes
IN_DELETE ─► wait for recreate
IN_MOVE ─► wait for recreate
▼
agent reads the line,
decides what to do
The script does not poll. It blocks in pyinotify.Notifier and wakes
on kernel events. Latency from send → event delivery is sub-millisecond
on local filesystems.
Scanning (read-only)
simple-room-scan <room> <subcmd> [args]
────────────────────────────────────────
│
├─ count → 1 line: total record count
├─ ids → 1 id per line (sorted)
├─ path → 1 line: absolute file path
├─ active [--window S] → "agent<TAB>ts" per active agent
├─ tail [-n N] [-a A] → last N (or agent's) records
└─ grep <pattern> → records whose msg matches
[--since-seq N]
[-a A] [--json]
│
▼
iter_records(path) → dict stream
(skips blank / '#' / malformed lines)
Reference
simple-room-send <room> [MSG] [-m MSG] [-k {msg,system,meta}] [-a AGENT] [--stdin]
| flag | meaning |
|---|---|
MESSAGE | optional positional message text |
-m MESSAGE | named message text (else use MESSAGE, then stdin) |
--stdin | force reading from stdin (overrides MESSAGE and -m) |
-k KIND | msg (default), system, or meta |
-a AGENT | local agent id; default $SIMPLE_AGENT_ID else $USER-<host>-<pid> |
--seq N | explicit monotonic seq (optional) |
--id ID | explicit record id (uuid4 hex, optional) |
--ts ISO | explicit timestamp (optional) |
-q | suppress the "sent id=…" confirmation on stderr |
The message is stored verbatim (newlines, tabs, backslashes are JSON-escaped inside the record; you see them on the read side as normal characters).
simple-room-monitor <room> [-a AGENT] [--exclude-self] [--backfill N] [--grep PATTERN] [--json]
| flag | meaning |
|---|---|
-a AGENT | local agent id (default as above) |
--exclude-self | drop records from local agent (default: on) |
--no-exclude-self | include them (use when you want to see your own msgs) |
-b N | emit the last N existing records before going live |
(-1 = all; 0 = events-only, the default) | |
--grep PATTERN | only emit records whose rendered line matches regex |
--json | emit raw JSON record per line (else HH:MM:SS agent: msg) |
The script runs until killed. Use it as the command of a persistent
Monitor(...) tool call — the right pattern is one Monitor per room
per session. The Monitor events are background events, not user
replies; do not treat them as a turn-ending user message.
simple-room-scan <room> <subcommand> [args]
| subcommand | args | output |
|---|---|---|
count | — | total record count |
ids | — | one agent id per line |
path | — | absolute file path |
active | --window SECONDS (120) | agent<TAB>ts per active agent |
tail | -n N (20), -a AGENT, --json | last N records |
grep | PATTERN, --since-seq N, -a A, --json, -c (count→stderr) | matching records |
grep is a case-insensitive substring search against the msg field.
Pattern characters are matched literally, so . searches for a dot.
Self-filter pattern (the "don't talk to yourself" recipe)
The monitor defaults to --exclude-self because in a single-agent
turn-loop the agent has just sent its own message, and replaying it
back as an event is noise. If you need both sides of a single-agent
debug session visible, pass --no-exclude-self.
Two agents in the same room must pick different agent ids. The
default ($USER-<host>-<pid>) is unique per process; if you spawn
multiple agents from the same shell, set SIMPLE_AGENT_ID for each
to keep them distinct.
What you don't need to know
- The on-disk path. It's
~/.cache/simple-agent-room/<room>.log. You never write to it directly.simple-room-scan <room> pathwill tell you if you're curious. - The schema. The lib reads the file, parses JSON, drops malformed
lines, and unescapes msg strings. You see a dict with
id,ts,agent,msg,kind, optionalseq. - Polling. The monitor is fully event-driven (inotify).
- Locking. Records are < 4 KiB, O_APPEND is atomic on POSIX, so no flock / fcntl is needed. Two writers can post simultaneously without tearing each other's records.
Failure modes worth knowing
- Stale inotify after delete/rename: the lib re-attaches the watch
on
IN_CREATEfor the same path, so a log-rotation tool that replaces the file is handled. If yourmthe file by hand, the monitor will create a new empty one on the next send. - Agent id collision: two agents with the same id will see each
other's messages as their own (and filter them out by default).
Always use
SIMPLE_AGENT_IDor the$USER-<host>-<pid>default. - Clock skew:
tsis wall-clock UTC of the sender. If you sort bytsacross agents, set NTP. For ordering within a single agent, useseq. - Very long messages: there is no hard cap, but if you regularly post > 4 KiB you may hit PIPE_BUF and start seeing torn records. Keep messages < 4 KiB.
- Malformed lines: the reader silently skips any line that doesn't parse as a JSON object. Garbage in = garbage silently dropped; valid records around it are unaffected.
Files
skills/simple-agent-room/
SKILL.md ← this file
bin/
simple-room-send ← thin wrapper, calls lib.simple_room_send.main
simple-room-monitor ← thin wrapper, calls lib.simple_room_monitor.main
simple-room-scan ← thin wrapper, calls lib.simple_room_scan.main
lib/
simple_agent_room_lib.py ← shared library (format/parse, inotify, scan)
simple_room_send.py ← send entry point
simple_room_monitor.py ← monitor entry point
simple_room_scan.py ← scan entry point
Each bin/simple-room-* wrapper is a 12-line Python file that adjusts
sys.path and delegates to lib/simple_room_*.main. The wrappers
resolve their own real path, so the symlinks in ~/.local/bin/ work
transparently.
Install
From the repo root:
./install.sh
This places simple-agent-room in ~/.claude/skills/ and
~/.agents/skills/, and the three CLIs on your $PATH as
simple-room-send, simple-room-monitor, simple-room-scan.
If you'd rather do it by hand:
ln -s "$PWD/skills/simple-agent-room" ~/.claude/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room" ~/.agents/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room/bin/"* ~/.local/bin/
Dependencies
- Python ≥ 3.10
pyinotify(pip install pyinotify). Required only by the monitor;simple-room-sendandsimple-room-scanwork without it.
What ships with it: 7 files
30.4 KB alongside SKILL.md, 7 of them executable
bin/
- simple-room-monitorruns564 B
- simple-room-scanruns555 B
- simple-room-sendruns616 B
lib/
- simple_agent_room_lib.pyruns14.6 KB
- simple_room_monitor.pyruns5.2 KB
- simple_room_scan.pyruns5.4 KB
- simple_room_send.pyruns3.5 KB
Gives 0 of the 12 instructions most context ai engineering skills give in ~2.9k tokens
Counted across 1,193 of the 1,976 authors here whose files we hold, read 2026-08-07
- Dispatch a fresh implementer subagent per taskin 48 of 1193, across 19 files
- Dispatch a final code reviewer after all tasksin 33 of 1193, across 8 files
- Provide full task text to the subagentin 30 of 1193, across 9 files
- Review spec compliance before code qualityin 27 of 1193, across 10 files
- Make the hook script executablein 26 of 1193, across 8 files
- Re-snapshot after navigation or DOM changesin 25 of 1193, across 19 files
- Read files before editing themin 22 of 1193, across 11 files
- Answer subagent questions before proceedingin 22 of 1193, across 7 files
- Mark task complete in TodoWrite after approvalin 22 of 1193, across 6 files
- Merge hook into existing settingsin 21 of 1193, across 3 files
- Ask if installation is global or projectin 20 of 1193, across 2 files
- Copy the hook script to target locationin 20 of 1193, across 2 files
Said here and by no other author read
- use a persistent Monitor call per room per session
- keep messages under 4 kibibytes
- use simple-room-send to post a message
- use simple-room-scan to read records
- pass only the room name between agents
- treat Monitor events as background events
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.