mcp-whatsapp
The mcp-whatsapp server exposes a personal WhatsApp account to LLMs via 41 tools, enabling comprehensive messaging, group management, privacy controls, and media handling.
Send Messages
Send text messages to individuals or groups
Send files (images, videos, documents, audio) with optional captions and view-once flag
Send voice notes (auto-converts non-OGG audio via ffmpeg)
Send polls with 2–32 options; vote on existing polls and retrieve tallies
Send contact cards (auto-synthesizes vCard 3.0 or accepts raw vCard)
Reply to messages with quoted context, or edit/revoke previously sent messages
Message Actions
React to messages with emoji (or clear reactions)
Mark specific messages or entire chats as read
Set typing/recording presence per chat
Read & Query
Search contacts by name or phone number (local cache)
List chats with previews, sortable by activity or name
List and filter messages by sender, date range, keyword, and chat
Get message context (messages before/after a specific message)
Check if phone numbers are registered on WhatsApp
Download media from messages to a local path
Request history sync (backfill) for specific chats on demand
Group Management
Create, leave, and list groups; get full group metadata
Add, remove, promote, or demote participants
Change group name, description/topic, announce-only mode, and locked mode
Get or reset group invite links; join groups via invite URL or code
Blocklist
Get the current blocklist; block or unblock contacts
Privacy & Presence
Set online availability (available/unavailable)
Get and update individual privacy settings (last seen, profile photo, status, read receipts, group add, etc.)
Update profile "About" text
Server Status
Check the WhatsApp bridge connection status and paired account details
Enables audio message functionality by converting audio files to WhatsApp-compatible .ogg Opus format when sending voice notes via the send_audio_message tool.
Provides local message caching and storage for chat history, contact information, and message persistence, enabling offline access and search capabilities.
Provides comprehensive WhatsApp integration with 41 tools for messaging, contact management, group administration, polls, media sharing, and chat history management, enabling AI agents to interact with personal WhatsApp accounts.
WhatsApp MCP Server
A single-binary Go MCP server that wraps whatsmeow to expose a personal WhatsApp account to LLMs. whatsapp-mcp serve runs as a lightweight HTTP daemon on 127.0.0.1:8765; MCP clients (Claude Desktop, Cursor, Claude Code, etc.) connect to it via HTTP — no process spawning, no stdin/stdout juggling. Messages are cached in local SQLite and only travel to the model when the agent calls a tool.
Unaffiliated. This is an independent open-source project. It is not affiliated with, endorsed by, or otherwise associated with Meta Platforms, Inc., WhatsApp, or whatsmeow. "WhatsApp" is a trademark of Meta Platforms, Inc., used here nominatively to describe interoperability.
This started as a fork of lharries/whatsapp-mcp and has since been rewritten as a single Go binary. What it adds over the original:
LID resolution — normalises
@lidJIDs to real phone numbers for accurate contact matching.Sent-message storage — outgoing messages are persisted locally so conversation history stays complete.
Disappearing-message timers — outgoing messages inherit the group chat's ephemeral timer automatically.
Targeted history sync — on-demand per-chat backfill via the
request_synctool.Extended tool surface — 42 tools (see below): reactions, replies, edits, revoke, mark-read, typing, is-on-whatsapp, full group admin, blocklist, polls (create + vote + tally), contact cards, view-once flag, presence, privacy settings, and the profile "About" text.
Single-instance enforcement — a
flock(2)onstore/.lockprevents twoserveprocesses racing on the same SQLite files.
Setup
Prerequisites
Go 1.25+ (build-time only; runtime needs just the compiled binary).
An MCP client that speaks HTTP (Claude Desktop, Cursor, Claude Code, etc.).
FFmpeg (optional) — required only for
send_audio_messagewhen the input is not already.oggOpus. Without it, usesend_fileto send raw audio.Windows: CGO must be enabled — see docs/windows.md.
Install
git clone https://github.com/Sealjay/mcp-whatsapp.git
cd mcp-whatsapp
make build # writes ./bin/whatsapp-mcpPair your phone (first run only)
Start the daemon, then open the pairing page in a browser:
./bin/whatsapp-mcp serve # starts on 127.0.0.1:8765
open http://127.0.0.1:8765/pair # macOS; or visit the URL manuallyScan the QR code with WhatsApp on your phone (Settings → Linked Devices → Link a Device). The pairing persists to ./store/whatsapp.db. When WhatsApp invalidates the session (roughly every 20 days), visit /pair again and re-scan.
Alternative (headless / CI): ./bin/whatsapp-mcp login renders the QR in the terminal. Use this when a browser isn't available.
Connect your MCP client
whatsapp-mcp serve is an HTTP daemon on 127.0.0.1:8765 (or $WHATSAPP_MCP_ADDR). MCP clients connect to it over HTTP:
// Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"whatsapp": { "url": "http://127.0.0.1:8765/mcp" }
}
}// Claude Code — .claude/mcp.json (project) or ~/.claude/mcp.json (user)
{
"mcpServers": {
"whatsapp": { "type": "http", "url": "http://127.0.0.1:8765/mcp" }
}
}// Cursor — ~/.cursor/mcp.json
{
"mcpServers": {
"whatsapp": { "type": "http", "url": "http://127.0.0.1:8765/mcp" }
}
}Restart the client. WhatsApp appears as an available integration. Closing and reopening the client reconnects to the daemon — no process spawn, no per-session handshake, no stdin/stdout juggling.
Sending and receiving files
WHATSAPP_MCP_MEDIA_ROOT gates both directions of file movement:
Sending —
send_fileandsend_audio_messageaccept amedia_pathargument pointing at the file to send. The path must live under the allowed root.Receiving —
download_mediawrites decrypted media to the daemon cache at<store>/<chat_jid>/. Passing the optionaloutput_pathargument additionally places the file at a caller-chosen location, which must also live under the allowed root. If a file already exists atoutput_paththe call is a no-op.
By default the allowed root is ./store/uploads/ (resolved relative to your -store directory). On first run, serve creates it automatically; drop files you intend to send into it and point output_path here if you want to read incoming media from the same place.
To allow a different directory, set WHATSAPP_MCP_MEDIA_ROOT (absolute path) when starting the daemon:
WHATSAPP_MCP_MEDIA_ROOT=/Users/me/whatsapp-shared ./bin/whatsapp-mcp serveOr add it to your launchd plist / systemd unit / shell profile so it persists across restarts.
Paths outside the allowed root are rejected with a clear error so Claude can ask you to move the file or update the env var. Symlinks inside the root are resolved before the check, so a symlink that points out of the root is also rejected. Do not place secrets inside the allowed root — the allowlist bounds what the tool can read or write, but anything inside is fair game.
Sandboxed clients (Claude.ai with Cowork, etc.)
Sandboxed MCP clients cannot read the daemon's local cache. To make downloaded media visible to them, point WHATSAPP_MCP_MEDIA_ROOT at a directory the client's sandbox can also read (a Cowork workspace mount, a shared volume, etc.), and tell the client to pass output_path on every download_media call into that root. A copy-pasteable system instruction:
When calling the WhatsApp MCP's
download_media, always passoutput_pathset to a path under your shared workspace. Without it the decrypted file lands only in the daemon's local cache, which is outside your sandbox and unreadable.output_pathmust live underWHATSAPP_MCP_MEDIA_ROOTon the daemon side; the basename is yours to pick.
Related MCP server: Brevo MCP Server
Architecture
One binary, seven internal packages:
cmd/whatsapp-mcp/ login / serve / smoke subcommands
internal/client/ whatsmeow client wrapper (send, download, events, history, features)
internal/daemon/ HTTP server, pairing state machine, /pair endpoint
internal/mcp/ mark3labs/mcp-go server + tool registrations
internal/media/ ogg parsing, waveform synthesis, ffmpeg shell-out
internal/security/ path allowlisting, filename sanitisation, log redaction
internal/store/ SQLite cache, LID resolution, query layerProcess lifecycle
serve runs as a long-lived HTTP daemon. MCP clients connect and disconnect freely; the daemon stays up and continues receiving WhatsApp events. A flock(2) on store/.lock prevents two instances racing on the same store (WhatsApp would kick one of the two linked-device connections anyway).
The trade-off: events are persisted to SQLite only while serve is running. If the daemon stops, the WhatsApp connection closes. On the next start, whatsmeow emits events.HistorySync events that backfill conversations into SQLite, but the recovery window is governed by WhatsApp's server-side retention for multidevice clients — not by this codebase. Messages that arrive during a gap long enough to outlast WhatsApp's retention are not recoverable. For shorter, known gaps, the request_sync tool triggers a per-chat backfill on demand.
Data storage
Everything lives under ./store/ (override with -store DIR):
store/messages.db— local chat/message cache, indexed for search.store/whatsapp.db— whatsmeow's own device/session state.store/.lock— ephemeral advisory lock for single-instanceserve.
Data flow
The client sends a JSON-RPC
tools/calltoserveover HTTP.The MCP layer dispatches to an internal handler.
The handler either queries the local SQLite store or calls whatsmeow directly (send, download, reactions, etc.).
Incoming WhatsApp events are persisted to the store in a background goroutine inside the same process, so query tools always see current state.
Running the daemon
The daemon is designed to run independently of any MCP client. Three supported lifecycle models:
macOS — launchd. Template at docs/launchd/com.sealjay.whatsapp-mcp.plist. Copy to ~/Library/LaunchAgents/, replace {{PATH_TO_REPO}} / {{STORE_DIR}} placeholders, launchctl load. Daemon runs from login onwards.
Linux — systemd user unit. Template at docs/systemd/whatsapp-mcp.service. Copy to ~/.config/systemd/user/, replace placeholders, systemctl --user enable --now whatsapp-mcp.
Claude Code SessionStart hook. For project-scoped lifetimes, drop docs/hooks/setup.sh into your project's .claude/hooks/ and configure settings.json to invoke it. The hook is idempotent — safe to run alongside launchd/systemd.
Manual. ./bin/whatsapp-mcp serve -addr 127.0.0.1:8765 in any terminal. Ctrl-C to stop.
First-time pairing happens in a browser: start the daemon, open http://127.0.0.1:8765/pair, scan the QR with your phone. No terminal required. WhatsApp's multidevice protocol rotates the linked-device session roughly every 20 days; when that happens, the /pair page serves a fresh QR automatically — visit it again and re-pair. The /pair/* endpoints are rate-limited (5 GET/min, 1 POST/min on /pair/reset) and CSRF-protected.
Flags and environment variables for serve:
-addr host:port(envWHATSAPP_MCP_ADDR, default127.0.0.1:8765).-allow-remote(explicit opt-in to bind a non-loopback address; requiresWHATSAPP_MCP_TOKEN).WHATSAPP_MCP_TOKEN— bearer token for/mcpand/pair/*when-allow-remoteis set. Required;serveexits if missing.WHATSAPP_MCP_MEDIA_ROOT— allowed root forsend_file/send_audio_messagemedia_pathanddownload_mediaoutput_path.WHATSAPP_MCP_DEBUG=1— enable verbose logging with partial phone-number redaction (last 5 digits visible).
Tools
42 tools, grouped by purpose.
Read / query
Tool | Purpose |
| Substring search across cached contact names and phone numbers |
| Query + filter messages; returns formatted text with context windows |
| List chats with last-message preview; sort by activity or name |
| Chat metadata by JID |
| Before/after window around a specific message |
| Download persisted media to a local path |
| Ask WhatsApp to backfill history for a chat |
Send
Tool | Purpose |
| Send a text message to a phone number or JID |
| Send image/video/document/raw audio with optional caption; |
| Send a voice note (auto-converts via ffmpeg if not |
| Send a poll with a question and 2+ options; |
| Cast a vote on a previously-seen poll; |
| Return the tally for a poll we have cached (includes 0-vote options) |
| Send a contact card; synthesises a vCard 3.0 from |
Message actions
Tool | Purpose |
| Mark specific message IDs as read |
| Ack the most recent incoming messages in a chat to clear the unread badge |
| React to a message (empty emoji clears an existing reaction) |
| Text reply that quotes a prior message |
| Edit a previously-sent message |
| Revoke (delete for everyone) a message |
| Set per-chat composing / recording presence |
Groups
Tool | Purpose |
| Create a group with a name and initial participants |
| Leave a group |
| List all groups the user is a member of |
| Full group metadata (participants, settings, invite config) |
| Add / remove / promote / demote participants ( |
| Change the group subject |
| Change the group description; empty string clears it |
| Toggle announce-only mode (only admins can send) |
| Toggle locked mode (only admins can edit group metadata) |
| Get the invite link; |
| Join a group via a |
Blocklist
Tool | Purpose |
| Return the current blocklist |
| Block a contact by phone number or JID |
| Unblock a contact |
Privacy / presence / status
Tool | Purpose |
| Set own availability ( |
| Current privacy settings as JSON |
| Change one privacy setting by |
| Update the profile "About" text; empty string clears it |
Admin
Tool | Purpose |
| Batch-check which phone numbers are registered on WhatsApp |
| Report whether the bridge is connected and which account it's paired as |
| Report the device-pairing state as a structured |
Deferred
Intentionally not exposed yet:
subscribe_presence— no persistence layer for presence events, skipped to avoid a dangling tool.Profile photo setter — upstream whatsmeow doesn't expose a user-level setter.
Approval-mode participants, communities, newsletters — low-use surface, deferred.
Limitations
Prompt-injection risk: as with many MCP servers, this one is subject to the lethal trifecta. Prompt injection in incoming messages could lead to private data exfiltration — treat the tool surface accordingly.
Re-authentication: WhatsApp may invalidate the linked-device session periodically; re-run
./bin/whatsapp-mcp loginwhen that happens.Message gaps when
serveisn't running: events only flow into SQLite while the binary is alive. Messages sent during an offline window are recovered on next reconnect only if WhatsApp's multidevice retention still holds them; for longer gaps userequest_syncper chat, or accept the loss.Single instance per store: only one
whatsapp-mcp servecan hold the store lock. Parallel MCP clients must point at different-storedirectories (and therefore different paired sessions).Windows: requires CGO and a C compiler — see docs/windows.md.
Upstream bounds: message fetch/send is bounded by what whatsmeow supports against the WhatsApp web multidevice API.
Log redaction is obfuscation, not anonymisation. Partial knowledge of your contacts allows correlation from the last 5 visible digits. Symlinks inside
./store/uploads/are resolved before the path check so they cannot escape, but the root itself is a trust boundary — only place files you intend to send inside it.
Development
make test # unit tests
make test-race # with -race
make vet # go vet
make e2e # build + JSON-RPC smoke over HTTP (requires -tags=e2e)
make smoke # boot-test the server without connecting to WhatsAppUpgrading whatsmeow
Weekly CI runs an upstream upgrade probe. To do it manually:
make upgrade-checkThis bumps go.mau.fi/whatsmeow@main, re-tidies, builds, and tests. If green, commit the go.mod / go.sum changes.
scripts/mdtest-parity.sh in CI fails the build early if upstream removes or renames any whatsmeow method we call — it's the canary for API drift.
Troubleshooting
connect failed …onserve— the daemon is not paired. Openhttp://127.0.0.1:8765/pairin a browser and scan the QR. Alternatively, run./bin/whatsapp-mcp loginin a terminal.another whatsapp-mcp instance is already running— only oneservecan hold the store lock. Check for a stray process (ps aux | grep whatsapp-mcp) or another MCP client pointed at the same-storedirectory.QR doesn't display — the terminal doesn't render half-block Unicode. Try iTerm2, Windows Terminal, or similar.
Device limit reached — WhatsApp caps linked devices. Remove one from Settings → Linked Devices on your phone.
No messages loading — after initial auth, it can take several minutes for history to backfill. Use
request_syncto target a specific chat.WhatsApp out of sync — delete both database files (
store/messages.dbandstore/whatsapp.db) and re-runlogin.ffmpeg not found—send_audio_messageneeds ffmpeg onPATHto convert non-Opus audio. Usesend_filefor raw audio instead.
Debug logging
By default, JIDs in stderr logs are redacted to …<last-4-chars-of-user-part> and message bodies are summarised as [<length>B: text|url|command]. Media CDN URLs are collapsed to <scheme>://<host>/…. To see message content while actively debugging:
As a flag:
./bin/whatsapp-mcp -debug serveAs an env var in your MCP client config:
"env": { "WHATSAPP_MCP_DEBUG": "1" }
Even with debug mode on, phone-number-shaped digit sequences in bodies and JIDs are partially masked — only the last 5 digits are visible (e.g. +15551234567 → ****34567). This means debug logs are safe to share in bug reports without leaking full phone numbers.
Honesty disclaimer. The partial-redaction scheme is obfuscation for log-reader convenience, not anonymisation. Someone with independent knowledge of your contacts can still correlate the last 5 digits with a specific phone number. Treat redacted logs as "probably safe to paste into a GitHub issue", not "anonymised".
For Claude Desktop integration issues, see the MCP documentation.
Contributing
Contributions welcome via pull request. See CONTRIBUTING.md.
Licence
MIT Licence — see LICENSE.
Available Tools
42 toolsblock_contactAIdempotent
Block a contact so they can no longer send the paired user messages or see your last seen, profile photo, or status; the blocked contact is not explicitly notified but will see undelivered messages on their side. Idempotent if already blocked. Reversible via unblock_contact. Returns the plain-text string Blocked <jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| jid | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint, destructiveHint, etc.), the description discloses that the blocked contact is not notified but will see undelivered messages, and specifies the return format. This adds significant behavioral context.
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 concise with no redundant information. It front-loads the main action and effects, making it efficient for an agent to parse.
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 the tool's simplicity (1 param, no output schema, annotations present), the description adequately covers the effects, return value, idempotency, notification behavior, and reversibility, making it complete.
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 sole parameter 'jid' is fully documented in the schema (100% coverage). The tool description does not add any additional parameter semantics beyond what the schema already provides, so a baseline score of 3 is appropriate.
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 the specific verb 'Block' and identifies the resource 'a contact'. It clearly explains the effects (cannot send messages, hide last seen, etc.) and distinguishes from the sibling tool 'unblock_contact'.
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 states it is reversible via unblock_contact and idempotent, providing guidance on when to use it (to block a contact) and an alternative. However, it does not explicitly state when not to use it or provide usage scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_groupA
Create a new WhatsApp group with the given name and initial participants; the paired user becomes admin and listed participants receive a you were added system message in the new chat. Reversible by calling leave_group (irreversible itself) or update_group_participants with remove. Returns a JSON object {jid, info} where jid is the new group's JID and info is the freshly-fetched group metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | group display name (subject) | |
| participants | Yes | initial members as bare phone digits or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behavioral traits beyond annotations: the paired user becomes admin, listed participants receive a system message, and the return format (JSON with jid and info). It also notes reversibility, adding context that annotations do not cover. No contradiction with annotations.
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 concise, consisting of three sentences that front-load the core purpose, then add side effects, reversibility, and return format. Every sentence contributes meaningful information with no redundancy.
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?
The description covers the main functionality, effects, and reversibility. It details the return value despite no output schema. It lacks mention of prerequisites or error handling, but given the simplicity and annotations, it is adequately complete.
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% with clear descriptions for both parameters. The description adds minimal semantic value beyond stating 'given name and initial participants', which paraphrases the schema. It does not provide additional constraints or examples.
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 clearly states the tool creates a new WhatsApp group with a specific verb and resource. It distinguishes from sibling tools by mentioning the effects (paired user becomes admin, participants receive a system message) and reversibility via leave_group or update_group_participants.
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 provides clear context for when to use the tool (creating a group) and explicitly mentions how to reverse the action using sibling tools (leave_group, update_group_participants). It does not explicitly state when not to use it, but the purpose is well-defined, making usage guidelines adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_messageADestructiveIdempotent
Revoke (delete-for-everyone) a message; recipients see a message was deleted notice and the local cache row is marked revoked. Permanent — there is no undo, and the original body cannot be restored once revoked. You can only delete your own messages unless you are a group admin. Use edit_message instead when you only want to correct text. Returns the plain-text string Message deleted on success.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| message_id | Yes | WhatsApp message ID of the message to revoke (use `message_id` from list_messages) | |
| sender_jid | No | JID of the original sender; required when deleting someone else's message as a group admin, leave empty when deleting your own (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds critical beyond-annotation details: permanence ('no undo', 'cannot be restored'), return string ('Message deleted'), and admin privilege nuance. Annotations already indicate destructive and non-read-only, but description enriches with concrete behavioral traits.
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 well-structured sentences front-loading the core action, then detailing effects, restrictions, and alternatives. Every sentence carries necessary information with no 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?
Completely covers what an agent needs: purpose, side effects (permanence), return value, privilege requirements, and sibling differentiation. No output schema exists, but description provides sufficient completion.
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 has 100% coverage with good parameter descriptions. The description adds value by clarifying that sender_jid is required for admin deletion of others' messages and that message_id should come from list_messages, providing additional usage context.
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?
Description clearly states the tool revokes (deletes-for-everyone) a message, with specific verb and resource. It also distinguishes it from edit_message, making the purpose 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?
Explicitly states when to use this vs edit_message: 'Use edit_message instead when you only want to correct text.' Also notes that only own messages can be deleted unless group admin, providing clear usage boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_mediaAIdempotent
Fetch the encrypted media payload (image, video, audio, document) for a previously-cached message, decrypt it, and write it to a local file under the store directory; returns the absolute path. For image and audio downloads at most 5 MiB, the decrypted bytes are ALSO embedded in the tool result as an ImageContent or AudioContent block so remote MCP clients can view or hear the payload without accessing the daemon's filesystem. Videos and documents are not embedded (too large or not renderable inline). Optionally also writes the decrypted file to output_path, which must live under the configured media root (WHATSAPP_MCP_MEDIA_ROOT, default <store>/uploads/). No notification is sent to the sender or chat. Idempotent — repeated calls for the same message return the cached file path. Prerequisite: the message must contain media; use list_messages to find media message IDs. Returns a JSON object {Success, Message, MediaType, Filename, Path} as the first content block, followed by an optional ImageContent/AudioContent block for renderable media.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| message_id | Yes | WhatsApp message ID of a media message (use `message_id` from list_messages) | |
| output_path | No | optional absolute path under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`); parent directory must exist; calls are skipped if the file already exists; omit to write only to the daemon cache |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behaviors beyond annotations: idempotency, no notification, embedding for small image/audio, file writing to cache or output_path. No contradiction with annotations; adds value by explaining side effects and return format.
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?
Description is well-structured, starting with main action, then details. At ~200 words, it is comprehensive without being excessively verbose. Each sentence adds value for clarity.
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 complexity and no output schema, description sufficiently covers prerequisites, behavioral nuances, return format (JSON + optional content block), and side effects. Minor gap: could explicitly state that media must be previously cached, but overall complete.
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% but description adds meaning: specifies JID formats for chat_jid, links message_id to list_messages, and clarifies output_path constraints (under media root, parent dir must exist, idempotent on file existence). Enhances understanding beyond 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?
The description clearly states the tool's action: fetching encrypted media payload, decrypting, writing to a local file, and returning absolute path. It distinguishes from siblings by focusing on downloading media from cached messages, unlike sending or managing tools.
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?
Provides clear context: prerequisite that message must contain media, recommends using list_messages to get media message IDs. Notes that videos/documents are not embedded, guiding users to alternative access. Lacks explicit alternatives but sufficiently contextualizes when to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_messageADestructiveIdempotent
Edit a previously-sent text message in place; recipients see the new body with an edited label. Only your own messages can be edited and only within WhatsApp's edit window (~15 minutes). Re-edit by calling again with another new_body; to remove the message entirely use delete_message (revoke). Returns the plain-text string Message edited on success.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| new_body | Yes | replacement message body text | |
| message_id | Yes | WhatsApp message ID of your own message to edit (use `message_id` from list_messages) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses behavioral traits beyond annotations: in-place edit with 'edited' label, time constraint, re-edit capability, and success return value. Consistent with all annotation hints.
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 sentences, no wasted words. Functionality first, then constraints and alternatives. Every sentence adds value.
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 no output schema, description provides return value. Covers all essential aspects: what it does, effect on recipients, limitations, re-edit, removal alternative, and success message. No gaps.
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?
Adds practical meaning beyond schema descriptions: specifies that message_id should come from list_messages and explains chat_jid format with examples. This significantly aids correct invocation despite 100% schema coverage.
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?
Clearly states 'edit a previously-sent text message' with specific verb and resource. Distinguishes from siblings like delete_message and send_message by explaining the in-place edit effect and edited label.
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 states when to use (editing own messages within 15-minute window) and when not (cannot edit others' messages; use delete_message to remove). Provides re-edit guidance and alternative tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_blocklistARead-onlyIdempotent
Fetch the paired user's current WhatsApp blocklist from the server. Read-only; blocked contacts are not notified by this call. Use block_contact / unblock_contact to mutate the list. Returns a JSON document with the list of blocked JIDs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds that blocked contacts are not notified, which is useful behavioral context beyond the annotations. No contradictions.
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 sentences with no wasted words. The purpose is front-loaded, followed by behavioral guidance and return value. Every sentence adds value.
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?
The tool is simple with no parameters. The description mentions the return format (JSON list of JIDs), which covers the output sufficiently. No missing context given the tool's simplicity.
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?
Input schema has zero parameters, so description does not need to add parameter info. Baseline for 0 parameters is 4, and the description does not attempt to describe parameters as none exist.
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 clearly states the verb 'Fetch', the resource 'WhatsApp blocklist', and the scope 'paired user's current'. It also distinguishes from sibling tools like 'block_contact' and 'unblock_contact' which are for mutation, making the purpose 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?
The description explicitly says it's read-only, that blocked contacts are not notified, and directs users to use 'block_contact' or 'unblock_contact' for mutations. This provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chatARead-onlyIdempotent
(reads local cache; works while disconnected) Fetch metadata for a single cached chat by JID. Read-only; no side effects. Use list_chats to discover chat JIDs, or get_group_info for live group metadata. Returns a JSON object describing the chat (JID, name, last-message metadata when requested), or the JSON literal null when the chat is not in the cache.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| include_last_message | No | if true, include the chat's most recent message in the result (defaults to true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes reading from local cache, working while disconnected, and returning null when not found, adding value beyond the annotations that already mark it as readOnly and idempotent.
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 sentences, front-loaded with core purpose, no wasted words.
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 adequately explains return format (JSON object or null) and key fields, making the tool behavior complete for agent use.
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 minimal extra meaning (return type), but doesn't significantly enhance param understanding.
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 clearly states the verb 'Fetch', the resource 'metadata for a single cached chat', the method 'by JID', and distinguishes from sibling tools list_chats and get_group_info.
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 states when to use (fetch metadata of cached chat), its read-only nature, and provides alternative tools for discovery and live data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_group_infoARead-onlyIdempotent
Fetch live group metadata (subject, topic, participants with admin flags, announce/locked settings, invite config) for the given group JID. Read-only; no side effects. Use list_groups to discover which groups exist. Returns a JSON object describing the group.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description's statement 'no side effects' adds little. However, it adds useful context about the return format ('Returns a JSON object') which goes beyond annotations.
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 concise sentences. The first packs dense information about what is fetched, the second states read-only nature and mentions the sibling tool. No wasted words.
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?
Without an output schema, the description adequately lists the returned fields (subject, topic, participants with admin flags, etc.). Could mention error handling, but openWorldHint suggests graceful handling. Fairly complete for a simple 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 coverage is 100% with a detailed description of the chat_jid parameter. The description only repeats that it's for a 'group JID', adding no new meaning beyond the schema's own description.
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 ('Fetch') and resource ('live group metadata'), enumerates the specific fields retrieved, and distinguishes itself from siblings like list_groups by mentioning that discovery 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?
Explicitly states 'Read-only; no side effects' and directs users to use list_groups for discovery, providing clear context for when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_group_invite_linkADestructive
Return a group's current invite link, or revoke and mint a fresh one when reset=true. Warning: reset=true permanently invalidates the previous link — anyone holding a previously-shared copy can no longer use it to join, and there is no undo. Prerequisite: admin. Use join_group_with_link to consume an invite. Returns a JSON object {link} containing the active invite URL.
| Name | Required | Description | Default |
|---|---|---|---|
| reset | No | if true, permanently revoke the existing invite link and mint a new one (defaults to false); previously-shared copies stop working | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but description adds detailed warning about permanent invalidation and no undo, plus admin prerequisite, providing beyond-annotation context.
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 sentences plus essential warning and prerequisite, no wasted words, front-loaded with core action.
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?
Covers purpose, usage, parameters, return format (JSON object {link}), prerequisites, and links to related tool. Complete for a simple tool with good annotations.
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%, baseline 3. Description adds meaning: explains reset parameter's effect and chat_jid format, adding value beyond schema definitions.
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?
Clearly states the tool returns or resets a group invite link, with specific verb 'Return' and resource 'group invite link'. Distinguishes from sibling 'join_group_with_link' which consumes the invite.
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?
Provides explicit context: use to get or reset link, warns about destructive reset, mentions admin prerequisite, and references join_group_with_link for consumption. Could be improved by stating when not to use, but sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_message_contextARead-onlyIdempotent
(reads local cache; works while disconnected) Fetch a specific cached message and the surrounding messages in its chat. Read-only; no side effects. Use list_messages for searching across many chats. Returns a JSON object with the target message and arrays of messages before and after it.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | messages to fetch after the target (default 5; non-positive values fall back to the default) | |
| before | No | messages to fetch before the target (default 5; non-positive values fall back to the default) | |
| message_id | Yes | WhatsApp message ID of the target message (use `message_id` from list_messages) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint, destructiveHint, idempotentHint. Description adds '(reads local cache; works while disconnected)' and 'Read-only; no side effects,' providing extra behavioral context beyond annotations. No contradictions.
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 concise sentences: purpose and context, side-effect nature, sibling distinction, and return format. No wasted words, front-loaded with key 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?
Despite no output schema, description explains return structure. Covers offline capability and defaults. Missing error handling or missing message case, but overall sufficient for the tool's complexity.
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% with default and descriptions. Description adds value by explaining return structure: 'Returns a JSON object with the target message and arrays of messages before and after it.' Also reiterates default behavior for 'before' and 'after' parameters.
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?
Description clearly states 'Fetch a specific cached message and the surrounding messages in its chat.' Verb 'fetch' and resource identification are specific. Distinguishes from sibling 'list_messages' by noting 'for searching across many chats.'
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 states 'Read-only; no side effects' and recommends 'Use list_messages for searching across many chats.' Also mentions 'works while disconnected' as context. Does not explicitly say when not to use, but provides a clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_poll_resultsARead-onlyIdempotent
(reads local cache; works while disconnected) Return the current vote tally for a cached poll. Read-only; no side effects. Zero-vote options are included so the response always lists every original option. Returns a JSON object {poll_message_id, chat_jid, tally} where tally is option_label -> vote_count.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| poll_message_id | Yes | WhatsApp message ID of the poll to tally (use `ID` from send_poll, or `message_id` from list_messages) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, non-destructive, and idempotent. The description adds valuable context: zero-vote options are always included, and it works from a local cache while disconnected. No contradictions with annotations.
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 extremely concise: two sentences that deliver key behavioral info upfront (cache/offline), then return format. No filler or redundancy.
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 simple read tool with 2 fully described params, the description covers return shape, zero-vote behavior, and connectivity context. No output schema needed; the description provides sufficient representation.
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 fully documents both parameters. The description adds minimal extra meaning beyond specifying that poll_message_id comes from send_poll or list_messages, which is helpful but not essential.
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 clearly states the action: 'Return the current vote tally for a cached poll.' It uniquely identifies this as the read operation for poll results, distinguishing it from siblings like 'send_poll' and 'send_poll_vote'.
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 notes it works while disconnected and reads a local cache, implying offline suitability. It explicitly states 'Read-only; no side effects,' which guides safe usage. While it doesn't list when not to use, the purpose is clear enough given the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_privacy_settingsARead-onlyIdempotent
Fetch the paired user's current WhatsApp privacy settings from the server. Read-only; no side effects. Use set_privacy_setting to change individual values. Returns a JSON document with keys like groupadd, last, status, profile, readreceipts, online, calladd, messages, defense, stickers and their current string values.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. Description adds context about being read-only and returning a JSON document with specific keys, which goes beyond annotations.
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 concise sentences covering purpose, constraints, and return format without unnecessary words.
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?
Completely describes the tool's purpose, side effects, return format, and alternative, making it fully understandable for an agent to invoke 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?
Input schema has no parameters, and schema description coverage is 100%. With zero parameters, baseline is 4. Description does not need to add param info but mentions return keys, which is beneficial.
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?
Clearly states it fetches the paired user's WhatsApp privacy settings from the server. Distinguishes from sibling tool set_privacy_setting by mentioning it is read-only and has no side effects.
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 tells when to use this tool (fetching) and when not to (changing), and points to the alternative tool set_privacy_setting for modifications.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusARead-onlyIdempotent
Report whether the embedded WhatsApp bridge is connected and which account it is paired with. Read-only; no side effects. Call this first when other tools fail with auth or connection errors. Returns a JSON object {connected, paired, own_jid?, own_phone?, hint?} — hint includes the URL of the local pairing UI when not yet paired.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive. Description adds valuable behavioral details: read-only, no side effects, return structure including hint URL. However, it does not specify error conditions (e.g., what happens if bridge is not configured), but this is minor given the context.
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 sentences, each with purpose: states functionality, behavioral guarantee, usage guidance, and return details. No fluff, information dense and front-loaded.
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, but description fully specifies the return JSON fields and their meaning. The tool is simple (no parameters, single purpose), and the description covers all necessary information for an agent to use it 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?
No parameters exist, so schema coverage is 100%. Description adds no parameter info, but none is needed. Baseline is 4 because no parameters means no additional semantics required.
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 clearly states the tool reports connection status and paired account for the WhatsApp bridge. It uses specific verbs ('Report', 'Call first') and distinguishes this tool from siblings that perform mutations or data retrieval.
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 advises calling this tool first when other tools fail with auth or connection errors, providing a clear usage scenario and diagnostic role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_on_whatsappARead-onlyIdempotent
Query WhatsApp servers to check which of the supplied phone numbers are registered on WhatsApp; the queried users are not notified. Read-only with no chat side effects. Use before send_message when you only have a phone number and need to confirm the contact exists. Returns a JSON object keyed by input phone, each value {is_in: bool, jid: string, verified_name?: string} (or similar).
| Name | Required | Description | Default |
|---|---|---|---|
| phones | Yes | phone numbers to check; digits only with no `+` prefix, spaces, or punctuation (e.g. `447700900000`); must be non-empty |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, non-destructive, idempotent, open world. The description adds value by explicitly stating no notification to queried users and no chat side effects, plus outlining the return format, which is not present in annotations.
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 with no redundancy. First sentence states core functionality and side effects, second gives usage recommendation, third describes return format. Information-dense and well-structured.
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 simple single-parameter read-only tool, the description covers purpose, behavior, usage context, and return format. No output schema exists, but the description compensates by describing the JSON structure.
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 100% coverage for the 'phones' parameter. The description provides essential formatting details (digits only, no + or spaces, example) and validation rule (non-empty), adding significant meaning beyond the schema's basic description.
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 clearly states it queries WhatsApp servers to check phone number registration, specifies that users are not notified, and distinguishes itself from sibling tools like send_message by focusing on existence check.
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 recommends use before send_message when only a phone number is available and confirmation of contact existence is needed. However, it does not mention when not to use it, such as when the contact is already known, but the context is largely clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
join_group_with_linkAIdempotent
Join a WhatsApp group via a chat.whatsapp.com/<code> invite URL or the bare invite code; existing members see a joined via invite link system message and the new chat appears for the paired user. Reversible via leave_group (which is itself permanent). Use get_group_invite_link to mint or read invite links. Returns a JSON object {jid} containing the joined group's JID.
| Name | Required | Description | Default |
|---|---|---|---|
| link_or_code | Yes | full invite URL (`https://chat.whatsapp.com/<code>`) or just the trailing invite code |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behavioral traits beyond annotations: it explains the system message, the new chat for the paired user, and reversibility via leave_group. Annotations indicate a write operation (readOnlyHint=false) and non-destructive, which align. It adds value without contradiction.
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 two sentences, front-loading the purpose and then adding relevant behavioral and reversibility details. Every sentence earns its place with no wasted words.
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 simple tool with 1 parameter, the description explains input format, behavioral effects, reversibility, and return type ({jid}). It also references a sibling tool, making it contextually complete despite lacking an output schema.
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 100% schema coverage, the baseline is 3. The description adds a useful format example ('https://chat.whatsapp.com/') and clarifies that either the full URL or bare code is accepted, providing slight extra meaning over the schema's description.
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 clearly states the tool's purpose: 'Join a WhatsApp group via a `chat.whatsapp.com/` invite URL or the bare invite code.' It uses a specific verb and resource, and distinguishes from sibling tools like create_group and get_group_invite_link.
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 provides clear context about the outcome (system message, new chat appearance) and mentions reversibility via leave_group. It doesn't explicitly state when not to use it, but it does reference a related tool (get_group_invite_link) for comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
leave_groupADestructiveIdempotent
Leave a WhatsApp group; remaining members see a you left system message and the paired user loses access to all future messages in the chat. Permanent — to rejoin you must be re-added by an admin or invited via a fresh link (join_group_with_link). Prefer setting privacy or muting on the client if you only want silence. Returns the plain-text string Left group <chat_jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal destructive and idempotent; description adds concrete details about permanence, user experience, and return value, adding value beyond annotations.
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 sentences plus a return note, no fluff, front-loaded with most critical information first.
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?
Covers effects, permanence, return value, and alternatives; no output schema needed as action returns trivial string.
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 covers 100% of the single parameter with detailed JID format; description adds no further semantics, so baseline score of 3 is appropriate.
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?
Clearly states 'Leave a WhatsApp group' and specifies the effects (system message, loss of access), distinguishing from sibling join_group_with_link.
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 suggests alternatives (privacy/muting) and explains when not to use, along with conditions for rejoining.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_chatsARead-onlyIdempotent
(reads local cache; works while disconnected) List cached WhatsApp chats (1:1 and group), optionally filtered by name substring and sorted by recency or alphabetic name. Read-only; no side effects. Use get_chat for a single chat by JID, list_groups for groups only. Returns a JSON array of chat objects (each with JID, name, last-message metadata when requested).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | zero-based page index for paging through results (default 0) | |
| limit | No | max chats to return (default 20) | |
| query | No | case-insensitive substring to match against chat name | |
| sort_by | No | sort order: `last_active` (most-recent first, default) or `name` (alphabetic) | last_active |
| include_last_message | No | if true, include each chat's most recent message in the result (defaults to true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, idempotentHint. The description adds that it reads local cache, works while disconnected, is read-only with no side effects. This adds value beyond annotations without contradiction.
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 three sentences, front-loaded with the core purpose, and every sentence adds necessary information. No 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?
Given 5 parameters with good schema coverage, no output schema, but description mentions returns JSON array of chat objects with details. It explains offline behavior and side-effect-free nature. Slightly incomplete on return format specifics, but adequate.
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 has 100% coverage with descriptions for all 5 parameters. The description adds context about filtering by name substring and sorting by recency or alphabetic name, and mentions return format. This adds marginal value beyond 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?
The description states it lists cached WhatsApp chats (1:1 and group) with optional filtering and sorting. It distinguishes from siblings by mentioning get_chat for a single chat and list_groups for groups only.
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 to use get_chat for a single chat by JID and list_groups for groups only. It also mentions it reads local cache and works while disconnected, but does not explicitly state when not to use it. This is clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_groupsARead-onlyIdempotent
List every WhatsApp group the paired user is currently a member of, fetched live from WhatsApp. Read-only; no side effects. Use get_group_info for detailed metadata about one specific group. Returns a JSON array of group-info objects (each with JID, subject, participants, settings, and so on).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds value beyond annotations by stating data is fetched live from WhatsApp and describing the return structure (JSON array with fields). Annotations already declare readOnly, destructive, and idempotent hints, and the description aligns with them.
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 concise sentences, each with a clear purpose: main action, side-effect declaration, alternative tool, and return type. No wasted words.
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 simple tool with no parameters and no output schema, the description adequately explains what it does, its safety, and the return format. No missing information for an AI agent to use it effectively.
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?
No parameters exist (schema coverage 100% with zero params). With no parameters to document, the baseline is 4. The description does not need to add parameter information.
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 clearly states the tool lists WhatsApp groups the user is a member of, with a specific verb and resource. It distinguishes from the sibling tool get_group_info by specifying its broader scope.
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 indicates when to use it (live listing of groups) and provides an alternative (get_group_info for detailed metadata). However, it does not explicitly state when not to use it, though the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_messagesARead-onlyIdempotent
(reads local cache; works while disconnected) Search and page through cached WhatsApp messages, optionally filtering by chat, sender, time range, and substring; can include surrounding context messages. Read-only; no side effects. Use get_message_context to expand around a single known message ID, or request_sync to backfill missing history. Returns a human-readable formatted text block listing matching messages.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | zero-based page index for paging through results (default 0) | |
| after | No | ISO-8601 UTC lower bound on message timestamp (inclusive) | |
| limit | No | max messages to return (default 20, capped at 100 server-side) | |
| query | No | case-insensitive substring to match within message body | |
| before | No | ISO-8601 UTC upper bound on message timestamp (inclusive) | |
| chat_jid | No | filter to messages in this chat (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) | |
| context_after | No | messages to include after each match (default 1, capped at 20 server-side) | |
| context_before | No | messages to include before each match (default 1, capped at 20 server-side) | |
| include_context | No | if true, attach a few surrounding messages to each match (defaults to true) | |
| sender_phone_number | No | filter to messages sent by this phone or JID (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds valuable context: 'reads local cache; works while disconnected' and 'returns a human-readable formatted text block', going beyond annotations.
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, front-loaded with key attributes (local cache, offline, search), then filter summary, then alternative tools, then return format. No wasted words.
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 10-parameter tool with no output schema, the description sufficiently explains what the tool does, the filtering capabilities, and return format. Lacks explicit mention of pagination behavior but the schema's page/limit parameters and the phrase 'page through' imply it.
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?
Input schema covers all 10 parameters with descriptions (100% coverage). The description briefly restates filters ('filtering by chat, sender, time range, and substring; can include surrounding context messages') but adds little new meaning beyond 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?
The description clearly states the tool reads local cached WhatsApp messages, searches and pages through them with various filters, and names sibling tools for alternative use cases (get_message_context, request_sync), distinguishing its purpose.
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 tells when to use this tool (searching/filtering messages) and when to use alternatives: 'Use get_message_context to expand around a single known message ID, or request_sync to backfill missing history.' Also notes it's read-only with no side effects.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_chat_readAIdempotent
Ack the most recent incoming messages in a chat to clear its unread badge; senders receive read receipts (subject to their privacy settings). Cannot be unread once acked. Use mark_read for ack-by-message-ID. Returns the plain-text string Acked N message(s) in <chat_jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | how many of the most recent incoming messages to ack (default 50) | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds value beyond annotations by noting read receipts are subject to privacy settings, the action is irreversible, and the exact return string format. Annotations already indicate idempotency and non-destructiveness; no contradictions.
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 three concise sentences, each essential: purpose, alternative, and return format. No redundant 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?
Given the tool's simplicity (two parameters, no output schema), the description covers all necessary context: action, constraints, sibling differentiation, and return value. No gaps identified.
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 descriptions already cover both parameters fully. The description adds context that 'limit' applies to the most recent incoming messages and defaults to 50, reinforcing the tool's 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 clearly states the tool acks the most recent incoming messages to clear the unread badge, specifies read receipts, and distinguishes itself from the sibling tool 'mark_read' by contrasting ack-by-chat vs ack-by-message-ID.
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 explicitly tells when to use this tool (for acking the most recent incoming messages in a chat) and when to use the alternative 'mark_read' (for ack-by-message-ID). It also warns that the action cannot be undone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_readAIdempotent
Mark specific incoming messages as read; senders receive read receipts (subject to their privacy settings) and the chat's unread badge decrements. Cannot be unread once acked. Use mark_chat_read to clear the unread badge for an entire chat without enumerating message IDs. Returns the plain-text string Marked N message(s) read in <chat_jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| sender_jid | No | JID of the original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) | |
| message_ids | Yes | list of WhatsApp message IDs to ack (use `message_id` values from list_messages); must be non-empty |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint=true, readOnlyHint=false, destructiveHint=false), the description adds crucial context: senders receive read receipts subject to privacy settings, unread badge decrements, and the action is irreversible. No contradictions.
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 concise sentences: main action and effects, limitation and alternative, return value. Front-loaded with purpose, no wasted words.
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 lacking an output schema, the description includes the return format. It covers behavior, limitations, alternative, and parameter details comprehensively for a tool with three parameters.
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%, but the description adds value by clarifying that message_ids must be non-empty and should come from list_messages, and provides JID format examples for chat_jid and sender_jid.
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 clearly states the verb 'mark' and the resource 'specific incoming messages' with specific effects (read receipts, unread badge decrement). It also implicitly distinguishes from sibling mark_chat_read by mentioning the alternative.
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 states when not to use (cannot be unread once acked) and provides an alternative tool (mark_chat_read) for clearing the entire chat unread badge without enumerating message IDs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pairing_statusARead-onlyIdempotent
Report the WhatsApp device-pairing state as a structured setup_state envelope for programmatic supervisors that surface the linking QR to their own clients (e.g. a polling daemon). Read-only; no side effects. Returns a JSON object {type:"setup_state", state, …} where state is ready (paired and connected; adds own_jid/own_phone), awaiting_qr (unpaired; adds qr_payload when a pairing code is cached), or error (pairing cache unavailable).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds value by explaining the three possible states (ready, awaiting_qr, error) and the fields included in each, giving behavioral detail beyond what structured annotations convey. No contradictions.
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 paragraph that front-loads the purpose and usage, then details the output structure and states. Every sentence contributes meaningful information with no repetition or fluff.
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 that the tool has no parameters and no output schema, the description fully explains what the tool does, when to use it, and what the return value looks like (including state values and additional fields). It is complete for an agent to select and invoke 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?
Tool has zero parameters, making schema coverage 100% complete. With no parameters, the description does not need to add parameter details. Baseline for zero parameters 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 explicitly states it reports WhatsApp device-pairing state as a structured `setup_state` envelope. It uses specific verbs ('report the ... state') and clearly identifies the resource. Among siblings, no other tool covers pairing state, so it is well-distinguished.
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 says it is 'for programmatic supervisors that surface the linking QR to their own clients (e.g. a polling daemon)', which gives clear context for when to use. It also notes the tool is read-only with no side effects. It does not explicitly exclude cases or name alternatives, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_syncAIdempotent
Ask WhatsApp servers to backfill historical messages for a chat into the local cache; messages arrive asynchronously and become queryable via list_messages once delivered. No effect on the chat itself or other users. If from_timestamp is omitted, the request anchors on the newest cached message. Returns a plain-text confirmation describing what was requested.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | No | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| from_timestamp | No | ISO-8601 UTC timestamp marking the lower bound; if omitted, anchors on the newest cached message in the chat |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds value beyond annotations by describing the async delivery, lack of side effects on the chat, and the plain-text response. No contradictions with annotations.
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 sentences with no wasted words; purpose is front-loaded, followed by key details. Excellent structure.
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?
All relevant aspects covered: purpose, behavior, parameter semantics, output format, and integration with sibling tool list_messages. No gaps given the simple input schema and annotations.
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 already covers 100% of parameters, but description adds meaningful behavior for from_timestamp (default behavior when omitted) beyond the schema's syntactic description.
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?
Description clearly states the verb ('Ask to backfill') and resource ('historical messages for a chat'), distinguishes from sibling tools by mentioning that messages become queryable via list_messages. No ambiguity.
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?
Provides context for when to omit from_timestamp, but does not explicitly state when to use this tool versus alternatives like list_messages (which retrieves already synced messages) or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_contactsARead-onlyIdempotent
(reads local cache; works while disconnected) Search the cached WhatsApp contact list by case-insensitive substring of name or phone number. Read-only; no side effects. Use is_on_whatsapp to verify whether an unknown phone number is registered. Returns a JSON array of contact objects (each with JID, push name, full name, and phone).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | case-insensitive substring to match against name or phone |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent behavior. The description adds valuable context: it reads a local cache, works while disconnected, and has no side effects. No contradiction with annotations.
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 concise, well-structured, and front-loaded with the essential detail about local caching and offline capability. Every sentence is informative with no redundancy.
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 simple search tool with one parameter and no output schema, the description adequately covers return format (JSON array of contact objects with fields), search behavior, and operational context (cached, offline-capable).
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% with a single parameter 'query' described as case-insensitive substring. The description restates this without adding new meaning, earning a baseline of 3.
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 clearly states the tool searches the cached WhatsApp contact list by case-insensitive substring of name or phone number. It distinguishes from sibling tool is_on_whatsapp by specifying that is_on_whatsapp should be used for checking unknown numbers.
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 explicitly advises when to use the alternative tool is_on_whatsapp for verifying unknown phone numbers, and notes that search_contacts works while disconnected and reads local cache, guiding appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_audio_messageA
Send an audio file as a WhatsApp voice note (waveform UI, push-to-play); non-ogg inputs are transcoded via ffmpeg before upload. Reversible via delete_message (revoke). Use send_file when you want the audio delivered as a regular attachment instead of a voice note. Prerequisites: ffmpeg must be on PATH for non-ogg inputs. Returns a JSON object {Success, Message, ID} where ID is the WhatsApp message ID on success.
| Name | Required | Description | Default |
|---|---|---|---|
| recipient | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` | |
| view_once | No | if true, mark the voice note as view-once (defaults to false) | |
| media_path | Yes | absolute path to the audio file; must sit under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`) | |
| mark_chat_read | No | if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral context beyond annotations: it discloses transcoding behavior for non-ogg inputs, prerequisite (ffmpeg on PATH), the return JSON structure with fields, and that the action is reversible. Annotations are consistent (readOnlyHint false), no contradiction.
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 compact with three sentences covering purpose, alternatives, prerequisites, and return format. No redundant phrases, though the information density is high – each sentence 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?
Despite no output schema, the description fully explains the return format (JSON with Success, Message, ID). It covers prerequisites, reversible nature, and distinguishes from sibling tools. For a tool with 4 parameters, it provides all necessary contextual 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?
The input schema has 100% description coverage, so the schema already fully documents each parameter. The description does not add new semantic details about parameters beyond what the schema provides. Baseline 3 is appropriate.
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 ('Send an audio file as a WhatsApp voice note') and clearly identifies the resource and output format (waveform UI, push-to-play). It distinguishes from the sibling tool send_file by stating the alternative use case, making the purpose unmistakable.
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 explicitly states when to use this tool (voice note) versus the alternative send_file (regular attachment). It also mentions reversibility via delete_message, providing clear context for when it's appropriate to invoke.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_contact_cardA
Send a WhatsApp contact card; recipients see a tappable contact entry they can save to their address book and the outgoing message is persisted to the local cache. When vcard is omitted a minimal vCard 3.0 is synthesised from name + phone. Reversible via delete_message (revoke). Returns a JSON object {Success, Message, ID} where ID is the WhatsApp message ID on success.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | contact display name; also used as the FN in the synthesised vCard | |
| phone | No | phone number (digits preferred); embedded in the synthesised vCard when `vcard` is not supplied | |
| vcard | No | raw vCard 3.0 string; when set, name+phone synthesis is skipped and this string is sent as-is | |
| recipient | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate a write operation (readOnlyHint=false) but description adds behavioral details: persistence to local cache, revocability via delete_message, and clear return format. No contradictions. However, it does not disclose any side effects or failures.
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 sentences efficiently cover purpose, behavior, parameter interaction, and return value. No fluff; every clause adds value.
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?
Covers return value, main behavior, and reversibility. Lacks error handling details or rate limits but is adequate for a contact card tool with no output schema. Moderate complexity warrants this score.
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% (all parameters described), description adds key behavior: synthesis of vCard when omitted, recipient format guidance. This enriches understanding beyond schema definitions.
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 clearly states the tool sends a WhatsApp contact card, describes the user-facing behavior (tappable, savable), and mentions persistence and reversibility. It distinguishes itself from siblings like send_message or send_file by specifying a contact card format.
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?
Provides implicit guidance by explaining when to omit vcard (synthesis from name+phone) but no explicit comparison to alternative tools for sending contacts (e.g., send_message with vCard text, send_file). Does not state when not to use this tool versus siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_fileA
Upload and send a picture, video, document, or raw audio attachment via WhatsApp; the recipient sees a media message and the outgoing row is persisted to the local cache. Reversible via delete_message (revoke). For voice notes use send_audio_message (which transcodes to ogg/opus); for plain text use send_message. Returns a JSON object {Success, Message, ID} where ID is the WhatsApp message ID on success.
| Name | Required | Description | Default |
|---|---|---|---|
| caption | No | optional caption for image/video/document submessages; ignored for raw audio | |
| recipient | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` | |
| view_once | No | if true, mark image/video/audio submessages as view-once; silently ignored for documents (defaults to false) | |
| media_path | Yes | absolute path to the media file; must sit under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`) | |
| mark_chat_read | No | if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds several behavioral traits beyond annotations: it's reversible via delete_message, persists to local cache, and returns a JSON object with specific fields. Annotations already indicate readOnlyHint=false (write operation) and destructiveHint=false, which the description reinforces. No contradiction.
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 two sentences, front-loaded with the main action, and efficiently covers usage guidelines and return value. Every sentence adds value without redundancy.
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 explicitly states the return JSON structure. It covers the tool's purpose, parameters (via schema), usage guidelines, and behavioral traits, making it fully informative for an agent to select and invoke 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?
Input schema has 100% coverage with detailed descriptions for all 5 parameters. The description does not add new parameter meaning beyond what the schema provides. Baseline 3 is appropriate.
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 clearly states it uploads and sends a picture, video, document, or raw audio via WhatsApp, specifying the recipient sees a media message and it's persisted to cache. It distinguishes from sibling tools like send_audio_message and send_message, making the purpose 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?
The description explicitly tells when to use alternatives: 'For voice notes use send_audio_message; for plain text use send_message.' It also mentions reversibility via delete_message, providing clear context on when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageA
Send a new WhatsApp text message to a person or group; recipients see it as a fresh message from the paired account and the row is also stored in the local cache. Reversible via delete_message (revoke) or edit_message (correct text); to quote a previous message use send_reply, for emoji acknowledgement use send_reaction. Returns a JSON object {Success, Message, ID} where ID is the WhatsApp message ID on success.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | message body text | |
| recipient | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` | |
| mark_chat_read | No | if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false and destructiveHint=false, and the description adds meaningful behavioral context: the message appears as a fresh message, is stored locally, is reversible, and returns a specific JSON. This enhances understanding beyond the annotations.
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 concise (two sentences plus return format), front-loaded with the core purpose, and efficiently includes alternatives, reversibility, and return structure without any redundant wording.
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 the tool's moderate complexity (3 parameters, no output schema), the description fully covers the effect, behavior, return format, and links to sibling tools. No gaps remain.
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% with clear parameter descriptions. The tool description reinforces the recipient format and the mark_chat_read effect, but does not add substantial new meaning beyond the schema. Baseline 3 is appropriate.
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 ('Send') and resource ('new WhatsApp text message'), and clearly distinguishes this tool from siblings like send_reply and send_reaction by stating when to use those alternatives. It also explains the effect (fresh message, local cache storage).
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 explicitly directs the agent to use send_reply for quoting, send_reaction for emoji acknowledgement, and mentions reversibility via delete_message or edit_message. This provides clear when-to-use guidance, though it does not explicitly state when not to use this tool (e.g., for replies).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_pollA
Send a new WhatsApp poll message with 2 to 32 options; recipients see a votable poll card and an outgoing row plus poll metadata is persisted locally so votes can be tallied. Reversible via delete_message (revoke). Use send_poll_vote to cast votes and get_poll_results to read tallies. Returns a JSON object {Success, Message, ID} where ID is the poll message ID on success.
| Name | Required | Description | Default |
|---|---|---|---|
| options | Yes | poll option labels; must contain between 2 and 32 entries | |
| question | Yes | poll question text shown above the options | |
| recipient | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` | |
| selectable_count | No | how many options each voter may pick; 1 = single-choice (default), higher = multi-select up to this cap |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that poll metadata is persisted locally, recipients see a votable card, and the message is reversible via delete_message; adds value beyond annotations.
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 sentences with all key info, though first sentence is dense; could be slightly more structured but still efficient.
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?
Covers behavior, reversibility, return format; no output schema, but description compensates; parameter details are fully in schema.
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%; description adds minimal extra meaning (e.g., recipients see a poll card) but mostly restates schema details.
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 clearly states it sends a WhatsApp poll message with 2-32 options, distinguishing it from siblings like send_poll_vote and get_poll_results.
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?
Provides explicit guidance on when to use this tool and mentions alternatives for voting and results; lacks explicit 'when not to use' but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_poll_voteAIdempotent
Cast or re-cast a vote on a previously-seen poll; each call replaces the caller's prior vote on that poll, and the new tally is broadcast to the chat. Reversible by calling again with the desired option set (or an empty list to clear). Prerequisite: the poll must be in the local cache, i.e. send_poll was used or we received the poll via sync. Returns a JSON object {Success, Message, ID} where ID is the vote message ID.
| Name | Required | Description | Default |
|---|---|---|---|
| options | Yes | option labels to pick; must match the poll's option text exactly, between 1 and 32 entries | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| poll_message_id | Yes | WhatsApp message ID of the poll to vote on (use `ID` returned by send_poll, or `message_id` from list_messages) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate idempotentHint=true and destructiveHint=false. The description adds critical behavioral details: each call replaces prior vote, broadcasts new tally, and is reversible. It also specifies the prerequisite and return format, going beyond what annotations provide.
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 concise with three sentences: main action, behavioral details, prerequisite, and return format. Information is front-loaded and every sentence adds value.
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 no output schema, the description explains the return object. It covers prerequisites, behavior, and usage. The sibling tools list includes related poll operations (send_poll, get_poll_results), providing sufficient context for selection.
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% with descriptions for each parameter. The description adds context about the 'options' parameter (must match exactly, 1-32 entries) not fully captured in the schema. It also clarifies that poll_message_id should come from send_poll or list_messages.
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 clearly states 'Cast or re-cast a vote on a previously-seen poll', specifying the action (vote) and resource (poll). It distinguishes from siblings like send_poll (create) and get_poll_results (retrieve results) by focusing on the voting act.
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 explains when to use the tool (to vote on a poll) and includes a prerequisite (poll must be in local cache). It also mentions reversibility. However, it does not explicitly list when not to use it or alternative tools for other actions like viewing results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_presenceAIdempotent
Set the paired user's own global online availability; contacts permitted by privacy settings see online or last-seen accordingly. Reversible by calling again with the inverse state. Use send_typing for per-chat composing/recording indicators instead. Returns a JSON object {success, message}.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | availability to broadcast: `available` (online) or `unavailable` (offline) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds behavioral details beyond annotations: reversibility, privacy settings effect on visibility, and return format. No contradiction with annotations.
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 redundancy. Front-loaded with core purpose, efficient and clear.
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?
Complete for a simple tool: schema documents parameter, annotations present, description adds behavior and return info. No gaps.
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% with clear parameter description. Description does not add substantial new meaning beyond 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?
The description clearly states the tool sets global online availability ('Set the paired user's own global online availability') and distinguishes from sibling send_typing. It uses specific verb and resource.
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 tells when to use this tool (global availability) and when not (per-chat indicators via send_typing). Also mentions reversibility, providing clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_reactionAIdempotent
Add or replace an emoji reaction on an existing message; recipients see the small emoji badge attached to the original message. Reversible by calling again with an empty emoji string (clears the reaction); for a fresh message use send_message and for a quoted reply use send_reply. Returns the plain-text string Reaction sent on success.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | No | single emoji to react with; pass an empty string to clear an existing reaction | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| message_id | Yes | WhatsApp message ID of the target message (use `message_id` from list_messages) | |
| sender_jid | No | JID of the original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses reversible behavior via empty emoji, return value of 'Reaction sent', and hints that it is idempotent (aligns with annotation). No contradiction with annotations.
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 concise sentences; first sentence immediately states core purpose. No superfluous content.
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 4-parameter tool with no output schema, the description covers all: purpose, usage guidance, return value, and parameter hints. Sibling tools are mentioned. Complete given the tool's complexity.
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 describes all parameters thoroughly. Description adds no significant new semantics beyond restating the emoji empty string case.
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 clearly states the verb 'Add or replace an emoji reaction on an existing message' and distinguishes it from siblings by specifying 'for a fresh message use send_message and for a quoted reply use send_reply'.
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 tells when to use (react to existing message) and when not (use send_message for fresh, send_reply for quoted reply), and explains reversibility with empty emoji.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_replyA
Send a text message that visibly quotes a previous message; recipients see the new text with the quoted message attached. Reversible via delete_message (revoke) or edit_message (correct text). Use send_message for a fresh non-quoting message and send_reaction for an emoji acknowledgement. Returns the plain-text string Reply sent on success.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | reply text body | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| target_message_id | Yes | WhatsApp message ID of the message being quoted (use `message_id` from list_messages) | |
| target_sender_jid | No | JID of the quoted message's original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses return value ('Reply sent' string) and reversibility, adding context beyond annotations (which already indicate non-destructive). No contradictions.
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 sentences, front-loaded with purpose, each sentence adds value: purpose, reversibility, alternatives, return value. No wasted words.
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 4-parameter tool with no output schema, the description covers purpose, usage, return value, and reversibility, making it fully adequate for an agent to invoke 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 baseline is 3. The description adds minimal additional meaning beyond schema descriptions; it does not elaborate on parameter formats or constraints.
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 clearly states it sends a text message that quotes a previous message, using specific verb 'send' and resource 'reply'. It distinguishes from siblings like send_message (fresh non-quoting) and send_reaction (emoji).
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 tells when to use (to quote a message) and when not (use send_message or send_reaction). Also mentions reversibility via delete_message or edit_message, providing complete guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_typingAIdempotent
Show or hide the per-chat typing or recording presence indicator; the recipient sees a transient typing... or recording audio... hint that auto-expires after roughly 25 seconds. Reversible by calling again with active=false. Use send_presence to set global online/offline availability instead. Returns the plain-text string Presence active for <chat_jid> or Presence paused for <chat_jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | indicator kind: empty string for text typing (default) or `audio` for voice-note recording | |
| active | Yes | true to show the indicator (composing or recording), false to pause it | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral details beyond annotations: the indicator is transient with roughly 25-second auto-expiry, reversible, and returns a specific string. Annotations (idempotentHint=true, etc.) are consistent and description enriches them.
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, efficiently front-loaded with the core action. Every sentence provides essential information without redundancy or fluff.
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?
The description covers purpose, usage guidelines, parameter details, behavioral traits, and return value. For a tool with 3 simple parameters and no output schema, it is fully complete.
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 description adds meaning for each parameter: active (show/pause), chat_jid (format explanation), kind (default vs audio). It also describes the return value, which is not in the schema, adding valuable context.
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 clearly states the tool's purpose: 'Show or hide the per-chat typing or recording presence indicator.' It specifies the verb (show/hide), resource (indicator), and scope (per-chat), and distinguishes it from the sibling tool send_presence.
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 explicitly tells when to use an alternative: 'Use send_presence to set global online/offline availability instead.' It also explains the reversible nature by calling again with active=false, providing clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_group_announceAIdempotent
Toggle announce-only mode on a group; when enabled, non-admin send attempts are rejected by WhatsApp servers and members see a system message about the change. Reversible by calling again with the inverse value. Prerequisite: admin. See set_group_locked for restricting metadata edits. Returns the plain-text string Group <chat_jid> announce_only=<bool>.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| announce_only | Yes | true to lock posting to admins only, false to allow all members to post |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already covering idempotentHint and destructiveHint, the description adds valuable behavioral details: non-admin attempts are rejected, members see a system message, and the return value string is specified.
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, front-loaded with main action, then elaborates on behavior and alternatives. No wasted words.
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 the simplicity (2 params, no output schema), the description covers behavior, prerequisites, return value, and a sibling, making it fully actionable.
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?
Input schema already describes both parameters well (100% coverage). Description adds context (non-admin rejection) but does not significantly extend semantics beyond 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?
The description clearly states the tool toggles announce-only mode on a group, with specifics on behavior (reject non-admin, system message). It distinguishes itself from sibling set_group_locked by mentioning the alternative for restricting metadata edits.
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 use (toggle announce-only), lists prerequisite (admin), indicates reversibility, and points to set_group_locked for metadata edits, providing clear alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_group_lockedAIdempotent
Toggle locked mode on a group; when enabled, only admins can change name/topic/icon and members see a system message about the change. Reversible by calling again with the inverse value. Prerequisite: admin. See set_group_announce for restricting who can post. Returns the plain-text string Group <chat_jid> locked=<bool>.
| Name | Required | Description | Default |
|---|---|---|---|
| locked | Yes | true to restrict subject/topic/icon edits to admins, false to allow all members | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already indicating non-readOnly, non-destructive, idempotent, the description adds useful behavioral context: reversibility by calling with inverse value, system message shown, and exact return string. No contradiction with annotations.
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 sentences, no wasted words, key information front-loaded (verb, resource, effect). Efficient and well-structured.
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 includes the return value format. Covers prerequisite, effect, reversibility, alternative, and system message. Complete for a toggle 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 covers both parameters with clear descriptions (100% coverage). Description adds little beyond schema, only reinforcing the toggle behavior for 'locked' parameter. Baseline 3 is appropriate.
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 clearly states the verb 'Toggle' and resource 'locked mode on a group', specifying the effect (only admins can change name/topic/icon, system message). It distinguishes itself from sibling tool set_group_announce.
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 states prerequisite 'admin' and provides an alternative tool (set_group_announce) for restricting posting. Guides when to use and when not to.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_group_nameAIdempotent
Change a group's display name (its subject); members see a system message naming the new subject. Reversible by calling again with the previous name. Prerequisite: admin (or non-locked group). Returns the plain-text string Group <chat_jid> renamed to "<name>".
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | new group subject (display name) | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes side effects (members see a system message), reversibility, and request/response behavior. Annotations already indicate idempotentHint=true, but description adds concrete meaning: calling again with previous name reverses it. No contradiction with annotations.
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 serving a purpose: action, effect plus reversibility, prerequisite and return format. No redundant words.
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?
Complete for a simple tool: covers prerequisite, behavioral effects, return format (since no output schema). All relevant aspects are addressed.
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% with good descriptions for both parameters. Description adds no new parameter details beyond what schema provides, so baseline 3 is appropriate.
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?
Description clearly states the action (change display name) and resource (group). It uses specific verb 'Change' and resource 'group's display name (its `subject`)', distinguishing it from sibling tools like set_group_announce or set_group_locked.
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 mentions prerequisite 'admin (or non-locked group)' and implies when to use (to rename a group). Reversibility is noted, which guides use. No explicit alternatives are stated, but the specificity relative to siblings is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_group_topicAIdempotent
Change a group's description/topic; members see a system message indicating the description was updated. Reversible by calling again with the previous text or with an empty string to clear. Prerequisite: admin (or non-locked group). Returns the plain-text string Group <chat_jid> topic updated.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | No | new topic/description text; pass an empty string to clear the topic | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behaviors beyond annotations: system message to members, reversibility, clearing via empty string, prerequisite, and the exact return string. No contradictions with annotations.
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, front-loaded with purpose, no fluff. Every sentence adds value.
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?
Complete for a simple tool: purpose, side effects, prerequisite, return value. No gaps given the annotations and schema coverage.
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 description adds no new param info beyond what the schema already provides (e.g., empty string to clear is also in schema). Baseline 3 is appropriate.
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?
Explicitly states 'Change a group's description/topic', distinguishing from sibling tools like set_group_name. The verb and resource are precise, and it mentions the system message side effect.
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?
Clearly states prerequisite (admin or non-locked group) and reversibility, providing context for when to use. However, it does not explicitly compare to alternative tools or give when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_privacy_settingAIdempotent
Change a single WhatsApp privacy knob (read-receipts, last-seen, online, group-add, etc.) for the paired account; takes effect immediately and may change who can see your activity or contact you. Reversible by calling again with the previous value (capture it via get_privacy_settings first). Not every name/value combination is valid — WhatsApp rejects invalid combinations server-side. Returns a JSON document echoing the updated settings.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | privacy knob to change; one of the WhatsApp setting names (e.g. `last`, `readreceipts`, `groupadd`, `online`) | |
| value | Yes | new value; one of the WhatsApp privacy values (e.g. `all`, `contacts`, `none`, `match_last_seen`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint true, destructiveHint false), description reveals immediate effect, potential visibility changes, and server-side validation, adding meaningful behavioral context.
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 focused sentences: action+effect, practical tip, and validity warning. No filler; front-loaded with core purpose.
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?
Covers purpose, effects, parameter constraints, reversibility, and return format. Adequate for a two-parameter mutation tool with no output schema.
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 100% schema coverage, description adds value by warning about invalid name/value combinations and guiding users to capture previous values, supplementing the schema's enum listings.
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?
Description clearly states it changes a single WhatsApp privacy knob, provides concrete examples (read-receipts, last-seen, etc.), and distinguishes from siblings like get_privacy_settings or block_contact.
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?
Advises capturing current value via get_privacy_settings for reversibility and warns about invalid server-side combinations, giving clear context though not explicitly stating when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_status_messageAIdempotent
Update the paired user's WhatsApp profile About text; contacts permitted by privacy settings see the new text on the profile screen. Reversible by calling again with the previous text or with an empty string to clear. Note: this is the static profile About line, not the temporary Status story feed. Returns a JSON object {success, message}.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | new About text; pass an empty string to clear |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate a write operation (readOnlyHint=false) that is idempotent and not destructive. The description adds that the operation is reversible by calling again with previous text, and specifies the return format {success, message}, providing context beyond annotations.
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 front-loaded sentences with no wasted words. The first sentence states the core purpose, the second adds important nuance about reversibility and return type.
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 simple single-parameter tool, the description fully explains what the tool does, how to use it, and what to expect in return. No additional context is needed.
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% for the single parameter 'text'. The description adds context (it's the static About line) but does not add meaning beyond the schema, which already states 'pass an empty string to clear'.
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 clearly states it updates the WhatsApp profile About text. It explicitly distinguishes this from the temporary Status story feed, differentiating it from sibling tools like send_message or set_privacy_setting.
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 provides clear context: when to update the About text, that it's reversible, and that it's not for Status stories. However, it does not explicitly name alternative tools or give when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unblock_contactAIdempotent
Unblock a previously blocked contact, restoring their ability to message the paired user and see your last seen/profile/status; the contact is not notified. Idempotent if already unblocked. Reversible via block_contact. Use get_blocklist to see who is currently blocked. Returns the plain-text string Unblocked <jid>.
| Name | Required | Description | Default |
|---|---|---|---|
| jid | Yes | Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description adds that the contact is not notified and returns a plain-text string 'Unblocked <jid>'. It also confirms reversibility. The idempotentHint annotation is reinforced by stating 'Idempotent if already unblocked'. No contradictions with annotations.
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 three sentences long, each providing essential information: the core function and effects, idempotency and reversibility, and related tool and return value. It is front-loaded with the most important details and contains no extraneous words.
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 simple tool with one parameter and no output schema, the description covers the purpose, effect, return format, related tools (get_blocklist, block_contact), and idempotency. It gives sufficient information for an agent to correctly select and invoke the 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 coverage is 100%, so baseline is 3. The description does not elaborate on the jid parameter beyond what the schema provides, but it doesn't need to; the schema already gives detailed format instructions. The description uses 'jid' in the return string, implicitly confirming its role.
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 clearly states the action 'Unblock a previously blocked contact' and describes the effect: restoring messaging ability, visibility of last seen/profile/status. It distinguishes from sibling tools by mentioning alternatives like get_blocklist and block_contact.
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 explicitly recommends using get_blocklist before blocking, and notes reversibility via block_contact. It also mentions idempotency, which guides usage when the contact might already be unblocked. It could be more explicit about when to use this specific tool, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_group_participantsADestructiveIdempotent
Add, remove, promote, or demote participants of a group; the chat shows a system message naming each affected participant. Reversible by calling again with the inverse action (add ↔ remove, promote ↔ demote). Prerequisite: the paired user must be a group admin. Returns a JSON object describing the per-participant outcome.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | mutation to perform: `add`, `remove`, `promote` (to admin), or `demote` (from admin) | |
| chat_jid | Yes | WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us` | |
| participants | Yes | participants to mutate, as bare phone digits or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint, idempotentHint, openWorldHint), the description discloses a side effect ('chat shows a system message naming each affected participant') and confirms reversibility, adding context about behavior without contradicting annotations.
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 three sentences long, front-loaded with the core action, and every sentence adds necessary information without redundancy or fluff.
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 the tool's moderate complexity (3 params, no output schema), the description covers purpose, prerequisites, side effects, reversibility, and return format, leaving no critical gaps for an AI agent.
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% with detailed parameter descriptions, so the baseline is 3. The description adds little extra meaning beyond what the schema already provides, though it does imply the return format ('JSON object describing the per-participant outcome').
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 clearly states the tool's action ('Add, remove, promote, or demote participants of a group'), the resource ('group'), and implicitly distinguishes from sibling tools like set_group_name or get_group_info by focusing on participant mutations.
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 provides explicit usage guidance by stating the prerequisite ('the paired user must be a group admin') and hinting at reversibility ('Reversible by calling again with the inverse action'), though it does not directly compare to alternative tools.
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.
1 tool update
v0.4.1- Added
pairing_status
35 tool updates
v0.3.0- Changed
block_contact1 field changed- changed
Input schema / properties / jid / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`"
- Changed
create_group2 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"group display name"New value: +"group display name (subject)" - changed
Input schema / properties / participants / descriptionPrevious value: -"phone numbers or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"initial members as bare phone digits or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
delete_message2 fields changed- changed
Input schema / properties / message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of the message to revoke (use `message_id` from list_messages)" - changed
Input schema / properties / sender_jid / descriptionPrevious value: -"original sender; leave empty when deleting your own messages (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"JID of the original sender; required when deleting someone else's message as a group admin, leave empty when deleting your own (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
download_media2 fields changed- changed
Input schema / properties / message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of a media message (use `message_id` from list_messages)" - added
Input schema / properties / output_pathAdded value: +{ + "description": "optional absolute path under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`); parent directory must exist; calls are skipped if the file already exists; omit to write only to the daemon cache", + "type": "string" +}
- Changed
edit_message2 fields changed- changed
Input schema / properties / message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of your own message to edit (use `message_id` from list_messages)" - changed
Input schema / properties / new_body / descriptionPrevious value: -"replacement text"New value: +"replacement message body text"
- Changed
get_chat1 field changed- added
Input schema / properties / include_last_message / descriptionAdded value: +"if true, include the chat's most recent message in the result (defaults to true)"
- Changed
get_group_invite_link1 field changed- changed
Input schema / properties / reset / descriptionPrevious value: -"if true, revoke the old link and return a new one"New value: +"if true, permanently revoke the existing invite link and mint a new one (defaults to false); previously-shared copies stop working"
- Changed
get_message_context3 fields changed- added
Input schema / properties / after / descriptionAdded value: +"messages to fetch after the target (default 5; non-positive values fall back to the default)" - added
Input schema / properties / before / descriptionAdded value: +"messages to fetch before the target (default 5; non-positive values fall back to the default)" - changed
Input schema / properties / message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of the target message (use `message_id` from list_messages)"
- Changed
get_poll_results1 field changed- changed
Input schema / properties / poll_message_id / descriptionPrevious value: -"ID of the poll message to tally"New value: +"WhatsApp message ID of the poll to tally (use `ID` from send_poll, or `message_id` from list_messages)"
- Changed
is_on_whatsapp1 field changed- added
Input schema / properties / phones / descriptionAdded value: +"phone numbers to check; digits only with no `+` prefix, spaces, or punctuation (e.g. `447700900000`); must be non-empty"
- Changed
join_group_with_link1 field changed- changed
Input schema / properties / link_or_code / descriptionPrevious value: -"full invite URL or the trailing invite code"New value: +"full invite URL (`https://chat.whatsapp.com/<code>`) or just the trailing invite code"
- Changed
list_chats6 fields changed- added
Input schema / properties / include_last_message / descriptionAdded value: +"if true, include each chat's most recent message in the result (defaults to true)" - added
Input schema / properties / limit / descriptionAdded value: +"max chats to return (default 20)" - added
Input schema / properties / page / descriptionAdded value: +"zero-based page index for paging through results (default 0)" - changed
Input schema / properties / query / descriptionPrevious value: -"case-insensitive substring to match"New value: +"case-insensitive substring to match against chat name" - changed
Input schema / properties / sort_by / descriptionPrevious value: -"last_active or name"New value: +"sort order: `last_active` (most-recent first, default) or `name` (alphabetic)" - added
Input schema / properties / sort_by / enumAdded value: +[ + "last_active", + "name" +]
- Changed
list_messages10 fields changed- changed
Input schema / properties / after / descriptionPrevious value: -"ISO-8601 lower bound"New value: +"ISO-8601 UTC lower bound on message timestamp (inclusive)" - changed
Input schema / properties / before / descriptionPrevious value: -"ISO-8601 upper bound"New value: +"ISO-8601 UTC upper bound on message timestamp (inclusive)" - changed
Input schema / properties / chat_jid / descriptionPrevious value: -"WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`"New value: +"filter to messages in this chat (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)" - added
Input schema / properties / context_after / descriptionAdded value: +"messages to include after each match (default 1, capped at 20 server-side)" - added
Input schema / properties / context_before / descriptionAdded value: +"messages to include before each match (default 1, capped at 20 server-side)" - added
Input schema / properties / include_context / descriptionAdded value: +"if true, attach a few surrounding messages to each match (defaults to true)" - added
Input schema / properties / limit / descriptionAdded value: +"max messages to return (default 20, capped at 100 server-side)" - added
Input schema / properties / page / descriptionAdded value: +"zero-based page index for paging through results (default 0)" - changed
Input schema / properties / query / descriptionPrevious value: -"case-insensitive substring to match"New value: +"case-insensitive substring to match within message body" - changed
Input schema / properties / sender_phone_number / descriptionPrevious value: -"WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`"New value: +"filter to messages sent by this phone or JID (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
mark_chat_read1 field changed- changed
Input schema / properties / limit / descriptionPrevious value: -"How many of the most recent incoming messages to ack."New value: +"how many of the most recent incoming messages to ack (default 50)"
- Changed
mark_read2 fields changed- added
Input schema / properties / message_ids / descriptionAdded value: +"list of WhatsApp message IDs to ack (use `message_id` values from list_messages); must be non-empty" - changed
Input schema / properties / sender_jid / descriptionPrevious value: -"required for group chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"JID of the original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
request_sync1 field changed- changed
Input schema / properties / from_timestamp / descriptionPrevious value: -"ISO-8601 UTC timestamp"New value: +"ISO-8601 UTC timestamp marking the lower bound; if omitted, anchors on the newest cached message in the chat"
- Changed
search_contacts1 field changed- changed
Input schema / properties / query / descriptionPrevious value: -"case-insensitive substring to match"New value: +"case-insensitive substring to match against name or phone"
- Changed
send_audio_message4 fields changed- changed
Input schema / properties / mark_chat_read / descriptionPrevious value: -"On successful send, ack recent incoming messages so the phone drops the unread badge."New value: +"if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false)" - changed
Input schema / properties / media_path / descriptionPrevious value: -"absolute path to the media file (must sit under the configured media root)"New value: +"absolute path to the audio file; must sit under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`)" - changed
Input schema / properties / recipient / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`" - changed
Input schema / properties / view_once / descriptionPrevious value: -"If true, mark the voice note as view-once."New value: +"if true, mark the voice note as view-once (defaults to false)"
- Changed
send_contact_card4 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"contact display name (also used for the synthesised vCard)"New value: +"contact display name; also used as the FN in the synthesised vCard" - changed
Input schema / properties / phone / descriptionPrevious value: -"phone number (digits preferred); used to synthesise the vCard when `vcard` is not supplied"New value: +"phone number (digits preferred); embedded in the synthesised vCard when `vcard` is not supplied" - changed
Input schema / properties / recipient / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`" - changed
Input schema / properties / vcard / descriptionPrevious value: -"raw vCard 3.0 string; when set, name+phone synthesis is skipped"New value: +"raw vCard 3.0 string; when set, name+phone synthesis is skipped and this string is sent as-is"
- Changed
send_file5 fields changed- changed
Input schema / properties / caption / descriptionPrevious value: -"Optional caption for image/video/document"New value: +"optional caption for image/video/document submessages; ignored for raw audio" - changed
Input schema / properties / mark_chat_read / descriptionPrevious value: -"On successful send, ack recent incoming messages so the phone drops the unread badge."New value: +"if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false)" - changed
Input schema / properties / media_path / descriptionPrevious value: -"absolute path to the media file (must sit under the configured media root)"New value: +"absolute path to the media file; must sit under the configured media root (`WHATSAPP_MCP_MEDIA_ROOT`, default `<store>/uploads/`)" - changed
Input schema / properties / recipient / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`" - changed
Input schema / properties / view_once / descriptionPrevious value: -"If true, mark image/video/audio submessages as view-once. Silently ignored for documents."New value: +"if true, mark image/video/audio submessages as view-once; silently ignored for documents (defaults to false)"
- Changed
send_message3 fields changed- changed
Input schema / properties / mark_chat_read / descriptionPrevious value: -"On successful send, ack recent incoming messages so the phone drops the unread badge."New value: +"if true, also ack recent incoming messages in the chat to clear the unread badge (defaults to false)" - changed
Input schema / properties / message / descriptionPrevious value: -"message body"New value: +"message body text" - changed
Input schema / properties / recipient / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`"
- Changed
send_poll4 fields changed- changed
Input schema / properties / options / descriptionPrevious value: -"poll options (2–32)"New value: +"poll option labels; must contain between 2 and 32 entries" - changed
Input schema / properties / question / descriptionPrevious value: -"poll question"New value: +"poll question text shown above the options" - changed
Input schema / properties / recipient / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`" - changed
Input schema / properties / selectable_count / descriptionPrevious value: -"how many options each voter may pick; 1 = single-choice"New value: +"how many options each voter may pick; 1 = single-choice (default), higher = multi-select up to this cap"
- Changed
send_poll_vote2 fields changed- changed
Input schema / properties / options / descriptionPrevious value: -"option names to pick (1–32); must match the poll exactly"New value: +"option labels to pick; must match the poll's option text exactly, between 1 and 32 entries" - changed
Input schema / properties / poll_message_id / descriptionPrevious value: -"ID of the poll message to vote on"New value: +"WhatsApp message ID of the poll to vote on (use `ID` returned by send_poll, or `message_id` from list_messages)"
- Changed
send_presence1 field changed- changed
Input schema / properties / state / descriptionPrevious value: -"own availability state"New value: +"availability to broadcast: `available` (online) or `unavailable` (offline)"
- Changed
send_reaction3 fields changed- changed
Input schema / properties / emoji / descriptionPrevious value: -"single emoji, or empty string to clear the reaction"New value: +"single emoji to react with; pass an empty string to clear an existing reaction" - changed
Input schema / properties / message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of the target message (use `message_id` from list_messages)" - changed
Input schema / properties / sender_jid / descriptionPrevious value: -"original sender; required in group chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"JID of the original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
send_reply3 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"reply text"New value: +"reply text body" - changed
Input schema / properties / target_message_id / descriptionPrevious value: -"WhatsApp message ID"New value: +"WhatsApp message ID of the message being quoted (use `message_id` from list_messages)" - changed
Input schema / properties / target_sender_jid / descriptionPrevious value: -"original sender; required in group chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"JID of the quoted message's original sender; required in group chats, omit in 1:1 chats (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
- Changed
send_typing3 fields changed- changed
Input schema / properties / active / descriptionPrevious value: -"True = composing/recording, false = paused"New value: +"true to show the indicator (composing or recording), false to pause it" - changed
Input schema / properties / kind / descriptionPrevious value: -"'' for text (default) or 'audio' for recording"New value: +"indicator kind: empty string for text typing (default) or `audio` for voice-note recording" - added
Input schema / properties / kind / enumAdded value: +[ + "", + "audio" +]
- Changed
set_group_announce1 field changed- changed
Input schema / properties / announce_only / descriptionPrevious value: -"true to lock posting to admins only"New value: +"true to lock posting to admins only, false to allow all members to post"
- Changed
set_group_locked1 field changed- changed
Input schema / properties / locked / descriptionPrevious value: -"true to restrict metadata edits to admins"New value: +"true to restrict subject/topic/icon edits to admins, false to allow all members"
- Changed
set_group_name1 field changed- changed
Input schema / properties / name / descriptionPrevious value: -"new group name"New value: +"new group subject (display name)"
- Changed
set_group_topic1 field changed- changed
Input schema / properties / topic / descriptionPrevious value: -"new topic text; empty string clears"New value: +"new topic/description text; pass an empty string to clear the topic"
- Changed
set_privacy_setting2 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"privacy knob to change"New value: +"privacy knob to change; one of the WhatsApp setting names (e.g. `last`, `readreceipts`, `groupadd`, `online`)" - changed
Input schema / properties / value / descriptionPrevious value: -"new value for the knob"New value: +"new value; one of the WhatsApp privacy values (e.g. `all`, `contacts`, `none`, `match_last_seen`)"
- Changed
set_status_message1 field changed- changed
Input schema / properties / text / descriptionPrevious value: -"new About text; empty string clears"New value: +"new About text; pass an empty string to clear"
- Changed
unblock_contact1 field changed- changed
Input schema / properties / jid / descriptionPrevious value: -"Send target: phone digits, `<digits>@s.whatsapp.net`, or group `<digits>-<timestamp>@g.us`"New value: +"Send target: digits only (E.164 without `+`, no spaces or punctuation); or `<digits>@s.whatsapp.net`; or group `<digits>-<timestamp>@g.us`"
- Changed
update_group_participants2 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"participant mutation to perform"New value: +"mutation to perform: `add`, `remove`, `promote` (to admin), or `demote` (from admin)" - changed
Input schema / properties / participants / descriptionPrevious value: -"phone numbers or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"New value: +"participants to mutate, as bare phone digits or individual JIDs (WhatsApp JID: individual as `<digits>@s.whatsapp.net` or bare phone digits, group as `<digits>-<timestamp>@g.us`)"
9 tool updates
- Added
send_typing - Added
set_group_announce - Added
set_group_locked - Added
set_group_name - Added
set_group_topic - Added
set_privacy_setting - Added
set_status_message - Added
unblock_contact - Added
update_group_participants
9 tool updates
- Removed
send_typing - Removed
set_group_announce - Removed
set_group_locked - Removed
set_group_name - Removed
set_group_topic - Removed
set_privacy_setting - Removed
set_status_message - Removed
unblock_contact - Removed
update_group_participants
41 tool updates
v0.1.0- First observed
block_contact - First observed
create_group - First observed
delete_message - First observed
download_media - First observed
edit_message - First observed
get_blocklist - First observed
get_chat - First observed
get_group_info - First observed
get_group_invite_link - First observed
get_message_context - First observed
get_poll_results - First observed
get_privacy_settings - First observed
get_status - First observed
is_on_whatsapp - First observed
join_group_with_link - First observed
leave_group - First observed
list_chats - First observed
list_groups - First observed
list_messages - First observed
mark_chat_read - First observed
mark_read - First observed
request_sync - First observed
search_contacts - First observed
send_audio_message - First observed
send_contact_card - First observed
send_file - First observed
send_message - First observed
send_poll - First observed
send_poll_vote - First observed
send_presence - First observed
send_reaction - First observed
send_reply - First observed
send_typing - First observed
set_group_announce - First observed
set_group_locked - First observed
set_group_name - First observed
set_group_topic - First observed
set_privacy_setting - First observed
set_status_message - First observed
unblock_contact - First observed
update_group_participants
TDQS
Scored across 42 tools
Most tools have clearly distinct purposes, with detailed descriptions that disambiguate overlaps like send_message vs send_reply vs send_reaction and mark_chat_read vs mark_read. A couple of pairs could still cause hesitation, notably get_status vs pairing_status and send_file vs send_audio_message, but the descriptions resolve them well enough.
The set follows a consistent snake_case verb_noun pattern throughout, such as get_chat, list_messages, send_poll, set_privacy_setting, and update_group_participants. Minor exceptions like pairing_status and is_on_whatsapp deviate from the convention but remain readable and predictable.
42 tools is well beyond the typical well-scoped range and falls into the too-many category. The surface is thorough, but it likely places a heavy selection burden on agents and contains enough related variants that consolidation could be possible.
The toolset gives cohesive lifecycle coverage for the WhatsApp domain: sending, editing, deleting, reading, searching, media handling, group management, privacy settings, contacts, blocking, presence, and polling. There are no obvious dead ends; mutating operations are paired with read/get/reverse operations.
Maintenance
Related MCP Connectors
Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.
Unified messaging MCP server: WhatsApp, Instagram, Telegram, SMS, Messenger & email support inbox
WhatsApp (Web + Business API), SMS, contacts, and call records via 2Chat's MCP server.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Related MCP Servers
- MIT
- FlicenseBqualityDmaintenanceA comprehensive MCP server providing Claude with full access to Brevo's marketing automation platform through the official SDK, featuring tools for email operations, contact management, campaigns, SMS, conversations, webhooks, e-commerce, and account management.163-
- AlicenseCqualityCmaintenanceEnables AI assistants to interact with WhatsApp through the WSAPI service, supporting comprehensive messaging, contact management, group operations, and account management functionality. Allows sending various media types, managing chats, and controlling WhatsApp sessions through natural language.10073MIT
- AlicenseBqualityDmaintenanceEnables sending WhatsApp Business messages including text, media, interactive lists/buttons, and template management through the WhatsApp Business API via Nango integration.11MIT