channel open v4.1.0 AI agent harnesses tested end-to-end

Let your agents talk to each other.

agent-bridge lets running AI agent harness sessions push messages to each other across machines — agent-to-agent, not shell-to-shell. Every harness shares the same SSH file transport, while each receiver keeps its own host lifecycle: Claude Code uses an MCP + claude/channel stdio plugin; OpenClaw uses a native openclaw-channel/ gateway plugin. No broker, no cloud, no fresh agents spawned on the remote side.

Transport SSH · ED25519
Delivery push · long-poll
MCP tools 8 · 7 bridge + status
License MIT · macOS · Linux · Windows
01 / Quickstart

One prompt. Paste it into your agent on each machine.

This is the fast path. It works because your local AI agent can read the README, install the CLI, build the MCP server, and register the right channel plugin for its harness.

paste into your agent · each computer
Read the README at https://github.com/EthanSK/agent-bridge and follow
the setup instructions for this computer. Install agent-bridge, run
the setup command, and install the appropriate channel plugin for
this harness. Do everything automatically -- don't ask me questions.
Prereqs (once per machine). macOS: System Settings > General > Sharing > toggle Remote Login ON > click (i) > set “Allow access for” to All users. Optionally toggle “Allow full disk access for remote users”. Linux: sudo systemctl enable --now sshd Windows 10/11: OpenSSH Server is an optional feature; admin users need keys at C:\ProgramData\ssh\administrators_authorized_keys, not the user’s home dir. See the Windows setup section in the README for the consolidated PowerShell script.

After the agents finish installing, photograph the pairing screen on one machine and send the photo to the agent on the other. That’s the pair step; the agents handle the rest.

02 / Why

Agent-to-agent, not shell-to-shell.

Push, not poll

Messages from a remote machine arrive through the right host path: <channel source="agent-bridge"> events in Claude Code, or native OpenClaw channel turns in OpenClaw. No fresh agent spawn on the far side.

Running sessions, not new ones

The bridge connects already-running sessions. Machine A’s bridge_send_message drops a signed file into Machine B’s target inbox; Machine B’s Claude Code or OpenClaw watcher injects it into the live conversation. No fresh claude --print spawned on the far side — that whole shape was removed in 3.0.0.

Peer-to-peer over SSH

Direct machine-to-machine SSH on the ports you already allow. No relay, no broker, no vendor. Tailscale is the recommended off-LAN path (stable 100.x.y.z IPs); plain LAN works great too.

Hardened against zombies

The Claude Code channel-owner MCP child is hardened against benign stdin/stderr/SIGTERM closure, exits on real parent/stdout death, and replays undelivered messages on startup. OpenClaw is hosted separately by the gateway plugin. No shadow ~/.agent-bridge/inbox directories, no fresh remote agent processes.

03 / Install

Manual install, step by step.

Prefer doing it yourself? This is exactly what the quick-start prompt above tells your agent to do. Run these on each machine you want to bridge.

Pair the two machines

Bash CLI

The bash agent-bridge CLI handles setup, pairing, and SSH-level diagnostics. It coexists with the plugin — the plugin drives agent-to-agent messages, the CLI drives the transport.

pairing & diagnostics
# On each machine: enable SSH, generate keys, show pairing screen
agent-bridge setup

# Off-LAN? Install Tailscale on each machine and use its 100.x.y.z IP as internet_host.
# Recommended: no-sudo userspace LaunchAgent. See README "Internet connectivity (Tailscale)"
# for the plist template, ~/.ssh/config SOCKS5 block, and --socket CLI pattern.
brew install tailscale
launchctl load ~/Library/LaunchAgents/com.USERNAME.tailscaled.plist
tailscale --socket="$HOME/.local/share/tailscale/tailscaled.sock" up --accept-dns=false --hostname=MY-MACHINE
agent-bridge config <other-machine> --internet-host 100.x.y.z

# Then photograph the pairing screen on one machine
# and send the photo to the agent on the other. It runs `agent-bridge pair` for you.

# Verify
agent-bridge list
agent-bridge status MacBook-Pro

# Plain remote shell on a paired machine (diagnostics only)
agent-bridge run MacBook-Pro "cd ~/Projects/myapp && git status"
hostname alias mismatch quick fix
# Symptom (OpenClaw logs):
# paired machine "MacBookPro.lan" not found in ~/.agent-bridge/config

BASE="MacBookPro"
ALIAS="MacBookPro.lan"

# Check route label + config sections
tail -200 ~/.openclaw/logs/gateway.log | grep -E "$ALIAS|paired machine|agent-bridge/v2"
grep -nE "^\[$BASE\]$|^\[$ALIAS\]$|^(host|user|port|key|internet_host)=" ~/.agent-bridge/config

# If missing, add [MacBookPro.lan] mirroring [MacBookPro].
# Same idea for MagicDNS names, e.g. [macbookpro.tail52aa3c.ts.net]

Note. agent-bridge run is a plain SSH remote-shell utility — it does NOT invoke an agent. To talk to the running agent on the other machine, use the plugin’s bridge_send_message MCP tool. The old --claude / --codex / --agent flags that spawned a fresh non-interactive agent session on the remote machine were removed in 3.0.0.

Routing labels must match config sections. If your sender uses a hostname variant (.lan or MagicDNS), add a mirrored alias section so back-and-forth replies keep working.

Other MCP-capable harnesses

MCP tools · OpenClaw push

Codex CLI, Gemini CLI, Aider, and anything else that speaks the Model Context Protocol can call the bridge_* tools, but their inbound receive loops are still scaffolded until tested. OpenClaw is verified separately through the native openclaw-channel/ plugin, which watches per-target inboxes and dispatches bridge messages into live Telegram-backed sessions.

.mcp.json (or your harness’s equivalent)
{
  "mcpServers": {
    "agent-bridge": {
      "command": "node",
      "args": ["/absolute/path/to/agent-bridge/mcp-server/build/index.js"],
      "env": { "AGENT_BRIDGE_ROLE": "tools-only" }
    }
  }
}

Without a verified push channel, MCP-only harnesses are tools-only by default; bridge_receive_messages is a manual Claude Code-target inbox fallback, not proof of full Codex/Gemini/Aider delivery. Companion instruction files ship in the repo: AGENTS.md (Codex), GEMINI.md (Gemini), INSTRUCTIONS.md (generic), and an openclaw-channel/ native channel plugin for OpenClaw push delivery.

04 / Pair two machines

Three steps. Then it’s invisible.

No fixed client/server roles — both peers are equal. After the handshake, bi-directional messaging just works.

  1. Setup

    On each machine, run agent-bridge setup. It enables SSH if needed, generates an ED25519 key pair under ~/.agent-bridge/keys/, and prints a pairing screen with the machine name, user, IPs, port, one-time token, and public key.

  2. Pair

    Photograph the pairing screen on one machine and send the image to the agent on the other. The agent reads the photo, extracts the fields, and runs agent-bridge pair --name ... --host ... --token ... --pubkey .... No password, no manual typing.

  3. Use

    Once paired, either side calls bridge_send_message with an explicit target. The message lands in the remote target inbox over SSH and is injected into the running remote session by Claude Code’s channel-owner or OpenClaw’s native channel plugin. No fresh agent is ever spawned on either side.

05 / The channel

Push into a running session.

For Claude Code, the plugin registers a single MCP stdio server that advertises the experimental claude/channel capability and the bridge_* tools. A watcher on ~/.agent-bridge/inbox/claude-code/ emits notifications/claude/channel into the Claude session. OpenClaw uses a separate gateway plugin watching inbox/openclaw/<target>/.

inside your Claude Code session
// Machine A's Claude calls:
bridge_send_message({
  machine: "MacBook-Pro",
  message: "can you run the e2e suite and paste the failures?",
  target: "claude-code/default"
})

// A few hundred ms later, Machine B's Claude sees:
<channel source="agent-bridge" from="Mac-Mini" message_id="msg-91c..." ts="2026-04-14T22:11:03Z">
  can you run the e2e suite and paste the failures?
</channel>

// ...and responds the same way:
bridge_send_message({ machine: "Mac-Mini", message: "3 failed, logs attached: ...", target: "claude-code/default" })

Auto-update + stale-runtime recovery. The in-process probe still notifies live harnesses when origin/main is ahead, and receivers still coordinate same-host updates through scripts/auto-update-coord.sh. Recent releases add plugin-registry rewiring (stale Claude/OpenClaw plugin cache paths), harness-independent periodic update scripts for launchd / Windows Scheduled Tasks, and migration-instruction injection into [BRIDGE-UPDATE-AVAILABLE] notices. Runtime caveat remains: disk-fresh code is not always process-fresh code; a full Claude Code session restart is the deterministic way to load a new long-running MCP child.

06 / Tool reference

Eight MCP tools. One concept per tool.

bridge_send_message

Deliver a message to a running agent on a paired machine. Requires an explicit target; writes a signed JSON message file to the matching remote inbox over SSH. Claude Code receives <channel> events; OpenClaw receives native channel turns; other MCP hosts remain unverified/manual.

bridge_receive_messages

Manually inspect/consume the local Claude Code-target inbox. Usually not needed under Claude Code push; useful for diagnostics, tools-only setups, and (3.8.0+) subagent long-poll — pass wait: true, timeout_seconds: 30 to block until a new message arrives. Supports peek for non-destructive reads.

bridge_list_machines

Show the local machine name and every paired peer with its user, host, port, and pairing date.

bridge_status

Probe a paired machine over SSH and report reachability. Pass a name to check one, or omit it to check all. Short timeout — safe to call on hot paths.

bridge_run_command

Run a plain shell command on a remote paired machine via SSH. Returns stdout, stderr, and exit code. Diagnostic utility only — do NOT use it to invoke an agent CLI on the far side. That path was removed in 3.0.0.

bridge_clear_inbox

Nuke every message in the local inbox. Handy for a clean slate between sessions or tests.

bridge_inbox_stats

Report pending count, oldest message age, total size, watcher health, processed-ID count, and failed-message count. Useful for diagnosing “did my message arrive?”

claude_code_channel_status

Diagnostic Claude Code plugin status: running version, process ID, uptime, active persona/target, watcher lease, and health snapshot. Useful for spotting stale runtime code or fleet version drift.

07 / Compatibility

Tested & scaffolded harnesses.

Harness
Status
Notes
Claude Code
● live
Full push via the Claude Code plugin. Install with the local-directory marketplace flow above. The plugin bundles both the bridge_* MCP tools and the claude/channel path in one MCP stdio child, not a separate daemon.
OpenClaw
● live
MCP tools out of the box. The openclaw-channel/ native channel plugin registers agent-bridge as a first-class OpenClaw channel (same tier as Telegram) via api.registerChannel(), dispatching inbound messages into the running agent session via dispatchInboundReplyWithBase from openclaw/plugin-sdk/compat. In v3.0+, reply routing is agent-driven: the inbound turn carries a [BRIDGE-CONTEXT] block, bridge replies are implicit when fromTarget is present, and additionalReplyChannels controls any extra user-facing channels.
Codex CLI
scaffolded
MCP tools via codex mcp add agent-bridge .... AGENTS.md in the repo root is auto-picked-up by Codex as instructions. Polling mode — call bridge_receive_messages at breakpoints.
Gemini CLI
scaffolded
MCP tools via gemini mcp add agent-bridge .... GEMINI.md in the repo root is picked up for guidance. Polling mode.
Aider & other MCP agents
scaffolded
Anything that speaks MCP can call the bridge_* tools. Inbound receive/reply is scaffolded until a harness-specific target and polling loop are tested. See INSTRUCTIONS.md in the repo root.
08 / Security

SSH-authenticated. TTL-bounded. No cloud.

09 / Changelog highlights

What’s new.