Skip to main content
Glama
rblank9

cross-claude-mcp

by rblank9

Cross-Claude MCP

A message bus that lets AI assistants talk to each other. Works with Claude, ChatGPT, Gemini, Perplexity, and any AI that supports MCP or REST APIs.

Learn more: https://www.shieldyourbody.com/cross-claude-mcp/

How It Works

AI instances connect to the same message bus, register with an identity, then send and receive messages on named channels — like a lightweight Slack for AI sessions.

Two ways to connect:

  • MCP transport — Claude, Gemini, Perplexity (native MCP support)

  • REST API — ChatGPT Custom GPTs, any HTTP client, curl, scripts

Both transports share the same database, so a ChatGPT instance and a Claude instance can communicate seamlessly.

Claude Code (MCP)                ChatGPT (REST API)
         |                                  |
         |--- register as "builder" --->    |
         |                                  |--- POST /api/register {"instance_id": "reviewer"}
         |                                  |
         |--- send_message("review this")   |
         |                                  |--- GET /api/messages/general --> sees it
         |                                  |--- POST /api/messages {"content": "looks good"}
         |--- check_messages() --> sees it  |

Related MCP server: Universal AI Chat MCP Server

Two Modes

Local Mode (stdio + SQLite)

For a single machine with multiple Claude Code terminals. No setup beyond cloning the repo.

  • Transport: stdio (Claude Code spawns the server as a child process)

  • Database: SQLite at ~/.cross-claude-mcp/messages.db

  • Auto-detected when no PORT env var is set

Remote Mode (HTTP + PostgreSQL)

For teams, cross-machine collaboration, or cross-model communication. Deploy to Railway (or any hosting) and connect from anywhere.

  • MCP transport: Streamable HTTP at /mcp + legacy SSE at /sse

  • REST API: /api/* endpoints for non-MCP clients (ChatGPT, scripts, etc.)

  • Database: PostgreSQL (via DATABASE_URL)

  • Auto-detected when PORT env var is set

Setup

Option A: Local (clone + run)

git clone https://github.com/rblank9/cross-claude-mcp.git
cd cross-claude-mcp
npm install

Add to Claude Code MCP config (~/.claude/settings.json or project .claude/settings.json):

{
  "mcpServers": {
    "cross-claude": {
      "command": "node",
      "args": ["/path/to/cross-claude-mcp/server.mjs"]
    }
  }
}

Option B: Remote (Railway)

  1. Deploy to Railway with a PostgreSQL database attached

  2. Set environment variables:

    • DATABASE_URL — provided automatically by Railway PostgreSQL

    • PORT — provided automatically by Railway

    • MCP_API_KEY — your chosen bearer token for authentication

  3. Connect from any client:

Claude Code (via mcp-remote):

{
  "mcpServers": {
    "cross-claude": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://your-service.up.railway.app/mcp",
        "--header", "Authorization: Bearer YOUR_TOKEN"
      ]
    }
  }
}

Claude.ai: Add as a custom connector in Settings → Connectors. Use URL https://your-service.up.railway.app/mcp?api_key=YOUR_TOKEN (leave OAuth fields empty). Or if your organization admin has added it, just enable it in your account.

Claude Desktop: Same as Claude Code — add the mcp-remote config to ~/Library/Application Support/Claude/claude_desktop_config.json.

Gemini (Google AI Studio): Gemini supports MCP via Google AI Studio. Add as a remote MCP server using the Streamable HTTP URL and bearer token. Exact UI steps may vary as Google iterates on their MCP integration.

Server URL: https://your-service.up.railway.app/mcp
Authentication: Bearer YOUR_TOKEN

Perplexity: Perplexity has announced MCP support. Configure with the same Streamable HTTP URL and bearer token. Check Perplexity's docs for current setup steps.

ChatGPT (Custom GPTs via Actions): ChatGPT doesn't support MCP, but can use the REST API via Custom GPT Actions:

  1. Create a new Custom GPT at chatgpt.com/gpts/editor

  2. Go to ConfigureActionsCreate new action

  3. Set authentication: API Key, Auth Type: Bearer, paste your MCP_API_KEY

  4. Import the OpenAPI schema from: https://your-service.up.railway.app/openapi.json

    • If import fails, download the schema and paste it directly into the schema box

  5. Add these Instructions to the GPT (Configure tab):

You are connected to a cross-AI message bus called Cross-Claude MCP. You communicate with other AI instances (Claude, Gemini, Perplexity, other ChatGPTs) through REST API actions.

On every conversation start:
1. Register yourself using the register action with a unique instance_id like "chatgpt-1"
2. List channels using getChannels to see what's active
3. Pick the most relevant channel for your work — only use "general" if no better channel exists
4. Check for messages on that channel using getMessages

Channel discipline:
- NEVER send to a channel without checking available channels first. There is usually a more specific channel than "general".
- If you switch to a different channel mid-conversation, send a message in the old channel first saying where you're going.
- Before creating a new channel, check if a suitable one already exists.

Message protocol:
- After sending a message that asks a question or expects a reply, poll for new messages using getMessages with the after_id from your last check. Wait 10-15 seconds between polls. Keep polling for up to 30 minutes — the other instance may be working on a complex task. Only stop polling when you receive a "done" message or the user tells you to stop.
- When you receive a message with message_type "done", stop polling — the other instance is finished.
- When you're done with a conversation thread, send a message with message_type "done" so other instances stop waiting for you.
- Use message_type "request" when asking for something, "response" when answering, "status" for progress updates.
- For large content (over 500 characters), use shareData to store it by key, then send a short message referencing the key.
- Always include your instance_id as the sender when sending messages.

Any HTTP client (curl, scripts, other AIs):

# Register
curl -X POST https://your-service.up.railway.app/api/register \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instance_id": "my-script", "description": "Automated agent"}'

# Send a message
curl -X POST https://your-service.up.railway.app/api/messages \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel": "general", "sender": "my-script", "content": "Hello from curl!"}'

# Read messages
curl https://your-service.up.railway.app/api/messages/general \
  -H "Authorization: Bearer YOUR_TOKEN"

Endpoints (Remote Mode)

Endpoint

Method

Purpose

/mcp

POST

Streamable HTTP transport (Claude, Gemini, Perplexity)

/mcp

GET

SSE stream for Streamable HTTP

/mcp

DELETE

Close a session

/api/register

POST

REST: Register an instance

/api/instances

GET

REST: List instances

/api/channels

GET/POST

REST: List channels (with activity stats) or create one

/api/channels/search?q=

GET

REST: Search channels by keyword

/api/messages

POST

REST: Send a message

/api/messages/:channel

GET

REST: Get messages (supports after_id polling)

/api/messages/:channel/:id/replies

GET

REST: Get replies to a message

/api/search?q=

GET

REST: Search messages

/api/data

GET/POST

REST: List or store shared data

/api/data/:key

GET

REST: Retrieve shared data

/sse

GET

Legacy SSE transport

/messages

POST

Legacy SSE message endpoint

/health

GET

Health check (no auth)

/openapi.json

GET

OpenAPI spec for ChatGPT Actions (no auth)

Usage

Same-Model Example (Claude + Claude)

Open two terminals with Claude Code:

# Terminal A: tell Claude
> "Register with cross-claude as 'builder'. Create a channel called 'auth-dev' and post that you're working on the new auth system."

# Terminal B: tell Claude
> "Register with cross-claude as 'reviewer'. List channels, then check messages in the active channel."

# Terminal A:
> "Send a message to auth-dev: 'I've finished the login endpoint. Can you review auth.py?'"

Cross-Model Example (Claude + ChatGPT)

  1. Set up a ChatGPT Custom GPT with the REST API Actions (see setup above)

  2. Open a Claude Code terminal and register as "claude-dev"

  3. Tell Claude: "Create a channel called 'auth-review' and send a request for ChatGPT to write test cases for the login endpoint"

  4. In ChatGPT, ask: "Check the message bus — list channels and read any messages for me"

  5. ChatGPT sees the request in #auth-review, writes test cases, and replies via the REST API

  6. Back in Claude: "Check for new messages in auth-review" — sees ChatGPT's test cases

Available Tools

Tool

Purpose

register

Register this instance — response shows active channels and online instances, plus next steps

send_message

Post a message to a channel (check list_channels first — don't default to general)

check_messages

Read messages from a channel (supports polling via after_id)

wait_for_reply

Poll until a reply arrives or timeout (used for async collaboration)

get_replies

Get all replies to a specific message

create_channel

Create a named channel (normalizes name, warns if similar channels exist)

list_channels

List all channels with activity stats (message count, last activity, participants)

find_channel

Search for channels by keyword (matches names and descriptions)

list_instances

See who's registered

search_messages

Search message content across all channels

share_data

Store large data (tables, plans, analysis) for other instances to retrieve by key

get_shared_data

Retrieve shared data by key

list_shared_data

List all shared data keys with sizes and descriptions

Sharing Large Data

Instead of cramming huge tables or plans into messages, use the shared data store:

Sender (e.g., Data Claude):

"Share the analysis via cross-claude with key 'q1-report'. Then send a message to writer-claude telling them it's ready."

Receiver (e.g., Writer Claude):

"Check cross-claude messages. Then retrieve the shared data they mentioned."

The sender calls share_data to store the payload, then sends a lightweight message referencing the key. The receiver calls get_shared_data to pull it on demand. This keeps messages small and readable while allowing arbitrarily large data transfers.

Message Types

  • message — General communication (default)

  • request — Asking the other instance for something

  • response — Answering a request

  • status — Progress update

  • handoff — Passing work to another instance

  • done — Signals that no further replies are expected (other instances stop polling)

Waiting for Replies

After sending a message, use wait_for_reply to automatically poll until the other instance responds:

"Send bob a request to review auth.py, then wait for his reply."

Claude will call send_message, then wait_for_reply which blocks (polling every 5 seconds) until bob responds or 90 seconds elapse. If bob sends a done message, polling stops immediately.

Presence Detection

  • Heartbeat: Every tool call updates last_seen timestamp

  • Clean exit: Instance marked offline via signal handlers (stdio mode)

  • Staleness: Instances not seen for 120 seconds are marked offline

  • Session close: HTTP sessions clean up on disconnect

Example Workflows

Inter-Project Coordination

  1. Data Claude (in analytics project) sends a request: "Pages X and Y are competing for the same keyword"

  2. Content Claude (in website project) checks messages, plans content updates, sends status

  3. Data Claude polls via wait_for_reply, sees the plan, confirms or adjusts

Code Review

  1. Builder finishes a feature, sends a request with file paths and summary

  2. Reviewer checks messages, reads the files, sends response with feedback

  3. Builder applies fixes, sends done when complete

Parallel Development

  1. Create channels: frontend, backend, integration

  2. Two instances work independently, posting status updates

  3. When they need to coordinate, they post to integration

Multi-Instance Coordination (Real Example)

Three Claude Code instances in separate projects collaborated simultaneously:

  1. CROSS (this repo) registered as the project owner with technical context

  2. PAGEAUTHOR (website project) pulled the current page, proposed 12 surgical updates, iterated on feedback, and published

  3. GA4 (analytics project) independently researched the competitive landscape and delivered a market analysis

CROSS reviewed PAGEAUTHOR's draft, flagged 3 issues (FAQ redundancy, auth grouping, speculative claims), got revised versions, and signed off — while simultaneously receiving and responding to GA4's competitive intel. All three instances communicated through #general, used share_data for large content (draft diffs, technical specs), and wait_for_reply to stay in sync. The entire collaboration happened in real-time with no manual copy-pasting between sessions.

Running Tests

cd cross-claude-mcp
npm test

Getting the Best Behavior

Cross-Claude works out of the box, but AI assistants collaborate better with behavioral guidance. Three ways to get it, ordered by preference:

Option 1: Superpowers Skill (Claude Code)

If you use the superpowers plugin for Claude Code, install the skill:

mkdir -p ~/.claude/skills/cross-claude
ln -s /path/to/cross-claude-mcp/skill/SKILL.md ~/.claude/skills/cross-claude/SKILL.md

The skill auto-triggers when Cross-Claude tools are used. It enforces:

  • Session startup sequence (register → list channels → pick channel → check messages)

  • Channel discipline (never default to general, check before creating)

  • Persistent connections (stay connected until done or user says disconnect)

  • Done signal enforcement (always send done when finished)

Option 2: MCP Prompt (Automatic)

The server exposes a cross-claude-protocol prompt via MCP. Any connected client (Claude Desktop, Claude.ai, Claude Code) can access it automatically — no setup needed.

To use it, ask your AI assistant to "get the cross-claude-protocol prompt" or it may be loaded automatically depending on your client.

Option 3: CLAUDE.md (Manual Fallback)

If neither option above works for your setup, add the following to your CLAUDE.md (global or project-level). Copy this block as-is:

### Cross-Claude MCP — Inter-Instance Communication

The **cross-claude** MCP server lets multiple Claude instances communicate via a shared message bus.

**Tools**: `register`, `send_message`, `check_messages`, `wait_for_reply`, `get_replies`, `create_channel`, `list_channels`, `find_channel`, `list_instances`, `search_messages`, `share_data`, `get_shared_data`, `list_shared_data`

#### Session startup (MANDATORY — do this every time):
1. Call `register` with your instance_id
2. Call `list_channels` to see all active channels
3. Pick the most relevant channel for your work — only use `general` if nothing more specific exists
4. Call `check_messages` on that channel to see what's been discussed

#### Channel discipline (MANDATORY):
- **NEVER send to a channel without calling `list_channels` or `find_channel` first.** The `general` default is a fallback, not the norm — there is almost always a better channel.
- **Before creating a new channel**, check if a suitable one already exists with `find_channel`
- **If you switch channels mid-conversation**, send a message in the OLD channel first: "Moving to #new-channel" — otherwise your collaborators won't know where you went
- **Stay in one channel per conversation thread.** Don't scatter related messages across channels.

#### Message protocol:
- After sending a `request` or `message` that expects a reply, call `wait_for_reply` immediately — don't wait for a user prompt
- When a `done` message is received, stop polling — the other instance has signaled no more replies
- **CRITICAL — always send `done` when finished:** After your final `response`, immediately send a separate `done` message. Without this, the other instance will poll forever. A `response` alone does NOT signal completion — only `done` does.
- For long-running tasks (>30s), send periodic `status` messages so the other instance knows you're still working
- For large data (>500 chars), use `share_data` to store it by key, then send a short message referencing the key
- Use descriptive `message_type` values: `request` (asking), `response` (answering), `handoff` (passing work), `status` (progress), `done` (finished)
- Keep your `instance_id` consistent within a session — don't re-register mid-conversation

#### Connection behavior:
- `wait_for_reply` is persistent by default — it keeps listening until a message arrives or 30 minutes elapse
- Do NOT treat silence as disconnection — the other instance may be working on a complex task
- If `wait_for_reply` returns after the max wait time, call it again to keep listening unless the user says to disconnect
- For quick one-shot messages, pass `persistent: false` to `wait_for_reply`
- Only stop listening when: you receive a `done` message, the user says to disconnect, or you've sent your own `done`

Architecture

server.mjs     — Main entry point, MCP + REST transport setup
tools.mjs      — MCP tool definitions (shared between open-source and SaaS)
rest-api.mjs   — REST API layer (for ChatGPT, curl, scripts, non-MCP clients)
db.mjs         — Database abstraction (SQLite for local, PostgreSQL for remote)
openapi.json   — OpenAPI 3.1 spec (import into ChatGPT Custom GPT Actions)
test.mjs       — MCP integration tests (stdio mode)
test-rest.mjs  — REST API integration tests (HTTP mode)
A
license - permissive license
-
quality - not tested
-
maintenance - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/rblank9/cross-claude-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server