whatsapp-mcp
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Cross-platform WhatsApp Model Context Protocol server with multi-account support and optional local Whisper transcription
WhatsApp MCP Server
This is a Model Context Protocol (MCP) server for WhatsApp.
With this server, an MCP client can search and read your WhatsApp messages (including images, videos, documents, and audio), search contacts, and send messages to individuals or groups. It can also send media files.
It connects to one WhatsApp account at a time through WhatsApp's web multi-device API using whatsmeow. Messages are stored locally in SQLite and are returned to an AI client only when it invokes the corresponding MCP tools.
The core bridge and MCP server are designed for macOS, Linux, and Windows. For two or more accounts, run one isolated bridge profile per account. See platform setup and the multi-account guide.
Fork and attribution
This repository is a maintained fork of Luke Harries' original whatsapp-mcp project. Credit for the original architecture and implementation belongs to Luke Harries and the upstream contributors. The original MIT copyright notice is preserved in LICENSE.
Improvements in this fork
- Supports isolated personal and work accounts with separate stores, ports, identities, and MCP registrations.
- Adds explicit confirmation before messages, files, group changes, chat-state changes, blocking, or typing-presence actions are executed.
- Expands group, account-identity, contact-resolution, chat-management, media, call-history, and targeted history-synchronization capabilities.
- Adds delivery/read receipt tracking and a bounded, replayable Server-Sent Events stream for live messages and receipts.
- Improves pairing with native QR image handling, phone-number pairing, clearer linked-device identities, and terminal fallback.
- Provides persistent-service guidance and platform-native data locations for macOS, Linux, and Windows; macOS Contacts.app access remains optional.
- Hardens media handling with collision-resistant downloads, portable filenames, correct document MIME metadata, and WhatsApp
FileNamesupport. - Adds locked Python dependencies, automated tests, race/static checks, and CI coverage across macOS, Linux, and Windows.
Caution: as with many MCP servers, WhatsApp MCP is subject to the lethal trifecta. Prompt injection could therefore lead to private data exfiltration. Keep the bridge bound to localhost, review tool calls, and require confirmation for outbound actions.
Installation
Prerequisites
- Go
- Python 3.11+
- An MCP client such as Codex, Claude Desktop, or Cursor
- uv (Python package and environment manager)
- FFmpeg (optional) — needed only to convert non-Opus audio into playable WhatsApp voice messages. Without FFmpeg, raw audio can still be sent with
send_file. - Whisper transcription (optional) — installed separately through the
whisperdependency extra described below.
Steps
Clone this repository
git clone https://github.com/DJNgoma/whatsapp-mcp.git cd whatsapp-mcpInstall UV and prepare the Python MCP server
UV creates an isolated Python environment, installs the exact dependencies recorded in
uv.lock, and launches the stdio MCP server for your MCP client. It manages the Python MCP component only; the Go WhatsApp bridge still runs separately.Install UV using the official instructions. Common commands are:
# macOS with Homebrew brew install uv # macOS or Linux curl -LsSf https://astral.sh/uv/install.sh | sh# Windows PowerShell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Open a new terminal if the installer updates your
PATH, then verify UV and prepare the locked environment:uv --version cd whatsapp-mcp-server uv sync --locked cd ..uv sync --lockedcreateswhatsapp-mcp-server/.venvand fails rather than silently changing the dependency lockfile.To enable local speech-to-text, install the optional faster-whisper backend instead:
cd whatsapp-mcp-server uv sync --locked --extra whisper cd ..Whisper requirements and behavior:
- Python 3.11 or newer on macOS, Linux, or 64-bit Windows.
- Internet access on first use to download the selected model. The default multilingual
basemodel is a practical CPU-friendly starting point; model weights are cached by the Hugging Face client. - Allow roughly 1 GB of free disk space and at least 2 GB of available RAM for the default model, dependencies, cache, and working data. Larger models require substantially more.
- A CPU is sufficient. NVIDIA GPU acceleration is optional and requires a CUDA/cuDNN combination supported by the installed CTranslate2 release.
- System FFmpeg is not required for transcription because faster-whisper decodes audio through PyAV. FFmpeg remains useful for converting outbound voice messages.
- Audio is transcribed locally. It is not uploaded to an external transcription API, although model weights are downloaded on first use.
Optional environment variables are
WHATSAPP_WHISPER_MODEL(defaultbase),WHATSAPP_WHISPER_DEVICE(defaultauto), andWHATSAPP_WHISPER_COMPUTE_TYPE(defaultdefault). Resource caps areWHATSAPP_WHISPER_MAX_FILE_BYTES=26214400,WHATSAPP_WHISPER_MAX_DURATION_SECONDS=900,WHATSAPP_WHISPER_MAX_SEGMENTS=500, andWHATSAPP_WHISPER_MAX_OUTPUT_CHARS=100000. Restart the MCP client after installing or changing these values. In the MCP client command, userun --extra whisper main.pyinstead ofrun main.pyso uv always activates the optional dependency when launching the server.Run and pair the WhatsApp bridge
The portable launcher chooses the native per-user data directory, prints it, and starts the bridge on localhost port
8741:# macOS or Linux python3 scripts/run_bridge.py --instance-id personal # Windows PowerShell py scripts/run_bridge.py --instance-id personalThe stores default to:
- macOS:
~/Library/Application Support/whatsapp-mcp/store - Linux:
$XDG_DATA_HOME/whatsapp-mcp/storewhen set, otherwise~/.local/share/whatsapp-mcp/store - Windows:
%LOCALAPPDATA%\whatsapp-mcp\store
On macOS and Linux, the launcher creates or tightens the store directory to
mode0700before the bridge writes linked-device state, messages, or media.
Windows uses the current user's application-data ACL instead of POSIX modes.
Give every concurrently running profile a distinct--instance-id; the
bridge returns it from/api/healthso service checks can distinguish a
healthy process from a different account already using the port.The first time you run it, the bridge writes the QR code to a temporary PNG and opens it automatically in your system image viewer. Current WhatsApp pairing uses two scans:
- Scan the newest QR image with your phone's regular Camera app.
- Tap the WhatsApp link that appears, then tap Continue in WhatsApp.
- Scan the newest QR image again inside WhatsApp to confirm linking.
WhatsApp rotates pairing codes, so always use the newest image. If the system image viewer cannot be opened, the QR code is displayed in the terminal as a fallback.
New pairings use the current host platform for their linked-device identity. Existing linked-device labels cannot be changed in place.
Alternatively, pair using your phone number in international format:
python3 scripts/run_bridge.py --instance-id personal --phone +15551234567 # Windows: py scripts/run_bridge.py --instance-id personal --phone +15551234567The bridge prints an eight-character code. On your phone, open WhatsApp > Settings > Linked Devices > Link a Device > Link with phone number instead, then enter it. Omit
--phoneto use QR pairing.Keep this process running while using the MCP server. For background startup, Linux systemd and Windows Task Scheduler instructions are in docs/platform-setup.md. On macOS, you can install the included LaunchAgent after pairing:
python3 scripts/install_macos_launch_agent.pyThe installer derives an instance ID from the profile's LaunchAgent label
and does not report success until/api/healthreturns that exact ID while
connected and logged in. A different bridge on the same port therefore
fails the install check instead of being mistaken for the requested profile.The optional Contacts.app helper remains macOS-only; WhatsApp contact/chat search works on every supported platform without it. Opt in on macOS with
python3 scripts/install_macos_launch_agent.py --with-contacts.- macOS:
Connect your MCP client
Get the store directory selected by the launcher, plus the absolute paths required by MCP clients:
python3 scripts/run_bridge.py --print-store-dir command -v uv cd whatsapp-mcp-server && pwdOn Windows, use
py scripts/run_bridge.py --print-store-dir,Get-Command uv, and(Resolve-Path whatsapp-mcp-server).Pathin PowerShell.For Codex on macOS or Linux, register the server using the absolute paths returned above:
codex mcp add \ --env 'WHATSAPP_STORE_DIR=/absolute/path/printed/above' \ --env 'WHATSAPP_BRIDGE_URL=http://127.0.0.1:8741/api' \ whatsapp -- \ /absolute/path/to/uv \ --directory /absolute/path/to/whatsapp-mcp/whatsapp-mcp-server \ run main.pyVerify the registration:
codex mcp get whatsappOn Windows, use PowerShell with the paths returned by
Get-Command uvandResolve-Path:codex mcp add ` --env "WHATSAPP_STORE_DIR=C:/Users/your-name/AppData/Local/whatsapp-mcp/store" ` --env "WHATSAPP_BRIDGE_URL=http://127.0.0.1:8741/api" ` whatsapp -- ` "C:/absolute/path/to/uv.exe" ` --directory "C:/absolute/path/to/whatsapp-mcp/whatsapp-mcp-server" ` run main.pyForward slashes are valid in these Windows command paths and avoid backslash escaping.
For Claude Desktop or Cursor, use the same absolute paths in this configuration:
{ "mcpServers": { "whatsapp": { "command": "/absolute/path/to/uv", "env": { "WHATSAPP_STORE_DIR": "/absolute/path/printed/above", "WHATSAPP_BRIDGE_URL": "http://127.0.0.1:8741/api" }, "args": [ "--directory", "/absolute/path/to/whatsapp-mcp/whatsapp-mcp-server", "run", "main.py" ] } } }Use forward slashes or escaped backslashes (
\\) in Windows JSON paths. Platform-specific Claude Desktop and Cursor config locations are listed in docs/platform-setup.md.Restart your MCP client and test
Restart Codex, Claude Desktop, or Cursor so it loads the newly registered server. For a safe first test, ask:
Use WhatsApp to list my five most recent chats. Do not send anything.
Platform support
CI is configured to build and test the Go bridge and Python MCP server on macOS, Ubuntu Linux, and Windows. Live account testing for this fork has been performed on macOS; Linux and Windows still need broader real-world validation, so bug reports and compatibility feedback are appreciated. Windows needs CGO plus a C compiler because the bridge uses SQLite; the exact MSYS2 setup and persistent-service instructions are in docs/platform-setup.md.
Architecture overview
This application consists of two main components:
Go WhatsApp Bridge (
whatsapp-bridge/): A Go application that connects to WhatsApp's web API, handles authentication via QR code, and stores message history in SQLite. It serves as the bridge between WhatsApp and the MCP server.Python MCP server (
whatsapp-mcp-server/): A Python server implementing the Model Context Protocol (MCP), which exposes standardized WhatsApp tools to compatible AI clients.
Data storage
- All message history, login state, and downloaded media are stored locally in the configured store directory
- Each account profile must have its own store directory, bridge port, service/process, and MCP process; never point two accounts at the same SQLite store
- The portable launcher uses each platform's per-user application-data directory;
whatsapp-bridge/storeremains the legacy direct-run default - Portable macOS/Linux launchers and the macOS installer enforce
0700account-state and log directories; migrated databases and copied private files are tightened to0600 - The database maintains tables for chats and messages
- Messages are indexed for efficient searching and retrieval
Bridge API notes
The bridge API is intentionally unauthenticated and bound only to 127.0.0.1.
Do not bind it to all interfaces, expose it through a reverse proxy, publish it
through a tunnel, or treat the MCP confirmation token as HTTP authentication.
Any local process able to reach the port can call the API directly. Use a
distinct port, store, process, MCP registration, and health instance_id for
every account profile.
The bridge exposes paginated /api/chats and /api/messages endpoints using limit and offset, returns phone_number where a direct chat can be resolved, and publishes live messages and receipts through the replayable GET /api/events Server-Sent Events stream. SSE clients should reconnect with Last-Event-ID; an event: reset response means the cursor fell outside the bounded replay window and the client should reconcile through the read endpoints.
Message reads union a direct chat's phone JID and LID aliases. Media captions and call records are retained, and local media filenames include the message ID to prevent collisions. The targeted POST /api/history-sync endpoint requests older or newer history from a stored message anchor; it cannot manufacture records WhatsApp does not return.
Usage
Once connected, Codex, Claude Desktop, Cursor, or another compatible MCP client can use the tools below.
MCP tools
The connected MCP client can access these WhatsApp tools:
- search_contacts: Search for contacts by name or phone number
- contacts_app_status: Check macOS Contacts.app availability and permission
- bridge_status: Report live bridge connectivity and whether database reads may be stale
- get_own_identity: Return the connected WhatsApp JID, phone number, display name, and device identity
- search_contacts_chats_and_groups: Search direct chats, groups, recent chats, and optional macOS Contacts.app entries
- list_messages: Retrieve messages with optional filters and context
- list_chats: List available chats with metadata
- list_joined_groups: List live WhatsApp groups and participant counts
- get_group_info: Read live group metadata, participants, and admin roles
- create_group: Prepare and explicitly confirm creation of a WhatsApp group
- add_participants_to_group / remove_participants_from_group: Prepare and explicitly confirm membership changes
- promote_participants_to_admins / demote_participants_from_admins: Prepare and explicitly confirm admin-role changes
- set_chat_read_state: Prepare and explicitly confirm marking a chat read or unread
- is_on_whatsapp: Validate phone numbers against WhatsApp without sending
- set_chat_mute / set_chat_archive: Prepare and explicitly confirm chat-state changes
- set_contact_block: Prepare and explicitly confirm blocking or unblocking a contact
- send_typing_indicator: Prepare and explicitly confirm composing, recording, or paused presence
- get_chat: Get information about a specific chat
- get_direct_chat_by_contact: Find a direct chat with a specific contact
- get_contact_chats: List all chats involving a specific contact
- get_last_interaction: Get the most recent message with a contact
- get_message_context: Retrieve context around a specific message
- send_message: Prepare and explicitly confirm a WhatsApp message to a phone number or group JID
- send_file: Prepare and explicitly confirm a file send (image, video, raw audio, document)
- send_audio_message: Prepare and explicitly confirm an audio send (requires an
.oggOpus file or FFmpeg) - download_media: Download media from a WhatsApp message and get the local file path
- whisper_status: Report whether optional local Whisper transcription is installed and show the selected model/device settings
- transcribe_audio_message: Download a WhatsApp audio message and transcribe it locally, with optional language and vocabulary hints
Media handling
The MCP server supports both sending and receiving various media types:
Media sending
You can send various media types to your WhatsApp contacts:
- Images, Videos, Documents: Use the
send_filetool to share any supported media type. - Voice Messages: Use the
send_audio_messagetool to send audio files as playable WhatsApp voice messages.- For optimal compatibility, audio files should be in
.oggOpus format. - With FFmpeg installed, the system will automatically convert other audio formats (MP3, WAV, etc.) to the required format.
- Without FFmpeg, you can still send raw audio files using the
send_filetool, but they won't appear as playable voice messages.
- For optimal compatibility, audio files should be in
- Document metadata: Document MIME types and filenames are preserved so files such as PDFs arrive with readable names and the correct type.
Media downloading
By default, the database stores media metadata rather than the complete file. Use download_media with the message's message_id and chat_jid to download it. The tool returns a platform-native local path that can be opened or passed to another tool.
Optional Whisper transcription
After installing the whisper extra, use transcribe_audio_message with the same message_id and chat_jid shown by message tools. The first request downloads the configured model and can therefore take longer. Subsequent requests reuse the cached model in the MCP process. Use whisper_status to diagnose installation or configuration without downloading a model.
Technical details
- The AI client invokes a tool on the Python MCP server.
- Read tools query the local SQLite cache; live operations call the Go bridge.
- The Go bridge communicates with WhatsApp and keeps the local cache up to date.
- Results return through the MCP server to the client.
- Outbound and state-changing operations require the confirmation flow described below before reaching WhatsApp.
Operational and safety boundaries
- Read tools query the local
messages.db. Usebridge_statusto determine whether the bridge is connected; results may be stale while it is stopped or disconnected. - Sending and media downloads require the live bridge. The default endpoint is localhost-only at
http://127.0.0.1:8741/api. - Contact search can optionally merge known WhatsApp direct chats with read-only Contacts.app results on macOS. Enable it with
python3 scripts/install_macos_launch_agent.py --with-contacts. Contacts without a known chat are markedhas_whatsapp_chat: false; the server does not assume that every address-book number has WhatsApp. - Contact-search tools require a non-empty name or phone-number fragment; blank queries return no contacts.
- Contacts.app access is opt-in. On first use, macOS asks whether WhatsApp MCP Contacts may access your contacts. If the helper is absent or permission is denied,
contacts_app_statusreports that state and WhatsApp-only contact and chat search continues to work. - Text, file, and audio sends use a two-stage flow. The first tool call returns a preview and a short-lived one-time token without sending. A second matching call is required after explicit user confirmation.
- Persistent service logs run at WARN level and omit message bodies by default. Interactive debugging can opt in with
--log-messages, but this writes private content to the console or configured log. - Group, read-state, mute, archive, block, and typing operations use the same exact-preview confirmation contract as outbound messages.
- Bridge JSON request bodies default to a 1 MiB cap (
WHATSAPP_BRIDGE_MAX_REQUEST_BODY_BYTES), and inbound media downloads default to 512 MiB (WHATSAPP_BRIDGE_MAX_MEDIA_DOWNLOAD_BYTES). Invalid or non-positive overrides fall back to those defaults; lower the values on resource-constrained machines. - MCP message/chat reads cap page sizes at 100, page numbers at 1,000, and per-side message context at 50. Invalid or excessive values are clamped again in the database helpers so negative SQLite limits cannot expand into full-store reads.
- Local Whisper transcription defaults to a 25 MiB input, 15 minutes of decoded audio, 500 segments, and 100,000 output characters.
whisper_statusreports the active limits; theWHATSAPP_WHISPER_MAX_*environment variables may lower or deliberately raise them for a trusted workstation. - The MCP currently cannot edit or delete messages, react, post statuses, make calls, or manage product-level lists and workflows.
Troubleshooting
- If you encounter permission issues when running
uv, add it toPATHor use its absolute path. Usecommand -v uvon macOS/Linux orGet-Command uvin Windows PowerShell. - Use
bridge_statusor the/api/healthendpoint to distinguish a stopped bridge from a stale local database. - For service logs and startup checks on macOS, Linux, and Windows, use the matching section in the platform setup guide.
Authentication issues
- QR code not displayed: Restart the bridge launcher. On macOS it uses the default image viewer, on Linux it uses
xdg-open, and on Windows it uses the registered image handler. If opening the image fails, use the QR code printed in the terminal. - WhatsApp already logged in: If your session is already active, the Go bridge reconnects without showing a QR code.
- Device limit reached: WhatsApp limits the number of linked devices. Remove an unused device from WhatsApp > Settings > Linked Devices, then retry.
- No messages loading: Initial history synchronization can take several minutes, especially for accounts with many chats.
- Partial history after recovery: Use the bridge's targeted history-sync endpoint with a stored oldest-message anchor. If WhatsApp returns no earlier records, the bridge cannot fill the gap; inspect logs and retain the local store.
- WhatsApp out of sync: Stop the bridge, unlink the affected linked device in WhatsApp, and move that profile's
whatsapp.dbaside before pairing again with the same store. Preservemessages.db; it contains local message history. Never repair one account using another account's store.
For client integration help, see the Codex MCP documentation, the MCP guide for connecting local servers (including Claude Desktop), or the Cursor MCP documentation. These client instructions apply across macOS, Linux, and Windows where the respective client is available; bridge-specific platform commands remain in the platform setup guide.
Quoted replies
Use reply_message(chat_jid, message_id, message) to prepare a text reply to a
specific message. list_messages now includes both identifiers on text as well
as media results. Copy the exact stored chat JID (including @lid where present).
The preview includes the original sender, quoted text/media type, and reply text;
a second call with identical arguments and its one-time confirmation_token
sends only after user approval. A changed quote, chat, or reply invalidates the
confirmation. There is no fallback to an ordinary message.
The bridge exposes read-only GET /api/reply/preview?chat_jid=...&message_id=...
and POST /api/reply with chat_jid, message_id, message, and the preview'sfingerprint. As with /api/send, the loopback REST API is a trusted local
interface; user confirmation is enforced by the MCP layer. The send endpoint
rechecks the fingerprint before sending. Successful responses include both the
new message_id and reply_to_message_id; storage warnings do not turn an
already accepted provider send into a retryable failure.
Text, image, video, document, audio, and sticker targets captured after this
upgrade retain shallow quote payloads in the private message_quotes table.
History sync also captures payloads when the sender namespace is known. Older
text can be quoted when the sender can be resolved reliably; older media without
its original payload and ambiguous group senders are rejected. This tool sends
text replies; sending new media as a reply is not currently exposed. Ordinary
send tools retain their existing behavior.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi