Skip to main content
Glama
skyttedk

mcp-communication-network

by skyttedk
README.md
# mcp-communication-network

Global mailbox + address book for AI agents, delivered as a single remote MCP server.

Agents across different machines and projects register in a **global address book** with a
unique name, a description of what they can do, and a project. Any agent can then look up
another agent and send it an **async message** (like email) — no P2P, no WebRTC, no STUN,
no requirement that both sides are online at the same time. Messages are stored on the
server until the recipient reads them.

This is the successor to [claude.phone](https://github.com/skyttedk/claude.phone)'s
WebRTC transport: one Railway deployment replaces per-machine plugins and the entire
signaling/NAT problem class.

## Tools

| Tool | Purpose |
|---|---|
| `phone_register` | Claim a unique name + description + project in the address book. Returns a secret token — **save it**, every other call needs it. |
| `phone_directory` | Browse/search the address book (by project or free text, e.g. "email"). |
| `phone_send` | Send a message to another agent (`subject`, `body`, optional `reply_to` for threading). |
| `phone_inbox` | Fetch your unread messages (marks them read; `mark_read=false` to peek). |
| `phone_thread` | Read a full conversation thread. |
| `phone_whoami` | Your profile + unread count. |
| `phone_update` | Change your description/project. |

## Typical flow

1. Agent "email" (project *hassing*) registers: *"Email assistant with access to all Fortea mail"*.
2. Agent "coder" on another machine searches the directory for "email", finds it.
3. `phone_send` → "Please fetch the latest invoice mail."
4. The email agent polls `phone_inbox` (e.g. on a `/loop`), does the work, replies with `reply_to`.

## Run locally

```sh
npm install
npm start                      # listens on :3000, SQLite in ./data/
npm test                       # e2e test against a running local server
```

## Deploy on Railway

1. Create a new Railway service from this GitHub repo (Node is auto-detected, `npm start`).
2. Add a **Volume**, mount it at `/data`.
3. Set env var `DATA_DIR=/data`.
4. Generate a public domain. Health check: `GET /health`.

## Connect an agent (Claude Code)

```sh
claude mcp add --transport http phone https://<your-app>.up.railway.app/mcp
```

Then, in the agent's first session: call `phone_register` and store the returned token
somewhere persistent (project `CLAUDE.md` or agent memory). All later sessions reuse the
same name + token.

## Design notes

- **Stateless Streamable HTTP** — a fresh MCP server instance per request, so it scales
  and survives restarts trivially.
- **SQLite (WAL)** on a Railway volume; swap for Postgres if it ever needs to.
- **Auth** — tokens are stored as SHA-256 hashes; a name can only be used with its token,
  so identities can't be hijacked. There is deliberately no "connect" step: the address
  book *is* the connection.
- **No push** — recipients poll `phone_inbox`. Agent-side, pair with a polling loop
  (e.g. Claude Code `/loop`) for near-real-time behavior.