Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Claude Whatsapp Channel

FreeNot checked

WhatsApp channel for Claude Code — send and receive messages, voice notes, and attachments from your running CLI session via a local MCP server.

GitHubEmbed

About

WhatsApp channel for Claude Code — send and receive messages, voice notes, and attachments from your running CLI session via a local MCP server.

README

Control your Claude Code session from WhatsApp. Send a message from your phone, it lands in the same CLI session you left running on your desk — with the same tools, the same working directory, the same context.

WhatsApp (your phone)
    ↕ Baileys v7 (WhatsApp Web Multi-Device)
server.cjs  (local MCP server)
    ↕ notifications/claude/channel
Claude Code (CLI session)

Text, voice notes, photos, documents — all of it arrives as a <channel> event in your session. Claude can reply with text, emoji reactions, or file attachments. Optional: approve tool-use permission prompts (Bash, Write, etc.) from your phone by replying yes <code> or no <code>.


Features

  • Two-way bridge — receive WhatsApp messages as channel events, reply through a standard MCP tool
  • Voice notes — inbound audio arrives as an attachment your session can transcribe with any speech-to-text tool you like
  • Attachments — images, videos, documents download on demand via download_attachment
  • Reactions — the react tool adds an emoji reaction to any received message
  • Message historyfetch_messages pulls the session's recent in-memory cache
  • Permission relay — remote-approve tool-use prompts from WhatsApp (Claude Code 2.1.81+)
  • Production-grade stability — exponential backoff, jitter, watchdog, graceful 515-reconnect, creds backup
  • Sender allowlist — gate on phone numbers (and optionally specific groups) to prevent prompt-injection
  • Local-only — nothing leaves your machine except the WhatsApp traffic. No Anthropic hosted sidecar.

Tools exposed to Claude

Tool What it does
reply Send text (and optionally file attachments) to a chat
react Add an emoji reaction to a received message
download_attachment Download media from a received message by its id
fetch_messages List recent messages from the session cache

Requirements

  • Node.js 20+ (Bun does not work — Baileys needs Node's WebSocket events)
  • Claude Code 2.1.80+ (2.1.81+ for permission relay)
  • A WhatsApp account — regular or Business. Keep in mind pairing creates a linked device, same as WhatsApp Web.

Quick start

1. Clone & install

git clone https://github.com/schenkei-code/claude-whatsapp-channel.git
cd claude-whatsapp-channel
npm install --legacy-peer-deps

(--legacy-peer-deps is needed because Baileys marks link-preview-js as a peer dep on a range npm resolves strictly.)

2. Pair your phone

Pick a state directory — anywhere writable is fine, but keep it out of version control. The default in examples is ~/.claude/channels/whatsapp.

# Linux / macOS
WHATSAPP_STATE_DIR=~/.claude/channels/whatsapp PAIR_NUMBER=4915112345678 node pair.cjs

# Windows (PowerShell)
$env:WHATSAPP_STATE_DIR="$HOME\.claude\channels\whatsapp"
$env:PAIR_NUMBER="4915112345678"
node pair.cjs

PAIR_NUMBER is optional — set it to your WhatsApp number (E.164 digits, no +) if you want a phone-pairing-code fallback when the QR flow can't be scanned. Either way, the script writes a PNG QR to <state-dir>/qr.png and opens it in your default image viewer.

On your phone: WhatsApp → Settings → Linked Devices → Link a Device, scan the QR. If the QR expires before you scan, a pairing code is printed after 60s; enter it under Link with phone number.

You'll see ✅ WhatsApp connected. when it's done — the process exits after a short delay, your credentials are saved inside <state-dir>/auth/.

Heads up: WhatsApp occasionally returns code 515 right after the first pair — that's not an error, it's a restart request. The script handles it automatically by reconnecting with a fresh socket. Let it finish.

3. Lock down the allowlist

By default the server accepts messages from anyone with your number. That is a prompt-injection vector. Create <state-dir>/access.json:

{
  "allowFrom": ["4915199999999"],
  "allowGroups": false,
  "allowedGroups": [],
  "requireAllowFromInGroups": false
}
  • allowFrom — array of E.164 digits (no +) that can write to Claude. Empty array = everyone (don't do that on a real account).
  • allowGroups — set to true if you want to let specific groups through.
  • allowedGroups — array of group JIDs in the form <groupid>@g.us.
  • requireAllowFromInGroups — if true, a group message is only forwarded when the sender is also in allowFrom.

See access.example.json.

4. Register the MCP server

Either add a project-scoped .mcp.json (see .mcp.example.json) or put a whatsapp entry under mcpServers in ~/.claude.json:

{
  "mcpServers": {
    "whatsapp": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/claude-whatsapp-channel/server.cjs"],
      "env": {
        "WHATSAPP_STATE_DIR": "/absolute/path/to/.claude/channels/whatsapp"
      }
    }
  }
}

Absolute paths, both of them. The server inherits WHATSAPP_STATE_DIR from this env block — make sure it matches the directory you paired into.

5. Launch Claude Code with the channel enabled

claude --dangerously-load-development-channels server:whatsapp

The --dangerously-load-development-channels flag is required because custom channels aren't on Anthropic's curated allowlist yet. Claude Code will ask for confirmation the first time — choose "I am using this for local development".

Send a WhatsApp message from an allowlisted number. In your CLI session you'll see a <channel source="whatsapp" chat_id="..." from="..." ...> tag arrive. Claude will read it and respond through the reply tool.

Permission relay (optional, Claude Code 2.1.81+)

When Claude wants to run a tool that needs approval, the local terminal dialog opens and a message is sent to WhatsApp:

🔐 Permission request [tbxkq]

Bash: rm -rf /tmp/foo

Reply "yes tbxkq" or "no tbxkq"

Reply on your phone — the plugin reacts with ✅ / ❌ to confirm, and Claude Code proceeds (or stops). Whoever answers first (terminal or phone) wins.

This is only enabled if the sender is in allowFrom — anyone who can reply through the channel can approve tool use, so don't run an open allowlist.

Troubleshooting

Symptom Likely cause Fix
❌ Error 401 / loggedOut Session invalidated from the phone Delete the auth/ folder inside your state dir and re-pair
❌ Error 440 Two devices competing on the same session Unlink this device on the phone, then re-pair
❌ Error 515 during pair Normal post-pair restart The script reconnects itself — wait for ✅ WhatsApp connected
Pairing code rejected Code expired (≈3 min TTL) or rate-limited Wait a few minutes, run pair.cjs again. Avoid rapid retries
Messages stop without error Zombie WebSocket Server watchdog forces reconnect every 30 min if inbound is silent. Restart Claude Code if it never recovers.
creds.json corrupted on disk Crash mid-save The server auto-restores from the backup snapshot on next start
Nothing arrives in Claude Sender not on allowlist, or MCP not loaded Check <state-dir>/access.json, then run /mcp in your session

If you see blocked by org policy on launch, a Team/Enterprise admin needs to enable channels first — see Anthropic's docs.

Architecture notes

This is a single-file MCP server (server.cjs). It owns the WhatsApp socket and exposes four tools. Inbound messages are gated on the sender allowlist, then pushed to Claude via notifications/claude/channel. Outbound replies are plain MCP tool calls.

Connection lifecycle follows a few hard-earned patterns:

  • 515 is not fatal — it's a normal restart request. Reconnect, don't exit.
  • Exponential backoff with jitter — factor 1.8, cap 30s, reset after 60s healthy.
  • Watchdog — no inbound messages for 30 min = force reconnect (zombie detection).
  • Creds snapshot — backup before every saveCreds, restore if the new file ends up corrupt.
  • Full listener cleanup — no leaks across reconnect cycles.
  • Only 440 and 401 terminate the process — everything else retries.

Based on research from the OpenClaw WhatsApp gateway, and the earlier work by diogo85/claude-code-whatsapp under MIT.

Security

  • Auth lives in <state-dir>/auth/ — same sensitivity as your WhatsApp Web credentials. Back up or wipe as you would any linked-device session.
  • Never commit auth/, creds.json, access.json, or qr.png. The shipped .gitignore covers them.
  • Permission relay means whoever is on your allowlist can approve tool use in your CLI session. Keep the list tight.
  • If you lose your phone, unlink from any other WhatsApp client and wipe the state dir.

License

MIT — see LICENSE.

from github.com/schenkei-code/claude-whatsapp-channel

Installing Claude Whatsapp Channel

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/schenkei-code/claude-whatsapp-channel

FAQ

Is Claude Whatsapp Channel MCP free?

Yes, Claude Whatsapp Channel MCP is free — one-click install via Unyly at no cost.

Does Claude Whatsapp Channel need an API key?

No, Claude Whatsapp Channel runs without API keys or environment variables.

Is Claude Whatsapp Channel hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Claude Whatsapp Channel in Claude Desktop, Claude Code or Cursor?

Open Claude Whatsapp Channel on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Claude Whatsapp Channel with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs