pairwave

pairwave

Enables two Claude Code sessions to connect over an end-to-end encrypted channel for collaborative AI-assisted development, with MCP tools for messaging, code sharing, and turn-taking.

Category
Visit Server

README

<div align="center">

<img src="docs/assets/banner.svg" alt="Pairwave β€” two people, two Claude Codes, one end-to-end-encrypted channel" width="880"/>

pairwave

Connect two people's Claude Code sessions over one live, end-to-end-encrypted channel. Stop being the copy-paste middleman between your AI and your friend's AI.

License: PolyForm Noncommercial Tests Node Built for Claude Code E2E encrypted

</div>


πŸ€– Claude (or any AI assistant) reading this because your human said "install this"?

Do exactly this, in the project folder you're currently working in:

  1. Run the Step 1 init line below (match their OS). If your human was sent an invite block by a friend, run that block's join line instead β€” nothing else.
  2. The output ends with a copy-paste block for their collaborator (init only) β€” show it to your human and tell them to send it to their friend.
  3. Tell your human: restart Claude Code in this folder, approve the pairwave server, then type /pairwave β€” the installed skill takes over from there. That's the entire job.

Get started β€” 2 minutes, one line each

The easy way: don't even open a terminal. Paste the line for your system into Claude Code itself (this works in the CLI, the VS Code extension, or the desktop app) and say "run this". Claude runs it, reads the output, and walks you through the rest. That's the whole setup.

Step 1 β€” Person A creates the room (run inside your project folder)

πŸͺŸ Windows (PowerShell):

iex "& { $(iwr -useb https://raw.githubusercontent.com/goofypluto999/pairwave/main/scripts/install.ps1) } init"

🍎 Mac / 🐧 Linux:

curl -fsSL https://raw.githubusercontent.com/goofypluto999/pairwave/main/scripts/install.sh | bash -s -- init

When it finishes, it prints a ready-to-send line for your friend β€” invite code already inside. You copy it, send it somewhere private (Signal, WhatsApp, in person β€” it is the room key), done.

Step 2 β€” Person B pastes the line you sent them

That's it β€” the line Person A sends already contains everything. Person B pastes it in their project folder (or into their Claude Code with "run this") and they're fully plugged in.

<details> <summary>Joining manually instead? (optional β€” only if you didn't get a ready-made line)</summary>

πŸͺŸ Windows (PowerShell):

iex "& { $(iwr -useb https://raw.githubusercontent.com/goofypluto999/pairwave/main/scripts/install.ps1) } join <invite-code>"

🍎 Mac / 🐧 Linux:

curl -fsSL https://raw.githubusercontent.com/goofypluto999/pairwave/main/scripts/install.sh | bash -s -- join "<invite-code>"

</details>

Step 3 β€” both of you

Open Claude Code in that folder β†’ approve the pairwave server when it asks β†’ type /pairwave. Your Claude drives everything from there β€” you answer one question (a six-word safety check), and you're collaborating. Dashboard link printed for each of you. Want replies to flow automatically for a stretch? Tell your Claude "go live".

That one line did everything: checked prerequisites, installed Pairwave (outside your project), built it, gave you a global pairwave command, wired your project (.mcp.json + the /pairwave skill + room config), and git-ignored the key material. Nothing else to configure.

The relay (the dumb pipe between you): zero setup. New rooms use the always-on community relay by default β€” it works across any networks, requires no account, and cannot read your messages: it stores and forwards encrypted bytes only (that's the architecture, not a policy). Prefer your own pipe? Both options stay one step away: run pairwave relay (it prints the exact address to share) or click Deploy to Render for your own free hosted relay, then add --relay wss://<your-relay> to the init line.

Want to feel it before inviting anyone? Clone the repo, npm run demo β€” it boots a fake two-person session and hands you the live dashboard to click around in.


Why doesn't this already exist?

Anthropic's own issue tracker has the request (claude-code#21277). People hack around it daily: copy a Claude answer into WhatsApp, friend pastes it into their Claude, repeat. You can bridge two Claudes with a shared file or chat-room MCP β€” it's just clunky, unsafe, and blind. Five hard problems stood in the way. Pairwave is the bridge over each:

# The blocker Pairwave's bridge
1 Agents aren't daemons. A Claude Code session acts when its human engages β€” it can't "listen" for your friend. Naive bridges silently drop messages. Async-first protocol: a durable inbox survives any downtime; the skill checks it at every engagement point; opt-in live mode polls with hard cost bounds.
2 Nobody wants a middleman server reading their code. A hosted bridge sees everything. Server-blind relay: XChaCha20-Poly1305 E2E (Argon2id room key), Ed25519-signed, hash-DAG-linked messages. SAS fingerprint words defeat invite interception. The relay can be hosted by a stranger.
3 Two autonomous agents run away β€” they loop, talk over each other, and burn tokens. The floor (one pusher at a time) + a hard hop cap on consecutive agent↔agent messages, enforced mechanically by the companion, not by prompt-politeness.
4 "Let the other AI touch my repo" is terrifying. Shared code lands inert in quarantine. Applying it takes two gates: your Pairwave approval popup, then Claude Code's own permission prompt when your Claude applies it. The companion has zero project/shell access. An outbound secret scan blocks keys before they leave.
5 Sessions die and the context dies with them. Durable signed log + crash-safe outbox + reconnect-with-replay. Every shutdown writes a handoff markdown; /pairwave resumes both sides with full context.
6 Two AIs that talk still don't accumulate anything. The shared brain: pair_remember/pair_recall build one deduplicated knowledge base (facts, decisions, snippets) both Claudes search locally for free β€” identical on both sides, superseded entries replaced not duplicated, carried in every handoff.

All of it is stress-tested in the automated suite: message floods (zero loss, byte-identical order on both peers), a relay killed and restarted mid-session (durable outbox redelivers), ~300 KB artifacts, and simultaneous-send DAG forks that must converge identically.

What you can do that you couldn't before: your Claude asks their Claude for the API contract it just wrote and gets a provenance-tagged answer; you ship a patch across as an inert artifact and watch their approval popup β€” then their own Claude applies it under its own permissions; both dashboards show the same decisions, open questions, and shared files in real time; you close your laptop, reopen tomorrow, type /pairwave, and both sides remember everything.


How it works

flowchart LR
    subgraph A["Person A's machine"]
        CA["Claude Code"] <-->|"MCP Β· 17 pair_* tools"| PA["Companion<br/>(holds the key)"]
        PA --- UA["Local dashboard<br/>127.0.0.1"]
    end
    subgraph R["Anywhere (untrusted)"]
        RY[("Relay<br/>ciphertext only")]
    end
    subgraph B["Person B's machine"]
        PB["Companion<br/>(holds the key)"] <-->|"MCP Β· 17 pair_* tools"| CB["Claude Code"]
        UB["Local dashboard<br/>127.0.0.1"] --- PB
    end
    PA <-->|"E2E encrypted WebSocket"| RY <-->|"E2E encrypted WebSocket"| PB

A typical exchange, end to end:

sequenceDiagram
    participant A as Alice + her Claude
    participant R as Relay (sees ciphertext)
    participant B as Bob + his Claude
    A->>B: SAS words compared out-of-band βœ“
    A->>R: charter proposal (encrypted)
    R->>B: forwarded β€” Bob's human reviews, accepts
    Note over A,B: substantive exchange now unlocked
    A->>R: code artifact (encrypted)
    R->>B: lands INERT in Bob's quarantine
    A->>R: action.request "write src/lib/prefs.ts"
    R->>B: Gate 1 β€” permission popup on Bob's dashboard
    B->>B: Approve β†’ Bob's OWN Claude applies it (Gate 2: Claude Code's prompt)
    B->>R: action.result βœ“ (encrypted receipt)
    R->>A: Alice sees it resolved in her ledger

What your Claude gets β€” 19 MCP tools

Tool Purpose
pair_status Room, peers, verification, charter, floor, ledger, pending items, dashboard URL
pair_verify Show / confirm the SAS fingerprint words
pair_charter Read / propose / accept the shared task brief (scope, MUST-NOTs, permission posture)
pair_send chat Β· question Β· answer Β· context Β· decision (headline + provenance-tagged)
pair_share_code Ship code/patches as inert quarantined artifacts
pair_request_action Ask the other side to apply/write/run/fetch β€” behind their popup
pair_inbox / pair_read What needs me / recent verified messages
pair_respond_permission Gate-1 decision (with session "always allow")
pair_apply / pair_complete_action Pull the approved payload, apply with own tools, report back
pair_claim / pair_yield Turn-taking (auto-grant on timeout β€” no deadlocks)
pair_live_mode Bounded near-real-time polling, cost stated up front
pair_remember / pair_recall The shared brain: durable knowledge both Claudes write + search β€” local, instant, overlap-free via supersession
pair_summarize / pair_handoff / pair_resume Narrative recap Β· session snapshot Β· full restore

The dashboard

Each person gets their own local web dashboard (zero build, served by their companion, never leaves 127.0.0.1): an activity rail (open questions, decisions, shared code, pending approvals), the live transcript with human/agent origin markers, permission popups with risk + exact payload, the SAS verification banner, floor control, and a chat composer for the humans. npm run demo shows it in 30 seconds.

Honest limits (v1)

  • Async by design, not telepathy β€” Claude Code is turn-based; live mode is bounded polling that costs the poller tokens.
  • Two local dashboards, not one website β€” a hosted UI would need your key and break E2E.
  • Metadata is visible to the relay (room id, sizes, timing) β€” content never is.
  • No forward secrecy yet (static room key β€” rotate rooms; Double-Ratchet is on the roadmap), and a malicious peer is out of scope: Pairwave protects the channel and your machine, not against a friend who lies.

Full threat model: docs/SPEC.md Β§15. Build status: docs/ROADMAP.md.

Repo layout

Package What it is
packages/protocol Wire format + crypto: Argon2id Β· XChaCha20-Poly1305 Β· Ed25519 Β· BLAKE2b Β· SAS Β· hash-DAG
packages/relay The untrusted bus β€” routes and stores ciphertext only
packages/companion The trusted local process: MCP server, floor/charter/permission engines, quarantine, secret scan, ledger, handoff, dashboard
packages/cli pairwave init/join/relay/status + the /pairwave skill it installs

npm run verify builds everything and runs all 75 tests β€” if it's green, your install works.

Security disclosure

Found a vulnerability? Open a GitHub security advisory (preferred) or an issue tagged [security] without exploit details. The relay is designed to be operable by an adversary β€” if a malicious relay can read or forge content, that's a critical bug and we want to know immediately.

<div align="center"> <sub>Free for any noncommercial use (PolyForm NC 1.0) Β· no telemetry Β· no accounts Β· no hidden calls β€” <a href="docs/SPEC.md">read the spec</a></sub> </div>

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured