whatsapp-local-mcp
Allows reading, searching, transcribing voice notes, and analyzing images from WhatsApp messages, providing tools for message retrieval, chat listing, status checking, and QR-based linking.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@whatsapp-local-mcpsummarize my WhatsApp from the last 12 hours"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
WhatsApp MCP for Claude
Read your own WhatsApp messages from inside Claude. Ask things like "summarize my last 12 hours of WhatsApp" or "who's waiting on a reply?", and Claude reads, searches, transcribes voice notes, and looks at images for you.
โ Runs 100% locally on your computer ยท ๐ Read-only - it can never send messages ยท ๐ฌ Works with Cowork and Claude Desktop
โก Quick start (Cowork - easiest, no terminal)
Most people should use this. You need two things:
Node.js 18+ - if you don't have it, get it from nodejs.org (just click Next โ Next โ Install, takes a minute).
A phone with WhatsApp to scan a QR code once.
Then open Cowork and paste this whole block into the chat:
Hi Claude. Please install the WhatsApp MCP for me. I'm NOT technical. The only things I'll
do are: double-click one installer file, restart Cowork, and scan a QR with my phone.
Repo: https://github.com/stevenpkm/whatsapp-local-mcp
Important: your sandbox CANNOT register the MCP or start it on Windows - only INSTALL.bat
(which I double-click on Windows) can. So your job is to get the files into my folder and
hand me the installer. Do this in order:
1. Download the SOURCE into the folder I gave you access to in this chat (use THAT folder,
don't pick another). Do NOT run `npm install` and do NOT copy node_modules - the installer
does that so the native binaries are correct. YOU download and extract the zip here (never
ask me to download it in a browser):
https://github.com/stevenpkm/whatsapp-local-mcp/archive/refs/heads/main.zip
(contents land in a "whatsapp-local-mcp-main" folder).
- If the download is blocked / hangs / is refused, that's my Cowork network-egress setting,
NOT a file problem (a `git clone` hits the same wall, so don't switch to clone). STOP and
tell me exactly: "Open Cowork Settings -> Allow network egress -> set the Domain allowlist
to 'All domains', then tell me to retry." Then download again. Never tell me to download
it myself.
- On Mac only: after extracting, run `chmod +x` on INSTALL.command and mac/*.command in that
folder (the zip strips the executable bit, or my double-click opens it in TextEdit).
2. Do NOT use computer-use, and do NOT open Explorer/Finder or any app yourself. Just tell me,
in plain text, the full path of that folder and to double-click INSTALL.bat (Windows) or
INSTALL.command (Mac) inside it - the one sitting next to the "windows" and "mac" folders.
A window runs ~2-5 min: it checks Node (if Node is missing it opens nodejs.org for me and I
double-click the installer AGAIN after installing), installs dependencies, and registers the
MCP, then says SUCCESS.
- Windows: if a blue "Windows protected your PC" box appears showing only a "Don't run"
button, tell me to click the small "More info" link FIRST, then the "Run anyway" button.
- Mac: if it opens in TextEdit or says "unidentified developer", tell me to right-click the
file -> Open -> Open.
3. Wait for me to say the installer finished. Then tell me to FULLY quit Cowork - tray icon
(Windows, near the clock; it may be hidden under the small "^" up-arrow) or menu-bar icon
(Mac) -> Quit, NOT just closing the window - and reopen it. Approve the tools prompt if one
appears.
4. After I reopen and say "scan": call mcp__whatsapp__relink_whatsapp, then send me to the
live page http://127.0.0.1:8765/qr (open it in your inline browser / preview, or tell me to
open that URL in my own browser). Do NOT paste the QR as an image - the live page
auto-refreshes when it expires and shows "Connected" when done. I scan from WhatsApp ->
Settings -> Linked Devices -> Link a Device.
5. Verify: call mcp__whatsapp__wait_for_link, then mcp__whatsapp__get_status. Confirm
connected: true, then tell me to try: "summarize my WhatsApp from the last 12 hours".
If any step fails, tell me exactly what failed and what you'll try next.
Begin now.That's it. The flow:
Claude downloads the project into your folder and tells you the folder path (it won't use computer-use or open windows for you).
Double-click
INSTALL.batin that folder. A black window runs ~2-5 min (checks Node, installs dependencies, registers the MCP), then says SUCCESS. (If Windows warns "protected your PC", click More info โ Run anyway.)Fully quit Cowork from the tray (right-click โ Quit, not just close the window) and reopen it. Approve the tools prompt if one appears.
Type
scan my WhatsApp. Claude shows the QR right in the sidebar - scan it from your phone (WhatsApp โ Settings โ Linked Devices โ Link a Device). Shows โ Connected when done.
Now try: "summarize my WhatsApp from the last 12 hours" ๐
(Optional) Want voice notes turned into text? You can add an OpenAI API key later - see "What it costs" below.
Related MCP server: WhatsApp MCP Server
๐ฌ What you can ask
You say | What Claude does |
"what's my WhatsApp status?" | checks the connection + cache health |
"list my WhatsApp chats" | shows all your chats by name |
"summarize my last 12 hours of WhatsApp" | transcribes voice notes, looks at images, and writes you a brief |
"search WhatsApp for invoice" | searches your local message history |
"what was Aaron's image at 3 pm about?" | finds the image and looks at it for you |
"re-link my WhatsApp" | shows a fresh QR to scan |
"my phone says it's disconnected" | reconnects |
Claude Desktop (Windows)
Install Node.js 18+ from nodejs.org.
Get the project into a stable folder (e.g.
Documents) - clone it, or download the zip and unzip:git clone https://github.com/stevenpkm/whatsapp-local-mcp.gitDouble-click
INSTALL.batin the project folder. It runsnpm installand writes awhatsappentry into%APPDATA%\Claude\claude_desktop_config.jsonso Claude knows to launch the MCP server.(Optional) For voice-note transcription, create
api-key.txtin the repo root and paste your OpenAI key (one line, no quotes).Fully quit Claude Desktop (tray icon โ Quit, not just close the window) and reopen it.
In chat, type
scan my WhatsAppand scan the QR on your phone.
macOS
The Node code is cross-platform, and macOS has its own one-click installer.
Install Node.js 18+ from nodejs.org (download the LTS
.pkg, open it, Install).Get the project into a folder (clone it, or download the zip and unzip).
Double-click
INSTALL.commandin the project folder. It runsnpm installand registers the MCP into~/Library/Application Support/Claude/claude_desktop_config.json(auto-detected - no manual editing).If macOS blocks it ("unidentified developer", or it opens in a text editor instead of running): open Terminal (Spotlight โ type Terminal), then paste
bash ", dragINSTALL.commandonto the window, type", and press Enter.
(Optional) For voice transcription, put your OpenAI key in
api-key.txtin the project root.Fully quit Cowork / Claude Desktop - click its menu-bar icon and choose Quit (Cmd-Q from the window may leave it running in the menu bar), then reopen.
In chat, type
scan my WhatsAppand scan the QR (the status page ishttp://127.0.0.1:8765/, or the QR pagehttp://127.0.0.1:8765/qr).
The bridge auto-starts when Cowork launches the MCP and survives Cowork restarts (detached), same as Windows. mac/restart-bridge.command restarts it if needed; mac/reset.command wipes auth + cache.
Linux
Same Node code; no .command wrapper, so run it manually:
git clone https://github.com/stevenpkm/whatsapp-local-mcp.git
cd whatsapp-local-mcp
npm install
node scripts/install-mcp-config.mjs # writes ~/.config/Claude/claude_desktop_config.json+------------------------------------------------------------+
| Your phone: WhatsApp (the master account) |
+--------------------------+---------------------------------+
| WhatsApp multi-device protocol
v
+------------------------------------------------------------+
| bridge.js (always running, detached background process) |
| - Holds the WhatsApp WebSocket connection |
| - Receives every message live -> caches text + media keys |
| - Survives Claude Desktop / Cowork restarts |
| - PID-locked: only one bridge runs at a time |
+--------------------------+---------------------------------+
| HTTP localhost:8765
v
+------------------------------------------------------------+
| index.js (MCP server, spawned by Claude Desktop/Cowork) |
| - Thin HTTP client to the bridge |
| - Exposes MCP tools to Claude |
+--------------------------+---------------------------------+
| stdio MCP
v
+------------------------------------------------------------+
| Claude (in chat) |
| - Calls MCP tools to read messages |
| - Looks at images directly via Claude's vision |
| - Writes briefs back to disk for the artifact to render |
+------------------------------------------------------------+Splitting the bridge from the MCP server is the whole trick - Claude Desktop crashes and restarts don't break the WhatsApp link.
Image analysis uses Claude's own vision through your Claude subscription. No separate Anthropic API key needed.
Nothing happens automatically. You only pay when you explicitly ask Claude to do something:
Activity | Where charged | Approx |
Bridge running 24/7, receiving + caching messages | Free | --- |
Text-only queries (search, list, status) | Free | --- |
Voice-note transcription (Whisper) | OpenAI API | ~$0.001 per voice note |
Image analysis (Claude vision) | Your Claude subscription | ~1.5K tokens per image |
Brief text analysis | Your Claude subscription | ~5-15K tokens per brief |
A typical daily brief over an active 12h WhatsApp window: a few cents on OpenAI + some Claude tokens.
To enable voice-note transcription, get an OpenAI API key at platform.openai.com/api-keys and paste it into api-key.txt in the project root (one line, no quotes).
Everything stays local by default. Cache lives in
data\store.json. Auth lives inauth\.The bridge connects only to WhatsApp's own servers via the Baileys library (open source).
When you ask Claude a question, only the specific messages relevant to that question are sent to Anthropic's servers as part of your normal Claude conversation.
If you enable Whisper transcription, voice-note audio bytes are sent to OpenAI for transcription, then the transcript is cached locally. After that, the audio is not re-sent.
No
send_messagetool exists by design - this MCP cannot send anything on your behalf, which significantly cuts down the prompt-injection blast radius.Don't share
auth/orapi-key.txt- they're sensitive..gitignoreexcludes them by default.WhatsApp ToS gray area: WhatsApp's official Terms of Service do not explicitly authorize third-party clients via Baileys-style multi-device automation. Read-only personal use has historically not been targeted, but there is no guarantee - use at your own risk.
Read tools (cache-only, free):
get_status- connection + cache healthlist_chats- all chats with names (not IDs)get_recent_messages- last N hours, filterable by chat / groupsearch_messages- case-insensitive substring searchget_brief/set_brief- read/write the daily brief artifact JSON
Media tools (lazy, on-demand):
get_image- return image bytes inline so Claude can SEE the picture (vision)set_description- cache Claude's description of an imagesave_image- write a single image to disk; returns absolute pathsave_voice- write a single voice note (.ogg) to disk; optionally also transcribe via Whispersave_media- generic save (image/audio/video/document) when the kind isn't known in advancelist_media_window- read-only preview of whatsave_media_windowwould save (withlikelyExpiredflag for media older than ~13 days)save_media_window- bulk save from the last N hours with bounded concurrency and per-item resultswhere_do_media_files_go- return the default folder path and how many files are already in itenrich_window- voice-only: download + transcribe voice notes via Whisper (no images - those go throughget_image)
Link management:
relink_whatsapp- start a fresh QR pairwait_for_link- block until the link succeedsforce_resync- soft reconnect
Error contract: every tool returns a structured envelope. Success: { ok: true, ...data }. Failure: { ok: false, code, error, ...context } where code is one of a closed set (media_expired, no_keys, download_failed, not_found, not_image, disk_error, permission_denied, disk_full, bridge_unreachable, bridge_restarting, timeout, transcribe_failed, no_api_key, invalid_argument, ...). The MCP response sets isError: true on failure so spec-compliant clients can branch without parsing strings. Bulk operations (save_media_window) return ok: true even when some items fail; failures appear inside items[].ok = false and are rolled up in errors: [{code, count}].
Saved-file paths. Save tools also emit an MCP resource_link content block with uri: file:///โฆ and the file's mime type, so capable clients can offer "open this file" affordances.
Default folder. Save tools write to <project>/data/media/<YYYY-MM-DD>/ by default. Filename format: <ISO-timestamp>__<chat-slug>__<sender-slug>__<msgId-tail>.<ext>. Override the folder per call with the folder parameter (absolute path).
Var | Default | Meaning |
|
| Local HTTP port the bridge listens on |
|
| Drop history-sync messages older than this many days |
|
| Skip voice notes longer than this when transcribing |
|
| Force reconnect if no socket activity in this long |
| (none) | Used by Whisper. Falls back to |
whatsapp-local-mcp/
README.md <- you are here
LICENSE <- MIT
.gitignore <- excludes auth/, data/, api-key.txt
.gitattributes <- keeps .command LF, .bat CRLF
package.json
INSTALL.bat <- Windows: double-click to install
INSTALL.command <- macOS: double-click to install
src/
bridge.js <- always-on WhatsApp connection + status dashboard
index.js <- MCP server (thin HTTP client)
whatsapp.js <- Baileys controller + reconnect/watchdog
store.js <- message cache (with .backup)
media-paths.js <- filename/folder helpers for saved media
errors.js <- shared error-code envelope
transcribe.js <- OpenAI Whisper client (voice notes)
scripts/
install-mcp-config.mjs <- registers the MCP in the Claude/Cowork config
doctor.mjs <- one-shot health check (node / registration / bridge)
windows/ <- Windows helper .bat files
install.bat <- runs npm install + registers the MCP
restart-bridge.bat <- restart the bridge
reset.bat <- nuclear: wipe auth + cache
mac/ <- macOS helper .command files
install.command <- runs npm install + registers the MCP
restart-bridge.command <- restart the bridge
reset.command <- nuclear: wipe auth + cache
auth/ (gitignored) <- WhatsApp credentials. DON'T SHARE.
data/ (gitignored) <- local message cache + brief.json + bridge.log
api-key.txt (gitignored) <- OpenAI key for voice transcriptionClaude says "MCP whatsapp: server disconnected"
Click windows\restart-bridge.bat to kill the old bridge and start a fresh one. The MCP server in Claude will reconnect on next tool call. If it persists, check data\bridge.log.
My phone shows the device "last active" stuck at some old time, even though Claude says connected
The WebSocket has gone zombie - TCP socket still open, but no real traffic. The bridge's keepalive + watchdog should auto-fix in ~3 minutes. If not, run windows\restart-bridge.bat.
440 / "stream conflict" errors Another linked device (or a stale one) is claiming the slot. On your phone: WhatsApp โ Settings โ Linked Devices โ log out everything that isn't your current entry. Then ask Claude to "re-link my WhatsApp".
get_image says "no media keys stored"
The message was cached before this code added media-key tracking. Only images received after the bridge restart with media-key support can be downloaded. Tomorrow's images will work.
get_image says "download failed"
Most likely the image is more than ~14 days old and WhatsApp's CDN has garbage-collected the encrypted blob. The media key is still valid, but the bytes are gone.
I want to nuke everything and start over
windows\reset.bat. Confirms with "YES", stops bridge, wipes auth\ and data\.
(This section is written for Claude itself, in case the user pastes this README into a chat and asks Claude to install the project.)
Your sandbox CANNOT register the MCP (it can't write Cowork's protected global config, and Cowork does NOT read a project .mcp.json) and CANNOT start a host process. So you can't finish the install yourself - the last mile is the user double-clicking INSTALL.bat (Windows) or INSTALL.command (Mac). Your job: get the source into their folder and hand off.
Put the SOURCE into the folder the user already granted this session - do NOT run
npm installand do NOT copynode_modules(a sandbox-built one has the wrong native binaries; the installer builds them on the host). Download the zip (https://github.com/stevenpkm/whatsapp-local-mcp/archive/refs/heads/main.zip) and extract it there - you do this, never tell the user to download it in a browser. If the download is blocked/hangs/refused, that is the Cowork network-egress setting (agit clonehits the same blocked host, so don't switch to clone) - STOP and tell them: "Open Cowork Settings โ Allow network egress โ set the Domain allowlist to 'All domains', then tell me to retry," then download again. On macOS, after extracting,chmod +xtheINSTALL.commandandmac/*.commandfiles - the zip strips the Unix exec bit, so otherwise the user's double-click opens the script in TextEdit instead of running it.Do NOT use computer-use, and do NOT open Explorer/Finder or any app. Just give them, in plain text, the folder's full path and tell them to double-click
INSTALL.bat(Windows) orINSTALL.command(Mac). The installer checks Node on the host (opening nodejs.org if it's missing or too old), runsnpm install, registers the MCP, then says SUCCESS. Don't runnode --versionyourself - your sandbox's Node isn't the user's machine's Node, so it proves nothing; the installer is the real check. (If SmartScreen/Gatekeeper warns: Windows More info โ Run anyway; Mac right-click โ Open.)After they say it finished, tell them to fully quit Cowork (tray / menu-bar โ Quit) and reopen. Approve the MCP-trust prompt if it appears.
Once back, call
relink_whatsapp, then send them to the live pagehttp://127.0.0.1:8765/qr(open it in your inline browser/preview, or have them open the URL). Do NOT paste the QR as an image - the live page auto-refreshes when it expires and shows Connected once linked. They scan from WhatsApp โ Settings โ Linked Devices โ Link a Device.Call
wait_for_link, thenget_statusto confirmconnected: true.(Optional) For voice transcription, have them paste an OpenAI key into
api-key.txtin the project root - never in chat.
A quick node scripts/doctor.mjs prints Node version, whether the global config has the entry, bridge reachability on 8765, and connection status - use it to check state instead of guessing.
From here, normal queries like "summarize my last 12 hours" work.
License
MIT - see LICENSE. Built on @whiskeysockets/baileys and the Model Context Protocol SDK.
Available Tools
19 toolsbackfill_historyA
Try to recover WhatsApp messages missed while the bridge was offline (e.g. you didn't open Cowork for a few days, leaving a gap in the history). For each of the most recently active chats it asks WhatsApp's on-demand history sync (Baileys fetchMessageHistory) for older messages, anchored at the newest cached message in that chat. Results arrive asynchronously and are cached. IMPORTANT: how far back WhatsApp actually serves is decided by WhatsApp, not us - run this to find out empirically for this account. Returns cacheBefore/cacheAfter (messagesAdded) and per-chat request info. If messagesAdded is ~0, WhatsApp didn't serve more for those anchors; a fresh re-link (relink_whatsapp) is the fuller-history fallback.
| Name | Required | Description | Default |
|---|---|---|---|
| chats | No | How many recently-active chats to backfill. | |
| count | No | Messages to request per chat (older than that chat's newest cached message). | |
| chatId | No | Limit to one chat (its raw JID). Overrides `chats`. | |
| settleMs | No | How long to wait for async history to land before reporting messagesAdded. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses async nature, caching, request anchoring, that WhatsApp controls how far back it serves, and return fields (cacheBefore/cacheAfter). No annotations provided, so description fully handles transparency.
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?
Concise paragraph with clear flow: purpose, mechanism, limitation, return info. 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 explains return values and what to do if results are poor. Covers async behavior, caching, and fallback sufficiently for an 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 covers 100% of parameter descriptions, so baseline 3. Description does not add new parameter-level detail beyond context but reinforces 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?
Clearly states the tool recovers missed WhatsApp messages when the bridge was offline, with specific verb 'recover' and resource 'history'. Distinguishes from siblings like relink_whatsapp by positioning it as a fallback.
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 ('bridge was offline') and when not to expect full history (WhatsApp decides). Provides alternative (relink_whatsapp) if messagesAdded is ~0.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrich_windowA
VOICE-ONLY enrichment for the last N hours. Downloads voice notes and transcribes them via OpenAI Whisper. Idempotent (skips already-transcribed). IMPORTANT: this tool no longer touches images - image analysis is done by Claude (you) via the get_image tool, using the Cowork subscription instead of OpenAI Vision. To produce a full brief with both voice transcripts and image descriptions: (1) call enrich_window for voice, (2) call get_image one-by-one for each image in the window and call set_description to cache your description, (3) then call get_recent_messages to read the enriched text and write the brief.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| maxItems | No | ||
| concurrency | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses idempotency (skips already-transcribed) and that it no longer touches images. It does not cover rate limits, auth needs, or error conditions, but the key behaviors are transparent.
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 well-structured with a clear opening sentence, idempotent note, important caveat about images, and a enumerated workflow. It is concise but every sentence adds value, though the workflow could be slightly tighter.
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 and only 3 parameters, the description provides good context but leaves gaps: 'maxItems' and 'concurrency' are undocumented, and there is no mention of error handling or prerequisites (e.g., linked account). The workflow is helpful but incomplete for complex scenarios.
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 0%, so the description must compensate. It explains the 'hours' parameter ('last N hours') but does not explain 'maxItems' or 'concurrency' explicitly. While 'concurrency' might be inferred from context, the agent gets incomplete parameter guidance.
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 does voice-only enrichment by downloading and transcribing voice notes via OpenAI Whisper. It explicitly contrasts with image processing, distinguishing it from siblings like get_image and set_description.
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 guidance: it is for voice enrichment only, and provides a step-by-step workflow (1) call enrich_window, (2) call get_image and set_description for images, (3) call get_recent_messages to write briefs. It also mentions that image analysis is done by Claude via get_image, clearly separating responsibilities.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
force_resyncA
Reconnect the WhatsApp socket. Use only when chats look stale; normally the bridge keeps itself connected.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavior. It states the action (reconnect socket) but does not elaborate on side effects (e.g., message loss, interruption of ongoing operations) or required permissions. Adequate for a simple action but lacks depth.
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 purpose, then usage guideline. No wasted words, 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?
Given no parameters, output schema, or annotations, the description provides necessary purpose and usage context. Could mention potential disruptions from reconnection, but overall sufficient 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?
No parameters in input schema, and schema coverage is 100% trivially. Baseline for zero parameters is 4. Description adds no parameter info, which is acceptable.
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 'Reconnect' and the resource 'WhatsApp socket', defining a specific action. It implies a manual intervention tool, which distinguishes it from automatic bridge behavior, but does not explicitly differentiate from the sibling tool 'relink_whatsapp'.
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 ('only when chats look stale') and when not to ('normally the bridge keeps itself connected'), providing clear context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_briefA
Return the most recently generated brief from data/brief.json, or null if none exists.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it reads a specific file and returns a brief or null. No side effects are implied, which is appropriate for a read operation. Could mention if the file might be empty or locked, but not required.
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?
One sentence, no fluff, action-first, and all key information included. Every word carries meaning.
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 zero parameters and no output schema, the description sufficiently explains what the tool does, what it returns, and the edge case (null). No missing context for the simplicity of 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?
No parameters exist, and schema coverage is 100% (no params). Baseline is 4; the description correctly omits parameter info as unnecessary.
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 resource ('most recently generated brief'), and the file location ('data/brief.json'), with a clear return behavior ('or null if none exists'). It is distinct from siblings like 'set_brief' or 'get_recent_messages'.
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 implies usage for retrieving the latest brief, but does not explicitly state when to use this tool versus alternatives (e.g., 'set_brief' for creating, 'get_recent_messages' for other data). No when-not or alternative mention.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_imageA
Download a specific cached image from WhatsApp and return its bytes inline as image content so Claude can see and describe it natively (Opus vision is sharper than gpt-4o-mini). Pass the msgId and chatId from a get_recent_messages result that has hasMedia=true and type=imageMessage. Fails gracefully if media keys are missing (message cached before key tracking was added) or expired (>~14 days old).
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | ||
| chatId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description fully carries burden. Discloses return format (inline bytes for Claude), graceful failure on missing/expired media, and implicit read-only nature. Could mention if any side effects occur, but download implies none.
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 purpose and usage. Efficient but could be slightly more structured (e.g., separate usage and behavior).
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, but describes return format and error cases. Covers essential aspects for a simple image retrieval tool. Adequate for the 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 has 0% coverage (no descriptions), but description adds meaning: msgId and chatId come from get_recent_messages results. This compensates well for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool downloads a cached image and returns bytes inline for Claude to see, mentioning a specific use case (Opus vision) and distinguishing from siblings like get_recent_messages and save_image.
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: pass msgId and chatId from get_recent_messages when hasMedia=true and type=imageMessage. Mentions failure conditions (missing keys, expiry). Lacks explicit 'when not to use', but context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_messagesA
Get messages from the last N hours from the local cache. Optionally filter to one chatId or exclude groups. Each message includes chat (the chat's human-friendly name) and from (sender's name). NEVER show the raw chatId, msgId, or sender JID to the user - always speak in names. The IDs are only for follow-up tool calls (e.g. get_image needs chatId+msgId).
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| limit | No | ||
| chatId | No | ||
| excludeGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that messages include human-friendly names and IDs are for follow-up calls. However, with no annotations, it omits behavioral traits like data freshness, caching behavior, or any side effects (e.g., cache invalidation).
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, front-loaded sentences with no redundancy. Every sentence adds value: purpose, return field format, and usage warning.
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?
Adequate for a simple retrieval tool but lacks explicit return structure (only mentions 'chat' and 'from' fields) and does not specify pagination or empty cache behavior. Given many siblings, could hint at differentiation.
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 0% schema description coverage, the description explains three of four parameters (hours, chatId, excludeGroups) in context but misses 'limit'. The explanations add meaning but are incomplete.
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 retrieves messages from the last N hours from local cache with optional filtering. The verb 'get' and resource 'messages' are specific, though it doesn't explicitly distinguish from sibling tools like 'search_messages' or 'get_brief'.
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 on when to use (for recent messages) and how to handle IDs, but lacks explicit when-to-use vs alternatives (e.g., 'search_messages' for richer queries) and no exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusA
Return current WhatsApp connection status (connected, retention, transcription, cache size, idle seconds, etc).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral transparency. It indicates a read-only operation ('Return...') but does not explicitly state side effects, authentication requirements, or rate limits. While it implies no side effects, more detail would be beneficial.
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, well-structured sentence. It front-loads the core purpose ('Return current WhatsApp connection status') and follows with specific examples. Every word contributes to understanding, with no redundancy or 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 zero parameters and no output schema, the description is mostly complete. It lists the types of information returned. It could mention that it is a quick, non-destructive operation, but the current text is adequate for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema provides 100% coverage. According to the rubric, a baseline score of 4 is appropriate. The description adds no parameter information because none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns the WhatsApp connection status and lists specific fields (connected, retention, transcription, etc.). The verb 'Return' and resource 'WhatsApp connection status' are unambiguous. Among siblings like get_brief or get_image, this is uniquely about connection status, making it easy to distinguish.
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 implies usage when connection status is needed, but does not explicitly state when to use or when not to use, nor does it mention alternatives. For a simple status check with zero parameters, the context is clear enough for an agent to understand its purpose, but explicit guidance is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_chatsA
List WhatsApp chats from the local cache, sorted by most recent activity. Each chat has both name (human-friendly, e.g. "XPENG MALAYSIA OWNER CLUB" or "Steve") and id (raw WhatsApp JID like "1234@g.us"). ALWAYS refer to chats by name when talking to the user - the id is only for follow-up tool calls and should never be shown to the user.
| Name | Required | Description | Default |
|---|---|---|---|
| excludeGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that data comes from a local cache, is sorted by recency, and distinguishes between human-friendly name and internal id. It does not mention potential error states or performance, but is largely transparent about its behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, both informative and free of fluff. The first sentence states the purpose, and the second provides critical usage guidance on name vs id. Every word 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?
Given the single undocumented parameter and no output schema, the description lacks completeness. It explains the chat fields but not the effect of excludeGroups, nor does it mention whether results are paginated or limited. With sibling tools that depend on this list, more detail would be beneficial.
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 one optional parameter (excludeGroups) with default false, but the description does not mention it at all. With 0% schema description coverage, the description should compensate by explaining this parameter's meaning, but it fails to do so.
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 lists WhatsApp chats from the local cache sorted by most recent activity. It distinguishes itself from sibling tools (e.g., get_recent_messages) by focusing on chats, not messages or media, and adds clarity by explaining name vs id fields.
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 guidance on how to present chat names to users (use name, hide id), but does not explicitly state when to use this tool versus alternatives. It implies it's the first step for chat-related operations, but lacks explicit when-not or alternative references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_media_windowA
Preview which media items would be saved by save_media_window. Read-only - does NOT download or write anything. Returns per-item entries with chatId, msgId, kind, sender, chat, timestampISO, sizeBytes, mimeType, and likelyExpired (true when the media-key is older than ~13 days and the CDN may have garbage-collected the blob). Use this BEFORE save_media_window so you can tell the user 'I would save 14 images and 6 voice notes, but 3 are likely expired - proceed?'
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| kinds | No | Which media types to include. | |
| limit | No | ||
| chatId | No | Limit to one chat. Optional. | |
| excludeGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description fully carries burden. It declares read-only, no download/write, and lists return fields including likelyExpired meaning. Covers essential 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 sentences plus example, no fluff. Purpose stated upfront, efficient use of text.
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, no output schema, and no annotations, description should provide more parameter context. It covers return fields and usage well but misses parameter details, leaving agent to guess or rely on sibling tool 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 40% (only kinds and chatId described). Description does not explain hours, limit, excludeGroups parameters, nor their role in previewing. Users cannot infer parameter semantics from text.
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 previews items for save_media_window, with specific verb 'Preview', resource 'media window', and notes read-only nature. Distinguishes from sibling save_media_window.
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 instructs to use BEFORE save_media_window and gives a concrete user-facing example. No exclusions needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relink_whatsappA
Delete stale credentials and start a fresh QR pair. Returns the raw QR data string in qr; render it as a scannable QR image and ask the user to scan it from their phone (WhatsApp โ Settings โ Linked Devices โ Link a Device). Cache is preserved.
| Name | Required | Description | Default |
|---|---|---|---|
| waitMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses credential deletion and cache preservation, but does not fully describe side effects (e.g., service interruption until re-link) or auth requirements. It is adequate but not thorough.
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. First sentence states purpose, second sentence details output and usage. Perfectly 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?
Given the tool's simplicity (1 optional param, no output schema, no annotations), the description covers operation and user instructions well. Missing only explanation of 'waitMs' and explicit relation to siblings. Nearly 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 schema has 0% description coverage and one optional parameter 'waitMs' (default 25000). The description does not explain this parameter at all, leaving the agent to guess its purpose (likely QR wait time). This is a significant gap.
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: 'Delete stale credentials and start a fresh QR pair.' It uses specific verbs ('delete', 'start') and resources ('credentials', 'QR pair'), and distinguishes from siblings like 'wait_for_link' which handles the subsequent step.
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 implies when to use the tool: when credentials are stale and need refreshing. It provides explicit instructions for rendering the QR and user action. However, it does not explicitly state when not to use it or mention alternatives beyond the implied sibling 'wait_for_link'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_imageA
Save a single WhatsApp image to disk. Pass the chatId + msgId from a get_recent_messages result. Default folder: /data/media//, named __.jpg. Returns the absolute path as a resource_link. On failure returns {ok:false, code, error} where code is one of: not_found, not_image, no_keys, media_expired, download_failed, disk_error, permission_denied, disk_full, timeout. The MCP response sets isError:true on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | ||
| chatId | Yes | ||
| folder | No | Absolute path where the file should land. Defaults to <project>/data/media/<date>/. | |
| filename | No | Override the filename. Path separators not allowed. | |
| timeoutMs | No | Per-download timeout. Default 30s for images. | |
| skipIfExists | No | If a file with the same name already exists, return its path without re-downloading. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the saving action and enumerates failure codes (not_found, not_image, etc.), aiding understanding. However, it does not explicitly mention side effects like overwriting or atomicity.
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, well-structured paragraph. It begins with the core purpose, then details input sources, naming convention, return format, and failure codes. Every sentence adds value, 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 tool with 6 parameters and no output schema or annotations, the description covers essential aspects: purpose, input requirements, storage location, naming, and failure modes. It lacks explicit success response structure, but the resource_link return is implied. Overall, it is fairly 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 description coverage is 67% (4 of 6 params described). The description adds meaning beyond schema by explaining the source of chatId/msgId (from get_recent_messages), default folder format, and naming convention. For parameters like timeoutMs and skipIfExists, it provides defaults not in 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 'Save a single WhatsApp image to disk', specifying the action (save) and resource (WhatsApp image). It distinguishes from siblings like 'save_media' (general media) and 'save_voice' (voice messages) by being image-specific.
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 instructs to 'Pass the chatId + msgId from a get_recent_messages result', providing clear context on when to use the tool. It does not explicitly state when not to use it or list alternatives, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_mediaB
Generic save-to-disk for any media kind (image / audio / video / document). Use save_image or save_voice when you know the type - they're clearer to read. Use this when you have a mixed list of msgIds and don't want to branch.
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | ||
| chatId | Yes | ||
| folder | No | ||
| filename | No | ||
| timeoutMs | No | ||
| skipIfExists | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. It only says 'save-to-disk' without disclosing side effects (e.g., overwriting, disk space), permissions, rate limits, or error states. The skipIfExists parameter suggests idempotency, but description does not elaborate.
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 and usage guidance. No wasted words, though it omits parameter information. Concise but incomplete.
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?
Tool has 6 parameters and no output schema, yet description covers only high-level purpose. Lacks information on return values, error handling, or parameter constraints. Incomplete 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 description coverage is 0%, yet description adds no parameter details. It does not explain msgId, chatId, folder, filename, timeoutMs, or skipIfExists. Agent cannot infer parameter meaning from description alone.
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's a generic save-to-disk for any media kind (image/audio/video/document). It distinguishes from siblings by naming save_image and save_voice as type-specific alternatives, making the tool's purpose and unique role clear.
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 using specific tools (save_image, save_voice) when the type is known for clarity, and recommends this tool for mixed lists of msgIds to avoid branching. Provides clear context and exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_media_windowA
Bulk-save WhatsApp media from the last N hours to disk. Downloads with bounded concurrency (default 3) and returns PER-ITEM results - items that fail (expired, no keys, network) are reported in items[].ok=false with a code, but the overall call still succeeds with ok:true. The errors array rolls up failure codes ({code, count}) for quick summarization. Default folder: /data/media//. Each item in the result has the absolute saved path. The call ABORTS the remaining work only on disk_full or disconnected - never on individual download failures.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| kinds | No | Which media types to save. | |
| chatId | No | ||
| folder | No | Override default folder. Must be an absolute path. | |
| maxItems | No | ||
| timeoutMs | No | Per-item download timeout. Defaults: 30s images, 60s voice, 120s video. | |
| transcribe | No | For voice notes: also run Whisper transcription. Requires api-key.txt. | |
| concurrency | No | ||
| skipIfExists | No | If a target file already exists, skip the download and return the existing path. | |
| excludeGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: concurrency, per-item success/failure, abort conditions only on disk_full/disconnect, default folder, error reporting structure. This is comprehensive and leaves no ambiguity about tool behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense paragraph with no wasted words. Each sentence adds value: purpose, behavior, failure handling, folder path, abort conditions. Front-loaded with main 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?
Given 10 parameters, no annotations, and no output schema, the description is remarkably complete. It explains the return format (items[], errors array, ok status), default folder, concurrency, and error handling. Only minor details like per-parameter defaults are left to the 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 description coverage is 50%. The description adds context (e.g., 'bounded concurrency (default 3)', 'per-item results') but does not fully compensate for undocumented parameters like excludeGroups and hours. 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 starts with a clear verb and resource: 'Bulk-save WhatsApp media from the last N hours to disk.' It distinguishes from sibling tools like save_image or save_voice by specifying bulk and time-window operation.
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 behavioral details but does not explicitly state when to use this tool versus alternatives like save_image or list_media_window. Usage context is implied but not directly contrasted with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_voiceB
Save a single voice note (.ogg) to disk. Same parameter contract as save_image. Optionally pass transcribe:true to also run Whisper transcription on the saved file (requires OpenAI API key in api-key.txt). Returns transcript inline when transcribed successfully. Same error-code set as save_image, plus: transcribe_failed, no_api_key.
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | ||
| chatId | Yes | ||
| folder | No | ||
| filename | No | ||
| timeoutMs | No | Per-download timeout. Default 60s for voice. | |
| transcribe | No | If true and no cached transcript exists, transcribe via Whisper after saving. | |
| skipIfExists | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description takes on full burden. It discloses that the tool saves to disk, optionally transcribes (requiring OpenAI API key), returns transcript inline, and lists error codes. Missing details on failure handling or overwrite behavior, but overall transparent.
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 (4 sentences) and front-loads the core purpose. It is efficient but could be slightly more structured, though it remains easy to read.
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 7 parameters, no output schema, and no annotations, the description covers purpose, optional transcription, and error codes, but lacks details on return values beyond transcript inline and does not provide example usage. It is adequate but leaves 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 description coverage is low (29% - only timeoutMs and transcribe have descriptions). The description adds meaning by mentioning transcribe:true and the same parameter contract as save_image, but does not explain chatId, msgId, folder, filename, or skipIfExists beyond the schema. Reliance on another tool's description is insufficient.
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 saves voice notes (.ogg) to disk and optionally transcribes them. It references save_image as a similar tool, helping differentiate from image saving but not from save_media or other siblings.
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 implies usage for voice notes and when transcription is needed, but does not explicitly state when not to use it or recommend alternatives. The reference to save_image provides some context but lacks clear when-to or when-not-to guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesA
Case-insensitive substring search across cached messages. Looks back hours hours (default 720 = 30 days). Returns chat and from as human-friendly names. NEVER show raw chat IDs or message IDs to the user.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| limit | No | ||
| query | Yes | ||
| excludeGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses case-insensitivity, the configurable time window, output formatting (human-friendly names), and a critical usage warning about raw IDs. It implicitly indicates a read-only operation.
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 with no redundant information. The first sentence states the purpose, the second adds a key parameter detail, and the third provides output format and a critical usage rule. Every 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?
Given no output schema or annotations, the description covers purpose, time window, and output format. However, it does not explain the remaining parameters (limit, excludeGroups), the exact return structure, or behavior when no results are found.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain parameters. It only explains the 'hours' parameter with its default and meaning. 'query', 'limit', and 'excludeGroups' are not mentioned, leaving significant gaps for the agent.
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 performs a case-insensitive substring search across cached messages. This specific verb+resource pairing distinguishes it from sibling tools like get_recent_messages, which retrieves without search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for searching messages with constraints (time window, human-friendly output) but does not explicitly state when to use this tool over alternatives or provide exclusions. The imperative note about never showing raw IDs gives some guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_briefA
Write a JSON brief object to data/brief.json. Called by Claude after analyzing messages, so the WhatsApp Brief artifact can render it.
| Name | Required | Description | Default |
|---|---|---|---|
| brief | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description should disclose behavioral traits. It states it writes to a file, but does not specify whether it overwrites, appends, or handles errors. No mention of auth, side effects, or file creation behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action, no unnecessary words. Every sentence serves a 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?
For a simple 1-parameter tool, the description covers purpose and basic context but lacks details on behavior (e.g., overwrite policy) and return value, leaving gaps for a complete understanding.
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 coverage is 0%, yet the description only mentions 'JSON brief object' without explaining the structure or required fields shown in the schema. It adds minimal value beyond the parameter name.
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 'Write a JSON brief object to data/brief.json', clearly identifying the verb (write) and resource (brief object to a file). It also distinguishes the tool from siblings like get_brief by specifying it is called after analysis for rendering.
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 'Called by Claude after analyzing messages', providing context for when to use. However, it does not explicitly exclude use in other cases or mention alternatives like get_brief for reading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_descriptionA
After viewing an image via get_image, save your description back to the cache. Future briefs reuse it without re-asking Claude (so each image only costs vision tokens once). Pass chatId + msgId + description (1-2 sentences ideally).
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | ||
| chatId | Yes | ||
| description | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses behavioral traits: it is a write operation that saves to cache, reduces vision token usage, and future briefs reuse the description. It doesn't fully cover idempotency or overwrite behavior, but provides valuable 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 two sentences, front-loaded with the main action, and contains no wasted words. It is efficiently 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?
The description covers the workflow, parameters, and rationale. It could be more explicit about the association between chatId/msgId and the image, but is mostly complete for a simple write 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?
The description only clarifies the description parameter's ideal length (1-2 sentences), but does not explain chatId and msgId. With 0% schema coverage, more parameter guidance is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('save') and resource ('description back to the cache'), and places it in the workflow after get_image, distinguishing it from siblings like set_brief.
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 tells the agent to use this tool after get_image and explains the benefit of caching. It also prescribes the description length (1-2 sentences). However, it doesn't mention alternatives or when not to use it, so it's not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_linkA
Block until WhatsApp connection.open fires or timeout. Use after relink_whatsapp to confirm the user scanned successfully.
| Name | Required | Description | Default |
|---|---|---|---|
| waitMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden. It mentions blocking behavior and timeout but lacks details on side effects, error handling, or whether it's safe to call multiple times. Adequate but not thorough.
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, concise and front-loaded. 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 the tool's simplicity (one optional parameter, no output schema), the description is complete. It covers purpose, usage, and parameter role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must add value. It mentions timeout generally but doesn't explicitly explain that waitMs is the timeout duration. The parameter name is self-explanatory, 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?
The description clearly states it blocks until a WhatsApp connection event or timeout, and it explicitly mentions its role after relink_whatsapp. It distinguishes itself from sibling tools by being a blocking/confirmation 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?
The description explicitly says 'Use after relink_whatsapp to confirm the user scanned successfully,' providing clear context and a specific use case. It does not list when not to use it, but the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
where_do_media_files_goA
Return the default folder save_image / save_voice / save_media_window write to (today's folder under /data/media/YYYY-MM-DD), plus how many files are already in it. Useful for answering 'where did you save them?' without filesystem access.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description describes the output (folder path and file count) and implies a read-only query. It's transparent about what the tool does.
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 purpose, no unnecessary words. 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?
For a simple query tool with no output schema, the description covers the key outputs and use case completely.
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 baseline 4 applies. The description adds no parameter information, which is fine since there are none.
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 returns the default folder for media saving operations (save_image, save_voice, save_media_window) along with file count, and distinguishes from siblings by being a query rather than a write operation.
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 'useful for answering "where did you save them?"', providing clear context. It doesn't list exclusions, but the purpose is straightforward.
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.
19 tool updates
v0.3.0- First observed
backfill_history - First observed
enrich_window - First observed
force_resync - First observed
get_brief - First observed
get_image - First observed
get_recent_messages - First observed
get_status - First observed
list_chats - First observed
list_media_window - First observed
relink_whatsapp - First observed
save_image - First observed
save_media - First observed
save_media_window - First observed
save_voice - First observed
search_messages - First observed
set_brief - First observed
set_description - First observed
wait_for_link - First observed
where_do_media_files_go
TDQS
Scored across 19 tools
Each tool has a clearly distinct purpose: message retrieval, media handling, connection management, and brief operations are all separate. Even the three save tools (save_image, save_voice, save_media) are differentiated by type and specificity, and descriptions reinforce the differences.
Almost all tools follow a clear verb_noun pattern (e.g., get_recent_messages, save_media_window). The only outlier is where_do_media_files_go, which uses a full question instead of a concise verb_noun. The overall pattern is strong and predictable.
19 tools is slightly above the typical 3-15 range, but the complexity of WhatsApp interaction (connection, caching, media, transcription, briefing) justifies the count. Each tool serves a unique purpose without redundancy.
The tool set covers reading, searching, caching, and analyzing messages well. However, it notably lacks any send_message or outgoing action capability, which is a significant gap for a messaging platform. The focus appears to be on passive analysis, but the omission limits potential workflows.
Maintenance
Related MCP Connectors
Let Claude or ChatGPT search, read and send your WhatsApp messages over MCP. OAuth sign-in.
Drive your real WhatsApp inbox from Claude โ send, reply, label, assign, and triage via TimelinesAI.
Your own WhatsApp as an MCP server: read, search and send from any MCP client.
Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceGives Claude Desktop read-only access to your WhatsApp chats and message history via a local MCP server.3 npm3MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to read and send WhatsApp messages, including media and call history, via a local bridge.MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude to interact with WhatsApp: read chats, search messages, send messages with a mandatory confirmation step, and transcribe voice notes locally, all with encrypted storage and prompt-injection scrubbing.MIT
- AlicenseNot gradedqualityBmaintenanceProvides Claude with read-only access to your WhatsApp chat history entirely on your local machine, enabling natural language search, summarization, and retrieval of messages without sending data to the cloud.11 npmMIT