pi-whatsapp0.3.0
WhatsApp integration for Pi Coding Agent with in-terminal, per-message approval
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-whatsapp
Read and search your WhatsApp conversations from Pi, and send messages only after you approve each one inside Pi's terminal.
This is an unofficial WhatsApp integration, not affiliated with WhatsApp or Meta. Using unofficial clients can lead to account restrictions.
Platform support
| Platform | Status |
|---|---|
| macOS (Apple Silicon) | Tested with a real account: QR linking, reading chats, approved text messages, downloading voice messages, autostart. |
| Linux (x86-64) | Tested on Omarchy (Arch Linux) with a real account: setup from Pi, QR linking, reading chats, approved messages, voice messages, autostart across reboots. |
| Windows | Experimental. Developed for it, not yet tested end to end. |
It needs the whatsapp-mcp bridge, which /whatsapp-setup can download for you.
How it works
- The whatsapp-mcp bridge (a separate Go program) connects to your WhatsApp account and serves the WhatsApp tools to Pi over MCP. It refuses to send anything without a signed approval for that exact message.
- This extension shows you each outgoing message in full before it is sent. Choosing Approve and send signs that one message with a key that exists only in this Pi process.
Reading and searching need no approval. Every text, file or voice message does, one at a time:
- Pi asks to send a message.
- The bridge freezes the exact recipient, text and attachment bytes.
- You review all of it in Pi. Control and invisible characters are shown as
⟨U+…⟩, and Cancel is selected by default. - Only after you approve does the bridge send. Each approval is single-use and expires after 120 seconds.
If you decline, Pi is told the message was not sent. Without Pi's interactive terminal (print, JSON or RPC mode), sending is refused.
Setup
Everything happens inside Pi; no second terminal is needed.
Install the extension:
pi install npm:pi-whatsappIn Pi, run
/whatsapp-setup. It:- downloads the
whatsapp-mcpbridge for your system and checks it against the SHA-256 checksum pinned in this package. You can instead point it at a bridge you built yourself:/whatsapp-setup /path/to/whatsapp-mcp; - shows a QR code in Pi to link this computer to your WhatsApp account. Scan it on your phone under Settings › Linked devices › Link a device;
- asks whether the bridge should start automatically when you log in, run until you log out, or not start yet. Nothing runs in the background without your choice;
- makes the WhatsApp tools available to Pi. Your
settings.jsonandmcp.jsonare not changed. Ifmcp.jsonalready defines awhatsappserver, it is left alone and takes precedence.
- downloads the
Ask Pi to read or send WhatsApp messages. Before the first message in a Pi session, Pi asks once whether this session may approve messages. After that, every message is still shown to you for approval.
The approval key exists only in the running Pi process and is never written to disk. When Pi quits or reloads, the bridge stops trusting it, and the next session asks again. /whatsapp-pair asks right away instead of at the first message. /whatsapp-status shows the bridge state, whether WhatsApp is linked and whether this session can approve messages. /whatsapp-uninstall undoes the setup; see Uninstall.
To send a file, ask Pi to copy it into the bridge's outbox folder and send it; every file is reviewed before it is sent. Received files that Pi downloads, such as voice messages, are saved in the bridge's downloads folder, where Pi can open them for you. Both folders are in the bridge's data directory, shown by whatsapp-mcp status.
Uninstall
Run /whatsapp-uninstall in Pi. It shows what it will remove and asks before changing anything. Then it:
- stops the bridge and removes its start-at-login service (launchd on macOS, systemd user service on Linux, Task Scheduler on Windows) with the bridge's own
whatsapp-mcp uninstall; - asks whether to keep your local data (the default) or purge it. Purging deletes the WhatsApp session, message history, downloads and the bridge's credentials through
whatsapp-mcp uninstall --purge, after a second confirmation in Pi and a third in the terminal, where you typeyes; - deletes Pi's WhatsApp settings and the bridge Pi downloaded, and removes the WhatsApp tools from the running Pi session.
A bridge you set up yourself with /whatsapp-setup /path/to/whatsapp-mcp and your mcp.json files are never deleted or changed. If the bridge cannot be found or fails, Pi says what is left to do; running /whatsapp-uninstall again is safe.
What remains afterwards:
- with Keep local data, the bridge's data directory, which Pi names at the end. Delete it later to remove your WhatsApp history from this computer;
- the link on your phone. Remove this computer under Settings › Linked devices in WhatsApp: deleting local data does not unlink it;
- the extension itself. Remove it from a terminal with
pi uninstall npm:pi-whatsapp(use the source thatpi listshows if you installed it another way).
Security notes
- The bridge enforces approval. Disabling this extension never lets a message through; it only removes the way to approve one.
- WhatsApp messages and contact names are untrusted input. They can contain instructions aimed at the model (prompt injection). The approval screen exists so that nothing is sent on the model's word alone. Read what you approve.
- Messages that Pi reads become part of the conversation sent to your model provider and saved in Pi's session files.
- The extension blocks the model's file and shell tools from the bridge's credentials, session data and pairing command; only the
outboxanddownloadsfolders stay open to it. This stops the direct routes a manipulated model would try, but it is not a sandbox. - This design protects against the model and against other local programs using the bridge's API. It does not protect against a program running as your user that can change the bridge, its data or Pi itself.
Development
npm install --no-package-lock --ignore-scripts
npm run typecheck
npm test
License
MIT