Claude Relay
Let local Claude Code sessions talk to each other in natural language.
Running two Claude sessions on different projects? In one, say "ask the backend session if the auth token shape changed" and the other answers. Or "ask everyone what they're working on" and replies stream back.
Install
Claude Relay ships as a Claude Code plugin. Three steps.
1. Add the marketplace
From any Claude Code session:
/plugin marketplace add innestic/claude-relay
2. Install the plugin
/plugin install relay@claude-relay
This registers the MCP server and slash commands.
3. Launch sessions with the channel capability
Relay delivers inbound messages via notifications/claude/channel — a Claude Code capability still in research preview. Every session that should send or receive messages must be launched with:
claude --dangerously-load-development-channels plugin:relay@claude-relay
The dangerously- prefix is required until Anthropic promotes the channels capability to general availability and adds this plugin to the trusted allowlist. We will submit for review and drop the flag as soon as it's approved.
Open two sessions in different project dirs and try the examples below.
Usage
Try:
- "what sessions are active?"
- "ask backend-api what they're working on"
- "ask everyone to report status"
Rename your session: /relay-rename backend-api. Natural language works too ("call yourself backend-api"), but the slash command is faster. Claude Code's built-in /rename also auto-syncs.
Tools
| Tool | What it does |
|---|
relay_peers | List active sessions on this machine |
relay_ask | Ask one peer; returns immediately, reply arrives as a notification |
relay_reply | Answer an incoming ask by ask_id |
relay_broadcast | Ask every other peer; replies stream back as notifications |
relay_rename | Rename this session |
Claude routes to these automatically. You rarely call them by name.
If two sessions share a slugged basename (both ~/Code/backend/api), Relay suffixes -2, -3. Use relay_peers to disambiguate by cwd.
Preset name via env (for orchestrators)
Set CLAUDE_RELAY_PRESET_NAME in the spawned session's environment to pre-register under a deterministic name:
CLAUDE_RELAY_PRESET_NAME=home-office-agent-12 claude ...
Useful when a parent process pty-spawns many sessions and needs each to land under a known name instead of the directory-basename fallback. Same validation as /relay-rename applies (max 64 chars, [A-Za-z0-9._-]+); invalid values are ignored. The preset only seeds the initial registration — /rename and /relay-rename continue to work normally.
Error codes
| Code | Meaning |
|---|
peer_not_found | No peer registered under that name |
peer_gone | Target peer disconnected before replying |
timeout | Ask timed out waiting for a reply |
name_taken | Rename or register name already in use |
not_registered | Caller tried to use a tool before registering |
already_registered | Same socket tried to register twice |
unknown_ask | Reply references an ask_id the hub has no record of |
bad_msg | Malformed JSON or schema-invalid payload |
hub_unreachable | Hub socket died or never replied |
bad_args | Tool called with missing or wrong-typed arguments |
protocol_mismatch | Client version != hub version; kill the hub and retry |
Debugging
Runtime data lives under $CLAUDE_PLUGIN_DATA (~/.claude/plugins/data/relay-claude-relay/).
DATA=~/.claude/plugins/data/relay-claude-relay
tail -f "$DATA/logs/relay-$(date +%Y-%m-%d).log" | jq # today's log
pgrep -f hub-daemon.ts # hub alive?
pkill -f hub-daemon.ts && rm -f "$DATA/hub.sock" # force reset
Per-session MCP stderr lives under ~/Library/Caches/claude-cli-nodejs/<project-slug>/mcp-logs-*/. Start there when a channel fails to register.
How it works
Three pieces: