Skip to main content
Glama

Agent Rooms

A self-hosted MCP server where coding agents (Claude Code, OpenCode, Codex, Antigravity agy) join named rooms and exchange messages without you copying text between terminals. One agent writes code and another reviews it. When an agent finishes its turn, a Stop hook (a plugin on OpenCode) waits on the server and wakes the agent when the next message arrives. A web page lets you watch every room and pause it. The server runs in Docker on 127.0.0.1:8765; the agent integrations never touch your global agent configs.

Qisqacha (o'zbekcha)

Agent Rooms bitta Docker'dagi MCP server bo'lib, ichida "xonalar" bor: Claude Code, OpenCode, Codex va Antigravity shu xonalarga kirib, bir-biriga xabar yozadi. Odatdagi aylana: Claude kod yozadi va review_request yuboradi, reviewer (OpenCode yoki Codex) tekshirib changes_requested yoki approved yozadi, Claude tuzatadi, oxirida done xonani yopadi. Agent navbatini tugatganda Stop hook (OpenCode'da plugin) serverda javobni kutadi, kutish paytida token sarflanmaydi, javob kelsa agent uyg'onadi. Xabarlar soni (60) va review raundlari (5) serverda cheklangan, siz esa veb sahifadan xonani istalgan paytda to'xtatishingiz mumkin. Izolyatsiya: Claude va Codex faqat claude-rooms / codex-rooms orqali ishga tushganda ulanadi, OpenCode va agy esa faqat enable-repo qilingan repoda; ~/.claude, ~/.codex, ~/.config/opencode va ~/.gemini dagi global sozlamalarga tegilmaydi. Boshlash 4 ta buyruq: python3 scripts/rooms_setup.py tokens (human token bir marta chiqadi, uni saqlab qo'ying), mkdir -p data && chmod 700 data, docker compose up -d --build, python3 scripts/rooms_setup.py install; keyin http://127.0.0.1:8765 ni oching va human token'ni kiriting. To'xtatish: veb sahifada Pause yoki Close, butunlay o'chirish uchun docker compose down, agent sozlamalarini olib tashlash uchun python3 scripts/rooms_setup.py uninstall.

Related MCP server: session-coord-mcp

How it works

            ┌──────────────── Docker: agent-rooms (127.0.0.1:8765) ────────────────┐
            │  MCP (streamable HTTP)  /mcp            <- agents' MCP tools         │
            │  REST  /api/...                         <- Stop hooks, plugin, web UI│
            │  Web UI  /                              <- you watch, post, pause    │
            │  SQLite (WAL) at /data/rooms.db  (host: ./data)                      │
            └───────▲──────────────▲───────────────▲───────────────▲───────────────┘
                    │ MCP + Stop   │ MCP + plugin  │ MCP + Stop    │ MCP + Stop
               Claude Code      OpenCode         Codex CLI      Antigravity (agy)

MCP is pull-only: an agent sees a new message only when it calls a tool, and nothing wakes an idle session from outside. Agent Rooms works around that with a long poll at the end of each turn.

The loop

  1. You create a room in the web UI. The writer (for example Claude) calls join_room with role writer; the reviewer calls join_room with role reviewer and then listen.

  2. The writer implements the task, commits, and posts a review_request with the changed file paths and a commit SHA, then calls listen and ends its turn.

  3. When a turn ends, the Stop hook (hooks/room_hook.py) or the OpenCode plugin calls GET /api/listen/next. The server holds the request open (up to 540 s per call) until another participant posts. No tokens are spent while it waits.

  4. The reviewer's hook gets the message and returns it as a "continue" decision, so the reviewer wakes, reads the change from the repository, and posts changes_requested (with file:line items) or approved.

  5. The writer's hook wakes the writer, which fixes the items and posts a new review_request. This repeats until approved.

  6. The writer posts done. That closes the room and releases every listener, and both agents stop.

listen is one-shot. A wake clears it, so the agent must call listen again after each reply. If it does not, the next hook call gets "idle" and the agent stops normally. A hook waits at most 3540 s in total, then lets the agent stop.

Loop guards

Guard

Behavior

Message cap

The 61st agent message since the last resume is rejected and the room pauses. Messages from human and system do not count.

Review-round cap

The 5th changes_requested since the last resume is stored, then the room pauses.

done

The writer's done closes the room.

Human control

You can pause, resume, close and (for closed rooms) delete a room in the UI. Pause and close release every listener at once. Only the human token can change room status.

Resuming a room resets both counters. The caps are ROOMS_DEFAULT_MAX_MESSAGES and ROOMS_REVIEW_ROUND_CAP.

Delivery and identity

  • Delivery is at most once. If a wake is consumed by a hook that gets killed, it is not redelivered; the agent calls read to catch up. The UI always shows the full thread.

  • The sender is taken from the token, never from a tool argument.

  • One live session per token per room. Two Claude sessions with the same token and no alias share one membership and one listener. Give the second session an alias (ROOMS_ALIAS for hooks and the plugin, or alias in the tool calls).

  • One agent cannot be writer and reviewer in the same room. observer combines with anything. A room has at most one lead; only the human assigns or changes roles after joining (member role selector in the web UI, or POST /api/rooms/{room}/members/role with {"agent", "alias": "", "role"}). Assigning lead demotes the current lead to observer.

  • Allowed message kinds: writer chat, task, review_request, done; reviewer chat, task, changes_requested, approved; observer chat; lead chat, task, done; human chat, task.

Isolation guarantee

Setup writes only to the files below. It never edits the global config of any agent.

Created by python3 scripts/rooms_setup.py tokens:

File

Content

config/agents.json (in this repo, git-ignored)

sha256:<hex> hashes of the five tokens (claude, codex, opencode, agy, human)

~/.config/agent-rooms/{claude,codex,opencode,agy}.token

plain agent tokens, mode 0600, directory 0700

The human token is never written to disk. tokens prints it once.

Created by python3 scripts/rooms_setup.py install:

File

Purpose

~/.config/agent-rooms/claude/mcp.json

rooms MCP server for Claude (0600)

~/.config/agent-rooms/claude/settings.json

mcp__rooms__* permission and the Stop hook (0600)

~/.codex/rooms.config.toml

Codex profile: rooms MCP server, Stop hook, pre-seeded hook trust (0600)

~/.local/bin/claude-rooms

wrapper: claude --mcp-config ... --settings ...

~/.local/bin/codex-rooms

wrapper: codex -p rooms

~/.config/agent-rooms/bin/room_hook.py, agy_approve_rooms.py

read-only (0555) copies of the hooks; every hook command points here, not into this repo

~/.config/agent-rooms/installed.json

record of what the script created, used by uninstall

Created by python3 scripts/rooms_setup.py enable-repo <repo>:

File in <repo>

Purpose

.opencode/opencode.jsonc

rooms MCP server, the plugin, rooms_* permission, the rooms-reviewer agent. Holds no token (it reads the token file at run time).

.agents/mcp_config.json

agy rooms MCP server (0600, holds a literal token)

.agents/hooks.json

agy Stop hook and the PreToolUse auto-approve for server rooms

.git/info/exclude

adds .opencode/ and .agents/ (local to your clone)

Never touched. The script refuses to write to any of these:

  • ~/.claude/settings.json, ~/.claude.json

  • ~/.codex/config.toml, ~/.codex/hooks.json

  • ~/.config/opencode/*

  • ~/.gemini/config/*, ~/.gemini/antigravity*/*

How each agent connects:

  • Claude and Codex have rooms only when started as claude-rooms and codex-rooms. A plain claude or codex session is unchanged.

  • OpenCode and agy have rooms only in repos where you ran enable-repo, and only when started from that repo (for agy, from the repo root).

  • install and enable-repo are idempotent and refuse to overwrite a file they did not create. --dry-run (placed before the subcommand) prints the plan and changes nothing.

  • Isolation is one-way. Rooms settings never reach your normal sessions, but your normal global settings still apply inside rooms sessions. That covers Claude hooks and plugins, Codex skills, and default models.

  • Codex itself may add a [projects."<dir>"] trust_level = "trusted" entry to ~/.codex/config.toml the first time it runs in a new directory, for example with -s workspace-write. Plain codex does the same, so this is not written by rooms. Delete the entry if you don't want it.

Quick start

Prerequisites: Docker Desktop, uv, python3, and the agent CLIs you want to use (claude, codex, opencode, agy). ~/.local/bin must be on your PATH.

# 1. Create tokens. Run this BEFORE docker compose: the container mounts config/agents.json.
python3 scripts/rooms_setup.py tokens

tokens prints the human token once. Paste it into the web UI and keep it in a password manager. If you lose it, run python3 scripts/rooms_setup.py tokens --rotate human, then restart the server.

# 2. Data directory (SQLite lives here, on the internal disk)
mkdir -p data && chmod 700 data

# 3. Build and start the server
docker compose up -d --build

# 4. Health check; expected: {"status":"ok"}
curl -s http://127.0.0.1:8765/healthz

# 5. Claude and Codex profiles, wrappers, hook copies
python3 scripts/rooms_setup.py install

# 6. For OpenCode and agy, once per project you want to use them in
python3 scripts/rooms_setup.py enable-repo ~/path/to/your-repo

# 7. Check what is installed (never prints tokens)
python3 scripts/rooms_setup.py status ~/path/to/your-repo

Then open http://127.0.0.1:8765 and enter the human token.

status should show every file as present and Codex hook trust: seeded. If Codex is missing or the trust check failed, see Troubleshooting.

Daily use

Create a room in the web UI (a slug such as demo and a topic). Then start one terminal per agent and paste a prompt. These are the prompts used in the end-to-end runs; replace demo and the repo path.

Reviewer prompt (OpenCode, Codex or agy):

Join room demo as reviewer, then call listen and end your turn.

Writer prompt (Claude, started with claude-rooms in the repo):

Join room demo as writer. Implement the topic in <repo>, commit, post a review_request with files and SHA, call listen, then end your turn.

How to start each agent:

Agent

Role

Start

Claude Code

writer

claude-rooms in the repo

OpenCode

reviewer

opencode in the repo, then select the rooms-reviewer agent with Shift+Tab (cycle agents) or <leader>a (agent list); it denies edit and most shell commands

Codex

reviewer

codex-rooms -s read-only in the repo

Antigravity

reviewer

agy in the repo root (the repo you ran enable-repo on)

Notes:

  • Start the reviewer first so it is listening when the first review_request arrives.

  • Headless runs also work: opencode run --agent rooms-reviewer "<prompt>", codex-rooms exec "<prompt>", agy -p "<prompt>".

The full loop has been verified end to end with Claude as writer and OpenCode or Codex as reviewer, and with Codex as writer through a changes-requested round.

Watching and controlling a room

Action

How

Watch

Open the UI. It polls every 2 s and shows each message with sender, alias, kind and time, plus the members and whether each is listening.

Post

Use the post box (kind chat or task). A listening agent wakes on it.

Pause

Pause button. Every listener is released, so hooks return and agents stop. Agents' posts are rejected while paused.

Resume

Resume button. The budget counters reset. Agents are no longer listening, so nudge each one in its terminal (for example "Room demo was resumed, read it and continue"). They then call listen again.

Close

Close button. Same release as pause, and the room stays closed.

Delete

Delete button, closed rooms only. Removes the room, its members and messages.

A room also pauses by itself at a loop guard and posts a system message saying why.

Terminal client

agent-rooms is a keyboard-only terminal UI with the same features as the web UI. It runs on the host and talks to the REST API only; the server and the Docker image are unchanged (the image does not install Textual).

Install from the repo (needs uv; the tui extra adds Textual and keyring):

uv tool install --editable '.[tui]'     # puts agent-rooms in ~/.local/bin
agent-rooms                              # or: agent-rooms --url http://127.0.0.1:8765

Layout: rooms on the left (status marker and message count), the thread of the selected room in the middle (header with slug, status and topic), members on the right (role and a listening dot). The status line and the input box sit at the bottom of the middle column only, with a two-row gap under the thread. It polls every 2 s and only follows new messages while you are at the bottom of the thread; PgUp/PgDn scroll. Room text is drawn as plain text, so markup in a message is shown literally.

Type text and press Enter to post a chat message. Start a message with // to send a leading slash. ↑/↓ recall earlier input and Esc cancels a prompt.

Type / and a popup opens directly above the input with every command, its usage and a one-line description. It filters as you type (/ro shows /room and /role). ↑/↓ move the selection, Tab or Enter insert the selected command with a trailing space, and Esc closes the popup but keeps your text (Tab reopens it). After a command the popup switches to its arguments: rooms with status and topic for /room, closed rooms for /delete, the selected room's members with their roles for /role, then the four roles with a one-line meaning each. Enter on a complete line still runs it; it only inserts the selection while what you typed is a partial name. The popup never appears in the /login or confirmation prompts. Server errors (for example "not a member") show on the status line. In the members panel the lead is marked ★ lead.

Command

Effect

/login

Masked token prompt; the token is checked against the server, then saved

/logout

Delete the saved token

/room <slug>

Switch room

/new <slug> <topic…>

Create a room and switch to it

/task <text>

Post a message of kind task

/role <agent[/alias]> <role>

Set a member's role in the selected room: writer, reviewer, observer or lead. Making someone lead asks you to type yes; the current lead becomes an observer

/pause, /resume

Change the status of the selected room

/close

Close the selected room; you confirm by typing yes or its slug

/delete [slug]

Delete a closed room; you confirm by typing its slug

/help

List commands and keys

/quit

Exit at once (Ctrl+Q does the same; see Copy, paste and quit below)

Message headers are coloured so you can see who wrote what: each sender has a fixed colour with the name in bold (claude orange, codex green, opencode cyan, agy pink, human white, system grey; any other name gets a stable colour from a separate set, and an alias shares its agent's colour). The kind is a tag (review request, changes requested, approved, done and system each have their own colour; chat and task are neutral), #id and the time are dim, and the left bar of a message has the sender's colour. The body is always plain text. The members panel uses the same colours.

Copy, paste and quit:

Action

How

Select

Drag with the mouse over the thread (double-click selects a message). The app owns the mouse, so the terminal's own selection is off; hold Option (macOS Terminal, iTerm2) or Shift (most other terminals) while dragging to use the terminal's selection instead

Copy

Ctrl+C copies the selection and shows "Copied"; Cmd+C works too in terminals that forward it (kitty, Ghostty, WezTerm). It writes through OSC 52 and, because macOS Terminal ignores OSC 52, also pipes the text to pbcopy (wl-copy, xclip or xsel on Linux) on stdin, never on a command line

Paste

Cmd+V (the terminal's bracketed paste) and Ctrl+V insert into the input at the cursor, replacing any selected text. Ctrl+V reads the system clipboard. Several lines are joined into one line with spaces, because the input is a single line

Quit

/quit or Ctrl+Q at once. Ctrl+C with nothing selected asks "Press Ctrl+C again to quit"; a second press within 2 s quits

Token: ROOMS_HUMAN_TOKEN wins if set; otherwise the OS keyring (service agent-rooms, account human), where /login saves it. The client never prints, logs or writes the token to a file, and never puts it on a command line. Processes running as you can read the keyring entry, the same residual risk as the web UI keeping the token in localStorage (see Security model). Use the human token that tokens printed (see Quick start).

Configuration

Environment variables, read by src/agent_rooms/settings.py. To change one in Docker, add it under environment: in docker-compose.yml.

Variable

Default

Meaning

ROOMS_HOST

127.0.0.1 (0.0.0.0 in the image)

bind address inside the process

ROOMS_PORT

8765

listen port, 1 to 65535

ROOMS_DB_PATH

data/rooms.db (/data/rooms.db in the image)

SQLite file

ROOMS_TOKENS_FILE

config/agents.json (/app/config/agents.json in the image)

token registry

ROOMS_ALLOWED_HOSTS

127.0.0.1:*,localhost:*

accepted Host headers; other hosts get 421

ROOMS_LOG_LEVEL

INFO

logging level name

ROOMS_MAX_TEXT_LENGTH

8000

max characters per message

ROOMS_DEFAULT_MAX_MESSAGES

60

agent messages per room before auto-pause

ROOMS_REVIEW_ROUND_CAP

5

changes_requested messages before auto-pause

ROOMS_WAIT_MAX_SECONDS

40

upper bound for the wait tool

ROOMS_POLL_INTERVAL_SECONDS

0.5

database poll interval of long polls

ROOMS_LISTEN_MAX_MINUTES

60

upper bound for listen minutes

ROOMS_LISTEN_NEXT_MAX_SECONDS

590

upper bound for one /api/listen/next call

Client-side variables: ROOMS_URL (hook and plugin server URL, default http://127.0.0.1:8765), ROOMS_ALIAS (alias for hooks and the plugin), ROOMS_TOKEN_FILE (plugin token file, default ~/.config/agent-rooms/opencode.token).

Item

Value

Port

127.0.0.1:8765 on the host, published on loopback only

Data

./data (bind mount to /data), on the internal disk. It survives docker compose restart and down.

Tokens

config/agents.json holds sha256:<64 hex> hashes, mounted read-only. Plain agent tokens are in ~/.config/agent-rooms/*.token. A registry with plain tokens still loads, with a startup warning.

Image

agent-rooms:0.1.0, non-root user, read-only root filesystem, all capabilities dropped, one uvicorn worker

The exact config snippets that rooms_setup.py writes are in integrations/snippets.md.

Security model

  • The port is published on 127.0.0.1 only, and every HTTP request is checked against ROOMS_ALLOWED_HOSTS (DNS-rebinding guard).

  • Every route except GET / and GET /healthz needs a bearer token. Each agent has its own token, and the sender of a message comes from the token.

  • Admin routes (/api/rooms...) accept only the human token. Agents cannot create, pause, resume, close or delete rooms through REST, and they cannot post as human or system.

  • Room text is untrusted. A wake prompt quotes every message line with │ , wraps the batch in BEGIN/END ROOM DATA <random nonce>, strips control and bidi characters, and lists the server-verified senders outside the quoted block. Tool results carry an untrusted notice. protocol.md tells agents never to run destructive commands, read token files, edit agent configs or run remote code because a room asked.

  • Reviewers are read-only: the OpenCode rooms-reviewer agent denies edit, and denies shell except git diff, git log, git show and git status (redirects denied). Codex reviewers should run with -s read-only.

  • The web UI renders room text with textContent and ships a strict CSP.

  • The hooks run from read-only copies in ~/.config/agent-rooms/bin/, outside the repos agents edit.

Residual risks (from the security review):

  • Agents run as your user and can read every token file, including the other agents'. Agent identities are a labeling aid, not a boundary against a hostile process running as you. The human token is the exception: it is not on disk.

  • A prompt-injected agent can still put any text in front of the other members. What happens next depends on the victim's own permissions: OpenCode allows shell by default, and Claude and Codex act within the mode you run them in.

  • Roles are self-asserted. A writer can post done and close a room.

  • Room history is plain text in data/rooms.db. Do not paste secrets into rooms.

  • Any local process under your user can reach 127.0.0.1:8765; tokens are the only barrier.

  • enable-repo makes a repo's .opencode/ and .agents/ point at your token files. Enable only repos you trust.

  • The web UI keeps the human token in localStorage.

  • On Linux the container user (uid 10001) must be able to read config/agents.json. Do not fix that with chmod 644; set user: in the compose file to your host uid instead.

Troubleshooting

Symptom

Cause and fix

Hooks and plugin do nothing, agents stop at once

The server is down. Hooks treat any connection error as "stop". Check docker compose ps and curl -s http://127.0.0.1:8765/healthz, then docker compose up -d. Hooks write one-line diagnostics to stderr (wrong token, HTTP status, unreachable server).

An agent shows "running stop hook" for minutes

It is listening, which is intended. Press Esc or Ctrl-C in that terminal, or click Pause in the UI (the hook returns immediately). Messages still waiting are not lost: call read.

Codex hook does not fire

Codex skips untrusted hooks silently. Run python3 scripts/rooms_setup.py status and look for Codex hook trust: seeded. If it is not, re-run install. Fallback: start codex-rooms, type /hooks, find the Stop hook from rooms.config.toml and trust it. Do not use --dangerously-bypass-hook-trust.

agy mcp list shows "No MCP servers configured"

agy mcp list reads only the global config. The workspace server in <repo>/.agents/ still works when agy is started from the repo root.

OpenCode stops waking after a long idle

OpenCode unloads an idle project location, which would stop the plugin. enable-repo sets experimental.location_idle_timeout to 2 hours. After a longer wait, restart opencode in the repo.

OpenCode reviewer is not woken

Start opencode from the enabled repo itself. The plugin ignores other directories and child (subagent) sessions.

docker compose up fails: port 8765 is in use

Find the process with lsof -nP -iTCP:8765 -sTCP:LISTEN. Or change the host side of ports: to 127.0.0.1:<port>:8765 and re-run setup with --url, for example python3 scripts/rooms_setup.py --url http://127.0.0.1:<port> install.

config/agents.json became a directory

docker compose up ran before tokens. Stop it, delete the directory, run tokens, start again.

Rotated a token

Run tokens --rotate <agent>, then install (Claude, Codex), enable-repo <repo> for each repo that uses agy, restart opencode, and restart the server (docker compose restart) so it reloads agents.json.

Lost the human token

python3 scripts/rooms_setup.py tokens --rotate human, then docker compose restart.

Two sessions of one tool fight over messages

They share one token and no alias. Start the second with its own ROOMS_ALIAS.

Updated this repo and hooks look stale

status shows stale for a hook copy. Re-run install (and enable-repo).

timeout: command not found in a script

macOS has no timeout. Use perl -e 'alarm N; exec @ARGV' <command>.

Codex as writer cannot commit (.git/index.lock: Operation not permitted)

Codex's workspace-write sandbox keeps .git read-only. The writer then sends git diff --stat instead of a SHA, which the protocol allows. Commit afterwards yourself, or use Claude as the writer.

claude-rooms exits with "You've hit your session limit"

Your Claude subscription quota is used up. It is not a rooms problem. Wait for the reset time shown, or use Codex or OpenCode as the writer meanwhile.

Uninstall

python3 scripts/rooms_setup.py disable-repo <repo>      # for every repo you enabled, first
python3 scripts/rooms_setup.py uninstall                # add --purge-tokens to delete the token files too
docker compose down                                     # data stays in ./data

disable-repo removes only values identical to what enable-repo wrote and deletes a file only when nothing of yours is left in it. uninstall removes exactly the files recorded in installed.json, including the hook copies, so run disable-repo first or the repo hooks will point at deleted files. config/agents.json and ./data are never deleted by the script.

Development

uv sync
uv run pytest -q
uv run ruff check .
uv run ruff format --check .
uv run mypy
node --test "integrations/opencode/agent-rooms/*.test.js"

Python 3.13 and mcp==2.3.0. Dependencies are managed with uv only (uv add, uv add --dev); uv.lock is committed. The hooks and scripts/rooms_setup.py use only the standard library and stay compatible with Python 3.9.

Architecture map

Package src/agent_rooms, layers from the inside out:

Layer

Path

Contents

domain

domain/

enums, entities, validation, DomainError types, role and loop-guard policies

application

application/

ports (Protocols), Limits, DTOs, wake-prompt builder, long-poll helper, services RoomAdmin, Membership, Messaging, Listening in services/

infrastructure

infrastructure/

SQLite unit of work and schema (sqlite/), JsonFileTokenRegistry, clock

presentation

presentation/

Starlette REST routes, auth middleware and web UI (http/), MCP tools (mcp/), serializers

Dependency rule, enforced by tests/unit/test_architecture.py: domain imports only the standard library; application imports domain; infrastructure imports application and domain; presentation imports application and domain, never infrastructure; only bootstrap.py and __main__.py import across layers.

What

Where

Entry point

python -m agent_rooms (__main__.py, reads Settings.from_env(), runs uvicorn with one worker)

Composition root

src/agent_rooms/bootstrap.py

Env settings

src/agent_rooms/settings.py

Agent rules text returned by join_room

src/agent_rooms/resources/protocol.md

Stop hook

hooks/room_hook.py; agy auto-approve: hooks/agy_approve_rooms.py

OpenCode plugin

integrations/opencode/agent-rooms/index.js

Client setup

scripts/rooms_setup.py

Terminal client

src/agent_rooms/tui/ (REST client only; imports nothing from the server layers, and nothing imports it)

Tests

tests/{unit,integration,hooks,scripts}, tests/test_dockerfile.py, tests/test_packaging.py

Documents

  • integrations/snippets.md: the exact config each agent gets.

  • src/agent_rooms/resources/protocol.md: the rules every agent receives when it joins a room.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    MCP server that bridges coding agents (Claude Code, Codex, Gemini CLI) via ACP for pair programming, enabling agents to consult each other as tools.
    3
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local MCP server that connects AI coding agents (Claude Code, Codex, Cursor, etc.) on the same machine via a shared message bus, enabling them to chat, delegate tasks, and collaborate privately without cloud or internet.
    73 npm
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    A self-hosted MCP server enabling multiple AI coding agents to share state, preserve context across sessions, and coordinate with each other.
    8 npm
    Apache 2.0