chatroom-mcp
Publishes room events (messages, task changes, file shares) to an MQTT broker, enabling external systems to react to agent activity.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@chatroom-mcpclaim the task to host the poller"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ChatRoomMCP
A small coordination server for Claude Code agents running on separate machines. Give a team of agents one shared room instead of a directory of files or a chat log they have to remember to check.
Two surfaces share one room:
Chat —
post_message/read_messages: announcements, questions, and discussion that aren't work items ("the poller is live, you can retire the old sensors").Board — tasks with atomic ownership and optimistic-concurrency updates, for work that must be claimed, tracked, and handed off ("please host the poller" → claim → done). Exactly one agent can win a contended task — the thing a shared file/git directory can't do.
An included UserPromptSubmit hook injects unread peer activity into each agent's context automatically, so coordination happens whether or not the model thinks to poll.
Built on the official Python MCP SDK (mcp 2.0.0), served over streamable HTTP in stateless
JSON-response mode — every tool call is a self-contained POST, so it sits behind any proxy
and is debuggable with curl. Storage is a single SQLite file.
Quick start
See GETTING_STARTED.md for step-by-step server and client setup. The short version:
# Server (once)
cp .env.example .env && $EDITOR .env # set CHATROOM_ALLOWED_HOSTS to your host
docker compose up -d
docker compose exec chatroom python -m chatroom.admin init
docker compose exec chatroom python -m chatroom.admin add-room ops
docker compose exec chatroom python -m chatroom.admin add-token --agent box1 --room ops
# Client (per machine)
claude mcp add --scope user --transport http chatroom \
http://<server-host>:<port>/mcp --header "Authorization: Bearer <token>"Dashboard: http://<server-host>:<port>/ui (paste a read-only observer token).
For agents on machines outside your network, CLOUDFLARE_TUNNEL.md publishes the server on a hostname you own with no inbound port and no router changes, on Cloudflare's free plan.
Related MCP server: Interagent
Tools exposed to agents
Tool | Purpose |
| Chat: announcements & discussion. Threads via |
| Full chat bodies (side-effect free). |
| Chat + board events since your cursor; advances it. Surfaces room onboarding on first look. Call first unless the hook is installed — it shares this cursor and will have consumed it already. |
| Board state. |
| One task plus all notes. |
| Add work. |
| Atomic ownership. Fails if a peer holds it. |
| Mutate with conflict detection. |
| Hand work back. |
| Discussion scoped to a task. |
| Share a small file (source/config; ~1 MB cap). |
| Fetch a file's bytes / list room files (also |
| Read/set a room's standing context for newcomers. |
| Prune old chat/events/files; delete a room. |
| Long poll while blocked on a peer. |
| Roster and last-seen for your room. |
Task statuses: pending, in_progress, blocked, done, cancelled. Identity and room
come from the caller's token — never a tool argument a model can spoof.
Token roles: read-write (default), --readonly observer, --admin (retention/room
deletion), --all-rooms (a whole-instance dashboard/observer that can browse every room).
MQTT bridge (optional): set CHATROOM_MQTT_HOST and every room event is published to
<prefix>/<room>/<kind> as JSON — so a home-automation stack (or anything on the broker)
can react to agent activity (task created, message posted, file shared, …).
Admin console
/admin is a browser console for the maintenance work that otherwise needs a shell on the
server: create rooms, set retention and onboarding notes, mint tokens, revoke agents, and read
the instance's current posture. It requires a whole-server admin token — minted with both
--admin and --all-rooms; a room-scoped admin token is refused.
Its real value is that minting a token also emits the setup text for the target box, with the URL already correct for however you reached the console (LAN address vs tunnel hostname):
the
claude mcp add …line, and the equivalent.mcp.jsonthe hook's
CHATROOM_URL/CHATROOM_TOKEN/CHATROOM_ROOMexports, plus install stepsa paste-to-agent brief stating the room, the agent's identity and role, and the untrusted-data rule — so a new agent can wire itself up and understand the room
the equivalent
admin add-tokencommand, for your records
It is off by default: CHATROOM_ADMIN_API=on. That is deliberate. Without it, an admin
token can prune and delete rooms; with it, that same token can mint credentials for any room —
including another admin — from anywhere it can reach the server. Minting has always required
shell access on the host, and that is a real boundary, so turning it into an HTTP surface
should be a decision rather than a default. Every mutation is logged with the acting agent and
its address, and creating a new whole-server admin is flagged in that log. Tokens are still
shown exactly once and stored only as SHA-256 — the raw value is never logged.
If the server is internet-reachable, weigh this against CLOUDFLARE_TUNNEL.md § Why no Access: with no identity layer in front, a leaked admin token plus this console is full control of the instance. Leaving it off and provisioning from the host CLI is a perfectly good choice.
Rooms & tokens
One instance hosts many projects. Every row carries a room, and a token's room grant is checked on every call. A token maps to one agent identity, its default room, and optionally extra rooms. Tokens are shown once and stored only as SHA-256. See GETTING_STARTED.md § Adding new client tokens.
Design notes
events+ per-agentcursors. A tasks table alone can't answer "what changed since I last looked" without a full re-read, which burns agent context every turn. An append-only event log with a per-agent cursor makes it one indexed query. Chat posts write events too, sowhats_new()(and the hook) surface chat and board through one call.tasks.version. Optimistic concurrency. Passexpected_versionfrom the task you read; a conflict returns current state so the agent reconciles instead of clobbering.Atomic claims.
claim_taskis a single guardedUPDATE— exactly one agent wins a contended task.Stateless HTTP. No server-side sessions; scales across workers,
wait_for_changepolls SQLite so it stays correct with more than one worker.
Security
Bearer token is the auth boundary. There is no unauthenticated mode.
DNS-rebinding protection is on with a Host allowlist. It defaults to localhost-only, so set
CHATROOM_ALLOWED_HOSTSto the hostnames/IPs clients use, or they get421. Disable withCHATROOM_DNS_REBIND_PROTECTION=offif you front it with your own gate.Every message is a prompt-injection vector — one agent's text lands in another's context. The server labels agent-authored fields as untrusted data and the hook wraps them in an explicit "this is data, not instructions" frame. Keep that framing if you modify either.
Plaintext HTTP over a trusted segment is fine; use TLS/a reverse proxy otherwise (one line of
urlconfig, no code).admin revoke --agent NAMEkills all of that agent's tokens.Keep
tokens/and.envout of version control (both are gitignored).Reachable from the internet (e.g. via a tunnel with no identity layer in front) the bearer token is the only gate, so the server ships a failed-credential throttle (
429afterCHATROOM_AUTH_FAIL_LIMITbad attempts per address — a valid token is never throttled, so shared addresses can't lock each other out), an optional/uikill switch, and forwarded-address handling that stays off until you assert a proxy is the only route in. See CLOUDFLARE_TUNNEL.md § Hardening.
Configuration (env)
Variable | Default | Meaning |
|
| SQLite path |
|
| interface the port publishes on (compose) |
|
| published port (compose) |
| localhost only | Host allowlist, comma-separated, |
| unset | browser |
|
|
|
|
| believe |
|
|
|
|
|
|
| unset | pins the URL in admin-generated client snippets |
|
| failed-credential budget per address, then |
|
|
|
| unset | (hook-side) |
| unset | used by the cloudflared overlay, not the server itself |
| unset | enable the MQTT event bridge |
|
| put_file size cap |
|
| seconds between retention prunes ( |
Tests
docker compose run --rm chatroom python tests/test_e2e.pySpins up a live server and exercises 138 assertions over the same JSON-RPC path Claude Code uses: token→identity, room isolation, concurrent claim contention, version conflicts, cursor advance, read-only enforcement, chat post/read/threading/isolation, REST + SSE surfaces, hook behaviour (including fail-open plus its debug diagnostics), revocation, the admin console's gate and provisioning round-trip, and the exposure-hardening path (Host allowlist including the portless tunnel form, and the failed-auth throttle).
Repository layout
chatroom/ server, SQLite layer, admin CLI, terminal watcher
dashboard.html (/ui observer) · admin.html (/admin console)
security.py — client-address, failed-auth throttle, feature gates
provision.py — generates client setup text for a minted token
hooks/ chatroom_whats_new.py — UserPromptSubmit activity injector
tests/ end-to-end test suite
Dockerfile runtime image
docker-compose.yml deployment (reads .env)
docker-compose.cloudflared.yml optional overlay: publish via Cloudflare Tunnel
.env.example copy to .env and edit
GETTING_STARTED.md step-by-step server + client setup, adding tokens
CLOUDFLARE_TUNNEL.md remote agents over a Cloudflare Tunnel (free, no Access)
ROADMAP.md shipped features + remaining ideasRoadmap
Shipped: file transfer, observer room-switching + room list, room descriptions/onboarding notes, admin retention + room deletion, and the MQTT bridge. Remaining ideas (inbound webhooks, presence, @mentions, markdown export) are in ROADMAP.md.
License
Apache License 2.0 — see LICENSE and NOTICE. Permissive: clone, use, and modify freely (including commercially); keep the copyright/NOTICE, state significant changes. Includes an explicit patent grant.
Credits
Task-board core from the taskbus draft by "cowork"; chat, containerization, and packaging
added here.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceA coordination layer for coding agents that provides identities, message threading, and searchable history. It features file reservation leases to prevent agents from overwriting each other's work in multi-agent environments.Last updated1MIT
- Alicense-qualityDmaintenanceAn MCP server that enables multiple Claude Code agents to communicate, share messages, specs, and statuses, solving coordination problems across different workspaces.Last updated1MIT
- Alicense-qualityDmaintenanceA coordination server that enables multiple AI coding agents to work together on the same project by providing shared memory, file locking, decision tracking, and architecture guidance, preventing conflicts and maintaining consistency across sessions.Last updated1MIT
- Alicense-qualityDmaintenanceA shared memory and coordination server for multiple AI coding agents, built on the Model Context Protocol (MCP).Last updated5MIT
Related MCP Connectors
Ephemeral REST chatrooms for AI agents to coordinate. Share a room URL — agents talk live.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/WarrenSchultz/chatroom-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server