WA MCP
Server Details
Read, search and reply to your WhatsApp chats from your AI, using your own number.
- Status
- Healthy
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 23 tools
Most tools target clearly distinct resources and actions, and the descriptions explicitly route between similar tools. There is some overlap among read/discovery tools (get_recent_chats, get_unanswered_chats, read_chat_history, search_messages) and among pairing/session tools, but the guidance is strong enough to avoid most misselection.
All tool names follow a consistent snake_case verb_noun pattern (send_message, read_chat_history, cancel_scheduled_message, etc.). Even multiword nouns remain predictable and readable.
At 23 tools the surface is heavy but appropriate for a full WhatsApp connector covering messaging, scheduling, media, contacts, pairing, subscription, and account management. Each tool has a recognizable role, though the set is near the upper bound of comfortable scope.
Core lifecycle coverage is strong: sending, reading, searching, editing, deleting, reacting, scheduling, media download/send, contacts, pairing, and account removal are all present. Minor gaps remain around group administration, contact/profile management, and message actions like pin/archive/star.
Available Tools
23 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). 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), 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) }.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | A scheduled message's id. Cancels it and, if it repeats, every later send. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, but the description adds substantial context beyond them: whole-series cancellation semantics, that already-sent/in-flight messages are silently refused with an explanatory result, and a per-call user-confirmation expectation. The free-plan note is minor but confirms availability rather than contradicting anything.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and usage are front-loaded and efficient, but the return-value paragraph balloons into a deeply nested field dump (recipient → name_source enum → canonical_jid / phone_jid / lid_jid) that is hard to parse as prose. With no output schema this detail is defensible, but it should be structured or trimmed rather than crammed into one run-on sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by documenting the return shape ({ cancelled, messages }) including the status enum and the distinction between series_id, occurrence and message_id. Combined with the destructive/idempotent annotations and the failure-case handling, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds real meaning: 'if it repeats, the whole series is cancelled (any of the series' ids works)' — the 'any id in the series is acceptable' rule is not obvious from the schema's phrasing. Slight deduction because the id-format/source guidance is deferred to a sibling rather than stated here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Cancels scheduled messages before they are sent') and immediately distinguishes the scope: single message vs. an entire repeating series. An agent can tell it apart from delete_message and schedule_message without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes to siblings: 'Find ids with list_scheduled_messages (filter by `to` or `text`)' and 'To change a scheduled message, cancel it and schedule it again with schedule_message.' It also states the when-not case (already sent or in-flight can't be cancelled) and a confirmation policy ('Confirm with the user first unless they asked for it').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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".
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Set to "DELETE" only after the user has confirmed the summary from the first call. Omit it to get that summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=true, but the description goes well beyond them: it names exactly what is destroyed (subscription cancelled, connector unlinked, the connector's copy of messages erased) and, crucially, what survives (WhatsApp account, chats, phone originals). It also discloses the mandatory two-call confirmation protocol, which is neither in the annotations nor inferable from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is longer than most definitions but front-loads the two things an agent most needs (what is removed, what is not), then the when-to-use, then the destructive mechanics, then the call protocol. Every sentence carries distinct information; nothing repeats the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by telling the agent the first call returns a summary whose purpose is user confirmation. Combined with the exhaustive effect list and the two-step procedure, an agent has everything needed to invoke this destructive tool safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `confirm` param is already documented, so the baseline is 3. The description earns an extra point by explaining the intent behind the parameter rather than restating it: the first call returns a summary to show the user, and `confirm: "DELETE"` is only sent after the user agrees.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Removes this WhatsApp connector (wa-mcp) and the user's account with the connector") and immediately scopes it against the likely misreading ("This does NOT delete the user's WhatsApp account"). That negative scoping is what separates it from siblings like unlink_whatsapp or manage_subscription without needing to open their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ("Use it when the user asks to delete their wa-mcp account or remove the connector") and notes there is no alternative channel ("the service has no website or account page"). It never names the closest sibling, unlink_whatsapp, so the agent must infer which of the two to pick when a user says "disconnect" rather than "delete".
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | The `id` of the user's own message, from read_chat_history or search_messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond the destructiveHint/idempotentHint annotations: it discloses the free-plan refusal, that everyone sees a deletion indicator, that it is irreversible, and the ~15-minute caveat where WhatsApp may not actually delete for everyone. These are exactly the operational traits an agent needs to set expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Action, scope, and prerequisites are front-loaded in the first sentences, and the confirmation warning follows logically. The return-value enumeration of chat contact fields is dense, but with no output schema it is carrying the burden of explaining what comes back, so it earns its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully specifies the return shape (message_id, status values, chat, warning, error) and explains when warning appears. Combined with the paid-plan, ownership, and revertibility constraints, nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100% and the single parameter is self-documented, so baseline is 3. The description adds real value by saying the chat is looked up automatically from the id and that the id comes from read_chat_history or search_messages, removing any doubt about needing a chat identifier.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource (deletes a WhatsApp message) plus the scope that matters most — 'for everyone in the chat' — and clarifies it works in both 1:1 and group chats. This distinguishes it cleanly from siblings like edit_message or mark_as_read without needing to open a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit prerequisites: paid plan only, must be the user's own message (from 'Me'), and points to read_chat_history / search_messages for the id. It also specifies a confirmation policy before invoking. It stops short of naming the direct alternative tools (edit_message, react_to_message) for an agent weighing modification options.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_mediaARead-onlyInspect
Fetches a photo, sticker, voice note, audio, video or document from a WhatsApp message, only when the user asks for it. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | No | Optional. The chat the message is in; only used as a fallback lookup. | |
| message_id | Yes | The WhatsApp message id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations by disclosing the two distinct return modes (small images as viewable images vs. everything else as a 15-minute download link), instructing the agent to share the link, and setting capability limits ('You cannot play or transcribe audio yourself'). The remaining gap is minor: no note on failure modes for expired or unsupported media.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each carrying distinct information: scope, return behavior, agent capability limit, and input provenance. Front-loaded with the core action and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the full burden of explaining return values — and it does so for both branches, including link expiry and the instruction to pass the link to the user. Combined with the input provenance guidance, an agent can call this correctly without further information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, and the description adds real value by telling the agent where message_id values come from and what they look like in search results. It does not, however, address chat_jid beyond the schema's own 'fallback lookup' note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Fetches) and enumerates the exact resource types it retrieves from a WhatsApp message, so the agent knows precisely what this returns. It is cleanly distinguished from siblings like search_messages and read_chat_history, which are framed as the source of message ids rather than the fetchers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gates usage ('only when the user asks for it') and names two concrete alternatives for obtaining the required input ('Get message ids from search_messages ... or read_chat_history'). It even explains how media appears in those results ('[voice note, 0:42]'), closing the loop on the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The complete new text of the message (it replaces the old text entirely). | |
| message_id | Yes | The `id` of the user's own text message, from read_chat_history or search_messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructive/idempotent/openWorld, and the description adds substantial context on top: paid-plan gating and refusal behavior, that edits are visible to everyone and marked as edited, and the ~15-minute window where WhatsApp may silently not apply the edit. That age-based warning is behavioural knowledge not derivable from any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and constraints, and nearly every sentence carries operational meaning. The return-value sentence is long and dense, but it substitutes for an absent output schema, so it is not waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and a destructive mutation, the description fully covers return shape ({message_id, status, chat, text, warning?, error?}), the meaning of warning, and the identity fields. An agent has everything needed to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description still adds provenance for `message_id` (must be the user's own text message, sourced from read_chat_history or search_messages) and clarifies that the chat is resolved automatically, so no chat parameter is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb + resource ('Edits the text of one of the user's own WhatsApp text messages for everyone in the chat'), with a plain-language analogy and explicit scope (1:1 or group). It is clearly separable from send_message, delete_message and react_to_message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives positive conditions (own text messages, id from read_chat_history/search_messages), exclusions (not captions of photos/videos/documents), a prerequisite (paid plan), and a distinct alternative path (call get_writing_style first unless text is dictated). It also states a confirmation norm before mutating shared chat state.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pairing_qrAInspect
Initiates pairing and returns a QR code (image, an auto-refreshing link, and a data URL). Best when the user can scan from another screen. 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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it is a non-read-only, non-idempotent, non-destructive, closed-world operation, and the description is consistent with that (it starts a pairing session, not a plain read). It adds useful lifecycle detail (re-calling reuses the running session rather than starting a new one) and mutual-exclusion warnings, but says nothing about what happens if an account is already linked, permission/auth requirements, or how long a QR stays valid. With annotations carrying the safety profile, this is solid but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each doing distinct work: what it returns, when to prefer it, and the retry/exclusion rules. The core action is front-loaded in the first clause with zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description valuably explains the return shape (image, auto-refresh link, data URL) and the expiry/retry loop, which is the main unknown for a pairing tool. The remaining gap is state handling — what to do if the account is already paired or a session is already running outside of restart_session.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so there is nothing for the description to disambiguate; the 4 baseline applies. The description correctly implies no inputs are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Initiates pairing and returns a QR code") and enumerates the return payload (image, auto-refreshing link, data URL). It also names the sibling it competes with (request_pairing_code) and why, so the agent can distinguish it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit preference rule ("Best when the user can scan from another screen"), a retry rule ("If the QR expires, call it again"), and hard exclusions: never combine with request_pairing_code, never call restart_session while pairing. This is exactly the when/when-not/alternatives guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | Yes | Number of chats to return (e.g. 20). Keep it small to save context. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered; the description adds real context beyond that: newest-first ordering, the meaning of name_source values, and when phone_jid/lid_jid are null. It stops short of noting any pagination or result-cap behavior, which is the only gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and ordering are front-loaded, then usage, then the alternative — a sensible order. The long parenthetical enumerating contact fields is dense, but it earns its place because there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully documents the returned shape (chat_jid, last-message preview, name, canonical_jid, phone_jid/lid_jid, phone_display) and the ordering, which is everything an agent needs to consume the result correctly for a one-parameter read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema itself explains limit ('Number of chats to return (e.g. 20). Keep it small to save context'), so the baseline of 3 applies. The description adds nothing about the limit parameter beyond what the schema already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the user's most recent WhatsApp chats (people and groups)') plus the ordering ('newest first') and the exact return fields. It is clearly separable from read_chat_history and get_unanswered_chats, both of which it names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives three concrete use cases ('what's new', finding a chat's JID before read_chat_history, picking up recent conversations) and explicitly routes the unanswered-reply case to get_unanswered_chats instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, and the description goes well beyond them: without an output schema it defines each return field, explains the derived boolean (ready = connected && loggedIn), and states the operational precondition for subsequent actions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence, then a tight bullet list of return fields, then the usage rule. Every line earns its place and nothing is repeated from the annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description fully documents the return payload and its semantics, and it supplies the readiness precondition an agent needs before calling send/write siblings. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline 4 applies; there is no parameter ambiguity to resolve and the description correctly spends no words on arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'Check the connection status of the WhatsApp session.' It is clearly distinct from siblings like get_pairing_qr, restart_session, and unlink_whatsapp, and the returned field list makes the resource boundary unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('when a send or read fails, or when unsure whether WhatsApp is linked') plus a hard gating rule ('only send or read when ready is true') that routes the agent away from prematurely calling send_message/read_chat_history.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_unanswered_chatsARead-onlyInspect
Fetch a list of recent chats where the user did not send the last message. Use this to find conversations waiting for a reply. Each chat has its chat_jid, 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 +)., the time and sender of the last message, and a preview.
| Name | Required | Description | Default |
|---|---|---|---|
| hours_ago | Yes | Mandatory. Fetch unanswered chats active within this many hours (e.g. 24). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds meaningful behavioral context by enumerating the returned fields and explaining the contact metadata semantics; it does not, however, mention result limits, ordering, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and usage are front-loaded in the first two sentences, and the remaining return-field detail is purposeful since no output schema exists. The long parenthetical contact-field enumeration is dense and has a stray punctuation artifact, but it is not padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Because there is no output schema, the description carries the burden of explaining the return shape, and it does so in detail: chat_jid, contact fields with name_source variants, last-message time/sender, and preview. It is nearly complete, though it omits any indication of result count limits or ordering.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single parameter hours_ago is fully documented in the schema with an example. The description adds no parameter-level meaning beyond what the schema already provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch a list of recent chats') with a precise filter ('where the user did not send the last message'). This filter clearly distinguishes it from the sibling get_recent_chats, letting an agent choose correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context: 'Use this to find conversations waiting for a reply.' However, it stops short of explicitly naming alternatives (e.g., get_recent_chats for all recent chats, read_chat_history for a single thread) or stating exclusions, so the routing is clear but not fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | No | Optional. The chat you're about to write in: a contact or group name, a phone number with country code, or a JID. Leave it out for the user's general style. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly/openWorld=false, so the description carries the behavioral load and does it well: it discloses the <5-message fallback, per-chat labelling, that only self-typed messages are included, and a best-effort caveat about re-linking. This is rich context beyond the annotations, though the sampling caveat is a bit buried mid-paragraph.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and usage are front-loaded in the first two sentences, which is strong. The long return-shape sentence is dense and somewhat heavy, but since no output schema exists, that detail is doing necessary work rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains the return object (source, chat, chat_messages, other_chats, hints, guidance, contact fields) and the sampling logic. An agent has everything needed to call it correctly and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already documents `chat`, so baseline is 3. The description adds genuine meaning beyond the schema: with `chat` it returns that chat's own messages, and it explains the fallback to global one-to-one samples when that chat is sparse, which the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — it shows how the user writes so composed messages sound like them — and names the sibling tools (send_message, schedule_message, edit_message) it supports. An agent can distinguish this from read_chat_history or search_messages without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to call it (before composing words for the user) and when to skip it (when the user dictated the exact text), with the relevant sibling tools named. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. 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), 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), 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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Optional. One scheduled message by id. | |
| to | No | Optional. Recipient: part of a name (accents and case ignored), a phone number in any format, or a JID. | |
| text | No | Optional. Only messages whose text contains this (case-insensitive). | |
| limit | No | Optional. Maximum messages to return (default 20, max 100). | |
| offset | No | Optional. Skip this many matches, for paging (default 0). | |
| status | No | Optional. Only these statuses, e.g. ["scheduled"] for upcoming or ["failed", "missed"] for problems. | |
| has_media | No | Optional. true: only messages with a file; false: only text messages. | |
| recurring | No | Optional. true: only repeating messages; false: only one-off messages. | |
| series_id | No | Optional. Every send of one repeating message. | |
| recurrence | No | Optional. Only these repeat frequencies. | |
| send_after | No | Optional. Only sends at or after this ISO 8601 date-time with offset. | |
| send_before | No | Optional. Only sends at or before this ISO 8601 date-time with offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds substantial behavioral context beyond them: 90-day retention, pagination that can stop early when rows are long, repeating-series row semantics, free-plan support, and detailed result-shape expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads purpose and use cases, and its long return-shape detail is largely justified because no output schema exists. Still, the nested recipient definition and repeated status/time-format notes make it denser and harder to scan than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 12 optional filters and no output schema, the description supplies the missing output contract, pagination guidance, retention policy, series semantics, and full-detail behavior for `id`. An agent can invoke the tool and interpret the response without further documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 12 filters and the baseline is 3. The description adds meaning by noting that all filters are optional and combine, that `id` switches the response to full detail, and that `limit`/`offset` interact with early stopping and `total > offset + returned` paging.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource plus scope: listing upcoming scheduled messages and past-send history. The use-case sentence distinguishes it from creation and cancellation flows by telling the agent to use it to find a message id before cancelling or changing that message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives three concrete situations for use: answering what is scheduled, checking whether sends went out, and locating an id before cancelling or editing. It does not explicitly name when not to use it or point to sibling alternatives such as search_messages; the cancel/edit alternative is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_subscriptionARead-onlyInspect
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. 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, scheduling, and editing, reacting to and deleting messages): without a subscription they are on the free plan.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful context about the free plan and Stripe portal handling, but it does not describe return contents, idempotency of portal-link generation, or behavior when the user is already subscribed versus on the free plan.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purposes and then adds the secondary label/paid-feature cases. It is somewhat dense in the second sentence, especially the parenthetical paid-feature list, but every clause contributes useful routing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only tool, the description is sufficiently complete about when to invoke it and what plan-related situations it covers. It does not explain the response shape, but with no output schema the only remaining gap is minor inference about what 'check status' returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero input parameters, so there are no parameter semantics to explain and the schema cannot provide additional parameter documentation. Baseline for a parameterless tool applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs and resources: check subscription status, retrieve pricing/payment links, and generate a Stripe portal link. It also clarifies the paid-feature/plan context, making it clear this is the subscription-management tool rather than a messaging or account tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use this tool to...' and 'Also use it when...', covering several concrete situations such as checking status, getting pricing, updating payment details, removing the wa-mcp label, and unlocking paid features. It does not name exclusions or alternatives, but the sibling set contains no competing subscription tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_as_readAIdempotentInspect
Mark a chat as read. Automatically fetches and marks the latest unread message if message_id is not provided. If providing message_id for a group chat, sender_jid must also be provided.
| Name | Required | Description | Default |
|---|---|---|---|
| jid | Yes | The chat to mark as read: a JID or a phone number with country code. | |
| message_id | No | Optional. A message `id` from read_chat_history; it and everything before it are marked read. Omit to mark the latest incoming message. | |
| sender_jid | No | Required with message_id in group chats: that message's `sender_jid` from read_chat_history. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description usefully adds the non-obvious auto-fetch behavior when message_id is omitted and the sender_jid dependency for group chats, which are not fully captured by annotations. It could mention whether read receipts are visible to the other party, but the added operational context is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler, with the primary action stated first and conditional behavior following. Every sentence conveys distinct operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With full schema coverage, no output schema, and annotations covering safety, the description captures the two non-obvious behaviors an agent needs: auto-fetch on omitted message_id and the sender_jid requirement for groups. It leaves minor gaps like whether read receipts are sent, but is otherwise sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description reinforces the message_id omission behavior and group-chat sender_jid requirement, but largely repeats schema content rather than adding meaning beyond it; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Mark a chat as read') that is clearly distinct from siblings like read_chat_history or send_message. It stops short of explicitly naming an alternative, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It describes one procedural condition ('Automatically fetches and marks the latest unread message if message_id is not provided') and a parameter dependency for group chats, which implies usage. However, it never says when to choose this over read_chat_history or get_unanswered_chats, so the guidance is only partially implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. Reactions sent this way don't appear in read_chat_history afterwards; this tool's result is the confirmation. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | Yes | One emoji, e.g. 👍 ❤️ 😂 😮 😢 🙏. An empty string "" removes the user's reaction. | |
| from_me | No | Optional, only if the message isn't found: true if the user sent it (read_chat_history shows it from "Me"). | |
| chat_jid | No | Optional, only if the message isn't found: the chat it is in (JID or phone number). | |
| message_id | Yes | The message `id` from read_chat_history or search_messages. Not a reaction's own id. | |
| sender_jid | No | Optional, only if the message isn't found and is in a group: its `sender_jid` from read_chat_history. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: replacement semantics (a new reaction overwrites the previous one, consistent with idempotentHint), removal via empty string, plan gating, and the non-obvious fact that reactions don't show up in read_chat_history so this tool's result is the only confirmation. It also discloses side effects on other chat participants. Slight deduction only because return-value detail is packed in the same breath as behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the action, then plan gate, then id source, then semantics, then return shape – a sensible order. It is long and the parenthetical enumeration of chat contact fields (name_source, canonical_jid, phone_jid, lid_jid, phone_display) is dense, but it earns its place given there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and a mutation tool, the description supplies the return shape, status values (reacted/removed/failed), and an error-recovery path. An agent has everything needed to invoke it correctly and interpret the result on the first attempt.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description goes further by explaining where message_id comes from, that chat/sender/from_me are auto-resolved, and that the three optional params are error-recovery-only. That is useful routing context, though the per-parameter explanations largely restate the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (react to a WhatsApp message with an emoji) and immediately scopes it: 1:1 or group, on the other person's messages or the user's own. The phone analogy ("like tapping and holding a message") plus the explicit contrast with read_chat_history/search_messages makes it unmistakable against siblings like send_message or edit_message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit preconditions (paid plan only, refused with a subscribe note on free), the correct source for the required id (read_chat_history or search_messages), a social caution (everyone sees it, confirm unless the user asked), and a precise fallback trigger (pass chat_jid/from_me/sender_jid only when the message isn't found). Nothing about when to use it versus alternatives is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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). 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 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.
| Name | Required | Description | Default |
|---|---|---|---|
| jid | Yes | The chat: a JID (…@s.whatsapp.net, …@lid, …@g.us) or a phone number with country code. | |
| limit | Yes | Number of messages to return, newest first (e.g. 20; max 200). | |
| before | No | Optional. For older messages: the `id` of the oldest message of the previous page, as the headline gives it. The page then starts just before that message. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond the readOnly/openWorld annotations: it states the ~90-day coverage, newest-first ordering, pagination via `before`, early page termination for long messages, media placeholders, and the exact return shape. These details materially help an agent predict what the call will return and how to continue paging.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded and every sentence carries useful information about retrieval, pagination, return shape, or related calls. Given the lack of an output schema, the detailed return-value explanation earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains the return object including `chat`, `participants`, contact fields, and message fields. It also covers pagination, media handling, date-range limits, and how to use returned ids with send_message, leaving no critical gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful semantics beyond the schema: `limit` may stop early when messages are long, and `before` should be the headline's oldest message id. It also reiterates that `jid` can be a JID or phone number, but the main value is the pagination behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Reads a chat's latest messages, newest first,' and immediately names the returned fields. It is clearly distinguishable from siblings like search_messages because it describes paged retrieval of a chat's recent history rather than search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit operational guidance: get chat JIDs from get_recent_chats or search_contacts, use `before` to page backward, and use `quote_id` with send_message to reply. It does not explicitly contrast with search_messages, which is the main missing alternative for older or targeted retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_feedbackBInspect
Use when the user reports a bug, requests a feature, or wants to contact the WhatsApp MCP developers. Works on the free plan too.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | ||
| title | Yes | ||
| context | No | ||
| description | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
"Works on the free plan too" adds genuine gating context the annotations do not carry, which is useful for an agent deciding whether the call will fail on a paid-tier check. However, with readOnlyHint=false and openWorldHint=false declared, the description still doesn't state where the submission goes, whether the user is identified, or whether repeated calls create duplicates (idempotentHint=false is declared but unexplained).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the decision criterion, and no filler. The trailing "works on the free plan" clause is slightly orphaned without naming what the paid plan implies, but it is not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter, non-idempotent mutation with no output schema and no parameter documentation, the description covers only the trigger and one availability note. It leaves undefined what the call returns (confirmation, tracking reference) and how the free-text fields should be shaped, which is a meaningful gap for a tool the agent must construct content for.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so all four parameters (type, title, description, context) depend on the description for meaning, and it says nothing about any of them. The agent must guess that title is a short summary, that description is the body, and that context is optional supplementary detail — none of which is stated anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the resource (feedback routed to the WhatsApp MCP developers) and the three triggering situations that map onto the enum values. It is clearly distinguishable from every sibling tool, none of which deal with developer feedback, though it phrases purpose as a usage trigger rather than a direct verb+resource statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit triggering conditions — user reports a bug, requests a feature, or wants to contact the developers — which an agent can match against conversation intent without inference. There are no exclusions or named alternatives, but no sibling tool could plausibly be confused with this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_pairing_codeAInspect
Initiates pairing and returns an 8-character code to enter in WhatsApp (Linked devices → Link with phone number). Best when the user is on the phone they want to link. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| phone_number | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare the non-read-only and non-idempotent nature, and the description adds useful behavioral constraints about conflicting tools and the returned pairing code. It does not cover code expiration or the full session-state effect, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose and return value, then adds usage constraints with no unnecessary text. Every sentence adds actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
It explains the return value and critical sibling conflicts, which makes the tool callable in context. The main remaining gap is the required phone_number parameter semantics, which are not covered by the schema or description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage for phone_number, and the description only indirectly implies it is the phone to link. It does not specify expected format, country code, or whether it must be the WhatsApp account number.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and outcome: it initiates pairing and returns an 8-character code. It also distinguishes this tool from the sibling get_pairing_qr by naming the alternative pairing method.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use this tool (best when the user is on the phone they want to link), names the alternative method, and states hard exclusions: never call it with get_pairing_qr and never call restart_session during pairing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotent=true and destructive=false, so the safety profile is partly covered; the description adds the non-obvious side effect that an in-progress pairing is cancelled, plus that no re-pairing is needed. It does not mention expected downtime, impact on queued/in-flight messages, or how to confirm the restart succeeded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with purpose followed by triggers then the exclusion. No filler, no restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, non-destructive, idempotent action with no output schema, the description covers purpose, triggers, and the main hazard. It stops short of telling the agent what to do afterwards, e.g. verifying recovery via get_session_status, which would make it fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly implies a no-argument, single-target operation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (reconnects) and resource (WhatsApp session) plus the key scope constraint: no new QR code or re-pairing. That constraint alone separates it from get_pairing_qr and unlink_whatsapp without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives three concrete trigger conditions (session stuck, messages not sending, stale connection state) and an explicit exclusion with the reason (do not use during pairing, it cancels the pairing in progress). Both when-to-use and when-not-to-use are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. To protect the user's number from WhatsApp's anti-spam bans, messages that start a conversation with someone who hasn't messaged the user in the last 90 days may be limited to 1 per minute and 10 every 12 hours; the result says so and explains why when it happens. People who have written to the user are never limited. 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), 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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Contact name, phone number with country code, chat JID (person or group), or a group's exact name. | |
| text | No | The message text. With media, the caption of a photo, video or document. Required unless media is given. | |
| media | No | Optional. A file to send: pass exactly one of url or message_id. The file is fetched when the message is sent. | |
| until | No | Optional, repeats only. Last day of the series: a date ("2026-12-31", through the end of that day) or a date-time with offset. | |
| send_at | Yes | When to send (the first send, for repeats): ISO 8601 with the UTC offset in effect on that date, e.g. "2026-10-10T09:00:00-06:00". | |
| timezone | Yes | The user's IANA timezone, e.g. "America/Mexico_City". Repeats keep the same local time in it, across daylight saving changes. | |
| recurrence | No | Optional. How often to repeat (default once). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark this as a non-read-only, non-idempotent write; the description goes far beyond that with operational detail an agent cannot get elsewhere: 100 upcoming messages per account, one-hour late-send window then marked 'missed', per-send failure recording with series continuation, anti-spam throttling for cold contacts (1/min, 10/12h) and the fact that inbound-writers are never limited, and file re-fetch at send time.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and every sentence carries real information (limits, DST, throttling, return shape). The weakness is form: one long unbroken paragraph that mixes usage rules, timezone guidance, recurrence semantics and an inline return-object spec, so it is harder to scan than it needs to be for a tool this heavily used.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating the returned fields (id, series_id, status values, recipient fields, send_at_local, when, occurrence, error) plus next_occurrences, and instructs the agent to read the times back to the user. For a tool with nested media params, enums and recurring-series state, nothing an agent needs to call or report correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description compensates for the harder parameters by adding rules the schema does not: the offset must be the one in effect on the target date (DST), the first send must be in the future and within a year, monthly-on-the-31st rolls to the last day, and `until` accepts a bare date or an offset date-time. It does not add syntax detail for `to` beyond what the schema already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Schedules a WhatsApp message ... to one person or group for a later time, once or repeating') and immediately distinguishes it from send_message by naming `to` resolution and from cancel_scheduled_message by pointing to that tool for changes. An agent can tell exactly what this tool does versus its siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use rules: paid plan only (and what happens on free), confirm recipient/text/file/time first unless already given, call get_writing_style only when composing text rather than relaying dictated words, and change a schedule by cancelling and re-scheduling. It also states exclusions ('Quoted replies aren't supported') and alternatives for file input ('prefer a link').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Part of a person's name, phone number or group name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnlyHint and openWorldHint, but the description adds real behavioral context: a hard cap of 20 matches, case-insensitive partial matching, the caveat that some groups (community announcement groups) may be missing, and disambiguation behavior. It also enumerates the returned fields including the null semantics for phone_jid/lid_jid, which matters because there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and usage rules are front-loaded and well ordered, but the parenthetical field enumeration is dense and the punctuation is garbled ('phone_display: ...)., plus is_group'), which interrupts scanning. The return-field detail earns its place given no output schema, yet the sentence structure could be tightened considerably.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing return fields, match limit, and the is_group distinction plus canonical_jid usage for downstream calls (send_message, read_chat_history). Combined with the fallback guidance, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single 'query' param, so the baseline is safe, but the description goes beyond it by adding 'nickname' (not in the schema wording) and by specifying case-insensitive partial matching and phone-digit matching. That gives the agent concrete query-construction guidance rather than restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('looks up') plus two precise resources (people in the user's WhatsApp contacts, and groups the user is in), with the match method spelled out (name, nickname, phone digits, case-insensitive partial group name). An agent can distinguish this from search_messages or get_recent_chats without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use conditions ('when a name is ambiguous or before messaging a person or group the user hasn't talked to recently'), a disambiguation rule ('ask the user which one they mean'), and a named fallback sibling ('if a group isn't found, try get_recent_chats'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Optional. Maximum number of results to return (default 20, max 100). | |
| query | Yes | The text to search for. | |
| before | No | Optional. For the next page: the `id` of the last (oldest) message of the previous results, as the headline gives it. Keep the same query and filters. | |
| chat_jid | No | Optional. Filter by a specific chat: a JID, a phone number with country code, or a contact name. | |
| sender_jid | No | Optional. Filter by who sent the message: a JID (…@s.whatsapp.net or …@lid), a phone number with country code, or a contact name. Every form of the person's number matches. A name that matches several people returns an error listing them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses the return shape, ordering, media handling, truncation behavior, pagination behavior, and the fact that only captions are searchable. This is unusually rich behavioral context for an agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the purpose, then efficiently covers return values, media, truncation, pagination, and alternatives. Despite its length, every sentence carries actionable information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description explains the returned structure in detail, including chats, senders, message fields, truncation flags, and pagination. Combined with annotations covering read-only and closed-world behavior, an agent has enough to invoke and interpret the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds useful meaning beyond the schema: it explains the page behavior for `limit`, how the `before` headline is used for older pages, and that searching is limited to the last 90 days.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: full-text search of message text and captions from the last 90 days. It explicitly scopes the search to all chats or one chat and distinguishes itself from read_chat_history for older messages or browsing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative directly: use read_chat_history for messages older than 90 days or to browse a chat. It also clarifies when to use chat_jid and how to continue with pagination via `before`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 messaged the user in the last 90 days (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. To protect the user's number from WhatsApp's anti-spam bans, messages that start a conversation with someone who hasn't messaged the user in the last 90 days may be limited to 1 per minute and 10 every 12 hours; the result says so and explains why when it happens. People who have written to the user are never limited. Sending can't be undone: confirm the recipient, text and file with the user first unless they already gave them. Returns { to, status (sent, failed, or scheduled), recipient, message_id, media?, text_message_id?, note?, error?, scheduled_id?, send_at? }: 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 +). scheduled means the new-contact limit moved the message to the next free minute: it goes out by itself at send_at (scheduled message scheduled_id), 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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Contact name, phone number with country code, chat JID (person or group), or a group's exact name (case, accents, spaces and punctuation ignored; part of a group name doesn't match). | |
| text | No | The message text. With media, the caption of a photo or document (for audio and stickers, it is sent as a separate message just before the file). Required unless media is given. | |
| media | No | Optional. A file to send. Pass exactly one of url, message_id or data. | |
| quote_id | No | Optional. The `id` of the message to reply to (from read_chat_history or search_messages). | |
| quote_participant | No | Optional. The quoted message's `sender_jid` (from read_chat_history). Usually looked up automatically from quote_id; pass it if a group reply asks for it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Extremely rich beyond the annotations: free-plan 90-day window, the 'Sent via wa-mcp.com' footer, media requiring a paid plan, anti-spam throttling of 1/min and 10/12h for new contacts, size limits, and that sends cannot be undone. However, 'Sending can't be undone' sits awkwardly against destructiveHint=false — not a genuine contradiction (no data is destroyed), but the description never reconciles the irreversibility with the declared safety profile, and the wall of plan/limit detail dilutes the core behavioral signal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single ~600-word paragraph that buries the return-value contract, the type-detection table, and the anti-spam limits inside the same block. Purpose is front-loaded, but the density and duplication with the schema make it hard to scan, and several clauses (Google Drive share instructions, HEIC/MOV examples) could be compressed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a destructive-free but irreversible write tool with a nested `media` object and no output schema, the description covers everything an agent needs: recipient resolution, plan gating, rate limits, quoting, file sourcing constraints, and even the full return shape (status sent/failed/scheduled, recipient fields, error handling).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description still adds real meaning: it explains the mutually exclusive sources of `media` (url vs message_id vs data with the 512 KB cap), the file-type detection table, what `to` accepts, and that `media.message_id` preserves the file's kind without copying its caption. It mostly restates schema content, which caps it below a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Sends a WhatsApp message to one person or group') and immediately enumerates the payload kinds (text, photo, document/PDF, voice note, audio, sticker). It is unambiguously distinguishable from siblings like schedule_message, edit_message, or react_to_message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete routing rules: call search_contacts first when a name is ambiguous, call get_writing_style before composing text yourself (and skip it for dictated text), use quote_id from read_chat_history/search_messages for replies, and confirm with the user before sending. Each alternative tool is named with the condition that selects it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlink_whatsappADestructiveIdempotentInspect
Logs out the current session and frees the token slot
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose destructiveHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds useful context by stating that the token slot is freed, but it does not mention consequences like needing to re-pair or what happens to existing chats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It efficiently communicates the core action and effect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with rich annotations and no output schema, the description covers the essential action and one key behavioral detail (freeing the token slot). It could be slightly more complete by noting that re-pairing will be required, but it is adequate overall.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters, there is no parameter semantics to explain. The baseline for a no-parameter tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('logs out the current session') and effect ('frees the token slot'), which is clear enough to distinguish it from siblings like restart_session or delete_account. However, it does not explicitly name or rule out those alternatives, so it falls short of the highest clarity score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance on when to use this tool versus alternatives such as restart_session or delete_account. It only states the effect, leaving the agent to infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
23 tool updates
- First observed
cancel_scheduled_message - First observed
delete_account - First observed
delete_message - First observed
download_media - First observed
edit_message - First observed
get_pairing_qr - First observed
get_recent_chats - First observed
get_session_status - First observed
get_unanswered_chats - First observed
get_writing_style - First observed
list_scheduled_messages - First observed
manage_subscription - First observed
mark_as_read - First observed
react_to_message - First observed
read_chat_history - First observed
report_feedback - First observed
request_pairing_code - First observed
restart_session - First observed
schedule_message - First observed
search_contacts - First observed
search_messages - First observed
send_message - First observed
unlink_whatsapp
Related MCP Connectors
- WhatSyncOAuthapp.whatsync
WhatsApp for Claude, ChatGPT or any AI agent: search, reply and send. Personal or Business API.
Your business WhatsApp for any AI: read and search chats, digests, team stats, sends you approve.
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 gradedqualityDmaintenanceLets 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.20 npm323MIT
- 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.6 npmISC
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with your personal WhatsApp account to search messages, list chats, and send messages. It stores all authentication and message data locally using SQLite for privacy and direct multi-device API connection.6 npm1ISC
- AlicenseNot gradedqualityDmaintenanceSend WhatsApp messages from your own personal number via AI assistant, with confirm-before-send and ability to read and summarize recent chats.20 npm1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.