docspluginsextensionswhatsapp

whatsapp

WhatsApp as a data source and action surface — the agent reads and sends messages and downloads media as a capability. It connects through the WhatsApp Web linked-device protocol, not a chat the agent talks over.

What the agent can do

  • Orient → read → act — list recent chats with previews and unread counts, look up a conversation by name or number, then read, send, or download.
  • Media — messages show a placeholder with an id; the agent downloads media to staging, and sends media by writing to staging first.
  • Persistent history — messages stream into a local store and survive restarts; WhatsApp delivers the historical backfill once, at pairing.

Pairing your phone

Pairing happens in the admin dashboard, on this agent's WhatsApp extension page — there are no credentials to paste. The agent links to your account as a device, the same way WhatsApp Web does, and the session is stored under ext/whatsapp/auth/. Under Pairing Status on that page:

  1. Optionally choose how much history to sync — Standard (~3 months) or Extended (~1 year). It only takes effect at pairing.
  2. Enter your phone number with country code (e.g. +1 415 555 0142) and click Pair Device.
  3. A 6-digit code appears. On your phone, open WhatsApp → Settings → Linked Devices → Link a Device → Link with phone number, and enter it.
  4. The page polls for up to two minutes and flips to Paired once linked, syncing recent history into a local store.

Once paired, the same page shows the linked status and synced-chat count, with an Unpair button to clear the session.

⚠ HEADS UP
Right after pairing, the connection may report a one-off stream error and reconnect on its own — that's expected.

Configuration

capabilities.json

json · extensions.whatsapp slice
{
  "extensions": {
    "whatsapp": {
      "enabled": true,
      "read_mode": "approval",
      "send_mode": "disabled"
    }
  }
}
FieldTypeDefaultEffect
read_modedisabled | approval | openapprovalDefault policy for reading chats, messages, and media.
send_modedisabled | approval | directdisabledDefault policy for sending. direct sends without prompting.
chatsRecord<jid, overrides>{}Per-chat overrides — allow or deny read and send independently for a specific contact.

pairing_history_depth (standard or extended) sets how much history WhatsApp delivers, and applies only at pairing time — changing it means unpairing and pairing again.

Tools

whatsapp__chats(limit?)

List recent WhatsApp chats with names, last-message previews, unread counts, and group status.

Parameters

  • optional limit[integer 1–50, default 20]Max chats to return.

Returns

CHAT_NAME (group) [N unread]
CHAT_NAME
…
when chats exist
No chats yet.
when empty store
Reading is disabled.
when read_mode = disabled and no readable chats

whatsapp__messages(chat, count?, query?)

Read messages from a WhatsApp chat by contact name, phone number, or JID. Optionally filter by keyword.

Parameters

  • chat[string]Chat identifier — name, phone number, or JID.
  • optional count[integer 1–100, default 20]Number of messages to return.
  • optional query[string]Keyword to filter messages — returns only those containing this text.

Returns

[YYYY-MM-DD HH:MM] SENDER: TEXT (ID: MESSAGE_ID)
when standard message line
[YYYY-MM-DD HH:MM] SENDER: [image|video|voice note|audio|document: FILENAME|sticker] [optional CAPTION] (ID: MESSAGE_ID)
when media message line
No messages available for this chat yet.
when empty chat
No messages matching "QUERY" in this chat.
when keyword filter matches nothing
Multiple chats match "QUERY". Please specify:
CHAT_NAME — JID (group)
…
when ambiguous chat identifier
No chat found matching "QUERY".
when identifier does not resolve
Access to this chat is restricted.
when ACL blocks read for this contact
WhatsApp not paired. Link a device in the admin panel first.
when session not initialized
WhatsApp not ready — connection timeout. Try again in a moment.
when connection stalled

whatsapp__download(message_id, chat)

Download media from a WhatsApp message to /staging/in/ for inspection with the Read tool.

Parameters

  • message_id[string]Message ID from whatsapp__messages output.
  • chat[string]Chat identifier (name, phone, or JID) containing the message.

Returns

Downloaded to /staging/in/FILENAME. Use the Read tool to view it.
when success — filename from document metadata or media_<truncated-id>.<ext>
Message not found or no longer in buffer.
when message ID not in store
Media download failed — the file may have expired. ERROR
when download failure
Access to this chat is restricted.
when ACL blocks read
WhatsApp not paired. Link a device in the admin panel first.
when session not initialized

whatsapp__send(chat, text?, file?)

Send a text or media message to a WhatsApp chat. Media is read from /staging/out/ with an optional caption.

Parameters

  • chat[string]Chat identifier (name, phone, or JID).
  • optional text[string]Message text. Required for text-only sends; used as caption when file is set.
  • optional file[string]Filename in /staging/out/ to send as media.

Returns

Message sent.
when success
Provide at least text or file to send.
when both text and file absent
File not found: /staging/out/FILENAME
when file path does not exist
No routable address for this contact.
when contact has no valid JID
Sending to this chat is disabled.
when ACL blocks send
Send failed: ERROR
when socket error or library exception
WhatsApp not connected.
when socket is null
WhatsApp not paired. Link a device in the admin panel first.
when session not initialized

whatsapp__watch(chat, instructions, id?)

Monitor a WhatsApp chat for new messages. Each new message is forwarded to the agent's channel with the configured instructions.

Parameters

  • chat[string]Chat identifier (name, phone, or JID).
  • instructions[string]Instructions delivered with each forwarded batch.
  • optional id[string]Custom watch ID. Auto-generated as watch_<random> if omitted.

Returns

Watch "ID" created for CHAT_NAME. New messages will be forwarded with your instructions.
when success
Instructions are required.
when empty instructions
Multiple chats match "QUERY". Please specify:
CHAT_NAME — JID (group)
…
when ambiguous chat identifier
No chat found matching "QUERY".
when identifier does not resolve
Access to this chat is restricted.
when ACL blocks read
Watches require a participant context.
when called outside an active conversation
WhatsApp not paired.
when session not initialized

Caveats

Delivery format: each fired batch arrives as a turn in the agent's channel — New WhatsApp messages in "CHAT_NAME": [YYYY-MM-DD HH:MM] SENDER: TEXT [YYYY-MM-DD HH:MM] SENDER: [media placeholder] CAPTION … Watch instructions: INSTRUCTIONS

whatsapp__unwatch(id)

Remove an active WhatsApp watch by ID.

Parameters

  • id[string]Watch ID to remove. List with whatsapp__list_watches.

Returns

Watch "ID" removed.
when success
Watch "ID" not found.
when unknown id

whatsapp__list_watches()

List all active WhatsApp watches with their chat, instructions, and creation timestamps.

Returns

ID: ID
  Chat: CHAT_NAME
  Instructions: INSTRUCTIONS
  Created: ISO_TIMESTAMP
when one block per watch, separated by blank lines
No active watches.
when none registered

Watches

With a dedicated channel, the agent can watch a chat in real time and have new messages forwarded to that channel with standing instructions, so it reacts as they arrive. Without a channel, the watch tools are hidden and the on-demand tools still work.

Notes & gotchas

🔒 SECURITY
send_mode: direct lets the agent message contacts autonomously, as you — recipients see it from your number. Prefer approval (or disabled) and grant direct only to trusted chats via the per-chat overrides.
⚠ HEADS UP
The agent holds a single WhatsApp connection. Opening another client for the same account elsewhere will conflict with it, so keep one live link per account.