Secure ephemeral channels for AI agent communication
Project description
agent-wormhole
A Claude Code session on your laptop can hand a file, a message, or a secret to a Claude Code session on another machine, sealed end to end so only the two of them can read it. Built on persistent secp256k1 identities, Nostr NIP-17 gift-wrapped DMs, and magic-wormhole for one-time pairing and bulk file transfer.
agent-wormhole is for agent collaboration that outlives a single terminal. Pair once, give each peer a name, and then agents can send context to each other as they work: the branch they are on, what they changed, logs, test output, screenshots, config snippets, or a file that needs review.
What you'd use it for
- Two people working on the same project, each with their own agent, sharing implementation notes, test fixtures, local repro steps, and review feedback without pasting everything through chat.
- One person coordinating agents on two machines: for example a local laptop agent driving the UI while a cloud or Linux box agent runs backend jobs, GPU tasks, browser tests, or long-running experiments.
- Parallel worktree sessions coordinating who edits what, and handing off context so the next session picks up where the last one left off.
- Getting a second opinion from another Claude running with a different model or prompt, and pulling the review back into the current session.
- Moving an API key, config file, or one-off artifact between machines, sealed end to end, addressable by peer name after first contact.
Quickstart
Install:
uv tool install agent-wormhole
# or
pip install agent-wormhole
A persistent keypair is created on first use at ~/.agent-wormhole/identity.key (mode 0600). See it:
$ agent-wormhole whoami
pubkey: 7f3a…
relays: wss://relay.damus.io, wss://nos.lol, wss://relay.primal.net
First contact (pairing)
The /agent-wormhole skill drives this; the two sides exchange identity envelopes over two short magic-wormhole codes (one each direction) and each writes the other into its trust file:
# Machine A → reads code aloud
agent-wormhole identity-envelope | wormhole send --text -
# Machine B → with A's code
wormhole receive <code-A> # prints A's envelope JSON
agent-wormhole trust <A-pubkey> alice --relays <relays>
# Then reverse so A trusts B too.
Steady state
Keep a listener running; it emits one JSON line per inbound message:
$ agent-wormhole listen
{"type":"text","from":"alice","content":"hi","received_at":1700000000}
{"type":"file","from":"alice","name":"report.pdf","saved_to":"/tmp/agent-wormhole/alice/files/report.pdf","size":4096,…}
Send by peer name:
agent-wormhole send alice "hello from laptop"
agent-wormhole send-file alice ./config.json
Manage trust:
agent-wormhole peers
agent-wormhole untrust alice
Using it from Claude Code
agent-wormhole ships with a Claude Code skill. Install it:
agent-wormhole setup | claude
That symlinks ~/.claude/skills/agent-wormhole/SKILL.md into the installed package, so the skill updates when you upgrade agent-wormhole.
Then either session can run:
/agent-wormhole pair <peer-name>to add a new peer (the skill walks both sides through it)./agent-wormholeto start the listener for an already-paired peer.
Outbound messages and files use agent-wormhole send / agent-wormhole send-file directly via Bash.
How it works
- Identity: each machine holds a long-lived secp256k1 keypair (
~/.agent-wormhole/identity.key, 0600). The x-only BIP-340 pubkey is the addressable name on the Nostr network. - Pairing: the skill runs
wormhole send/receiveto swap identity envelopes between two trusted hosts (one short code per direction). Each side callsagent-wormhole trustto record the peer. - Text messages: NIP-44 v2 encryption + NIP-17 three-layer gift-wrap (rumor → seal signed by sender → gift wrap signed by an ephemeral key). Relays see only
kind=1059events tagged for the recipient. Sender identity is hidden from the relay. - File transfer:
send-filespawns awormhole sendsubprocess, posts the negotiated code in an encrypted file-offer DM, and the recipient's listener auto-invokeswormhole receive(transfer authenticated by magic-wormhole's PAKE). - Relay pool: the listener and sender connect to N relays concurrently, dedupe events by id, and reconnect with backoff on disconnect.
Configuration
Relay list resolution order: AGENT_WORMHOLE_RELAYS env var (comma-separated) → ~/.agent-wormhole/config.json ({"relays":[…]}) → bundled defaults (damus, nos.lol, primal).
The wormhole CLI must be on PATH; it ships with the magic-wormhole Python dep.
Security
- Identity keys never leave their machine. Losing the keyfile means re-pairing with every peer.
- Messages are NIP-44 v2 (ChaCha20 + HMAC-SHA256, HKDF over ECDH x-coord). All known canonical test vectors pass.
- NIP-17 gift-wrap hides the sender from the relay. The recipient's pubkey is necessarily visible to the relay (it's used as the
#psubscription filter); run your own relay or trust the chosen relay set's anonymity properties if you need stronger anonymity. - File transfer uses magic-wormhole's PAKE handshake; only the negotiated short code (delivered over the encrypted DM) can complete the transfer.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_wormhole-0.2.1.tar.gz.
File metadata
- Download URL: agent_wormhole-0.2.1.tar.gz
- Upload date:
- Size: 173.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d47ed9b7da3c07e28f595623ced3d2b670bfd1d9dfd7780107fc9f868c66b9a
|
|
| MD5 |
e889a50fc8f5dc5b3b846743d34967da
|
|
| BLAKE2b-256 |
a9937b9e4baa2ce6affd37af2af54c0506e15a864f143c29d24bfa250cc63670
|
Provenance
The following attestation bundles were made for agent_wormhole-0.2.1.tar.gz:
Publisher:
publish.yml on noncuro/agent-wormhole
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_wormhole-0.2.1.tar.gz -
Subject digest:
6d47ed9b7da3c07e28f595623ced3d2b670bfd1d9dfd7780107fc9f868c66b9a - Sigstore transparency entry: 1685716924
- Sigstore integration time:
-
Permalink:
noncuro/agent-wormhole@fdcec6e47c3e7419ba7ba647ee7dce2e5ea8ca12 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/noncuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdcec6e47c3e7419ba7ba647ee7dce2e5ea8ca12 -
Trigger Event:
push
-
Statement type:
File details
Details for the file agent_wormhole-0.2.1-py3-none-any.whl.
File metadata
- Download URL: agent_wormhole-0.2.1-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3313c89a44b51612ca792868aa57b7be717650c69aa9ee93d19cdcd66e677417
|
|
| MD5 |
4b54b8ba9ae7ede4868593895cb68bce
|
|
| BLAKE2b-256 |
795bdbd5d5bbb3937af00f0a20fbb1f225525d225dfcaef53b658b7fee226989
|
Provenance
The following attestation bundles were made for agent_wormhole-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on noncuro/agent-wormhole
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_wormhole-0.2.1-py3-none-any.whl -
Subject digest:
3313c89a44b51612ca792868aa57b7be717650c69aa9ee93d19cdcd66e677417 - Sigstore transparency entry: 1685716965
- Sigstore integration time:
-
Permalink:
noncuro/agent-wormhole@fdcec6e47c3e7419ba7ba647ee7dce2e5ea8ca12 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/noncuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdcec6e47c3e7419ba7ba647ee7dce2e5ea8ca12 -
Trigger Event:
push
-
Statement type: