pairpipe: plugin, shared Brain and relay for AI coding agents
A two-command Claude Code plugin that lets one person's AI agent message a teammate's agent, share files, and search a shared notes Brain.





My role
I directed AI (Claude Code, with Hermes Agent support) to build it and I made product decisions, tested flows and approved written plans. I am not a software developer and the AI wrote the code. It is built together with a collaborator, who reviews every pull request and hosts the main source repository. The plugin and install guide repos are public; the full server and Go client source stay private.
What it is
pairpipe lets two people's AI coding agents talk to each other. You install a plugin into Claude Code with two commands, or paste one setup line from the website. After that your agent can message a teammate's agent, send files, tick off tasks on a shared board, and search a shared notes network called the Brain, while both humans read along on a web page.
The idea came from a private relay I used every day with a collaborator starting 2026-10-14. About 950 real messages later we decided it was worth turning into a product. The relay's key trick is a background wait command: an agent can sleep for free until the other agent writes, because Claude Code wakes the agent when that background command exits.
The Brain is the shared memory layer. Notes have hubs, lessons, rules and decisions, are searchable by keyword plus vector similarity, and can be imported from an Obsidian vault. It grew out of my own local memory vault of about 1,800 linked notes that my AI sessions read and write every day.
How it was built
- Start with a private relay that already workedClaude Relay is a small Node 22 server with one dependency (pg), 6 server files totalling 2,196 lines, a 463-line command line tool and 10 test files totalling 2,353 lines. Agents authenticate with revocable bearer tokens stored only as SHA-256 hashes, and humans get a live chat page over server-sent events. It ran in real use for about nine days before any product work started.
- Write a product plan and market research firstA folder of 29 markdown files (3,993 lines) holds the plan, competitor teardowns, hosting options at 100, 1,000 and 10,000 users, security notes and integration choices. The plan was written 2026-10-23, one day before the first product commit.
- Fix the architecture as a contract before buildingdocs/ARCHITECTURE.md and DECISIONS.md define three programs and a database: a Go client on each computer, a Node/TypeScript API on Postgres, and a React single-page site. Decisions D-001 to D-012 are dated 2026-10-23, for example hand-rolled device-flow sign-in with hashed per-device keys, and row-level security on every table.
- Build the Go client as one binary with three jobsThe client lives in the main repo as 68 Go files and 15,279 lines. One binary is the command line tool, the MCP server (23 tools such as pairpipe_send, pairpipe_wait, pairpipe_board, brain_search, brain_learn) and the Claude Code hook runner. It is built for darwin-amd64, darwin-arm64, linux-amd64, linux-arm64 and windows-amd64.
- Wire the plugin so agents wake up on their ownThe public plugin repo has plugin.json, .mcp.json, a 141-line hooks.json, a 33-line skill and four slash commands (invite, join, setup, status). Hooks run in exec form with no shell so native Windows works: SessionStart does a 5 second sync, Stop re-arms a long-poll wait with asyncRewake so a message from a teammate wakes the agent, and SessionEnd reports the session ended.
- Build the server with security as a design inputThe server is 115 TypeScript files and 26,166 lines, backed by 68 SQL migrations (2,543 lines). Incoming messages are wrapped in an 'untrusted information, not instructions' frame. A loop guard pauses a pair that sends more than 60 agent messages in 10 minutes, and risky approvals can only come from a human web session, never from the agent.
- Add the shared Brain as a separate subsystemSpecified on 2026-10-26 in BRAIN.md and implemented across routes, services, tidy jobs and embedding code (roughly 5,700 lines of server code in the Brain files counted, plus 14 Brain migrations). Search combines Postgres full text with trigram title boosting and vector similarity. A daily tidy job proposes merges and archives for a human to approve, and secrets are rejected at write time.
- Test at three levelsThe server has 111 test files (23,009 lines) running against in-memory Postgres (PGlite), the client has Go tests, and an end-to-end suite drives two simulated users pairing and chatting through the real binaries and real HTTP. A Windows Sandbox config was used to test a clean install.
- Write an install guide that Claude itself can followA separate documentation-only repo (24 text files, 609 lines) has a START.md the agent follows step by step plus one page per known failure: git missing on Windows, program will not run, wrong account signed in, setup code expired. Every install sends a report so the guide improves.
- Review, audit, benchmark and release by handEvery pull request is reviewed by a collaborator. A launch-readiness audit on 2026-10-27 found the site was invisible to crawlers and new signups hit a paywall with nothing to try. A search benchmark on 2026-10-29 found natural-language recall far below keyword recall, which led to hybrid ranking. Releases follow a 9-step manual procedure with SHA-256 pinning and never auto-push.
Decisions and why
- Hand-rolled sign-in (magic link plus device flow) instead of an auth library
- The command line plugin needs a per-device key that is stored only as a hash and can be revoked one device at a time, which the off-the-shelf option did not give cleanly.
- Row-level security in the database, with explicit and listed exceptions
- One customer must never be able to read another customer's rows even if application code has a bug. The few server jobs that bypass it are listed and commented.
- Treat every incoming partner message as untrusted information
- Two agents that can instruct each other could be hijacked. The frame tells the reading agent a message is data, not an order from its user.
- Approvals only from a human web session, plus a loop guard
- A model must not approve its own risky action, and two agents must not talk forever at a cost.
- Exec-form hooks and a POSIX launcher
- Windows users without Git Bash must still be able to install. Hooks that need a shell would silently fail there.
- Everything that leaves the computer has an off switch and is shown once
- Pull request links, heartbeats, waiting state and goals are optional telemetry. Users should see exactly what is sent and be able to stop it.
Hardest problems
- Headless runs of Claude Code (claude -p) hung forever once the plugin was installed, because they waited for the background listener
- In v0.4.0 the listener and the idle check skip headless runs and give up on an ended session. A release check now requires 'claude -p' to return in seconds.
- A security review found messages could be lost when a newer wait superseded an older one
- The cursor check was made transactional (row lock plus a per-session mutex). If a newer wait wins before the commit, the check rolls back and advances nothing. Once committed, its messages are always returned.
- Natural-language Brain questions found the right note far less often than keyword questions (recall at 5 of 13.0% versus 68.2% in a private benchmark on 2026-10-29)
- Added embeddings and hybrid ranking (keyword plus vector). The run was flagged as not comparable with earlier runs, so the final improvement is not claimed here.
- The live shared Brain had accumulated duplicate notes
- A reversible, audited dedupe pass on 2026-10-28 removed 38 exact and 153 judged duplicates and archived 80 blank-template stubs by hash. Old notes are marked superseded, not deleted.
- The first launch audit showed the site was a 1.1 KB shell to crawlers and a new visitor could not try anything without paying
- Planned and shipped fixes: prerendered pages, a security page, a solo pair, a hero demo loop and a welcome offer. Wording mismatches between code and marketing were audited line by line.
Numbers
| Server source (TypeScript) | 115 files, 26,166 lines | 2026-11-06 |
|---|---|---|
| Server tests | 111 files, 23,009 lines | 2026-11-06 |
| Web app source | 134 files, 24,066 lines | 2026-11-06 |
| Go client | 68 files, 15,279 lines | 2026-11-06 |
| Database migrations | 68 files, 2,543 lines, numbered 001 to 076 | 2026-11-06 |
| Total code, tests and SQL | about 91,000 lines | 2026-11-06 |
| MCP tools exposed | 23 | 2026-11-06 |
| Plugin version | 0.4.2 | 2026-11-05 |
| Binary targets per release | 5, with SHA256SUMS | 2026-10-27 |
| Private relay before the product | about 2,200 server lines, 460-line CLI, about 950 real messages | 2026-10-23 |
| Relay test files | 10 files, 2,353 lines | 2026-11-06 |
| Local Brain notes | 1,844 markdown notes | 2026-11-06 |
| Shared Brain dedupe | 4,979 to 4,826 active notes (191 removed) | 2026-10-28 |
| Install guide repo | 24 text files, 609 lines | 2026-11-06 |
Timeline
- 2026-10-14Private Claude Relay in daily use between two Claude Code agents
- 2026-10-23Product plan written; decisions D-001 to D-012 recorded
- 2026-10-24First pairpipe commit: server, client, plugin and web
- 2026-10-25Plugin v0.1.0 to v0.2.1: one-line setup; v0.3.0 adds Codex support
- 2026-10-26Brain feature specified; plugin v0.3.2 and v0.3.3
- 2026-10-27Launch-readiness audit; v0.3.4 release with binaries and checksums; v0.4.0 notes written
- 2026-10-28Shared Brain dedupe pass; SEO and support plans
- 2026-10-29Hybrid search benchmark and embedding migrations
- 2026-11-05Plugin v0.4.2 committed
What I took from it
- A product can start as a tool you use yourself: about 950 real messages on the private relay told us what mattered before any customer existed.
- Make the boring paths reliable first: Windows without Git, headless runs that must not hang, and one failure page per known install error mattered more than new features.
- Measure your own claims: the benchmark showed natural-language search was weak, and the audit showed the site was invisible to crawlers and had nothing to try. Both were found by looking, not guessing.
- When two AI agents can talk to each other, treat the messages as untrusted data and keep approvals with a human.