agent-intercom
A local, zero-dependency MCP mailbox that lets coding agents (Claude Code, Codex CLI, Antigravity, or any MCP client) message each other and receive mail in their open sessions.
mail_send(to, body, reply_to?)— drop a message in another agent's inbox; usemail_peersnames forto, and setreply_towhen answering a specific message id.mail_check(wait_seconds?)— read and consume your own new messages; withwait_seconds(max 300) it blocks until one arrives instead of polling.mail_peers()— list known agent names and when each last started.Live push (optional) — with the daemon installed, new mail lands as a fresh turn in an open session (Claude Code's peer socket, Codex
turn/start,agy agentapi send-message), so nobody polls.Exactly-once delivery — messages are claimed by rename before push or read; a failed push returns the file to the inbox and retries.
Targeted addressing — pick a session via
claude.<session>,codex.<thread-id>,gemini.<conversation>, or routes in~/.agent-mail/routes.json.Cross-machine bridging —
bridge.shmoves mail over SSH to agents on hosts with no shared filesystem.Caveats — local, unauthenticated mailbox; treat inbox content as untrusted input, and push relies on undocumented CLI internals that updates can break.
Click on "Deploy 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., "@agent-intercomask codex to review the diff in src/parser.ts and wait for its reply"
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.
Let Claude Code, Codex CLI and Antigravity (Gemini) message each other, and land each message straight in the other agent's open session.
If it saves you time, a ⭐ helps other people find it.
Get started · See it work · How push works · Across machines · CLI · Security · Contributing
Get started
npx agent-intercom installUsing Claude Code only? Install it as a plugin instead:
/plugin install agent-intercom --marketplace iambashar/agent-intercomOn Claude Code older than 2.1.275: /plugin marketplace add iambashar/agent-intercom, then /plugin install agent-intercom@agent-intercom. The plugin also adds a skill that teaches Claude the mailbox conventions.
The npx command registers the MCP server with every CLI it finds. Restart them, and each agent gets three tools: mail_send, mail_check and mail_peers. Then ask in plain words:
You → Claude: Ask codex to review the diff in
src/parser.tsand wait for its answer.
Turn on live push so nobody has to poll. Install it globally, because the daemon needs a stable path:
npm i -g agent-intercom
agent-intercom install --pushCLI | Registration | Extra for push |
Claude Code |
| nothing; uses Claude Code's peer socket |
Codex CLI | a managed block in | nothing; uses the Codex app-server daemon |
Antigravity ( |
| a session hook in |
Use --only claude|codex|gemini for one CLI, and --local to pin a git checkout instead of npx. agent-intercom uninstall removes all of it, including the push daemon.
The oldgemini CLI no longer accepts personal Google AI Pro sign-ins; Google moved those users to the Antigravity CLI (agy). Its agent is named gemini here by default.
Related MCP server: Escritório
See it work
Neither agent polls. The request appears in Codex as a new turn the moment it is sent, and the reply lands in Claude the same way.
What you get
Supported agents
Agent | Mailbox name | How a message reaches the open session |
| Claude Code's local peer-messaging socket, the channel | |
| The shared app-server daemon the Codex TUI runs on: | |
|
| |
Any other MCP client | anything | No push. It reads with |
Tool | What it does |
| Drop a message in another agent's inbox |
| Read and consume your messages; with |
| List known agents |
How push works
sequenceDiagram
autonumber
participant C as Claude Code
participant M as ~/.agent-mail/codex/inbox
participant P as pushd
participant X as Codex CLI (open session)
C->>M: mail_send(to: "codex", body)
M-->>P: file appears (fs.watch, no polling)
P->>M: claim: rename to <id>.json.pushing
P->>X: turn/start with the message
X-->>P: turn accepted
P->>M: move to read/
Note over X: Codex works on it, then replies with mail_send(to: "claude")Delivered once. The daemon renames a message before pushing it, and
mail_checkrenames before reading. Whoever wins the rename delivers it.Fails safe. A failed push puts the file back in the inbox and retries after 30 s. If no session is open, the message waits for
mail_check.Addressing. Pick a session with
claude.<session-name>,codex.<thread-id-prefix>orgemini.<conversation-prefix>. Otherwise the most recently active session gets it, or the one named in~/.agent-mail/routes.json:{ "claude": "api-server", "codex": "019f018a" }
Push relies on undocumented internals of all three CLIs, and an update can change them without notice. When that happens, pushes fail, get logged, and the mail falls back to the inbox. Protocol details:docs/live-push.md.
Claude Code: docs/claude-monitor.md.
agent-intercom watch claudeunder the Monitor tool wakes the session when mail arrives.Codex: docs/codex-listen.md. A listener prompt that loops on
mail_check(wait_seconds=300).
Across machines
Agents on a machine with no shared filesystem, such as a GPU server or an HPC cluster, join over SSH with bridge.sh. It moves each message to the machine its recipient lives on, and pulled mail is pushed like any other.
BRIDGE_HOST=gpu-box REMOTE_AGENTS="claude-gpu" ./bridge.shflowchart LR
subgraph laptop["💻 Laptop"]
A[claude] & B[codex] & G[gemini]
end
subgraph gpu["🖥️ gpu-box"]
R[claude-gpu]
end
laptop <-- "bridge.sh · rsync over SSH" --> gpuMore: docs/remote-bridge.md.
More than one session per CLI
Names are just AGENT_NAME. Give each session its own, for example claude-api and claude-web:
npx agent-intercom install --only claude --claude-name claude-apiCLI
agent-intercom install [--only claude|codex|gemini] [--claude-name N] [--codex-name N] [--gemini-name N] [--local] [--push]
agent-intercom uninstall MCP entries, agy hook and push daemon
agent-intercom push install push daemon as a login service (launchd / systemd --user)
agent-intercom push uninstall
agent-intercom push run push daemon in the foreground
agent-intercom status unread/read counts per agent
agent-intercom watch <name> one line per new message, without consuming it
agent-intercom serve the MCP server on stdioSecurity
This is a local mailbox with no authentication. Any process running as you can write to ~/.agent-mail/*/inbox, and an agent treats a message as input to act on. With push on, that input reaches your open sessions without you typing anything.
Treat inbox contents as untrusted text. Don't let one agent approve destructive actions because a message told it to.
Pushed messages are labelled
[agent-intercom] message <id> from <sender>. Claude Code also marks them as from another session, not from you.Push reads tokens only your user can read (
~/.claude/sessions/*.key, the agy session token) and talks only to local sockets. Nothing leaves the machine.Claude Code's session socket already accepts any process running as your user, so agent-intercom opens nothing that wasn't reachable before.
See SECURITY.md to report a problem. Set AGENT_MAIL_DIR to move the mailbox, for example into a project folder.
🤝 Contributing
Contributions are welcome, from a typo fix to support for a new agent.
I want to… | Start here |
Fix something small | |
Support another coding agent | |
Report a push that broke after a CLI update | |
Ask a question or pitch an idea |
Read CONTRIBUTING.md before opening a pull request. Everyone here follows the code of conduct.
Develop
git clone https://github.com/iambashar/agent-intercom && cd agent-intercom
npm test # node --test, no dependencies
python3 scripts/build-assets.py # rebuild the README artworkZero runtime dependencies; Node 20+. See CONTRIBUTING.md and the changelog.
MIT licensed · made for people who run more than one coding agent
Available Tools
3 toolsmail_checkRead new messagesA
Fetch the unread messages addressed to you ("agent"), oldest first. Use it when you expect a reply or want to see if another agent wrote to you. Reading consumes the messages: each one is moved to your read folder and is not returned again, so act on or note what you need. With wait_seconds above 0 the call blocks until at least one message arrives or the time runs out. Returns each message as "[] from (re ) at :" followed by its body, or "no new messages". When live push is installed, new mail may already appear in your session without calling this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| wait_seconds | No | How long to wait for a message if the inbox is empty, in seconds (0 to 300). 0 returns immediately. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses the key non-obvious behavior beyond annotations: reading consumes messages by moving them to a read folder and they are not returned again, blocking semantics of wait_seconds above 0, and the exact return format or 'no new messages'. This is exactly the behavioral context annotations (readOnlyHint=false, idempotentHint=false) gesture at but cannot explain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and scope, then adds consumption warning, blocking behavior, and return format in a tight series of sentences. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-param tool with no output schema, the description covers ordering, consumption side effect, blocking semantics, return format, and the live-push caveat – everything an agent needs to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so baseline is 3; the description adds the blocking semantics ('blocks until at least one message arrives or the time runs out') which clarifies the practical effect of wait_seconds beyond the schema's 'how long to wait'. It'd be a 5 with a note on the 300s cap, but the schema already states that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fetch) and resource (unread messages addressed to you), with scope ('agent'), ordering ('oldest first'), and distinguishes itself from siblings by covering inbox consumption rather than peer listing or sending.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for when to call it ('when you expect a reply or want to see if another agent wrote to you') and warns that live push may make calling unnecessary, but doesn't explicitly compare against mail_peers or mail_send.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_peersList agents on the mailboxARead-onlyIdempotent
List every agent name that has a mailbox here, so you know valid recipients for mail_send. Read-only: it changes nothing. Returns one line per agent: " - last started ", or "never started" for an agent that has mail waiting but has not run yet. Your own name is marked "(you)". A recent start time suggests the agent is active, but it does not guarantee a session is open right now.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/idempotent/non-destructive, but the description adds the return format that no output schema provides: one line per agent, the '<name> - last started <ISO time>' shape, the 'never started' case, the '(you)' marker, and the caveat that a recent start time does not guarantee a live session. That is substantive behavior beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, then safety, then exact return format and caveats. Every sentence earns its place; nothing is redundant padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully specifies the return format and its edge cases, and the caveat about start time vs. live session prevents a real misuse. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to describe and the baseline of 4 applies. No parameters exist to be ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('every agent name that has a mailbox here') and immediately ties it to its purpose as a recipient lookup for mail_send, distinguishing it from both siblings. An agent can tell exactly what this does without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context ('so you know valid recipients for mail_send'), naming the downstream tool it serves. It does not explicitly contrast with mail_check or state when not to call it, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_sendSend a message to another agentA
Deliver a text message from you ("agent") to another coding agent's inbox, for example to hand off a task, ask a question or report a result. Call mail_peers first if you are unsure of the recipient name. To answer a message you received from mail_check, pass its id as reply_to. Each call writes one new message and never edits or removes existing mail. If the recipient has not started yet, the message waits in its inbox. Returns "sent to "; keep the id if you expect a reply that references it.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient agent name as listed by mail_peers, e.g. "codex", "claude" or "gemini". Letters, digits, _ and -, with optional .suffix segments. | |
| body | Yes | Message text, in plain text or Markdown. Include everything the recipient needs, since it cannot see your conversation. | |
| reply_to | No | Optional. The id of the message you are answering (the value in [brackets] from mail_check), so the recipient can match the reply to its question. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=false, idempotentHint=false, destructiveHint=false, openWorldHint=false), and the description goes beyond them with genuinely new traits: each call appends one new message and never edits or removes existing mail, and a message to a not-yet-started recipient queues in its inbox. It also discloses the return format ("sent <id> to <name>"), which no output schema provides. It stops short of stating auth requirements or any rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and use cases, then layered with prerequisites, semantics, and return value in a logical order; every sentence carries information. It is a touch long at five sentences with a trailing tip about keeping the id, which is useful but the least essential element.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return value, the append-only side-effect model, and the queuing behavior for offline recipients. Combined with the prerequisites and reply workflow, an agent has everything needed to invoke it correctly in a single call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds cross-tool meaning the schema cannot: the recipient name must come from mail_peers, and reply_to should be the bracketed id obtained from mail_check. That workflow linkage is real added value over the field-level text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (deliver a text message to another agent's inbox) and immediately enumerates the use cases: hand off a task, ask a question, report a result. It is clearly distinguishable from mail_check (receiving/replies) and mail_peers (name discovery), so an agent can pick it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternatives and the exact conditions that select them: call mail_peers first if unsure of the recipient, and pass mail_check's message id as reply_to when answering. Both the before-call prerequisite and the reply path are spelled out rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.2.6- Changed
mail_check5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / wait_seconds / defaultAdded value: +0 - changed
Input schema / properties / wait_seconds / descriptionPrevious value: -"Block up to this long for a message"New value: +"How long to wait for a message if the inbox is empty, in seconds (0 to 300). 0 returns immediately." - added
Input schema / properties / wait_seconds / maximumAdded value: +300 - added
Input schema / properties / wait_seconds / minimumAdded value: +0
- Changed
mail_peers1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
mail_send6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / body / descriptionAdded value: +"Message text, in plain text or Markdown. Include everything the recipient needs, since it cannot see your conversation." - added
Input schema / properties / body / minLengthAdded value: +1 - changed
Input schema / properties / reply_to / descriptionPrevious value: -"Id of the message you are replying to"New value: +"Optional. The id of the message you are answering (the value in [brackets] from mail_check), so the recipient can match the reply to its question." - changed
Input schema / properties / to / descriptionPrevious value: -"Recipient agent name, e.g. \"codex\" or \"claude\""New value: +"Recipient agent name as listed by mail_peers, e.g. \"codex\", \"claude\" or \"gemini\". Letters, digits, _ and -, with optional .suffix segments." - added
Input schema / properties / to / patternAdded value: +"^[\\w-]+(\\.[\\w-]+)*$"
3 tool updates
v0.1.0- First observed
mail_check - First observed
mail_peers - First observed
mail_send
TDQS
Scored across 3 tools
The three tools map to clearly distinct actions: sending mail, checking/consuming inbox, and listing available peers. There is no overlap—mail_send writes, mail_check reads, and mail_peers is explicitly read-only. An agent can pick the right tool without hesitation.
All tools follow the exact same mail_<verb> pattern: mail_send, mail_check, mail_peers. The convention is predictable, readable, and consistent throughout.
Three tools exactly cover the minimal inter-agent mail model: send, receive, and discover recipients. There is no redundancy and no obviously missing core operation for this scope.
Core lifecycle is covered—compose/send, read/consume, and recipient discovery. Minor gaps exist: there is no tool to retrieve previously read (consumed) mail or view a sent/outbox history, though agents can work around this by acting on messages immediately or saving IDs.
Maintenance
Related MCP Connectors
Shared memory and mail for your AI agents. Verified with Claude Code; other MCP clients in testing.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Give an AI agent its own email address: send, reply, read, and wait for mail.
End-to-end encrypted messaging and work coordination for autonomous AI agents.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables local AI coding agents to message each other on one machine using a durable SQLite mailbox and live-ask tools.9MIT
- AlicenseNot gradedqualityCmaintenanceEnables peer-to-peer messaging and coordination between Claude Code sessions via a shared mail server, with tools for roster, ask, dm, inbox, board, and claim.0ISC
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code, Codex and opencode sessions on the same machine to message each other live over a local pipe, with threaded replies and offline queuing, and to delegate or spawn one another as background subagents. Messages persist in SQLite and any running server can take over as broker, so peers stay reachable without a daemon.19 npm3MIT
- AlicenseAqualityAmaintenanceLocal agent-to-agent messaging and coordination for coding sessions on one machine, through MCP and a CLI. Includes threaded mail, full-text search, per-repository agent rosters, advisory file reservations, and optional notifications. Integrations cover Claude Code, Codex, Cursor, Devin, Grok, OpenCode, and Antigravity. Standalone agents and T3 Code sessions can share the same local server.2221MIT