Skip to content

About

Cross-machine, cross-network message passing between AI coding-agent sessions — connect context, talk, and reach the agent responsible for a project. Built on Claude Code's own cross-session messaging, exposed as MCP tools.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agents-msger

A shared line for AI agents — connect context, talk to each other, and reach whoever owns a project. Across machines, across networks.

license python python deps requires status agents


The problem

Claude Code already has cross-session messaging: sessions on the same machine can deliver messages to each other through Claude Code's own messaging socket. But that stops at the edge of one machine. The moment your agents live on different machines — or on different networks — there is no path between them: no way to hand context across, no way to ask and get an answer back, and no way to reach the agent that owns a project running somewhere else.

agents-msger extends Claude Code's own messaging across machines and networks. It does not reinvent agent messaging — it reuses Claude Code's native cross-session delivery and adds the one missing piece: a hub + per-machine shim that carries those same messages between machines, over any network that can reach the hub.

What it does

  • 🔗 Connect context. Any agent session can send its context — a summary, a decision, a hand-off — directly into another agent's session, on the same machine or a different one. The receiving agent picks it up on its next turn.
  • 💬 Communicate. Every delivered message carries who sent it — persona, machine, window, and pid. So a back-and-forth is natural: the recipient knows exactly which agent (and which session) to answer, and replies by addressing that sender back.
  • 🎯 Reach the responsible agent. Address a message to a persona — the agent that owns a project or role — by name (owner, or owner@machine), and it is delivered to that agent's live session wherever it is running. "Ask whoever is responsible for X" becomes a first-class, routable action.
  • 🧭 Never lose the right session. Agents routinely fail to find each other: a persona isn't one session — the same agent may be open in several tmux panes or windows, or on several machines, and name-based addressing picks the wrong one or none. agents-msger keys every session by its unique pid, so a name is only a soft label that never collapses two sessions together. You always reach the exact session you mean (owner@machine#<pid>), several panes of the same persona are each addressable, and a dead or stale session never shadows the live agent.

This makes agents-msger a substrate for multi-agent orchestration: an orchestrator agent discovers who is live with relay_who, delegates to the agent that owns a project, and collects the reply — across machines, through three tools.

See it in action

One agent hands a task to the agent responsible for it on another machine; that agent receives it as a Message from @… turn, acts, and replies through the relay:

A two-agent conversation over agents-msger

Starting the hub and a shim, and listing who is reachable:

Running the hub and shim, then relay_who

Names and machines are placeholders.

Supported agents

Agent runtime Status
Claude Code ✅ Supported
OpenAI Codex 🚧 Planned
Other MCP-capable agents 🚧 Planned

The name is plural on purpose: the design is runtime-agnostic and aims to let any AI agent join the same line. Today, Claude Code sessions can send and receive; other runtimes are on the roadmap.

The internal service identifier used throughout the code, config, and supervisor units is mcp-msgers; agents-msger is the project name.

How it works

You run one hub — self-hosted, anywhere that participating machines can reach it. It holds the only registry and routing table. Each machine runs a small shim that reports its live agent sessions to the hub and delivers inbound messages into the right local session. Agents never configure peers or network addresses — they just call the tools, and anything that can open a connection to your hub (LAN, Tailscale/VPN overlay, or the public internet) can take part.

  agent session A (machine-a)                        agent session B (machine-b)
   │  relay_send(to="owner@machine-b")                  ▲  (message arrives next turn)
   ▼  (MCP tool call)                                   │  (delivered into the session)
   shim (machine-a)  ───►  ┌───────────────┐  ◄───────  shim (machine-b)
                           │   the hub     │
   shim (machine-a)  ───►  │ registry /    │  ◄───────  shim (machine-b)
      (heartbeat)          │ routing       │              (heartbeat + long-poll)
                           └───────────────┘

Step by step, when agent A on machine-a messages the agent that owns a project on machine-b:

  1. Discovery (no config). On each machine the shim scans the local agent session registry and learns every live session: its owner persona (derived from the session's working directory), its process id, and the messaging socket it listens on. Nothing is hand-configured.
  2. Heartbeat. Every few seconds each shim sends that list to the hub, so the hub holds a fresh, authoritative picture of which agents are reachable right now — and marks a session not-alive the moment it stops appearing.
  3. Send. Agent A calls relay_send(to="owner@machine-b", …). Its local shim attaches the sender's identity automatically — machine, tmux window, and pid, recovered by walking its own process tree — and POSTs the message to the hub. The agent supplied only who to reach.
  4. Routing & resolution. The hub looks up owner on machine-b. If that owner has one live session, it wins; if several, the newest — or the exact one named with #session. If the owner has no live session, the call fails loudly (ok:false), never a silent "queued".
  5. Long-poll delivery. machine-b's shim is holding an open long-poll to the hub; the queued message returns immediately. The shim resolves that owner's socket locally (it never trusts a socket path from the network) and writes the message, in Claude Code's own native format, into the socket Claude Code opened for that session.
  6. Arrival. On its next turn, Claude Code surfaces the message in the owner's session as a Message from @<sender> turn, carrying the sender's identity (from-name, plus from-window and from-pid), so the owner knows exactly who and where it came from.
  7. Replying. There is no magic reverse channel: because the message says exactly who and where it came from, the owner replies the same way — by addressing the original sender back (relay_send(to="alice@laptop", …), or #<pid> to hit that exact session).

Two liveness signals keep this honest: relay_status() distinguishes "that agent's machine is down" from "wrong address", and a session whose process is alive but whose socket went missing (e.g. just after a reboot) is surfaced explicitly rather than silently dropped.

Requirements

  • Python 3.8+ — standard library only, no third-party packages. The hub and shim run on a stock python3.
  • Claude Code on every participating machine — this is the real dependency. agents-msger does not implement messaging; it rides on Claude Code's own cross-session messaging, which means it relies on Claude Code internals that are not a stable public API and may change between Claude Code versions:
    1. The messaging socket — created by Claude Code, not by this tool. Each interactive Claude Code session opens and listens on a Unix-domain socket at /tmp/cc-socks/<pid>.sock (macOS) or $XDG_RUNTIME_DIR/cc-socks/<pid>.sock (Linux, e.g. /run/user/<uid>/… — tmpfs, so it is cleared on reboot). The shim only connects to it to deliver.
    2. The session registry — also written by Claude Code. Claude Code writes a <pid>.json record per session under $CLAUDE_CONFIG_DIR/sessions (and/or ~/.claude/sessions); the shim reads it to discover live sessions (pid, messagingSocketPath, cwd, name, sessionId, startedAt, kind, runtime).
    3. The native message format. The shim writes the exact payload Claude Code expects on that socket (a type: "user" message carrying a <cross-session-message> envelope, priority: "next"), so Claude Code surfaces it as a Message from @<sender> turn.
  • crossSessionInbound: "accept" must be set in a receiving session's settings; otherwise Claude Code holds cross-session input instead of delivering it.

Not to be confused with a separate helper that merely links session-registry directories to make sessions addressable — agents-msger is the cross-machine transport layer, and the socket/registry themselves are Claude Code's.

Getting started

Clone the repo onto each machine.

1. Run the hub once, on one machine:

python3 hub.py --port 8465

2. Run a shim on every machine. Write ~/.config/mcp-msgers/config.json with { "host": "<name>", "hub_url": "http://<hub-address>:8465", "role": "shim" }, then:

python3 shim.py serve

3. Register the MCP tools in each machine's agent client:

{
  "mcpServers": {
    "agents-msger": {
      "command": "python3",
      "args": ["/absolute/path/to/shim.py", "mcp"]
    }
  }
}

Or with the Claude Code CLI:

claude mcp add agents-msger -- python3 /absolute/path/to/shim.py mcp

MCP tools

Tool What it does
relay_send(to, message, from_name?) Send to owner / owner@machine / owner@machine#session. Fails loud if the target has no live session. The sender's identity is attached automatically.
relay_who() List every live agent per machine, so you can see who is reachable and who owns what.
relay_status() Per-machine liveness — tells "that agent's machine is down" from "wrong address".

Roadmap

  • Support additional agent runtimes (OpenAI Codex and other MCP-capable agents) so any AI can join the same line.
  • Richer context hand-off (structured payloads, not just text).
  • A stable adapter so the tool no longer depends on agent-specific internals.
  • Authentication and hardening for use beyond a trusted network.

Project status

Early preview. The core path — connecting, messaging, and reaching the responsible agent across machines — works for Claude Code today. It is designed to run on a trusted, private network (e.g. a personal VPN/overlay); it is not yet hardened for untrusted networks. APIs may change; pin a commit if you depend on it.

Contributing

Issues and pull requests are welcome. Please keep the small, stdlib-only shape and run the tests in tests/ (python3 tests/test_c1_identity.py).

License

MIT © agents-msger contributors.


Keywords: MCP · Model Context Protocol · AI agents · agent orchestration · multi-agent orchestration · orchestrator · AI agent coordination · multi-agent · agent-to-agent · agent communication · shared context · context hand-off · cross-machine · cross-network · messaging · Claude Code · CLI

About

Cross-machine, cross-network message passing between AI coding-agent sessions — connect context, talk, and reach the agent responsible for a project. Built on Claude Code's own cross-session messaging, exposed as MCP tools.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages