pi-telephone
Agent sessions call each other across machines on your Tailscale network, in Pi and Claude Code.
Package details
Install pi-telephone from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-telephone- Package
pi-telephone- Version
0.2.2- Published
- Oct 22, 2026
- Downloads
- 690/mo · 13/wk
- Author
- ordinath
- License
- MIT
- Types
- extension, skill
- Size
- 1.5 MB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"skills": [
"./skills"
],
"extensions": [
"./pi/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-telephone
Agent sessions call each other across machines on your Tailscale network. Works with Pi and Claude Code in any combination: Pi to Pi, Pi to Claude Code, Claude Code to Claude Code, on one machine or across machines, including machines shared from someone else's tailnet.
A session is unreachable until you turn its telephone on. An inbound message wakes an idle session, the agent answers with a reply, and the reply comes back to the caller.
How it works
- Every machine runs one small exchange daemon, started on demand by the first session that needs it.
- Sessions talk to their local exchange over a Unix socket; exchanges talk to each other over HTTP on port 47474, bound only to the machine's Tailscale IP.
- The caller of every network request is identified by
tailscale whois, never by what the request claims. - A machine accepts calls only from its owner's Tailscale login and from logins you trust.
- Each session has an allowlist of callers; the default admits only your own sessions.
- A reply to a message your session sent is always accepted.
Requirements
- Node.js 20 or later.
- Tailscale, logged in.
- Claude Code 2.1.224 or later (2.1.248 or later when
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICis set).
Install
Pi:
pi install npm:pi-telephone
Claude Code:
claude plugin marketplace add Ordinath/pi-telephone
claude plugin install telephone@pi-telephone
The command-line tool for status and trust comes with the npm package: npx pi-telephone status.
Use
Addresses are session@machine, for example reviewer@bobs-mbp; a bare reviewer means this machine.
| Pi | Claude Code | |
|---|---|---|
| Turn on | /telephone on [name] or ctrl+alt+t |
/telephone:on [name], or start with PI_TELEPHONE_NAME=<name> claude |
| Turn off | /telephone off |
/telephone:off |
| See who is reachable | /telephone list |
/telephone:list |
| Send a message yourself | /telephone call <address> <message> |
/telephone:call <address> <message> |
| Allow a caller | /telephone allow <entry> |
/telephone:allow <entry> |
| Trust a person's machines | /telephone trust <login> |
/telephone:trust <login> |
Agents use the telephone tool: send delivers and returns, ask waits for the answer, reply answers an inbound message, list shows reachable sessions.
Allowlist entries: owner (your own sessions, the default), local (this machine), user:<login> (every session of that Tailscale user), <session>@<machine> (* works in either part; a short machine name matches only inside your own tailnet), and * (anyone this machine trusts).
Files
Agents send images, audio, documents and archives with files on send, ask
or reply, for example { action: "send", to: "reviewer", files: ["./photo.png"], message: "What do you see?" }. The message is optional with files. Paths expand
~ and resolve relative to the session's working directory. File bytes never
pass through the sending model's context; do not paste contents or base64.
- Pi:
/telephone file <address> "path with spaces.png" [message]. - Claude Code:
/telephone:file <address> "path with spaces.png" [message].
Files arrive under ~/.pi-telephone/inbox/<session>/<message id>/, with their
local paths listed in the inbound message. Pi attaches images automatically;
Claude Code uses telephone action view with file set to the received path.
Pi draws received images inline when the terminal supports images (for example iTerm2, Kitty, Ghostty or WezTerm) and the show-images setting is on, and otherwise shows a placeholder.
view shows images up to 3.5 MB; for larger ones Claude Code opens the path
with its Read tool, which asks for permission unless you allow
Read(~/.pi-telephone/inbox/**) in your Claude Code permission settings.
Treat received files as untrusted data and never run them.
Defaults: 10 files and 50 MB total per message, a 1 GB inbox, and 7 days of
retention. Copy anything worth keeping. The exchange's config.json fields
maxFiles, maxFileBytes, inboxMaxBytes and inboxDays control these limits.
Both exchanges and receiving sessions need 0.2.0 or later for files; text
messages still work with older versions.
Upgrading
After updating the package, run npx pi-telephone stop once so the exchange
restarts on the new version (or /telephone restart in Pi). Restart sessions
that should send or receive files.
Connecting two people
- In Tailscale, share a machine with each other, in both directions.
- Each side trusts the other's Tailscale login:
/telephone trust friend@example.comin Pi,/telephone:trust friend@example.comin Claude Code, ornpx pi-telephone trust friend@example.com. - In each session that should take their calls:
/telephone allow user:friend@example.com.
Security model
- Only Tailscale peers can reach an exchange, and the caller's identity comes from Tailscale.
- Machine trust and the session allowlist both have to admit a caller; replies to your own calls are the only exception.
- Only a human widens access: through a command, or by approving a confirmation dialog when an agent asks.
- Inbound text is framed as another agent's message, not the user's; Claude Code adds its own guard for messages from other sessions.
- A session that is not listening does not exist to callers: "not reachable" never reveals whether a session exists.
Troubleshooting
npx pi-telephone statusshows the exchange, its Tailscale address, trusted users and local sessions;npx pi-telephone listshows every reachable session.- The exchange logs to
~/.pi-telephone/exchange.log. - With the macOS application firewall on, allow incoming connections for
node. - Claude Code's
crossSessionInboundsetting applies to telephone calls:refusedrops them andholdwaits for your approval.