Skip to main content
Glama

npm CI License: MIT GitHub stars

Node 20+ Zero dependencies MCP Claude Code Codex CLI Antigravity

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 install

Using Claude Code only? Install it as a plugin instead:

/plugin install agent-intercom --marketplace iambashar/agent-intercom

On 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.ts and 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 --push

CLI

Registration

Extra for push

Claude Code

claude mcp add, user scope

nothing; uses Claude Code's peer socket

Codex CLI

a managed block in ~/.codex/config.toml (backed up first)

nothing; uses the Codex app-server daemon

Antigravity (agy)

agy mcp add

a session hook in ~/.gemini/config/hooks.json

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.

NOTE

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

Claude Code's local peer-messaging socket, the channel SendMessage uses between sessions. Arrives labelled as from another session.

codex

The shared app-server daemon the Codex TUI runs on: turn/start, or turn/steer when a turn is already running.

gemini

agy agentapi send-message into the conversation. Each session registers itself once through a hook.

Any other MCP client

anything

No push. It reads with mail_check, or blocks with mail_check(wait_seconds=300).

Tool

What it does

mail_send(to, body, reply_to?)

Drop a message in another agent's inbox

mail_check(wait_seconds?)

Read and consume your messages; with wait_seconds (max 300) it blocks until one arrives

mail_peers()

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_check renames 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> or gemini.<conversation-prefix>. Otherwise the most recently active session gets it, or the one named in ~/.agent-mail/routes.json:

    { "claude": "api-server", "codex": "019f018a" }
WARNING

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 claude under 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.sh
flowchart 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" --> gpu

More: 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-api

CLI

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 stdio

Security

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.

Good first issues Help wanted Discussions

I want to…

Start here

Fix something small

Good first issues

Support another coding agent

docs/adding-an-agent.md

Report a push that broke after a CLI update

Bug report

Ask a question or pitch an idea

Discussions

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 artwork

Zero runtime dependencies; Node 20+. See CONTRIBUTING.md and the changelog.

MIT licensed · made for people who run more than one coding agent

⭐ Star · 🐛 Report a bug · 💡 Discuss

Available Tools

3 tools
mail_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
wait_secondsNoHow long to wait for a message if the inbox is empty, in seconds (0 to 300). 0 returns immediately.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 mailboxA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesRecipient agent name as listed by mail_peers, e.g. "codex", "claude" or "gemini". Letters, digits, _ and -, with optional .suffix segments.
bodyYesMessage text, in plain text or Markdown. Include everything the recipient needs, since it cannot see your conversation.
reply_toNoOptional. 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

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 3 tool updatesv0.2.6
    • Changedmail_check5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / wait_seconds / default
        Added value: +0
      • changedInput schema / properties / wait_seconds / description
        Previous 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."
      • addedInput schema / properties / wait_seconds / maximum
        Added value: +300
      • addedInput schema / properties / wait_seconds / minimum
        Added value: +0
    • Changedmail_peers1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedmail_send6 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / body / description
        Added value: +"Message text, in plain text or Markdown. Include everything the recipient needs, since it cannot see your conversation."
      • addedInput schema / properties / body / minLength
        Added value: +1
      • changedInput schema / properties / reply_to / description
        Previous 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."
      • changedInput schema / properties / to / description
        Previous 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."
      • addedInput schema / properties / to / pattern
        Added value: +"^[\\w-]+(\\.[\\w-]+)*$"
  2. 3 tool updatesv0.1.0
    • First observedmail_check
    • First observedmail_peers
    • First observedmail_send

TDQS

A4.7/5.0

Scored across 3 tools

Disambiguation5/5

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.

Naming Consistency5/5

All tools follow the exact same mail_<verb> pattern: mail_send, mail_check, mail_peers. The convention is predictable, readable, and consistent throughout.

Tool Count5/5

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.

Completeness4/5

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

ActivityNo data
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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 npm
    3
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Local 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.
    2
    22
    1
    MIT