WA MCP
Server Details
Read, search and reply to your WhatsApp chats from your AI, using your own number.
- Status
- Healthy
- Uptime
- 100.0% over the last 24 hours
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- bernardoruz/wa-mcp
- GitHub Stars
- 0
- Server Listing
- WA MCP
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 25 tools
Most tools are clearly separated by resource and action (send/schedule/edit/delete/react on messages; read vs search vs list chats), and descriptions explicitly cross-reference alternatives (e.g. get_recent_chats vs get_unanswered_chats, QR vs pairing code, unlink vs delete_account). However, the five chat-discovery/reading tools (get_recent_chats, get_unanswered_chats, read_chat_history, search_messages, search_contacts) form a cluster where an agent could still pick the wrong one, and mark_as_read/mark_as_unread are easy to swap.
Every tool is snake_case verb_noun with a consistent, predictable verb vocabulary (get_, list_, search_, send_, schedule_, cancel_, delete_, mark_, manage_, report_, restart_, unlink_). No mixing of camelCase or vague standalone verbs.
25 tools is at the heavy end for a WhatsApp connector; while each maps to a real capability, some could be consolidated (mark_as_read/mark_as_unread, get_pairing_qr/request_pairing_code, the three chat-listing tools). The surface feels broad rather than tightly scoped.
Core messaging lifecycle is well covered: send text/media/poll, quote replies, read, search, schedule/cancel, edit, delete, react, mark read/unread, plus pairing, session recovery, billing and feedback. Gaps are mostly inherent or peripheral — no poll-result reading, no group administration or contact creation, and no single-message fetch outside history/search.
Available Tools
25 toolscancel_scheduled_messageADestructiveIdempotentInspect
Cancels scheduled messages before they are sent. Pass id to cancel that message; if it repeats, the whole series is cancelled (any of the series' ids works). It also cancels a queued send_message (its scheduled_id) that hasn't gone out yet. Messages already sent, or being sent right now, can't be cancelled; the result says so. Find ids with list_scheduled_messages (filter by to or text). To change a scheduled message, cancel it and schedule it again with schedule_message. Confirm with the user first unless they asked for it. Works on the free plan too. Returns { cancelled, messages }, the cancelled messages { id, series_id (shared by every send of a repeating message), kind? ("queued" for a send_message that was queued to go out automatically; absent for scheduled messages), status (scheduled, processing, sent, failed, missed or cancelled), recipient (contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +).), text?, media?, send_at (UTC), send_at_local, when (readable local time and how far away), timezone, recurrence, occurrence? (0 = first send of a series), until?, sent_at?, message_id? (once sent), error? (why it failed or was missed) }.
Inputs: id (required).
delete_accountADestructiveIdempotentInspect
Removes this WhatsApp connector (wa-mcp) and the user's account with the connector. This does NOT delete the user's WhatsApp account: their WhatsApp account, chats and phone are not affected. Use it when the user asks to delete their wa-mcp account or remove the connector; this tool is the only way to do it (the service has no website or account page). It cancels the wa-mcp subscription, unlinks this connector from WhatsApp, and erases the connector's own copy of the user's messages and data (the originals stay in WhatsApp on the phone). Two steps: first call it without confirm (nothing is deleted) and show the user the summary it returns; once the user agrees, call it again with confirm: "DELETE".
Inputs: confirm.
delete_messageADestructiveIdempotentInspect
Deletes one of the user's own WhatsApp messages for everyone in the chat (like "Delete for everyone" on the phone), in a 1:1 chat or a group. Paid plan only: on the free plan the call is refused with a note on how to subscribe. Pass the message's id from read_chat_history or search_messages; the chat is looked up automatically. Only messages the user sent (from "Me") can be deleted. Everyone in the chat sees that a message was deleted, and it can't be undone, so confirm with the user first unless they asked for it. Returns { message_id, status (deleted or failed), chat, warning?, error? }: chat is the conversation, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). warning is set when the message is more than about 15 minutes old: WhatsApp may not delete it for everyone; tell the user.
Inputs: message_id (required).
download_mediaARead-onlyInspect
Fetches a photo, sticker, voice note, audio, video or document from a WhatsApp message, only when the user asks for it. Paid plan only: on the free plan the call is refused with a note on how to subscribe. Small images are returned as an image you can look at. Everything else returns a download link valid for 15 minutes: share it with the user. You cannot play or transcribe audio yourself. Get message ids from search_messages (media appears as e.g. "[voice note, 0:42]") or read_chat_history.
Inputs: message_id (required), chat_jid.
edit_messageADestructiveIdempotentInspect
Edits the text of one of the user's own WhatsApp text messages for everyone in the chat (like "Edit" on the phone), in a 1:1 chat or a group. Paid plan only: on the free plan the call is refused with a note on how to subscribe. Pass the message's id from read_chat_history or search_messages and the full new text; the chat is looked up automatically. Only text messages the user sent (from "Me") can be edited, not captions of photos, videos or documents. If you are writing the text yourself rather than sending words the user gave you, call get_writing_style for this chat first and write it the way the user writes; skip that for dictated text. WhatsApp doesn't render Markdown: use bold, italic, strikethrough and "- " lists, and never send tables, # headings, double asterisks or text links. Write a table as short lines (e.g. "Ana: $200") and paste URLs plain. Only format when it suits the message. Everyone in the chat sees the new text marked as edited, so confirm the wording with the user first unless they gave it. Returns { message_id, status (edited or failed), chat, text, warning?, error? }: chat is the conversation, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). warning is set when the message is more than about 15 minutes old: WhatsApp may not apply the edit; tell the user.
Inputs: text (required), message_id (required).
get_pairing_qrAInspect
Initiates pairing and returns a QR code (image, an auto-refreshing link, and a data URL). The QR must be scanned with the camera of the phone that has the user's WhatsApp, so it has to be shown on a different screen (another phone, a computer or a tablet). If the user is talking to you on the same phone that has their WhatsApp, and has no second screen to show the QR on, do NOT use this — use request_pairing_code instead. If the QR expires, call it again: it reuses the running pairing session. Use only ONE pairing method at a time: never call request_pairing_code and get_pairing_qr together, and never call restart_session while the user is pairing.
Inputs: no named parameters.
get_recent_chatsARead-onlyInspect
Lists the user's most recent WhatsApp chats (people and groups), newest first: each with its chat_jid, a preview of the last message, and the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). Use it for "what's new", to find a chat's JID before read_chat_history, or to pick up recent conversations. To find chats waiting for a reply, use get_unanswered_chats instead.
Inputs: limit (required).
get_session_statusARead-onlyInspect
Check the connection status of the WhatsApp session. Returns:
connected: Network connected (WebSocket to WhatsApp)loggedIn: Paired / authenticated (valid session credentials)ready:connected && loggedIn— safe to send and readlastSync: Last successful sync with WhatsAppstatusSummary: Human-readable status Call it when a send or read fails, or when unsure whether WhatsApp is linked; only send or read whenreadyis true.
Inputs: no named parameters.
get_unanswered_chatsARead-onlyInspect
Lists one-to-one chats whose last message came from the other person within the last hours_ago hours (default 24, max 72), so the user may owe them a reply. Groups aren't included. Checks the 50 most recent active chats in that window, newest first; an empty list means none of them is waiting for a reply. Each chat has its chat_jid, the time and sender of the last message, a preview, and the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). Use it for "who do I need to reply to?". For a general look at recent activity, including groups and chats where the user wrote last, use get_recent_chats instead.
Inputs: hours_ago.
get_writing_styleARead-onlyInspect
Shows how the user writes, so messages you write for them sound like them. Call it before drafting a message for the user (send_message, schedule_message, edit_message) when you are composing the words; skip it when the user dictated the exact text. With chat, returns the user's own recent messages in that chat; if they wrote fewer than 5 there (a new contact or a mostly incoming chat), or without chat, adds a few of their messages from each of their one-to-one chats of the last 30 days, labelled by chat, so you can pick the closest relationship. Only messages the user typed themselves are included; messages sent through this server are left out (best effort: a few may appear after WhatsApp is re-linked). Returns { source (chat, chat+global or global), chat, chat_messages, other_chats: [{ chat, messages }], hints, guidance }: chat and each other_chats chat have the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). hints summarizes the sample (median_length, emoji_rate, top_emoji, laughs, capitalized_rate, ending_punctuation_rate, burst_rate). Copy the style, never the content.
Inputs: chat.
list_scheduled_messagesARead-onlyInspect
Lists the user's scheduled messages: upcoming ones and the history of past sends (sent, failed, missed, cancelled; kept 90 days). Every filter is optional and they combine. It also lists send_message calls that were queued to go out automatically (kind "queued"), so it shows whether a queued message went out. Use it to answer "what's scheduled?", to check whether scheduled messages went out (and why one failed), and to find a message's id before cancelling or changing it. A repeating message shows one row per send: the next upcoming one plus its past sends. Returns { total, returned, offset, counts_by_status, upcoming (soonest first), history (newest first) }, each message in short form { id, series_id? (only when it differs from id), kind? ("queued" only), status, recipient { name, phone_display, canonical_jid }, text? (the first 150 characters; text_truncated: true when cut), media?, send_at (UTC), when (readable local time and how far away), recurrence, occurrence?, until?, sent_at?, message_id?, error? }. With id, that one message comes in full: { id, series_id (shared by every send of a repeating message), kind? ("queued" for a send_message that was queued to go out automatically; absent for scheduled messages), status (scheduled, processing, sent, failed, missed or cancelled), recipient (contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +).), text?, media?, send_at (UTC), send_at_local, when (readable local time and how far away), timezone, recurrence, occurrence? (0 = first send of a series), until?, sent_at?, message_id? (once sent), error? (why it failed or was missed) }. A page holds up to limit messages but stops early when they are long. If total is more than offset + returned, page with offset (the headline gives the next one) or narrow the filters. Works on the free plan too.
Inputs: id, to, kind, text, +9 more.
manage_subscriptionAIdempotentInspect
Use this tool to check the user's subscription status, retrieve pricing and payment links for new subscriptions, or generate a secure Stripe portal link for the user to update their credit card or cancel an active subscription. This is the only way to pay, upgrade to Pro, buy or change a plan: the wa-mcp.com website has no account or login, and creating a new key there doesn't pay for the number already linked. Also use it when the user wants to remove the "Sent via wa-mcp.com" label from their messages or unlock paid features (sending files, opening received files, scheduling, and editing, reacting to and deleting messages): without a subscription they are on the free plan. If the user has a team plan code from their company, pass it as team_code to move this number onto the company's plan; the user's own subscription, if any, then stops renewing. Teams of 10+ people can ask wa-mcp support for a team plan.
Inputs: team_code.
mark_as_readAIdempotentInspect
Mark a chat as read. Without message_id it marks the latest incoming message (and everything before it). If providing message_id for a group chat, sender_jid must also be provided. The sender sees blue ticks (in one-to-one chats, only if the user has read receipts on), and the chat also shows as read on the user's phone, including a chat marked unread. Reading a chat with read_chat_history doesn't mark it as read; call this only when the user asks.
Inputs: jid (required), message_id, sender_jid.
mark_as_unreadAIdempotentInspect
Marks a chat as unread: the unread dot appears on it on the user's phone and other devices, like "Mark as unread" on the phone. Useful as a reminder to come back to a chat. It only sets the dot: blue ticks already sent stay sent, and the sender sees nothing. mark_as_read clears it. Call this only when the user asks. If it answers that WhatsApp is re-syncing, ask the user to open WhatsApp on their phone and try again in a minute. Returns { status: "unread", chat }, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +).
Inputs: jid (required).
react_to_messageAIdempotentInspect
Reacts to a WhatsApp message with an emoji (like tapping and holding a message on the phone), in a 1:1 chat or a group, on the other person's messages or the user's own. Paid plan only: on the free plan the call is refused with a note on how to subscribe. Pass the message's id from read_chat_history or search_messages; the chat, the sender and whether the user sent it are looked up automatically. A new reaction replaces the user's previous one on that message; pass emoji "" to remove it. Everyone in the chat sees the reaction, so confirm with the user first unless they asked for it. Returns { message_id, status (reacted, removed or failed), emoji, chat, error? }: chat is the conversation, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). If the message can't be found, the error asks for chat_jid (and from_me or sender_jid); pass them only then.
Inputs: emoji (required), message_id (required), from_me, chat_jid, +1 more.
read_chat_historyARead-onlyInspect
Reads a chat's latest messages, newest first: id, timestamp, sender and text (media as placeholders like "[voice note, 0:42]"; fetch the file with download_media, paid plan). Returns { chat, participants?, messages }: chat is the conversation and, in groups, participants maps each message's sender_jid to that sender, both with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). Covers about the last 90 days. jid can be a chat JID or a phone number. A message that was edited shows its latest text with edited: true. A shared contact card has shared_contacts: [{ name, phone_jid, lid_jid, phone_display }], from the card; send_message takes phone_jid or lid_jid as to. A page holds up to limit messages but stops early when they are long; to go further back, pass the before the headline gives (the id of the oldest message shown). To reply to one of these messages, pass its id as quote_id to send_message (in groups, also its sender_jid as quote_participant). Get chat JIDs from get_recent_chats or search_contacts.
Inputs: jid (required), limit (required), before.
report_feedbackAInspect
Sends a bug report, feature request or message from the user to the WA MCP developers. It's stored with the user's account and phone number so we can follow up; nothing is posted publicly. Each call creates a new report and returns its feedback_id, so call it once per issue. Use when the user reports a bug, asks for a feature, or wants to contact us. Works on the free plan too.
Inputs: type (required), title (required), description (required), context.
request_pairing_codeAInspect
Initiates pairing and returns an 8-character code to enter in WhatsApp (Linked devices → Link with phone number). Use this when the user has only the one phone (the phone with their WhatsApp): the code is typed into WhatsApp on that same phone, so it needs no second screen or camera — unlike the QR code. Use only ONE pairing method at a time: never call request_pairing_code and get_pairing_qr together, and never call restart_session while the user is pairing.
Inputs: phone_number (required).
restart_sessionAIdempotentInspect
Reconnects WhatsApp without requiring a new QR code / re-pair. Use this when the session seems stuck, messages aren't sending, or the connection state is stale. Do NOT use it while the user is pairing (it would cancel the pairing in progress).
Inputs: no named parameters.
schedule_messageAInspect
Schedules a WhatsApp message (text, or a file with optional caption) to one person or group for a later time, once or repeating (e.g. "every Monday at 9:00"). Paid plan only: on the free plan the call is refused with a note on how to subscribe. to works like send_message's and is resolved now, so a wrong name fails right away. Time: pass send_at as an ISO 8601 date-time with the user's UTC offset for that date (e.g. "2026-10-10T09:00:00-06:00"), and timezone as the user's IANA timezone (e.g. "America/Mexico_City"). Use the timezone and current time you know for the user; if you don't know them, ask. Mind daylight saving time: the offset must be the one in effect on that date. The first send must be in the future and at most a year ahead. Messages go out within about a minute of send_at; if the server is down for more than an hour past send_at, that send is marked missed instead of being sent late. Repeats: recurrence once (default), daily, weekly, biweekly, monthly, quarterly, semesterly or yearly, always at the same local time (a monthly message on the 31st goes on the last day of shorter months); optional until (a date like "2026-12-31", or a date-time with offset) ends the series. Each send is tried once: a failure is recorded (see list_scheduled_messages) and the series continues. Quoted replies aren't supported. Files: media.url or media.message_id (checked now and fetched again at send time; message_id only for one-off messages, so prefer a link); media.data isn't accepted. The result gives the local time and how long until it (when) and, for repeats, the first sends: read them back to the user. To change a scheduled message, cancel it with cancel_scheduled_message and schedule it again. At most 100 upcoming scheduled messages per account. If you are writing the text yourself rather than sending words the user gave you, call get_writing_style for this chat first and write it the way the user writes; skip that for dictated text. WhatsApp doesn't render Markdown: use bold, italic, strikethrough and "- " lists, and never send tables, # headings, double asterisks or text links. Write a table as short lines (e.g. "Ana: $200") and paste URLs plain. Only format when it suits the message. To tag (mention) someone in a group so they get notified, write @ followed by their full phone number with country code, digits only (e.g. "@5215512345678", not "@Ana" or "@+52 55…"); WhatsApp shows their name in its place. Get the number from phone_display (read_chat_history participants or search_contacts). Never use the digits of a lid_jid. Messages that start new conversations have extra protection against WhatsApp's anti-spam bans and may be delayed or refused; the result says so and when. Sending the same text, especially with a link, to many people who haven't written to the user can get their number temporarily or permanently banned, even when spaced out: write each person their own message (not just a name swap), and warn the user about this risk when they ask for outreach. Confirm the recipient, text, file and time with the user first unless they already gave them. Returns the scheduled message { id, series_id (shared by every send of a repeating message), kind? ("queued" for a send_message that was queued to go out automatically; absent for scheduled messages), status (scheduled, processing, sent, failed, missed or cancelled), recipient (contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +).), text?, media?, send_at (UTC), send_at_local, when (readable local time and how far away), timezone, recurrence, occurrence? (0 = first send of a series), until?, sent_at?, message_id? (once sent), error? (why it failed or was missed) } plus next_occurrences for repeats.
Inputs: to (required), send_at (required), timezone (required), text, +3 more.
search_contactsARead-onlyInspect
Looks up people in the user's WhatsApp contacts by name, nickname or phone digits, and the groups the user is in by group name (case-insensitive partial match). Returns up to 20 matches, each with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +)., plus is_group (true for a group: its canonical_jid is the group JID and name_source is group_subject; the raw WhatsApp data is under raw). Use it when a name is ambiguous or before messaging a person or group the user hasn't talked to recently. If several match, ask the user which one they mean. Some groups (e.g. community announcement groups) may be missing: if a group isn't found, try get_recent_chats.
Inputs: query (required).
search_messagesARead-onlyInspect
Searches the text and captions of messages from the last 90 days, across all chats or within one chat, using full-text search. Returns { chats, senders?, messages }, newest first: each message has its id, timestamp, chat_jid, sender and text; chats maps each chat_jid to its chat and, for group messages, senders maps each sender_jid to that sender, both with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). Media shows up as e.g. "[voice note, 0:42]" or "[image] caption", but only captions are searchable. An edited message is found and shown by its latest text, with edited: true. Texts longer than about 300 characters are shortened around the match (text_truncated: true); read the chat with read_chat_history for the whole message. A page holds up to limit matches but stops early when they are long; when more may exist, the headline gives the before to pass for the next, older page. For messages older than 90 days or to browse a chat, use read_chat_history.
Inputs: query (required), limit, before, chat_jid, +1 more.
send_messageAInspect
Sends a WhatsApp message to one person or group: text, or a file (photo, document/PDF, voice note, audio file or sticker) with optional text as its caption. On the free plan, text works only to people who have written to the user (starting new conversations needs the paid plan), and "Sent via wa-mcp.com" is added at the end of it; files (media) need the paid plan. to can be a contact name, a phone number with country code, or a JID (…@s.whatsapp.net, …@lid, …@g.us); if a name could match more than one contact, call search_contacts first. To reply to a specific message (a quoted reply), pass its id from read_chat_history or search_messages as quote_id. To send a file, pass media with exactly one source: media.url, a link to the file; media.message_id, the id of a photo, video, voice note, audio, document or sticker message from read_chat_history or search_messages, to send that file on to someone (e.g. "send Ana the photo Juan sent me"); or media.data, base64 for small files you generated yourself (up to 512 KB). You can't pass on a file the user attached to this conversation: ask them to upload it to Google Drive, click Share, set access to "Anyone with the link", and paste the link here; pass that link unchanged as media.url. Google Drive file links, and Google Docs (sent as PDF), Sheets (XLSX) and Slides (PDF) links work directly; so does any public direct link to a file. Don't upload the user's files to other sites without asking them. The type is detected from the file: JPEG/PNG/WebP/GIF go as photos, MP4 (H.264) as a video, OGG/Opus audio as a voice note, other audio (MP3, M4A) as an audio file, everything else (PDF, Office files, other videos such as iPhone MOV/HEVC, HEIC) as a document. A file sent on with media.message_id keeps its kind (a voice note stays a voice note, a document keeps its name) and isn't marked as forwarded; its original caption isn't copied, so pass text for one. Limits: photos, videos and audio 16 MB, documents 32 MB. If you are writing the text yourself rather than sending words the user gave you, call get_writing_style for this chat first and write it the way the user writes; skip that for dictated text. WhatsApp doesn't render Markdown: use bold, italic, strikethrough and "- " lists, and never send tables, # headings, double asterisks or text links. Write a table as short lines (e.g. "Ana: $200") and paste URLs plain. Only format when it suits the message. To tag (mention) someone in a group so they get notified, write @ followed by their full phone number with country code, digits only (e.g. "@5215512345678", not "@Ana" or "@+52 55…"); WhatsApp shows their name in its place. Get the number from phone_display (read_chat_history participants or search_contacts). Never use the digits of a lid_jid. Messages that start new conversations have extra protection against WhatsApp's anti-spam bans and may be delayed or refused; the result says so and when. Sending the same text, especially with a link, to many people who haven't written to the user can get their number temporarily or permanently banned, even when spaced out: write each person their own message (not just a name swap), and warn the user about this risk when they ask for outreach. Sending can't be undone: confirm the recipient, text and file with the user first unless they already gave them. Messages are sent at a safe pace to protect the user's number; when several go at once, some may be queued and sent automatically. Returns { to, status (sent, failed, or queued), recipient, message_id, media?, text_message_id?, note?, error?, scheduled_id?, send_at?, position? }: recipient is who the message went to, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). queued means it wasn't sent yet but goes out by itself at about send_at (number position in line; scheduled_id finds it in list_scheduled_messages and cancels it with cancel_scheduled_message), so don't send it again. message_id can be used as quote_id later. With media, media says how the file was sent ({ sent_as, mimetype, size_bytes, file_name? }) and note explains a fallback (e.g. a HEVC video sent as a document); tell the user. If WhatsApp rejects the send, the result is an error that still includes recipient and error.
Inputs: to (required), text, media, quote_id, +1 more.
send_pollAInspect
Sends a WhatsApp poll (a question with 2 to 12 answer options that people tap to vote) to one person or group, from the user's number. Use it when the user wants to ask a group or a person to choose between options, e.g. "ask the family group which day works for dinner". Paid plan only: on the free plan the call is refused with a note on how to subscribe. to works like send_message's: a contact name, a phone number with country code, a JID, or a group's exact name; if a name could match more than one contact, call search_contacts first. By default each person picks one answer; pass allow_multiple: true to let people pick as many options as they want (e.g. "which days can you come?"). The options must all be different. Votes show up on the user's phone; this server can't read poll results, so don't offer to count the votes. If this number is busy sending other messages, the poll is refused with when to try again. WhatsApp doesn't render Markdown: use bold, italic, strikethrough and "- " lists, and never send tables, # headings, double asterisks or text links. Write a table as short lines (e.g. "Ana: $200") and paste URLs plain. Only format when it suits the message. Messages that start new conversations have extra protection against WhatsApp's anti-spam bans and may be delayed or refused; the result says so and when. Sending the same text, especially with a link, to many people who haven't written to the user can get their number temporarily or permanently banned, even when spaced out: write each person their own message (not just a name swap), and warn the user about this risk when they ask for outreach. Sending can't be undone and everyone in the chat sees the poll: confirm the recipient, question and options with the user first unless they already gave them. Returns { to, status (sent or failed), recipient, message_id, question, options, allow_multiple, error? }: recipient is the chat the poll went to, with the contact fields (name; name_source: address_book, push_name, group_subject, business, phone or unresolved; canonical_jid: the JID to pass to send_message and read_chat_history; phone_jid and lid_jid: the chat's phone-number and LID forms, null when unknown or for groups; phone_display: the number as +). If WhatsApp rejects the poll, the result is an error that still includes recipient and error.
Inputs: to (required), options (required), question (required), allow_multiple.
unlink_whatsappADestructiveIdempotentInspect
Unlinks the user's WhatsApp from WA MCP, like removing a linked device on the phone. The wa-mcp account and subscription stay; to use WA MCP again, link the same number with get_pairing_qr or request_pairing_code. To use a different number, set up a new connection instead. Use only when the user asks to disconnect or unlink. If messages just stopped arriving, use restart_session instead; to remove the account and all data, use delete_account.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
WhatsApp for Claude, ChatGPT or any AI agent: search, reply and send. Personal or Business API.
Connect your own WhatsApp number to Cursor, Claude and ChatGPT: catch up, search, send replies.
Your own WhatsApp in Claude and ChatGPT: read chats, draft replies, send messages you approve.
WhatsApp CRM for AI agents: search contacts, read chats, manage the sales pipeline, send messages.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceLets AI assistants read, search, and send messages from a linked WhatsApp account, with full-text search, media handling, and contact and group management.45 npmGPL 3.0
- AlicenseNot gradedqualityBmaintenanceLets an AI agent search and read your own WhatsApp chats from a self-hosted Cloudflare Worker, with full-text search across all messages, per-chat paging, and the ability to save contact names for numbers that appear unnamed. It is read-only, so it can never send messages on your behalf.45 npm404MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with your personal WhatsApp account, allowing them to search messages and contacts, retrieve chat history, and send messages to individuals or groups. Uses WhatsApp Web API with local data storage for privacy and security.14 npmISC
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to read, search, send, and manage WhatsApp chats, including transcribed voice messages and media, through a linked-device connection and searchable archive.45 npmGPL 3.0
Glama MCP Gateway
Add one secure layer between your agents and this server.