whatzap-cli
v0.1.3
Published
Send WhatsApp messages from the terminal
Maintainers
Readme
whatzap
Give Claude, OpenClaw, and your shell scripts a WhatsApp voice.
A lightweight CLI that connects AI agents and terminal workflows to WhatsApp — no API keys, no paid services. Built on the WhatsApp Web protocol via Baileys. Connects directly to your account via QR code, just like WhatsApp Web.
Send messages and reach groups by name · Record conversation history as JSONL · Persistent daemon, zero reconnections
AI Integration
whatzap is built to work seamlessly with Claude Code and OpenClaw. Run whatzap init once and any agent can send messages, resolve contacts by name, watch groups, and read conversation history — no phone numbers needed, no reconnections.
"Send a WhatsApp to João saying the deploy is live"
"Message the dev team that tests passed"
"Watch Jane's messages"
"Add the family group to my watch list"The Claude Code skill is installed automatically by whatzap init. For OpenClaw, whatzap acts as a drop-in WhatsApp backend — authenticated, persistent, and ready from ~/.whatzap/history/. To reinstall the skill manually:
whatzap install-skillNote: Contact resolution by name requires macOS —
find-contactuses AppleScript to query Contacts.app. On other platforms, agents will prompt for the phone number.
Requirements
- Node.js 18 or later
- A WhatsApp account
- macOS (Linux support is partial —
find-contactrequires macOS Contacts)
Installation
npm install -g whatzap-cliFirst-time setup
whatzap initInstalls the Claude Code skill and authenticates with your WhatsApp account via QR code. Run once after installing.
Command Reference
| Command | Description |
|---|---|
| whatzap init | First-time setup: install skill + QR authentication |
| whatzap login | Re-authenticate after logout |
| whatzap logout | Disconnect and delete saved credentials |
| whatzap send-message <phone> <message> | Send a text message (phone with country code) |
| whatzap send-group <group name> <message> | Send a message to a WhatsApp group |
| whatzap find-contact <name> | Search macOS Contacts by name, returns JSON |
| whatzap add-watch <phone\|group name> | Start recording messages for a contact or group |
| whatzap remove-watch <phone\|group name> | Stop recording messages |
| whatzap list-watch | List all watched contacts and groups |
| whatzap setting set default-country-code <code> | Set default country code for number normalization |
| whatzap install-skill | Reinstall the Claude Code skill |
| whatzap restart | Restart the background daemon |
| whatzap stop | Stop the background daemon |
Usage
Send a Message
whatzap send-message <phone> <message>Phone must include the country code. Multi-word messages don't need quotes.
whatzap send-message +5511999999999 Hello from the terminal!
whatzap send-message +15555550100 Meeting in 10 minutesSend to a Group
whatzap send-group <group name> <message>Group name is matched case-insensitively. The longest prefix matching a known group is used as the name; the rest is the message.
whatzap send-group family Oi pessoal!
whatzap send-group Work Team Meeting in 5 minutesFind a Contact (macOS only)
whatzap find-contact <name>Returns a JSON array of matching contacts:
[{"name":"John Doe","phones":["+15555550100"]},{"name":"John Smith","phones":["+5511988887777"]}]Useful for scripting:
PHONE=$(whatzap find-contact "John Doe" | jq -r '.[0].phones[0]')
whatzap send-message "$PHONE" On my way!Watch a Contact or Group
Record all incoming and outgoing messages for a contact or group:
whatzap add-watch +5511999999999 # by phone
whatzap add-watch family group # group by name
whatzap add-watch Work TeamMessages are written to ~/.whatzap/history/ as newline-delimited JSON:
{"ts":"2026-03-22T10:00:00.000Z","d":"in","n":"Carlos","text":"Hello!"}
{"ts":"2026-03-22T10:01:00.000Z","d":"out","text":"Sure, see you there!"}| Field | Description |
|---|---|
| ts | ISO 8601 timestamp |
| d | "in" (received) or "out" (sent) |
| n | Sender display name (incoming only) |
| text | Message text |
Non-text messages (images, audio, stickers) are not recorded. History is capped at the 100 most recent messages per contact or group.
Manage the Watch List
whatzap list-watch
whatzap remove-watch +5511999999999
whatzap remove-watch family groupWatch list changes take effect immediately — no daemon restart needed.
Default Country Code
whatzap setting set default-country-code 55Phone numbers without a + prefix will have the country code prepended automatically:
whatzap send-message 11999999999 Hello! # treated as +5511999999999How It Works
whatzap uses a daemon architecture to maintain a persistent WhatsApp connection without reconnecting on every command:
whatzap <command>
→ src/index.ts (parse & dispatch)
→ src/commands/*.ts (command handlers)
→ src/daemon/client.ts (IPC over Unix socket)
→ src/daemon/server.ts (background daemon)
→ src/services/whatsapp.ts (Baileys WebSocket)
→ ~/.whatzap/auth/ (persisted credentials)The daemon runs as a detached background process and communicates via a Unix domain socket at ~/.whatzap/daemon.sock. It auto-starts on first use if credentials are available.
Runtime Data
All runtime data lives in ~/.whatzap/:
| Path | Description |
|---|---|
| auth/ | Baileys session credentials |
| daemon.sock | Unix socket for IPC |
| daemon.pid | Daemon process ID |
| settings.json | Watch list and default country code |
| history/ | Recorded messages — one .jsonl per watched contact/group |
History filenames are derived from WhatsApp JIDs (e.g. 5511999999999_s-whatsapp-net.jsonl for contacts, 120363000000_g-us.jsonl for groups).
Development
git clone https://github.com/CarlosAugustoAlves/whatzap-cli.git
cd whatzap-cli
npm install
npm start -- send-message +5511999999999 test # run without compiling
npx tsc --noEmit # type-check
npm run build # compile to dist/
node dist/index.js --help # run compiled outputNo automated test suite — verification is manual against a real WhatsApp account.
See CONTRIBUTING.md for contribution guidelines.
License
MIT — see LICENSE for details.
Disclaimer
This project uses the WhatsApp Web protocol via Baileys. Use responsibly and in accordance with WhatsApp's Terms of Service. Automated or bulk messaging may violate those terms and result in account restrictions.
