Relay
Links a self-hosted WhatsApp account as a linked device, exposing tools to read and search chat history, follow live events, download and analyse attachments, and send, reply to, edit, delete, react to, forward, draft, and schedule WhatsApp messages, as well as manage groups and presence.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Relay
Your WhatsApp, as 37 MCP tools for Claude and ChatGPT: self-hosted, failover-ready, and free to run.
Relay links your own WhatsApp account as a linked device (like WhatsApp Web) on a computer you control and exposes it to AI assistants through the Model Context Protocol. Ask Claude to summarise a group chat, find the address a friend sent last month, transcribe a voice note, or draft and send a reply. It acts only when you ask it to.
┌──────────┐ ┌──────────┐
│ ChatGPT │ │ Claude │ claude.ai · Desktop · Code · mobile
└────┬─────┘ └────┬─────┘
│ owner sign-in │ x-api-key
│ ┌────────▼──────────┐
│ │ Cloudflare doorway│ claude-proxy/ (free Worker)
│ └────────┬──────────┘
│ │ client key
┌────▼─────────────────────────────▼──────────┐
│ Relay (relay-worker/) │ owner-only MCP endpoint
│ queue encrypted at rest · AES-256-GCM │ Worker + D1 (free tier)
└───────────────┬────────────────┬─────────────┘
outbound │ long poll │ long poll outbound only:
HTTPS only │ │ no open ports at home
┌───────────────▼─────┐ ┌──────▼──────────────────┐
│ Primary bridge │ │ Standby bridge │
│ macOS·Linux·Windows│ │ macOS·Linux·Windows │
│ WhatsApp linked │ │ (optional) its own │
│ device #1 │ │ linked device #2 │
└─────────────────────┘ └─────────────────────────┘
WhatsApp keys and message history never leave these machinesYou don't need the hosted part: a single bridge with Claude Desktop or Claude Code on the same computer works with no hosting at all.
Why Relay
37 WhatsApp tools, not just "send a message"
Read and search history, follow live events with a durable cursor, download and analyse attachments up to 500 MB (local transcription, PDF/OCR, video frames, optional local vision), send and reply, edit, delete, react, forward, polls, drafts, scheduled messages, groups and presence. Full reference ↓
About 4-second failover that never sends twice
Run an optional standby bridge on a second computer. If the primary sleeps or loses its connection, the standby starts serving after about 4–5 seconds of silence (about 7 s with the free-tier setting), then steps back when the primary returns.
Reads in progress are handed over. If a device goes silent in the middle of a read-only request, the relay re-queues that request for the other device.
Writes are never re-queued or retried automatically (send, edit, delete, react, groups and so on). Each queued request is claimed by exactly one device (an atomic
UPDATE … WHERE status='queued'). A write that times out is reported as may have executed, with an instruction to check the chat instead of retrying.send_messagealso accepts arequestId, so a retry with the same ID is de-duplicated, and an interrupted scheduled send is marked uncertain rather than re-sent.
Built-in defences against indirect prompt injection
Incoming WhatsApp content is written by other people, so Relay treats it as data, never instructions:
Every MCP server Relay exposes (local, remote and relay) carries server instructions saying that message text, attachments and contact names are untrusted and must not be followed as instructions.
Attachment and analysis results are labelled as untrusted content.
Writes happen only through explicit, schema-validated tool calls.
READ_ONLY=trueturns off every outgoing action, andALLOWED_CHATSlimits which chats the AI can see at all.Reading never sends read receipts, so an AI browsing your chats doesn't reveal that you've seen them.
These measures reduce the risk; they can't make a language model immune to manipulation. See SECURITY.md.
Cross-platform, runs on free tiers
The bridge is plain Node.js, so it runs on macOS, Linux and Windows. It also runs on Android (Termux) as an experimental option.
Auto-start templates for launchd, systemd and Task Scheduler, installed with one command.
No AI API key, no subscription and no per-message fees. The relay and the Claude doorway both run on Cloudflare's free Workers and D1 plans. See free-tier budget for the numbers.
Related MCP server: W Agent
5-minute quickstart
You need: Node.js 22.13+ and WhatsApp on your phone.
git clone https://github.com/viaanshetty3-debug/relay-whatsapp-mcp.git && cd relay-whatsapp-mcp
npm install
npm run setupnpm run setup (macOS, Linux and Windows):
generates strong random keys (32 bytes each, from
crypto.randomBytes),asks for your relay and Cloudflare doorway URLs. Both are optional: press Enter to stay local-only,
writes a private
.env(and, if you use them,relay-worker/.secrets.jsonandclaude-proxy/.secrets.jsonfor deploying),prints ready-to-paste configs for Claude Desktop, Claude Code and ChatGPT.
Then link WhatsApp:
npm startOpen http://127.0.0.1:8787, choose Connect WhatsApp, and on your phone go to WhatsApp → Settings → Linked devices → Link a device and scan the QR code. Paste the printed config into your AI client and ask it:
Check my WhatsApp connection and list my 3 most recent chats. Don't send anything.
To see your configs again later: npm run setup -- --print. If anything seems off, run npm run doctor. In a few seconds it checks Node, your .env, the bridge and WhatsApp session, the relay and the Claude doorway, and says what to fix.
Keep it running
npm run service # bridge (+ relay agent, if configured), restarts automatically if it crashesAuto-start on login
npm run autostart # install and start
npm run autostart -- --dry-run # preview what will be installed
npm run autostart -- --uninstall # removePlatform | Mechanism | Template |
macOS | launchd user agent | |
Linux | systemd user service |
|
Windows | Task Scheduler, at logon, no admin needed |
Each template has instructions for installing it by hand at the top. Logs go to data/service.log on macOS and Windows, and journalctl --user -u whatsapp-relay on Linux.
Use it from anywhere (optional)
Deploy the relay (free Worker + D1):
cd relay-worker npx wrangler login npx wrangler d1 create whatsapp-relay # paste the printed database_id into wrangler.toml npx wrangler deploy # prints https://whatsapp-relay.<you>.workers.devRun
npm run setupin the repo root and give it that address. It writesrelay-worker/.secrets.json; upload it withcd relay-worker && npx wrangler secret bulk .secrets.json. Later redeploys can usenpm run deploy, which does both.Deploy the Claude doorway (free):
cd claude-proxy npx wrangler login npm run deploy # wrangler deploy + upload .secrets.jsonIts
wrangler.tomllinks it straight to thewhatsapp-relayWorker with a service binding: Cloudflare doesn't let one Worker call another on the same account by its public URL. If your relay is hosted elsewhere, delete the[[services]]block. Add the resultinghttps://whatsapp-claude.<you>.workers.devaddress asCLAUDE_DOORWAY_URLin.env, then runnpm run setup -- --print.In claude.ai → Settings → Connectors → Add custom connector, use the printed URL, choose No sign-in, and add the request header
x-api-key.
ChatGPT: ChatGPT custom connectors can't send custom headers, so they can't use the relay's client key. Expose the bridge itself over HTTPS (PUBLIC_URL, for example with deploy/SELF-HOST.md) and connect ChatGPT with OAuth, which is built into the bridge.
Free-tier budget
Cloudflare's free plan currently allows 100,000 Worker requests and 100,000 D1 rows written per day (check Cloudflare's pricing for current limits).
Setup | Requests/day (approx.) | Fits the free tier? |
One bridge, idle | ~37,000 (one 2-second long poll at a time) | ✅ |
Primary + standby, default | ~37,000 + ~115,000 | ❌ over the request limit |
Primary + standby, | ~37,000 + ~29,000 | ✅ (failover takes ~7 s instead of ~4–5 s) |
Each poll also writes about two D1 rows (device liveness), so an always-on primary uses roughly 70% of the free daily writes. Tool calls add a few requests and writes each.
Add a standby later (24/7)
On a second computer: clone, npm install, npm run setup, and choose 2) standby. Paste RELAY_REMOTE_URL, RELAY_AGENT_KEY and RELAY_AGENT_ID from the primary's .env. Then npm start and link WhatsApp again on that machine, so it's a separate linked device. Never copy data/ between machines: two bridges sharing one WhatsApp session will break both. If your relay is on workers.dev, setup sets RELAY_WATCH_MS=3000 on the standby to stay within the free tier.
Tool reference
Access: 🟢 read-only · 🟡 write (changes WhatsApp or local state) · 🔴 destructive · ⚪ local cache only
Tool | Access | What it does |
Chats and messages | ||
| 🟢 | Connection state, live event cursor, counts and capabilities |
| 🟢 | Chats with names, unread counts, previews and exact chat IDs (JIDs) |
| 🟢 | Search contact names and WhatsApp IDs |
| 🟢 | Read messages newest first, with pagination; never sends read receipts |
| 🟢 | Literal text search across one chat or every permitted chat |
| 🟢 | Live messages, edits, receipts, reactions and presence after a durable cursor |
| 🟢 | Export a page of history as JSON or plain text |
Sending and changing messages | ||
| 🟡 | Send a text or reply; |
| 🔴 | Edit your own text message (WhatsApp time limits apply) |
| 🔴 | Delete your own message for everyone |
| 🟡 | Add or remove an emoji reaction |
| 🟡 | Forward a message to another permitted chat |
| 🟡 | Create a poll |
| 🟡 | Send read receipts for specific messages, only when you ask |
Media | ||
| 🟢 | Find photos, videos, voice notes, stickers and documents in history |
| 🟢 | Download an attachment up to 500 MB (inline if small, otherwise a file handle) |
| 🟢 | Inspect an attachment as a native image, audio or document, or as a file handle |
| 🟢 | Read a cached attachment in bounded chunks |
| 🟢 | Check local transcription, PDF, video-frame and vision support |
| 🟢 | Start a local analysis job: transcription, text extraction or visual description |
| 🟢 | Job status and paginated results |
| ⚪ | Cancel a queued or running analysis job |
| ⚪ | Remove a cached download or upload (doesn't touch WhatsApp) |
| 🟡 | Start a chunked upload for sending a file up to 500 MB |
| 🟡 | Append up to 1 MB to an upload (safe to retry at the same offset) |
| 🟡 | Send an image, video, audio or document |
Groups, presence and chat settings | ||
| 🟢 | Group subject, description, participants and roles |
| 🔴 | Change a group's subject or description |
| 🟡 | Online/offline, typing or recording indicators |
| 🟢 | Receive a chat's typing and presence events through |
| 🟡 | Archive/unarchive, mute/unmute |
Drafts and scheduling | ||
| 🟡 | Save or update a local draft without sending |
| 🟢 | List drafts |
| 🔴 | Delete a draft |
| 🟡 | Schedule a text for an ISO 8601 time; interrupted sends become uncertain, never re-sent |
| 🟢 | Scheduled messages and their delivery status |
| 🔴 | Cancel a pending scheduled message |
The bridge also exposes the resource whatsapp://recent (recent permitted messages, labelled untrusted).
Configuration
npm run setup writes .env. Every value can also be set as a normal environment variable. See .env.example.
Variable | Default | Purpose |
|
| Where the local bridge listens |
| generated | Owner token for the dashboard and local MCP (≥ 32 characters) |
|
| Reconnect a saved WhatsApp session on start |
|
| Block every outgoing action, draft change and schedule |
| all chats | Comma-separated chat JIDs the AI may access |
| local | Public HTTPS origin if you expose the bridge directly (enables OAuth) |
|
| WhatsApp credentials, SQLite history, media cache |
| none | Your relay's HTTPS origin (leave unset for local-only) |
| generated | Shared by your devices; the key also encrypts the relay queue |
| generated | Unique per device; used for failover and read handoff |
|
| Set |
|
| Standby only: how often to check the primary ( |
| none | Optional bearer credential if your relay sits behind an extra access layer |
Relay secrets: WA_AGENT_KEY, WA_CLIENT_KEY (relay-worker/.env.example). Doorway secrets: RELAY_URL, PROXY_KEY, CLIENT_KEY, SITE_KEY (optional) (claude-proxy/.env.example).
Troubleshooting
Start with npm run doctor. It catches most of the problems below automatically.
Symptom | Fix |
| Install the current LTS from nodejs.org; check with |
No QR code, or "session rejected" | In the dashboard choose Retry pairing. On your phone, remove stale entries under Linked devices. |
AI says "Start the WhatsApp bridge first" | The local MCP adapter talks to the running bridge: run |
Claude connector: | The |
Claude connector: | The doorway can't reach a relay on the same Cloudflare account by URL. Keep the |
Claude connector: | Upload the doorway secrets: |
"Your Mac bridge is offline" from the relay | No device has polled for 45 seconds. Check that |
| Two devices are using different |
A send timed out and "may have executed" | Intended behaviour: check the chat with |
Both devices answer for a few seconds | Harmless overlap during failover; each request is still handled exactly once. |
Auto-start doesn't start (macOS) |
|
Auto-start doesn't start (Linux) |
|
Auto-start doesn't start (Windows) | Task Scheduler → WhatsApp Relay → History, and |
Port 8787 in use | Set |
Project layout
src/ bridge: WhatsApp session (Baileys), SQLite store, MCP tools, dashboard API, remote agent
public/ dashboard (no build step, no external assets)
scripts/ setup helpers, service runner, auto-start installers (macos/, linux/, windows/)
relay-worker/ hosted relay: Cloudflare Worker + D1; src/lib/ holds the broker and encrypted queue protocol
claude-proxy/ Cloudflare Worker "doorway" for claude.ai custom connectors
deploy/ Docker / self-hosting recipes (see deploy/SELF-HOST.md, deploy/HOSTING.md)
test/ Node test suite (+ Python tests for media and session transfer)
setup.mjs `npm run setup`Development
npm test # bridge, relay broker, failover, setup, auto-start
(cd claude-proxy && npm test) # doorway
(cd relay-worker && npm test) # standalone relay
python3 -I -m unittest discover -s test # optional media worker / transfer helpersSee CONTRIBUTING.md.
Verified end to end
Before release, the full path (a Claude-style MCP client → Cloudflare doorway → relay Worker + D1 on the free plan → two bridges in demo mode, primary and standby) was deployed with the commands in this README and tested live:
Check | Result |
Wrong | rejected (401) |
| 37 tools |
Tool call round trip ( | ~0.4–0.8 s each |
Same | one message |
Primary frozen (like a closed laptop lid) | standby answered the next request after 3.97 s |
Primary frozen partway through a read ( | read handed to the standby and answered; the late primary's result was refused (409) |
A write after failover | exactly one message |
macOS launchd auto-start | starts; a killed bridge restarts in ~2 s; a killed runner is restarted by launchd; uninstall removes everything |
Linux (systemd) and Windows (Task Scheduler) auto-start are installed and checked for real on GitHub-hosted machines in CI.
Limits and honest caveats
Relay uses Baileys, an unofficial WhatsApp Web client. WhatsApp changes can break it, and automated use can lead to account restrictions. Use it for your own account and normal conversations.
Only history that WhatsApp syncs to the linked device is available.
AI clients read live data when they call a tool. Relay doesn't make an idle conversation run on its own, and there are no automatic AI replies.
WhatsApp credentials and history are stored unencrypted inside a private
data/directory on each bridge. Protect that machine (disk encryption, a login password).
License
MIT. Dependencies keep their own licenses. WhatsApp is a trademark of WhatsApp LLC; Relay is not affiliated with or endorsed by WhatsApp, Meta, Anthropic or OpenAI.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Free WhatsApp MCP server for ChatGPT and Claude: read and search chats, every send you approve.
WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.
Ask questions across your WhatsApp inbox from Claude, ChatGPT, Cursor or any MCP client.
Let Claude or ChatGPT search, read and send your WhatsApp messages over MCP. OAuth sign-in.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA self-hosted WhatsApp bridge that exposes a stdio MCP server with ~20 tools for reading conversations, sending messages, managing groups, contacts, and aliases, enabling AI agents to operate WhatsApp directly.4MIT
- AlicenseNot gradedqualityCmaintenanceA self-hosted WhatsApp bridge with an AI agent enabling searchable context, message drafting, and approval workflow via MCP protocol for Claude Desktop and other MCP clients.1MIT
- FlicenseNot gradedqualityAmaintenanceConnects a Claude Code (or any MCP) session to a WhatsApp account as a linked device or via Meta's official Cloud API, enabling bidirectional chats, group support, media exchange, local voice-note transcription, and scheduled tasks. Inbound messages are gated by pairing codes, allowlists and per-group policies, and Claude's tool permission requests can be approved or denied remotely with an emoji reaction.-
- AlicenseNot gradedqualityBmaintenanceRuns locally and pairs an existing WhatsApp account as a linked device, enabling Claude Code, Codex, and other MCP clients to read chats, retrieve media, draft replies, and send messages only after client-enforced human approval.41 npmMIT