Skip to main content
Glama
ijustseen

change-ping-mcp

by ijustseen
README.md
# change-ping-mcp

A local [MCP](https://modelcontextprotocol.io) server: a small in-memory event bus for independent AI agents working in the same repository.

Several agents can edit one repo from different clients (any MCP host). They do not share a chat and should not block each other. When a **contract** changes — not private internals — the author sends a short ping. The other agent reads the summary and keeps working against the current API.

## Why

Agents are good at their own slice of the code and slow to notice that a neighbor just renamed a response field or added a Prisma column. PR comments and a shared chat arrive too late and too long.

`change-ping-mcp` is a shared local channel:

- **Contracts only** — APIs, database schemas, shared types, Zod/OpenAPI. Refactors, typos, and local edits stay off the bus.
- **Summaries only** — one to three concrete sentences, no diffs, no fluff.
- **No locks** — nobody waits for anybody. A ping is a signal, not a barrier.

A good ping looks like this:

```
[API_UPDATED] POST /api/v1/auth: field token renamed to authToken
```

## How it works

One Node.js process holds an `EventBus` (history array + `EventEmitter`) and exposes two MCP tools:

| Tool | Purpose |
| --- | --- |
| `emit_change_ping` | Accept `sender` (this agent's id in the project), `type`, and `summary`, then store the ping |
| `get_latest_pings` | Return the latest N pings |

The two URLs are **not two buses and not tied to a specific IDE**. Same process, same history, same tools. Only the MCP transport changes:

| URL | Transport | When to use it |
| --- | --- | --- |
| `http://127.0.0.1:3333/mcp` | Streamable HTTP | Default: current protocol |
| `http://127.0.0.1:3333/sse` | HTTP + SSE (`POST /messages`) | If the client still speaks legacy SSE |

Try `/mcp` first. If the client cannot connect, use `/sse` on the same server.

History lives in process memory (up to 200 pings) and is cleared on restart.

While the process is running, the same bus is visible in the browser: [http://127.0.0.1:3333](http://127.0.0.1:3333). The feed updates in real time, including pings from agents. The page form can send a test ping.

## Run

Node.js 18+ is required.

```bash
npm install
npm run dev
```

The server listens on `http://127.0.0.1:3333` — open that URL in a browser. Health check:

```bash
curl http://127.0.0.1:3333/health
```

Build without `tsx`:

```bash
npm run build
npm start
```

Override bind address with `PORT=3333 HOST=127.0.0.1 npm run dev`.

## Connect any agent

Point any MCP client at the bus as a remote/HTTP MCP server. Config shape differs by host; the URL does not.

```json
{
  "url": "http://127.0.0.1:3333/mcp"
}
```

If the host only supports legacy SSE:

```json
{
  "url": "http://127.0.0.1:3333/sse"
}
```

Where to put that URL is up to the client (`mcp.json`, `opencode.json`, `claude_desktop_config.json`, and so on). The server name can be anything; the tools are `emit_change_ping` and `get_latest_pings`.

When to ping belongs in the *working* project's agent rules (`AGENTS.md`, system prompt), not in this repository. The server runs without that; agents just will not know to call the tools.

## Typical loop

1. Agent A calls `get_latest_pings` before touching a shared contract.
2. Does its work.
3. If it moved an API, schema, or shared type — `emit_change_ping` immediately.
4. Agent B repeats step 1 and picks up the change.

Agents do not sync sessions and do not send full diffs. The bus only stores short facts the neighbor depends on.

## License

MIT