Skip to main content
ClaudeWave

Persistent WhatsApp daemon over Unix socket. SLSA L2 signed. Allowlist + rate limiter. Sub-second warm-call latency.

PluginsOfficial Registry0 stars0 forksGoApache-2.0Updated today
ClaudeWave Trust Score
87/100
Trusted
Passed
  • Open-source license (Apache-2.0)
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
  • Documented (README)
Flags
  • !Install pipes a remote script into a shell (curl | sh)
Last scanned: 9/8/2026
Install as a Claude Code plugin
Method: Clone
Claude Code
/plugin marketplace add yolo-labz/wa
/plugin install wa
1. Inside Claude Code, add the marketplace and install the plugin with the commands above.
2. Follow any post-install configuration from the README.
3. Restart the session if commands or hooks do not show up immediately.
Use cases

Plugins overview

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="docs/assets/hero-dark.svg">
  <source media="(prefers-color-scheme: light)" srcset="docs/assets/hero-light.svg">
  <img alt="wa: persistent WhatsApp daemon for Claude Code" src="docs/assets/hero-dark.svg">
</picture>

<div align="center">

# wa

**Personal WhatsApp automation CLI + daemon, written in Go.**

A hexagonal Go daemon that owns a WhatsApp Multi-Device session and a thin JSON-RPC client that talks to it — safe enough to let a language model send messages on your behalf, crash-safe enough to survive a power loss mid-migration, and paranoid enough to refuse every destructive flag you might expect.

[![CI](https://github.com/yolo-labz/wa/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/yolo-labz/wa/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/yolo-labz/wa?sort=semver)](https://github.com/yolo-labz/wa/releases)
[![Go](https://img.shields.io/github/go-mod/go-version/yolo-labz/wa)](./go.mod)
[![License](https://img.shields.io/github/license/yolo-labz/wa)](./LICENSE)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
[![Nix flake](https://img.shields.io/badge/nix-flake-5277c3?logo=nixos&logoColor=white)](./flake.nix)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/yolo-labz/wa/badge)](https://scorecard.dev/viewer/?uri=github.com/yolo-labz/wa)
[![SLSA L2](https://slsa.dev/images/gh-badge-level2.svg)](https://slsa.dev/spec/v1.0/levels)
[![Verified by Sigstore](https://img.shields.io/badge/sigstore-verified-3a86ff?logo=sigstore&logoColor=white)](https://docs.sigstore.dev/)

[Quickstart](#quickstart) · [Install](#install) · [Manual](./docs/manual.md) · [Architecture](#architecture) · [Security](./SECURITY.md) · [Contributing](./CONTRIBUTING.md) · [Português (BR)](./README.pt-BR.md)

</div>

---

## Capability

**Pattern.** Persistent WhatsApp daemon over a Unix socket — one `wad` process holds the Multi-Device session, ratchet store, and websocket; a thin `wa` JSON-RPC client invokes it.

**Trade-off.** ~30 MB RSS per profile and a 5–8 s cold connect, in exchange for sub-second warm-call latency on every subsequent `wa send`. Per-call session reattachment is avoided entirely.

**Use when.** A shell pipeline, cron job, or Claude Code plugin needs to dispatch WhatsApp messages with predictable latency and a non-overridable safety pipeline (default-deny allowlist + rate limiter + warmup ramp + append-only audit log) sitting below every RPC path.

```bash
brew install yolo-labz/tap/wa
wad &                                                # daemon, single instance per profile
wa pair                                              # QR-code pairing on first run
wa allow add 5511999999999@s.whatsapp.net --actions send
wa send --to 5511999999999@s.whatsapp.net --body "hello"
```

## Demo

![wa CLI demo](./docs/assets/wa-demo.gif)

Every frame is real output from the binaries in this repo, recorded against a
throwaway unpaired daemon in a temp directory — which is why `doctor` shows one
honest `WARN` and no JID, phone number, or session data appears anywhere.

The recording is generated, never hand-edited. The source of truth is the
plain-text [`docs/assets/wa-demo.tape`](./docs/assets/wa-demo.tape); regenerate
the GIF from a clean checkout with one command:

```bash
nix develop -c ./scripts/record-demo.sh
```

## How `wa` compares

Closest peers in the reverse-engineered-WhatsApp ecosystem:

| Capability                                 | `wa` (this repo) | [`whatsmeow`](https://github.com/tulir/whatsmeow) direct | [`whatsapp-web-cli`](https://github.com/jlguenego/whatsapp-web.cli) |
|--------------------------------------------|:---:|:---:|:---:|
| Persistent daemon (sub-second warm-call)   | yes | no (per-call session attach) | no (browser-driven) |
| JSON-RPC over Unix socket                  | yes | n/a (library, not a daemon) | no (Chrome bridge) |
| Default-deny allowlist (per-action)        | yes | manual implementation        | no |
| Non-overridable limiter (2/sec + 30/min)   | yes | manual implementation        | no |
| Warmup ramp for fresh sessions             | yes | manual implementation        | no |
| Append-only JSON-Lines audit log           | yes | manual implementation        | no |
| SLSA L2 + Sigstore signed releases         | yes | n/a                          | no |
| Dual SBOM (CycloneDX 1.6 + SPDX 2.3)       | yes | n/a                          | no |
| `CGO_ENABLED=0` static binary              | yes | depends on consumer          | no (browser-driven) |
| Inbound prompt-injection firewall          | yes | n/a                          | no |

For multi-tenant REST gateways see [`EvolutionAPI`](https://github.com/EvolutionAPI/evolution-api) or [`WAHA`](https://github.com/devlikeapro/waha) — different shape of problem, listed in [What this is NOT](#what-this-is-not).

## What this is

Two binaries, one repo:

- **`wad`** — long-running daemon that owns the WhatsApp session, the SQLite ratchet store, and the websocket to `web.whatsapp.com`. Runs under `systemd` (Linux), `launchd` (macOS), or a NixOS module. Single-instance per profile, **never as root**.
- **`wa`** — thin JSON-RPC client that speaks to `wad` over a unix socket. This is what shell scripts, cron jobs, and Claude Code plugins actually invoke.

It is built on [`go.mau.fi/whatsmeow`](https://github.com/tulir/whatsmeow) — the library that powers `mautrix-whatsapp` at production scale — because it is the only reverse-engineered WhatsApp library actively maintained in 2026. It also ships a safety-first **MCP server** (`wa mcp serve`) so an AI agent drives WhatsApp through the same non-bypassable safety pipeline — draft-gated by default. See [MCP server](#mcp-server).

## What this is NOT

- **Not** a bulk-messaging tool. The rate limiter is non-overridable and there is no `--force` flag anywhere.
- **Not** a multi-tenant SaaS. Each `wa` install is scoped to one person, with optional multi-profile isolation for work/personal splits.
- **Not** a Matrix bridge. Use [`mautrix-whatsapp`](https://github.com/mautrix/whatsapp) if that's what you want.
- **Not** a REST gateway. Use [`EvolutionAPI`](https://github.com/EvolutionAPI/evolution-api) or [`WAHA`](https://github.com/devlikeapro/waha) if that's what you want.
- **Not** the official WhatsApp Cloud API. This project uses the reverse-engineered Multi-Device protocol via `whatsmeow`.

## Quickstart

```bash
# Install (Homebrew — macOS + Linuxbrew)
brew install yolo-labz/tap/wa

# Or via Nix (recommended for NixOS/nix-darwin users)
nix profile install github:yolo-labz/wa

# Or the checksum-verified installer (80 lines — inspect first if you like)
curl -fsSL https://raw.githubusercontent.com/yolo-labz/wa/main/install.sh | bash

# Or Docker — single distroless container (~12 MB); /data holds the session
docker compose up -d   # see docker-compose.yaml; pair via `docker compose exec`

# Start the daemon (default profile)
wad &

# Pair your phone — QR code in terminal
wa pair

# Allowlist yourself (default-deny policy)
wa allow add 5511999999999@s.whatsapp.net --actions send

# Send a message
wa send --to 5511999999999@s.whatsapp.net --body "hello from wa"

# Install as a persistent system service
wad install-service --profile default

# Hand it to an AI agent — MCP over stdio, draft-gated sends by default:
# the agent PROPOSES messages into a human-review queue; nothing leaves
# until you run `wa draft approve`. Add to Claude Desktop/Code, Cursor:
#   {"mcpServers": {"wa": {"command": "wa", "args": ["mcp", "serve"]}}}
wa mcp serve --help
```

The recipient flag is spelled `--to`, `--jid`, or `--group` depending on the command; `--chat <jid>` is accepted as a universal alias on all of them (the original flags still work).

For the full tour including multi-profile setup, shell completion, migration, and the audit log, see **[`docs/manual.md`](./docs/manual.md)**.

## MCP server

`wa mcp serve` exposes the daemon to AI agents over the [Model Context Protocol](https://modelcontextprotocol.io) (stdio transport). Every tool call runs through the **same non-bypassable safety pipeline** as the CLI — default-deny allowlist, enforced short-window limits (2/second with burst 2; 30/minute with burst 30; no daily ordinary-send cap) with warmup, and an append-only audit log. Sends default to **draft mode**: the model proposes a message into a human-review queue and nothing leaves until you run `wa draft approve`. That draft-gate is the point — it is what makes handing WhatsApp to an autonomous agent safe.

Live on the official [MCP Registry](https://registry.modelcontextprotocol.io) as **`io.github.yolo-labz/wa`**; one-click install via the signed `.mcpb` bundle on each [release](https://github.com/yolo-labz/wa/releases), or wire it manually into Claude Desktop/Code or Cursor:

```json
{ "mcpServers": { "wa": { "command": "wa", "args": ["mcp", "serve"] } } }
```

**Tools (12):**

| Tool | Purpose |
|---|---|
| `wa_send_message` | Send (or draft) a message through the safety pipeline |
| `wa_send_media` | Send (or draft) a media file |
| `wa_schedule_message` | Schedule a send for later (drafts respected) |
| `wa_draft_review` | List pending drafts awaiting human approval |
| `wa_search_messages` | Full-text search across synced messages |
| `wa_get_thread` | Fetch recent messages of one chat |
| `wa_list_chats` | List chats with recent activity |
| `wa_resolve_contact` | Resolve a name/phone to a JID |
| `wa_group_info` | Group metadata and participants |
| `wa_wait_for_reply` | Block until a matching inbound event arrives |
| `wa_transcribe_voice` | Transcribe a voice note |
| `wa_status` | Daemon connection and session status |

It also serves **resources** (read-only context surfaces) and **prompts** (pre-built workflows) per the MCP spec. Scope the surface with `--toolsets`; the send mode is `dra
claude-codedaemongolangsigstoreslsasupply-chainwhatsappwhatsmeow

What people ask about wa

What is yolo-labz/wa?

+

yolo-labz/wa is plugins for the Claude AI ecosystem. Persistent WhatsApp daemon over Unix socket. SLSA L2 signed. Allowlist + rate limiter. Sub-second warm-call latency. It has 0 GitHub stars and its last recorded update is dated 2026-09-08.

How do I install wa?

+

You can install wa by cloning the repository (https://github.com/yolo-labz/wa) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is yolo-labz/wa safe to use?

+

Our security agent has analyzed yolo-labz/wa and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.

Who maintains yolo-labz/wa?

+

yolo-labz/wa is maintained by yolo-labz. The last recorded GitHub activity is dated 2026-09-08, with 6 open issues.

Are there alternatives to wa?

+

Yes. On ClaudeWave you can browse similar plugins at /categories/plugins, sorted by popularity or recent activity.

Deploy wa to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: yolo-labz/wa
[![Featured on ClaudeWave](https://claudewave.com/api/badge/yolo-labz-wa)](https://claudewave.com/repo/yolo-labz-wa)
<a href="https://claudewave.com/repo/yolo-labz-wa"><img src="https://claudewave.com/api/badge/yolo-labz-wa" alt="Featured on ClaudeWave: yolo-labz/wa" width="320" height="64" /></a>

More Plugins

wa alternatives