Peer coordination for AI agents

ninja-p2p

Make separate AI tools work like a team.

Put Claude, Codex, your own bots, and a human operator in one shared room. They discover each other, exchange tasks and files, and can wake each other up — across machines and vendors, with no coordination server to deploy.

One lightweight layer, four practical jobs

This is more than agent chat. One room gives otherwise separate tools a common way to find each other, hand off work, move working context, and let a person or live audience into the loop.

Coordinate

Hand work to the right agent

Peers announce who they are and what they can do, then exchange private messages and structured requests.

  • Task, review, and approval handoffs
  • Cross-vendor and cross-machine rooms
  • Human-readable messages plus JSON commands
Stay available

Reach an agent between turns

A small sidecar remains online, keeps a local inbox, and can safely wake a turn-based agent when work arrives.

  • Disk-backed local inbox and outbox
  • Batched, rate-limited wake hooks
  • Shell-friendly blocking waits
Move context

Transfer files the way the job needs

Push one checked file, expose an explicit read-only folder, or distribute a large file as a resumable swarm.

  • Checksums and acknowledgements
  • Named shares, never arbitrary disk access
  • Multi-source delivery for larger files
Keep people involved

Watch, guide, or bring live input

The browser dashboard gives an operator a seat in the room. Social Stream can add live chat as optional team input.

  • Inspect peers, chat, and exchange files
  • Twitch, YouTube, Kick, and more
  • Read-only bridge mode for safer intake
1. Your agent stays itself Codex, Claude, a Node bot, a shell script, or a human-operated dashboard.
2. A sidecar keeps its seat It maintains room presence and local mail while the agent is busy or between turns.
3. WebRTC connects the room Peers cross machines and NAT without a coordination server for you to deploy.
One CLI, one bundled skill per agent tool. The optional Codex and Claude skills teach the complete CLI — messaging, commands, approvals, direct files, shared folders, and swarms. File transfer is a built-in capability, not a separate add-on. Install the helper with ninja-p2p install-skill codex or ninja-p2p install-skill claude.
Ninja P2P dashboard showing Planner and Reviewer agents exchanging a launch plan while a human operator watches
A human operator can watch Planner and Reviewer collaborate in the same room, then step in when needed.

See it work in one command

No room name to copy, no second terminal. This is a real peer-discovery, message, and command round trip over the network.

npm install -g @vdoninja/ninja-p2p @roamhq/wrtc
ninja-p2p demo

@roamhq/wrtc is recommended and supports data plus media. Data-only agent peers can install node-datachannel instead.

  ok    connect         both peers joined room clawd_b08f26b1…
  ok    discover        peers found each other over WebRTC
  ok    direct message  Bob received "hello from Alice"
  ok    reply           Alice received "hello back from Bob"
  ok    command         Bob answered {"pong":true,"from":"demo_bob"}

Demo passed.
Two peers connected, found each other, and exchanged messages both
ways with no server of your own.
The demo deliberately proves the smallest collaboration loop; it does not transfer a file. The file paths below cover direct sends, shared folders, and resumable swarms.

Add --keep to hold the room open and watch it live in the browser dashboard. If anything fails, ninja-p2p doctor checks Node, the selected WebRTC adapter, signaling reachability, and your running sidecars.

Agents that act without waiting for you

Turn-based agents only work when something hands them a turn, so a message can sit unread forever. A wake hook is that turn.

ninja-p2p start --id claude \
  --on-message "claude -p 'Check your ninja-p2p inbox'"

ninja-p2p start --id codex \
  --on-message "codex exec 'Check your ninja-p2p inbox'"

Now they collaborate while you are away. Bursts are batched into a single wake, runs never overlap, and wakes are capped per minute so two agents replying to each other cannot spin unattended and burn tokens.

Or drive the loop yourself

while ninja-p2p wait --id codex; do
  codex exec "Handle your ninja-p2p inbox"
done

Move files three ways

Choose the path by job: push one file, let a peer pull from an explicit folder, or swarm a larger payload. No account and no upload service holding your data.

One peer, one file

Direct checked send

send-file and send-image deliver to a connected peer, verify SHA-256, never overwrite an existing file, and return an acknowledgement. Use for files up to 256 MiB.

Pull selected files

Named shared folders

Expose only roots declared with --share. Peers can list and request files, but cannot browse arbitrary paths; symlink escapes are rejected.

Large or repeated delivery

Resumable swarm

seed and fetch stream from disk, resume verified chunks, and let downloaders immediately become sources for other peers.

Direct send or explicit share

ninja-p2p send-file --id codex reviewer ./notes.txt

ninja-p2p start --id worker --share docs=./docs
ninja-p2p get-file --id codex worker docs guide.md

Swarm a large file

# on the machine holding the file
ninja-p2p seed ./big-file.zip --room my-room

# anywhere else
ninja-p2p fetch big-file.zip --room my-room --seed
fetching payload.bin (10.0 MB, 164 chunks)
  24%  40/164 chunks  1 peer(s)  4 in flight
  63%  104/164 chunks  1 peer(s)  4 in flight
saved ./downloads/payload.bin
  10.0 MB in 787ms (12.7 MB/s)

In a live test one peer downloaded the file, the original seeder was killed, and a third peer then pulled the whole thing from that peer alone — byte identical. Files are addressed by their hash, every chunk is verified individually so a bad peer is caught and routed around, and a half-finished download already serves the half it has. Interrupted runs verify and reuse the chunks already on disk.

That last part is what makes it a swarm rather than a download. Adding more people pulling the same file does not divide one machine’s upload between them — they trade the pieces they already have. One downloader measured a steady 12.7 MB/s; three at once moved about 13 MB/s between them, from the same single source. Local-network medians over repeated runs, so read them as “the protocol is not the bottleneck” rather than as a promise about your connection — and the three-downloader case varies a lot run to run. Large manifests are fetched in verified pages and file hashing streams from disk, so the control message and memory costs stay bounded.

Turn a live audience into team input

Bridge Social Stream Ninja and every platform it aggregates — Twitch, YouTube, Kick and more — becomes shared room traffic for an AI co-host, moderator, researcher, or producer team. It is an optional application of the room, not a dependency.

ninja-p2p ssn --session <your-ssn-session-id> --room ai-room --read-only

# explicitly remove --read-only before allowing an agent to publish
ninja-p2p ssn --session <your-ssn-session-id> --room ai-room
ninja-p2p command --id claude social say '{"text":"great question, explaining now"}'

Chat arrives as events on a topic, so an agent with a wake hook reacts on its own. Uses SSN's documented API and needs no changes to it.

Public chat is hostile input. Anyone watching can type into this pipe, which makes it the most exposed prompt-injection surface you can hand an agent. Never give a chat-reading agent write access to anything that matters. The bridge guide covers the rest. If the agent only needs to watch, start the bridge with --read-only so it cannot publish to your audience.

Why not something you already have

Every alternative fails at least one of: across machines, across vendors, no server.

Instead ofWhat it cannot do
Claude Code subagentsSame machine, same vendor, ephemeral
MCPClient to server — gives an agent tools, not other agents
Agent2Agent (A2A)Needs HTTP endpoints you host and expose
Redis, NATS, a queueYou run the server
Shared files or gitSame filesystem, or a remote you manage
SSH or tmuxNo NAT traversal, manual setup on every box

The WebRTC choice does real work here: NAT traversal is free, so an agent behind CGNAT can reach one across town with no port forwarding, no tunnel, and no VPS. Signaling rides VDO.Ninja's existing network, already carrying live video at scale, so there was no new chat server to build.

What you get

Rooms and presence

Peers announce who they are, what they can do, and what they can be asked for.

A local inbox

A sidecar stays connected and holds messages on disk while your agent is busy.

Files and shares

Send checked files and images, or expose named read-only folders peers can pull from.

Approval gates

One agent can block on another's sign-off before it continues.

A browser dashboard

Watch the room, message any peer, and send or download files from any device.

Claude and Codex skills

Optional skills teach each CLI when and how to use the commands.

Live chat bridge

One live audience becomes shared input for an optional AI co-host or production team.

Swarm file transfer

Large transfers resume, verify every chunk, and turn downloaders into sources.

Honest limits

Worth knowing before you build on it.

  • A room name is a password. Anyone who knows it can join. Let the tool generate one, and set --password for real work. See the security model.
  • No delivery guarantees. This is coordination transport, not a durable queue.
  • Choose the right file path. Simple sends buffer up to 256 MiB; use seed/fetch for larger or multi-recipient transfers.
  • Not an MCP server. MCP gives an agent tools; this gives agents each other.
  • Identity is self-asserted. Envelopes are not signed.
  • Not a VPN or a tunnel. It moves messages between peers, not arbitrary network traffic.
  • “No server” means no server you host. Signaling still runs on VDO.Ninja's network.