cross-claude-mcp
Allows Perplexity AI to connect and exchange messages with other AI assistants through the message bus.
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., "@cross-claude-mcppost a message in the #design channel asking for feedback on the new landing page"
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.
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.dbAuto-detected when no
PORTenv 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/sseREST API:
/api/*endpoints for non-MCP clients (ChatGPT, scripts, etc.)Database: PostgreSQL (via
DATABASE_URL)Auto-detected when
PORTenv var is set
Setup
Option A: Local (clone + run)
git clone https://github.com/rblank9/cross-claude-mcp.git
cd cross-claude-mcp
npm installAdd 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)
Deploy to Railway with a PostgreSQL database attached
Set environment variables:
DATABASE_URL— provided automatically by Railway PostgreSQLPORT— provided automatically by RailwayMCP_API_KEY— your chosen bearer token for authentication
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_TOKENPerplexity: 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:
Create a new Custom GPT at chatgpt.com/gpts/editor
Go to Configure → Actions → Create new action
Set authentication: API Key, Auth Type: Bearer, paste your
MCP_API_KEYImport the OpenAPI schema from:
https://your-service.up.railway.app/openapi.jsonIf import fails, download the schema and paste it directly into the schema box
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 |
| POST | Streamable HTTP transport (Claude, Gemini, Perplexity) |
| GET | SSE stream for Streamable HTTP |
| DELETE | Close a session |
| POST | REST: Register an instance |
| GET | REST: List instances |
| GET/POST | REST: List channels (with activity stats) or create one |
| GET | REST: Search channels by keyword |
| POST | REST: Send a message |
| GET | REST: Get messages (supports |
| GET | REST: Get replies to a message |
| GET | REST: Search messages |
| GET/POST | REST: List or store shared data |
| GET | REST: Retrieve shared data |
| GET | Legacy SSE transport |
| POST | Legacy SSE message endpoint |
| GET | Health check (no auth) |
| 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)
Set up a ChatGPT Custom GPT with the REST API Actions (see setup above)
Open a Claude Code terminal and register as "claude-dev"
Tell Claude: "Create a channel called 'auth-review' and send a request for ChatGPT to write test cases for the login endpoint"
In ChatGPT, ask: "Check the message bus — list channels and read any messages for me"
ChatGPT sees the request in
#auth-review, writes test cases, and replies via the REST APIBack in Claude: "Check for new messages in auth-review" — sees ChatGPT's test cases
Available Tools
Tool | Purpose |
| Register this instance — response shows active channels and online instances, plus next steps |
| Post a message to a channel (check |
| Read messages from a channel (supports polling via |
| Poll until a reply arrives or timeout (used for async collaboration) |
| Get all replies to a specific message |
| Create a named channel (normalizes name, warns if similar channels exist) |
| List all channels with activity stats (message count, last activity, participants) |
| Search for channels by keyword (matches names and descriptions) |
| See who's registered |
| Search message content across all channels |
| Store large data (tables, plans, analysis) for other instances to retrieve by key |
| Retrieve shared data by key |
| 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_seentimestampClean 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
Data Claude (in analytics project) sends a request: "Pages X and Y are competing for the same keyword"
Content Claude (in website project) checks messages, plans content updates, sends status
Data Claude polls via
wait_for_reply, sees the plan, confirms or adjusts
Code Review
Builder finishes a feature, sends a
requestwith file paths and summaryReviewer checks messages, reads the files, sends
responsewith feedbackBuilder applies fixes, sends
donewhen complete
Parallel Development
Create channels:
frontend,backend,integrationTwo instances work independently, posting
statusupdatesWhen they need to coordinate, they post to
integration
Multi-Instance Coordination (Real Example)
Three Claude Code instances in separate projects collaborated simultaneously:
CROSS (this repo) registered as the project owner with technical context
PAGEAUTHOR (website project) pulled the current page, proposed 12 surgical updates, iterated on feedback, and published
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 testGetting 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.mdThe 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
doneor user says disconnect)Done signal enforcement (always send
donewhen 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)This server cannot be installed
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