
Intercom
io.github.MuhammadTalhaMT由 GitHub 帳號 MuhammadTalhaMT 發布v2.1.0更新於 Oct 24, 2026
Relays messages between two Claude Code sessions on different machines using the Channels API
概覽
在不同機器上的兩個 Claude Code 工作階段之間搭橋,讓一個助理透過 HTTP 傳訊息給另一個,並以頻道通知形式收到回覆。
- 可以做什麼
- 向另一台機器上配對的 Claude Code 工作階段傳送訊息,可標註所回覆的來信編號以及預期回覆時間
- 查詢尚未完成的消息,查看狀態是已送出、已送達行程還是已回答
- 在本地 Claude Code 對話中以頻道通知形式接收來信
- 提供免驗證的健康檢查端點,回報本執行個體的角色與版本
- 適用情境
- 適合兩位開發者各自在自己的機器上執行 Claude Code、需要兩個工作階段直接互相詢問 API、資料結構或實作細節,而不必再透過聊天工具轉述的情況。也適用於 Windows、容器與主機之間,或原生跨工作階段訊息無法使用的非 Anthropic 供應商環境。
- 執行需求
- 透過 npx 以 stdio 在本機執行,需要 PATH 中有 Bun,且 Claude Code 版本為 2.1.80 或更新。兩台機器必須能透過 HTTP 互相連線,建議使用 Tailscale。需要設定 MY_ROLE、REMOTE_HOST(host:port 或通道網址)與 INTERCOM_SECRET,且兩端必須一致;INTERCOM_PORT、INTERCOM_HOST、INTERCOM_SEND_TIMEOUT_MS 為選用。啟動 Claude Code 時需加上開發頻道參數。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Intercom,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Claude Intercom
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.
[intercom-demo]What Intercom does that native can't
Claude Code has native cross-session messaging now. Here's where Intercom is still the answer:
- Two different people. This is the big one. Native connects your sessions — the inbox is tied to your own OS user and cross-machine delivery rides your own Remote Control. A backend dev on their laptop and a frontend dev on theirs are two accounts, and native can't join them. That two-person hotline is exactly what Intercom was built for.
- Native Windows. Native messaging is macOS and Linux only. Intercom is Bun over HTTP and doesn't care what OS you run.
- Your network, not Anthropic's. Native cross-machine messages relay through Anthropic servers. Intercom POSTs straight over your own network, VPN or tunnel.
- Any provider. Works on Bedrock, Vertex and Foundry, and in telemetry-disabled environments, where native messaging is switched off.
- Container to host. Native discovery works through files on disk, so a session in a container and one on the host can't see each other. Intercom just needs a reachable port.
- Honest delivery.
send_messagereportssent,delivered-to-processandansweredas three separate states, plus acheck_messagetool. 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.
Why?
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.
Architecture
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.
Requirements
- Claude Code v2.1.80 or later
- Bun runtime
- Both machines must be able to reach each other over HTTP. Tailscale is the recommended way — see Connecting the two machines
Set it up with Claude
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.
Prefer to do it by hand? The manual steps are below.
Quick Start
1. Install
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?
Then use "command": "bun" with "args": ["/path/to/claude-intercom/intercom.ts"] in the config below instead of the npx form.
2. Configure
Copy the example config into your project's .mcp.json.
First generate a secret, and use the same value on both machines:
Then export it in the shell you launch Claude Code from, rather than typing it into the config:
.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):
Machine B (e.g. frontend — can be behind NAT):
3. Start
On both machines:
4. Talk
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.
Connecting the two machines
Use Tailscale. 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:
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:
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.
Tools
send_message
Sends a message and returns immediately with an id. It does not wait for an answer — the reply arrives later as its own inbound message.
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_message
Answers 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:
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.
Configuration
How It Works
- Claude Code spawns
intercom.tsas a subprocess (MCP server over stdio) - The script declares
claude/channelcapability — this registers it as a Channel - It starts an HTTP server listening for incoming messages
- When a message arrives (authenticated via shared secret), it calls
mcp.notification()withmethod: 'notifications/claude/channel' - Claude Code surfaces the notification in the conversation as a
<channel>tag, carrying the message id - Claude reads it and can reply using
send_messagewithreplyToset to that id, which POSTs to the remote machine - The original sender matches the
replyToagainst its own outbound record and marks that messageanswered
The stdio leg is not an implementation detail you can swap for HTTP. It is what attaches the server to a specific live Claude Code session — the claude/channel capability is registered over that connection, and it's the reason mcp.notification() lands in a conversation at all. Host this remotely and the notification goes to whatever MCP client connected instead.
Security
- Shared secret authentication:
POST /messagerequires anX-Intercom-Secretheader matching the configured secret, compared in constant time. Anything else gets a401 Unauthorized.GET /healthis deliberately not authenticated, so you can verify a tunnel end to end — it reports this instance's role and version to anyone who asks, so treat a reachable intercom as discoverable. - The secret is only as private as the transport: it is sent as a plaintext header on every message. Over Tailscale (WireGuard) or an HTTPS tunnel that is fine. Over plain HTTP on a shared network, anyone on the path can read it and then use it.
- No replay protection: messages carry an
idand atimestamp, but neither is checked for freshness or reuse. Someone who captures a single authenticated request on a cleartext link can resend it verbatim, as often as they like. - No default secret:
INTERCOM_SECREThas no fallback value. Leave it unset, leave a docs placeholder in place, or reference a${VAR}you never exported, and the intercom starts unpaired — it binds no port andsend_messagerefuses, explaining why. The unexpanded-${VAR}case matters because Claude Code passes a missing variable through as literal text, which would otherwise give both machines the same guessable secret. - Inbound is treated as data, not instructions: the server tells the receiving Claude that a channel message comes from another person's session — it can't approve anything, can't change configuration, a slash command in the text is inert, and requests for credentials or env files should be refused and surfaced to you.
- No data persistence: Messages are forwarded in real-time and not stored.
- Configurable bind address: By default listens on
0.0.0.0for cross-machine access. SetINTERCOM_HOST=127.0.0.1when a tunnel is doing the reaching, so only the tunnel can connect.
Warning: Those instructions are a default, not a boundary. You cannot fix prompt injection with prompt instructions — anyone holding your secret and address can put text into your Claude session, and the only real limits are that session's own permission prompts. Native cross-session messaging enforces this properly with hold/accept/refuse inbound controls; this does not. Use a strong secret, keep it off the public internet, and don't pair with a peer you wouldn't hand a terminal to.
Endpoints
POST /message body:
id and replyTo are optional — a message without them still delivers, it just can't be correlated.
The body is schema-validated before anything reaches your session. content is required and capped at 32,000 characters; id and replyTo must look like machine ids ([A-Za-z0-9_-], ≤64); role and timestamp may not contain < > " ' or any Unicode control, zero-width, or bidi-override character, because those are what a sender would use to forge the <channel …> wrapper the message is rendered inside. Anything else gets a 400, and a body over 64 KB gets a 413.
Use Cases
- Backend + Frontend collaboration: Backend Claude answers API questions from frontend Claude using the actual codebase
- Monorepo with split teams: Different Claude sessions working on different packages can coordinate
- Code review relay: One Claude reviews code and sends findings to the author's Claude session
- CI/CD notifications: Point your CI webhook at the intercom to push build results into a Claude session
Star History
[Star History Chart]License
MIT
來源:README.md,提交 5a25ffe
工具
0版本歷史
1- v2.1.0最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
