agent-relay 0.2.1

Agent-to-agent messaging for AI coding tools. Local or networked — run a relay server and let Claude talk to Gemini across the internet.
Documentation

agent-relay

Crates.io docs.rs License: Apache-2.0

Agent-to-agent messaging for AI coding tools. Let Claude, Gemini, GPT, and human devs coordinate in real time.

No server. No database. No config. Just the filesystem.

[dependencies]
agent-relay = "0.1"

The problem

You have 3 Claude sessions, a Gemini agent, and a human all editing the same repo. Claude #1 starts refactoring auth.rs. Claude #2 has no idea and starts editing the same file. Gemini rewrites a function that Claude #1 just deleted. The human comes back to merge conflicts everywhere.

The fix

# Install
cargo install agent-relay

# Claude session 1
agent-relay register --agent claude --session claude-1
agent-relay send "refactoring auth module, stay away from src/auth/"

# Claude session 2 checks before editing
agent-relay inbox --session claude-2
# [NEW] claude (claude-1): refactoring auth module, stay away from src/auth/

# Gemini replies
agent-relay send -f gemini-1 -a gemini --to claude-1 "got it, working on tests instead"

# Human checks what's happening
agent-relay agents
# SESSION          AGENT           PID      HEARTBEAT
# claude-1         claude          12345    08:31:20
# claude-2         claude          12346    08:31:22
# gemini-1         gemini          12400    08:31:25

Library API

use std::path::PathBuf;
use agent_relay::Relay;

let relay = Relay::new(PathBuf::from(".relay"));

// Register
relay.register("claude-opus", "session-1", std::process::id());

// Send (None = broadcast to all)
relay.send("session-1", "claude-opus", None, "refactoring auth");

// DM a specific agent
relay.send("session-1", "claude-opus", Some("session-2"), "can you review?");

// Check inbox (marks messages as read)
let msgs = relay.inbox("session-2", 10);
for (msg, is_new) in &msgs {
    println!("[{}] {}: {}", if *is_new { "NEW" } else { "read" }, msg.from_agent, msg.content);
}

// Poll for new messages (for integration into loops)
let count = relay.poll("session-2");
if count > 0 {
    // trigger action — spawn agent, send notification, etc.
}

CLI Commands

Command Description
register --agent NAME --session ID Register an agent
unregister --session ID Remove an agent
send MESSAGE Broadcast a message
send --to SESSION MESSAGE DM a specific agent
inbox --session ID Read messages (marks as read)
unread --session ID Count unread messages
agents List active agents
cleanup Remove dead agents + old messages
watch --session ID --exec CMD Poll for new messages, optionally run a command

Watch mode

Auto-trigger a command when messages arrive:

# Spawn Claude to respond when new messages come in
agent-relay watch --session my-agent --exec "claude -p 'check agent-relay inbox and respond'"

# Or just get notified
agent-relay watch --session my-agent --interval 5

How it works

  • One JSON file per message in .relay/messages/
  • One JSON file per agent in .relay/agents/
  • Read tracking: each message has a read_by array
  • Dead agents cleaned up by PID check
  • Old messages cleaned up by timestamp
  • Atomic writes (tmp + rename) prevent corruption

All agents that point to the same .relay directory see each other. That's the entire protocol.

Integration with AI tools

Claude Code (CLAUDE.md)

Before editing any file, check for team messages:
$ agent-relay inbox --session $SESSION_ID

Gemini / Cursor / Windsurf

Same pattern — add relay commands to your agent's system prompt or MCP tool definitions.

MCP Server

Wrap agent-relay as an MCP tool server so AI agents can call relay_send, relay_inbox, etc. natively. (Coming in v0.2)

Origin

Extracted from Aura — the semantic version control engine for AI-generated code. Aura uses agent-relay's messaging protocol to coordinate multiple Claude Code agents editing the same repository.

License

Apache-2.0