# WhatsApp connector (MCP)

A local WhatsApp connector for AI agents. It exposes WhatsApp as **MCP tools**
(search contacts, read/send messages, status, pairing) and ships a
**weekly-report skill** for group digests.

It runs as two processes:

```
MCP clients ─┐
(Claude Code, ├─ spawn  wa-mcp  (stdio MCP server, on-demand) ─┐
 Cursor, …)  ─┘                                                 │
                                                                ├─► wa-bridge ─► WhatsApp
plain HTTP / scripts ───────────────────────────────────────────┘  (REST :8080,
                                                                     always-on service)
```

- **`wa-bridge`** — an always-on OS service (launchd on macOS, `systemd --user`
  on Linux). Holds the WhatsApp Web socket 24/7 and exposes a local REST API on
  `http://localhost:8080`. This is the persistent daemon.
- **`wa-mcp`** — a short-lived MCP server an agent spawns on demand over stdio.
  It translates MCP tool calls into bridge REST calls. Not a daemon.

## What's inside the zip

```
install.sh                   one-command installer (this is what you run)
uninstall.sh                 full teardown
bin/wa-mcp                   MCP server (frozen Python, stdio)
bin/wa-bridge                bridge daemon (Go whatsmeow)
.mcp.json                    MCP server descriptor (for the Desktop plugin model)
.claude-plugin/              Claude Desktop plugin manifest + local marketplace
skills/whatsapp-weekly-report/   the weekly-report skill + HTML digest template
VERSION  build-manifest.json     version + provenance (git sha, sha256, toolchain)
```

## Requirements

- **macOS** (Apple Silicon or Intel) or **Linux** with a user `systemd` session.
- Windows is not supported yet (the installer is bash and the service backend is
  macOS/Linux only).
- Grab the zip that matches your OS/arch — the **scripts are identical** across
  zips, but the bundled binaries are target-specific.

---

## Install

```bash
unzip whatsapp-<os>-<arch>-<version>.zip -d whatsapp
cd whatsapp
./install.sh
```

`install.sh` will:

1. **Install + start the bridge service** (`wa-mcp --install` under the hood) and
   copy the binaries into a stable app dir so the unzipped folder can be deleted.
2. **Register the MCP with Claude Code** if the `claude` CLI is present
   (`claude mcp add --scope user whatsapp …`). If it isn't, the installer prints
   the exact command to run later — the bridge install still completes.
3. **Begin pairing** — if WhatsApp isn't linked yet it opens the QR page and
   prints the URL.

Then on your phone: **WhatsApp ▸ Settings ▸ Linked Devices ▸ Link a Device** and
scan the QR. If it says *already linked*, you're done.

The install is **idempotent** — re-running it repairs/upgrades and otherwise does
nothing (it won't restart a healthy bridge or duplicate the registration).

### App locations

| | macOS | Linux |
|---|---|---|
| App dir (binaries + store) | `~/Library/Application Support/whatsapp-mcp` | `~/.local/share/whatsapp-mcp` |
| Service | `~/Library/LaunchAgents/com.whatsapp-mcp.bridge.plist` | `~/.config/systemd/user/com.whatsapp-mcp.bridge.service` |

---

## Uninstall

```bash
./uninstall.sh
```

Logs WhatsApp out (unlinks the device), removes the service, wipes the local
store/credentials, and unregisters the MCP from Claude Code. Safe to re-run.

---

## Using it from Claude Code

`install.sh` registers it automatically at **user scope** (available in every
project). Verify:

```bash
claude mcp list          # → whatsapp: …/bin/wa-mcp  ✓ Connected
```

Then in any Claude Code session just ask, e.g. *"what's my WhatsApp status"* or
*"last message from <name>"*. To remove only the Claude Code wiring (leaving the
bridge running): `claude mcp remove whatsapp -s user`.

---

## Connecting additional agents

MCP is an open protocol — **any** MCP client can use the same `wa-mcp`, and they
all share the one bridge (one WhatsApp account per machine).

**Any MCP client (Cursor, Cline, Zed, a custom SDK agent):** point it at the
installed binary. The path is whatever `install.sh` printed as `WA_MCP=`:

```json
{
  "mcpServers": {
    "whatsapp": {
      "command": "/Users/<you>/Library/Application Support/whatsapp-mcp/bin/wa-mcp"
    }
  }
}
```

Each client spawns its own `wa-mcp` over stdio; the bridge serializes access, so
multiple agents can use it concurrently.

**No MCP at all — talk to the bridge directly.** Any process (script, cron,
another service) can hit the REST API:

```bash
curl -s http://localhost:8080/api/status      # {"connected":true,"logged_in":true,...}
# /api/send, /api/download, /api/logout, /pair, /qr.png
```

---

## The Claude Desktop plugin model (alternative)

This same zip can be installed as a **Claude Desktop plugin** instead of via
`install.sh` — Desktop's *Upload local plugin* accepts the zip directly, spawns
`wa-mcp` on demand, and `bootstrap()` installs the bridge automatically. Note the
Desktop plugin and the standalone install **share one service** (same label + app
dir), so use one model at a time, not both.

---

## Troubleshooting

- **"bridge is down" / tools time out:** ask the agent to run `restart_bridge`
  (an MCP tool) — it bounces the service without unpairing. Or check
  `curl http://localhost:8080/api/status`.
- **Status shows `service_loaded: true` but unreachable:** the bridge is wedged —
  `restart_bridge` fixes it.
- **Re-pair:** run the `pair_whatsapp` tool, or open `http://localhost:8080/pair`.
- **Logs:** `<app-dir>/bridge.log` (contains chat metadata — treat as private).
