Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Description from the maker (original English)
Relays messages between two Claude Code sessions on different machines using the Channels API
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
MY_ROLE, REMOTE_HOST, INTERCOM_SECRET, INTERCOM_PORT, INTERCOM_HOST, INTERCOM_SEND_TIMEOUT_MSValues marked secret are keys to your account. Never share them or paste them into a chat.
You need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"intercom": {
"command": "npx",
"args": [
"-y",
"claude-intercom"
],
"env": {
"MY_ROLE": "your-value",
"REMOTE_HOST": "your-value",
"INTERCOM_SECRET": "your-value",
"INTERCOM_PORT": "your-value",
"INTERCOM_HOST": "your-value",
"INTERCOM_SEND_TIMEOUT_MS": "your-value"
}
}
}
}Run this in your terminal
claude mcp add intercom --env MY_ROLE=your-value --env REMOTE_HOST=your-value --env INTERCOM_SECRET=your-value --env INTERCOM_PORT=your-value --env INTERCOM_HOST=your-value --env INTERCOM_SEND_TIMEOUT_MS=your-value -- npx -y claude-intercomFill in the empty values before running it.
Paste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"intercom": {
"command": "npx",
"args": [
"-y",
"claude-intercom"
],
"env": {
"MY_ROLE": "your-value",
"REMOTE_HOST": "your-value",
"INTERCOM_SECRET": "your-value",
"INTERCOM_PORT": "your-value",
"INTERCOM_HOST": "your-value",
"INTERCOM_SEND_TIMEOUT_MS": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"intercom": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"claude-intercom"
],
"env": {
"MY_ROLE": "your-value",
"REMOTE_HOST": "your-value",
"INTERCOM_SECRET": "your-value",
"INTERCOM_PORT": "your-value",
"INTERCOM_HOST": "your-value",
"INTERCOM_SEND_TIMEOUT_MS": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
INTERCOM_PORT envINTERCOM_HOST envINTERCOM_SEND_TIMEOUT_MS envThese settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 6, 2026
The registry name was verified with the GitHub account MuhammadTalhaMT, which owns the repo
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
You need to fill in: MY_ROLE, REMOTE_HOST, INTERCOM_SECRET
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (2.1.0) reached the registry 3 months ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.
In the same category: Spec Driven Development, Remote Desktop Commander, Safe Fetch
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
MCP server for fetching URLs, safe against SSRF, DNS rebinding, and redirect-to-internal attacks.
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
Two-way communication bridge between Claude Code sessions using the Channels API.
Let two Claude Code instances on different machines talk to each other in real-time. One sends a message, the other receives it instantly as a channel notification and can reply back.
Claude Code has native cross-session messaging now. Here's where Intercom is still the answer:
send_message reports sent, delivered-to-process and answered as three separate states, plus a check_message tool. You find out when the other side never picked it up, instead of planning around an answer that was never coming.If you're on macOS or Linux and you just want your own sessions talking to each other, native is simpler — use that. Everything else above is what this is for.
If you have a backend developer and a frontend developer each running Claude Code on separate machines, they currently have to relay questions through Slack/Discord/copy-paste. Claude Intercom creates a direct hotline between the two AI sessions — one Claude can ask the other about endpoints, schemas, or implementation details and get answers from the actual codebase.
Machine A Machine B
(e.g. backend dev) (e.g. frontend dev)
Claude Code A Claude Code B | | +-- intercom.ts ---HTTP POST----> intercom.ts --+ | (channel) <--HTTP POST-- (channel) | | | +-- stdio (MCP) --+ +-- stdio (MCP) -----+ | | Claude A Claude B
Both instances run the same intercom.ts file. Each listens for HTTP messages and pushes them into its local Claude Code session via the Channels API. Each also exposes send_message and check_message tools that Claude can call.
Paste this into a Claude Code session on each machine and it will walk you through the whole thing. Run it on machine A first, keep the secret it gives you, then run it on machine B.
Set up claude-intercom on this machine so this Claude Code session can message
a Claude Code session on my other machine.
Work through this in order, and stop and ask me whenever you need something only I can tell you.
bun --version works and that claude --version is 2.1.80 or newer. If Bun is missing, tell me how to install it for my OS and stop there.tailscale ip -4. If that returns an address we'll use Tailscale. If Tailscale isn't installed, tell me it's the recommended option and ask whether I want to install it or use something else..mcp.json in this project with an "intercom" server: command npx, args ["-y", "claude-intercom"], and env MY_ROLE, REMOTE_HOST (the other machine plus :8788), INTERCOM_SECRET, INTERCOM_PORT set to 8788. If .mcp.json already exists, merge the intercom entry into it instead of overwriting the file. Make sure .mcp.json is gitignored, it holds the secret.claude --dangerously-load-development-channels server:intercom and explain that the flag is needed because the channels capability is still experimental, and that messages only arrive while both sides are running.send_message reports sent / delivered-to-process / answered separately, so "delivered" means the remote process accepted it, not that the other Claude has read it.Don't invent configuration keys. The only environment variables are MY_ROLE, REMOTE_HOST, INTERCOM_SECRET, INTERCOM_PORT and INTERCOM_SEND_TIMEOUT_MS.
Prefer to do it by hand? The manual steps are below.
Nothing to install. npx fetches it on first run, on both machines.
You do need Bun on your PATH — the server uses Bun.serve for its HTTP listener, and the npx entry point hands off to it.
Prefer to run from source?
git clone https://github.com/MuhammadTalhaMT/claude-intercom.git
cd claude-intercom bun install
Then use "command": "bun" with "args": ["/path/to/claude-intercom/intercom.ts"] in the config below instead of the npx form.
Copy the example config into your project's .mcp.json.
First generate a secret, and use the same value on both machines:
openssl rand -base64 32
Then export it in the shell you launch Claude Code from, rather than typing it into the config:
export INTERCOM_SECRET='the-value-you-just-generated'
.mcp.json is a project file, and project files get committed. Claude Code expands ${VAR} in .mcp.json — in command, args, env, url and headers — so the config below can be checked in and shared with your teammate while the secret itself never leaves your environment.
Machine A (e.g. backend — static IP or VPS):
{
"mcpServers": { "intercom": { "command": "npx", "args": ["-y", "claude-intercom"], "env": { "MY_ROLE": "backend", "REMOTE_HOST": "MACHINE_B_IP:8788", "INTERCOM_SECRET": "${INTERCOM_SECRET}", "INTERCOM_PORT": "8788" } } } }
Machine B (e.g. frontend — can be behind NAT):
{
"mcpServers": { "intercom": { "command": "npx", "args": ["-y", "claude-intercom"], "env": { "MY_ROLE": "frontend", "REMOTE_HOST": "MACHINE_A_IP:8788", "INTERCOM_SECRET": "${INTERCOM_SECRET}", "INTERCOM_PORT": "8788" } } } }
On both machines:
claude --dangerously-load-development-channels server:intercom
In either Claude Code session:
"Send a message to the other developer asking what API endpoints are available for the dashboard."
Claude will use the send_message tool to POST the message to the other machine. The other Claude receives it as a channel notification and responds.
Use [Tailscale](https://tailscale.com). Install it on both machines and they get stable private addresses on your own tailnet. Then point each side at the other's tailnet address:
"REMOTE_HOST": "other-machine:8788"
This is strictly better than exposing a port to the internet: no public listener, no port forwarding, the address doesn't change when your ISP reassigns your IP, and device identity is enforced by Tailscale rather than resting entirely on a shared string. Set INTERCOM_HOST to your tailnet address — or to 127.0.0.1 if you are also fronting it with a tunnel — to be certain nothing outside can reach it at all.
Alternative: ngrok
If you can't use Tailscale, ngrok still works:
# On the machine behind NAT
ngrok http 8788
"REMOTE_HOST": "your-subdomain.ngrok-free.app"
ngrok hostnames are detected and switched to HTTPS automatically. For any other tunnel — Cloudflare, Caddy, a reverse proxy of your own — write the scheme into REMOTE_HOST explicitly (https://your-host), or the secret goes out over cleartext HTTP.
Note this does put a publicly reachable endpoint in front of your Claude session, gated only by the shared secret — pick a strong one, and consider INTERCOM_HOST=127.0.0.1 so only the tunnel can reach the listener.
send_messageSends a message and returns immediately with an id. It does not wait for an answer — the reply arrives later as its own inbound message.
| Argument | Required | Description |
|---|---|---|
message | Yes | The text to send |
replyTo | No | The id of the incoming message this answers, so the sender can correlate it |
expectReplyWithin | No | How long a reply should reasonably take: "30s", "5m", "2h" |
The acknowledgement deliberately does not claim the other developer received it. An HTTP 200 proves the remote *process* accepted the message, not that the other Claude ever read it.
check_messageAnswers the question a fire-and-forget channel otherwise can't: is this reply slow, or is it never coming? Pass an id, or omit it to list everything outstanding.
Every message sits in one of three states:
| State | Meaning |
|---|---|
sent | We tried, but the remote process never acked it. The other machine is probably unreachable |
delivered-to-process | Their intercom took it. Their Claude may or may not have read it — that session could be idle, closed, or out of usage |
answered | A reply came back carrying replyTo for this id |
expectReplyWithin is what makes "overdue" mean anything, and it's per message rather than one global timeout — so a quick endpoint lookup and a long investigation aren't judged on the same clock.
| Environment Variable | Required | Default | Description |
|---|---|---|---|
MY_ROLE | Yes | developer-a | Label for this instance (appears in message tags) |
REMOTE_HOST | Yes | localhost:8789 | Address of the other machine (host:port or tunnel URL). Include https:// for any TLS tunnel that isn't ngrok |
INTERCOM_SECRET | Yes | *none* | Shared secret — must match on both sides. There is no default: unset, left as a docs placeholder, or an unexpanded ${VAR}, and the intercom refuses to pair |
INTERCOM_PORT | No | 8788 | Port to listen on for incoming messages |
| INTERCOM_HOST | No | 0.0.0.0 | Interface to b
Only the beginning is shown; read the rest in the repo