Skip to main content
Glama

Agent Wire

Let Codex and Claude Code talk to each other.

Agent Wire gives coding agents a common address book, inbox, reply API, and shared work list. Each agent reports its own task and status. It runs locally, stores messages and reports in SQLite, and delivers messages through each runtime's own session interface. Both agents use the same MCP tools. It has no dependency on a terminal manager or tab labels.

flowchart LR
    Codex <-->|MCP tools| Broker[Agent Wire · local broker]
    Claude[Claude Code] <-->|MCP tools| Broker
    Broker -->|App-server tool output| Codex
    Broker -->|Session inbox| Claude

Alpha software for Linux and macOS with Python 3.11+. Native adapters do not gate enrollment, reporting, or delivery on runtime versions. They validate live native session identities and sockets; incompatible protocol requests still fail. Windows, remote hosts, Claude Channels, and automatic runtime launching are outside this first release.

Set it up with your agent

Paste this into Claude Code or Codex. Run it once in each client you use.

Set up Agent Wire (https://github.com/kevinmanase/agent-wire) for this
coding client on my machine. It lets my Claude Code and Codex sessions
message each other and share a work list. Read
https://github.com/kevinmanase/agent-wire/blob/main/docs/setup.md for detail.

1. Install the CLI if `agent-wire --version` fails:
   `uv tool install git+https://github.com/kevinmanase/agent-wire.git`
   (or pip into a venv). Use its absolute path in every config below.
   After upgrading, restart the broker so it runs the same version as the hooks.
2. Make sure one broker runs: if `agent-wire ping` fails, install
   `agent-wire serve` as a user service (launchd on macOS, a systemd user
   unit on Linux) that restarts on failure, then check `agent-wire ping`.
3. Add a user-level stdio MCP server named `agent_wire` running
   `<abs path>/agent-wire mcp`, with no `--identity`, so all conversations share it.
4. Add hooks that run `<abs path>/agent-wire hook claude` (or `hook codex`),
   timeout 30: `SessionStart` (matcher `startup|resume|clear|compact`),
   `UserPromptSubmit`, `Stop`, and `PreToolUse`, `PostToolUse`,
   `PermissionRequest` (matcher `.*`). Claude hooks record the sender's
   permission mode. For Codex, the broker reads its native session metadata,
   including mailbox enrollments that use the actual Codex thread UUID.
   Claude checks the sender's mode before delivering to a bypass session.
5. Copy `skills/agent-wire/SKILL.md` from the repo into this client's
   skills directory (`~/.claude/skills/agent-wire/` or `~/.codex/skills/agent-wire/`).

Rules: merge into existing settings; never overwrite other servers or hooks.
Never change permission modes or inbound-message policy, never commit or
print identity files, and never clear a conversation. Finish by running
`agent-wire sessions --table` and telling me what to restart or approve so
the new hooks and MCP tools load.

Related MCP server: set-agent-comm

One orchestrator, several agents

I mainly talk to one orchestrator. It keeps track of the work, coordinates the other agents, and brings questions back to me. A worker can stay in Claude Code while another uses Codex, with each keeping its native tools, context, and permission controls.

Agent Wire supplies the shared work list and messages. The orchestrator is a role you give an agent, not a scheduler built into Agent Wire. It can read reports, ask an enrolled worker for an update, and follow up on a reply.

Outside a coding agent

Read the same work list from an ordinary shell, without making a model call:

agent-wire sessions --table

The table shows each enrolled session's runtime, reported status, recent contact, freshness, and task. Use it to see who is working, waiting, or blocked. Freshness measures recent contact. The * marker means a new prompt arrived since the report. Use the JSON output's reported_at field to check the report's age; fresh heartbeats can coexist with old reports.

Inside a coding agent

With the MCP server configured, ask your orchestrator:

Read the shared work list. Summarize who is working, waiting, or blocked, and flag stale sessions or reports needing an update. Ask the reviewer for an update on its current task.

The agent can use sessions_list to read reports, agents_list to resolve the intended recipient, and message_send to send the update request. The reviewer uses message_ack and replies with in_reply_to. Each participant publishes its own progress through session_update.

Both interfaces read the same local broker. A reply is useful coordination; tests and review still establish whether the work is finished.

Alongside herdr

I pair Agent Wire with herdr, a terminal workspace manager with a tmux-style workflow. My herdr-customizations repo shows the tab naming setup with a screenshot, a naming skill, and hooks for Claude Code and Codex. The customization is optional; Agent Wire works independently of it.

Quick start

Install from this repository (there is no PyPI release yet):

python3 -m venv .venv
.venv/bin/python -m pip install 'git+https://github.com/kevinmanase/agent-wire.git'
.venv/bin/agent-wire serve

Keep the broker running. In another terminal, discover native sessions:

agent-wire discover

Use the session IDs and socket paths returned by discovery. Enroll each session you want to participate, with a distinct name:

agent-wire register --name coder --runtime codex \
  --session CODEX_THREAD_ID --socket /absolute/path/to/app-server-control.sock
agent-wire register --name reviewer --runtime claude \
  --session CLAUDE_SESSION_ID --socket /absolute/path/to/claude-inbox.sock

Each command returns an identity_file. It contains a private session credential. Use the appropriate file for the sender:

agent-wire send --identity /path/to/coder-identity.json \
  --to reviewer --body 'The interface is ready. Please report any mismatches.'
agent-wire status --identity /path/to/coder-identity.json MESSAGE_ID

The CLI prints JSON. queued and submitted do not mean the recipient read the message. acknowledged means it explicitly acknowledged receipt. A reply records reply_id; it does not prove the requested work is complete.

Use an absolute installed executable path if agent-wire is not on your PATH. All commands accept --state /private/directory before the subcommand.

MCP tools in both agents

Configure a stdio MCP server that runs:

agent-wire mcp --identity /absolute/path/to/this-session-identity.json

Tool

Purpose

agents_list

Find explicitly enrolled recipients

sessions_list

Read the shared task/status list, including freshness

session_update

Replace your own task/status report

session_ask

Set or clear only your ask, keeping the rest of your report

message_send

Send text; set in_reply_to for a reply

messages_read

Read pending messages, optionally after a cursor

message_ack

Acknowledge a received message

message_status

Inspect a message you sent or received

A bound MCP server belongs to one native conversation. Do not share that configuration between unrelated Codex threads: an app-scoped MCP process may serve several conversations. For shared configurations, run agent-wire mcp without --identity and enroll through the optional SessionStart hook; each authenticated tool call supplies that conversation's session_handle. The read-only sessions_list directory needs no credential within the local OS user's private broker socket.

See setup examples for both clients, hook registration, permission behavior, and a model-free two-mailbox walkthrough.

Shared work list

Each agent publishes its task at the start of work, on meaningful changes, before waiting for input, and before finishing. Both read the same list:

agent-wire sessions --table
agent-wire sessions --runtime claude --status working
agent-wire report --identity /path/to/own-identity.json \
  --task 'Implement shared session registry' --status working \
  --repository /path/to/repo --branch feature/session-reports
agent-wire report --identity /path/to/own-identity.json \
  --task 'Ship the API change' --status waiting --lane api --stage REVIEW \
  --role worker --ask-to kevin --ask-kind approve --ask-text 'Approve the merge?'
agent-wire ask --identity /path/to/own-identity.json \
  --to kevin --kind decide --text 'Merge api before mobile?'
agent-wire ask --identity /path/to/own-identity.json \
  --to kevin --kind decide --text 'Merge order?' \
  --option 'api first (recommended)' --option 'mobile first'
agent-wire ask --identity /path/to/own-identity.json --clear

Reports include a task, working/waiting/blocked/idle/done status, optional detail/repository/branch/ticket, and timestamps. They can also name a lane, a stage, a role (main, lead, or worker), and an ask: what the session needs from a person, with to, text, and kind (decide, act, or approve), and optionally 2 to 4 preset answers in options (--option or --ask-option, repeatable; recommended first). The broker records when an ask was first raised and keeps that time while the same ask stays. An ask is a claim, never approval. agent-wire ask and session_ask change only the ask; report still replaces the whole report, ask included. The table shows lane, stage, and a short ask column when any entry has them.

An opt-in Claude hook raises Claude Code's question and plan-approval dialogs as native asks, so a person can answer them from outside the terminal with agent-wire answer <session> --ask-at <raised_at> -- <answer>. See setup. Codex's question tools work the same way through its app server, with the heartbeat hooks; see setup.

To dismiss a stale question you already handled in the agent conversation, run agent-wire dismiss <session> --ask-at <raised_at>. This clears only that ask from the shared report, including any answer not yet relayed. It sends no answer or approval to the agent and leaves the native dialog alone. Like answer, it takes no session credential; local integrations can call ask_dismiss with session and raised_at. A newer question is never cleared by an older dismissal.

Write ticket so a floor can group every report on the same work: the Linear issue key, such as ENG-2649, or <repo>#<number> for the GitHub issue, such as team-floor#11, or for the pull request when there is no issue, such as team-floor#14. Put nothing else in the field: no title and no PR prefix.

Hooks report activity and remind the agent to publish; they never infer task summaries or completion. After a new prompt, the previous report is marked as needing an update. After five minutes without a report or hook heartbeat, the entry is stale. Stale does not mean offline or finished, and idle does not mean done.

Only enrolled sessions appear. Unreported entries stay explicitly unreported; this is not an inventory of every process on the machine. Results are paginated (--after/next_after), stale entries are included by default, and --fresh filters to recent contact. Finished entries are folded away by default: done, no contact for more than 6 hours, no open ask, and no message in flight. The table ends with a line such as 12 finished sessions hidden (--all to show), and --all shows them. Folding only hides entries from the list; it never retires or deletes anything. The CLI prints JSON unless --table is requested. See reporting and hook setup and the optional reporting skill for both agents.

Delivery behavior

  • Messages persist across broker restarts. Recipients explicitly enroll; discovery alone does not enroll them.

  • Codex messages arrive as tool output. Claude messages use its peer inbox and keep its inbound controls.

  • Native adapters never resume old conversations or launch new agents. Re-enrollment retires the previous credential and address.

  • A session ends when its Claude Code or Codex process exits. The broker checks the recorded process ID and start time locally whenever it lists or routes, and retires the session exactly like retire. After /clear, a new Claude Code or --no-daemon Codex session replaces the old one from the same process. On the Codex app server, which plain codex uses, a thread ends when the server unloads it, about a minute after /clear or after its TUI exits, and the broker then retires it the same way.

  • A transport failure after writing begins becomes unknown. It is not automatically retried.

  • Reuse an idempotency key for a retry of the same send. Expiry, bounded inboxes, rate limits, and reply-hop limits constrain loops.

  • Agent Wire does not execute message bodies, forward permission approvals, or clear conversations.

The local OS user is the trust boundary. This is not a sandbox between mutually hostile agents running as the same user. State and the broker socket are private to that user; session credentials prevent accidental sender confusion and scope message access. See security and protocol and adapter notes.

Development and contributions

git clone https://github.com/kevinmanase/agent-wire.git
cd agent-wire
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
.venv/bin/python -m pytest
.venv/bin/ruff check .
.venv/bin/ruff format --check .

Tests use isolated state and fake runtime sockets; no accounts, API keys, or model calls are required. Live runtime checks are separate, explicit exercises. See verification for the tested native paths, a live Codex → Claude → Codex exchange, and both agents publishing shared work reports. Contributions to adapters, cross-platform support, and delivery semantics are welcome. Start with CONTRIBUTING.md.

License

Copyright © 2026 Kevin Manase and Agent Wire contributors.

GNU AGPL version 3 only. You may use Agent Wire commercially. Covered redistribution and modified network-served versions carry reciprocal source-sharing obligations under the license. The license does not require a pull request to this repository; upstream contributions are warmly encouraged.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables local agent-to-agent messaging between Claude Code sessions via file-based channels, with a registry, MCP tools and CLI for sending, reading, and tracking messages.
    2
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to message each other by @nickname via an MCP server, with contacts, presence, and durable delivery across local and remote agents.
    3
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables agents to communicate asynchronously via private inboxes and to ask a human a question and block until answered. Provides MCP tools for sending messages, checking unread messages, and listing peers.
    Apache 2.0