Recipes: an agent and your WhatsApp
Give your agent WhatsApp tasks for catch-up, questions, context and scheduled local checks.
Use this page when you want your AI agent (for example Claude Code, Codex, Cursor or Gemini CLI) to do regular work with your WhatsApp: a morning summary, a report on a chat, who owes what, what you have not answered. Each recipe gives you a request to copy, the commands the agent may run, and whether it writes anything to WhatsApp. At the end you can run the agent on a schedule, with limits it cannot get around.
Terms on this page:
- Agent — an AI program that runs commands on your computer for you.
- Skill — a file that tells the agent how to use
wa.wa skill installputs it where the agent looks for it. - MCP client — an AI app without a terminal, such as Claude Desktop. It reaches
wathrough the MCP serverwa personal mcpinstead of running commands. - Headless mode — the agent takes one request, does it and exits, with no conversation. Claude Code calls it
-pmode; Codex calls itcodex exec. - cron — the scheduler built into Linux and macOS. It starts a command at set times.
What the recipes do
Every recipe below reads the local store, which wa personal serve keeps filled from your phone. Reads never connect
to WhatsApp, so they run beside serve.
| Recipe | Writes to WhatsApp | Fits a schedule |
|---|---|---|
| Morning summary | no | yes |
| Weekly report on a chat | no | yes |
| Who owes what | no | yes |
| What you have not answered | no | yes |
| Find something that was said | no | yes |
| Draft a reply | only after your yes | no |
Once, first
-
Install
waand link it: see installation and linking. -
Keep the store filled:
wa personal server install, thenwa personal server start.wa personal server statussays whether it runs. -
Give the agent the skill:
wa skill installThe skill goes to the folders of Claude Code (
~/.claude/skills/whatsapp-cli/) and of Codex and Gemini CLI (~/.agents/skills/whatsapp-cli/).wa skill showprints the same text, if your agent keeps skills somewhere else. -
Save the requests below in files, for example in
~/wa-recipes/. The schedule commands read the request from a file.
An MCP client needs no skill. Connect the MCP server (wa personal mcp config prints the entry for its settings);
see the MCP server.
What the agent may do
An agent on a schedule works without you, so put the limits into settings, not into the request. An agent can misread "send nothing". It cannot get around a setting that it is not allowed to change.
Limit what the agent may run. This is a setting of the agent. For example, Claude Code in -p mode runs only the
commands in --allowedTools. With no wa personal messages send in the list, the agent cannot call it:
claude -p "$(cat ~/wa-recipes/morning.md)" --allowedTools "Bash(wa personal inbox:*)"Limit what the profile may do. This works for every agent:
wa personal config set permissions.messages readonly
wa personal config set permissions.reactions readonly
wa personal config set permissions.polls readonly
wa personal config set permissions.chats readonly
wa personal config show # check the permissions in force
wa personal config set sends_per_hour 5 # or: at most five sends an hour
wa personal recipients add 100000000000001@lid # and only to the chats on this listreadonly on one resource does not cover the others: messages alone still lets the agent react or mark a chat
read. recipients add looks the chat up on WhatsApp, so it connects; while serve runs, it runs inside serve, on
its connection.
permissions limits your own commands too, until you change it back:
wa personal config unset permissions.messages. To limit only the agent, give it a profile of its own. Every attempt
to send, refused ones included, is in wa personal sends list. See permissions.
Never in bulk, never to strangers. WhatsApp bans accounts that send to many people at once, or to numbers that never wrote to them. No recipe here sends on its own.
Reading gives nothing away. No command in the recipes below marks anything read: nobody sees that the agent
opened a chat. Only chats mark-read sends a read receipt.
Running on a schedule
-
Claude Desktop scheduled tasks. The task runs on your computer, so it has
waand your store. See Claude's scheduled tasks. -
cron and
claude -p. No app needed, on any computer that is on at that time:30 8 * * * claude -p "$(cat ~/wa-recipes/morning.md)" --allowedTools "Bash(wa personal inbox:*)" >> ~/wa-recipes/morning.log 2>&1cron starts jobs with an almost empty environment. If Node comes from nvm, fnm or Volta, it is not on cron's
PATHand the job fails withnode: not found, exit code 127. Put the folder ofwhich nodeat the top ofcrontab -e:PATH=/home/you/.nvm/versions/node/v24.0.0/bin:/usr/local/bin:/usr/bin:/binRun the first job by hand and read the log. See Claude's headless mode.
-
cron and
codex exec. The same for Codex. Its sandbox closes file writes by default, andwawrites its run records and the saved point of--new:30 8 * * * codex exec --sandbox danger-full-access "$(cat ~/wa-recipes/morning.md)" >> ~/wa-recipes/morning.log 2>&1 -
Inside an open Claude Code session:
/loop, or "remind me at 15:00". It works while the session is open.
Claude's cloud routines do not fit: they run on another computer, where there is no wa and no store of yours.
Morning summary
Writes to WhatsApp: no. Allow: Bash(wa personal inbox:*).
Run
wa personal inbox --new --json. Group the messages by chat. For each chat, one line: who writes and what they want. Put first what needs an answer today.
--new shows each message once. wa remembers where it stopped in each chat, and the next run starts there.
Since when is "new"
wa personal inbox— other people's unread messages.wa personal inbox --new— since the last--newrun. Onlywaknows that point; nobody else sees it.wa personal inbox 'date>2d'— the last two days; the saved point stays where it was.
None of them marks anything read. kind:dialog keeps one-to-one chats, kind:group groups.
Weekly report on a chat
Writes to WhatsApp: no. Allow: Bash(wa personal messages list:*).
Read the last 7 days of the group
[email protected]:wa personal messages list [email protected] "date>7d" --limit 200 --json. If the answer has apage.nextstep, follow it. Write a report: what was decided, who took on what and by when, which questions are still open. Give each point its date and author.
The store holds what the phone pushed when wa linked and what serve received since. An older stretch is not there
until wa personal messages sync [email protected] asks the phone for it
(older history).
Who owes what
Writes to WhatsApp: no. Allow: Bash(wa personal review:*), Bash(wa personal messages context:*),
Bash(wa personal search messages:*).
Run
wa personal review --new --json(the first time, the last 3 days; then from the last--new, a point per chat). Sort it into three lists: what I owe, what I wait for from others, what needs clarifying. Give each point its chat, date and the message ids it rests on. If the answer says"complete": false, tell me what is missing.
review and serve also keep a list of tasks: wa personal tasks list state:open shows what waits on you
(groups).
What you have not answered
Writes to WhatsApp: no. Allow: Bash(wa personal review:*).
Run
wa personal review 'date>7d' --unanswered --json. Show the questions nobody answered: who asked, in which chat, and how long ago.
Find something that was said
Writes to WhatsApp: no. Allow: Bash(wa personal search messages:*), Bash(wa personal messages context:*).
Search for "invoice" with
wa personal search messages invoice --json. For each hit, readwa personal messages context <locator> --jsonand tell me who said what, and when.
Search reads only the local store. See search.
Draft a reply
Writes to WhatsApp: only after your yes. This one is for a conversation with the agent, not for a schedule.
Read the last 20 messages of the chat
100000000000001@lidand suggest an answer to their last question. Do not send it — show me the text.
Once you agree, the agent sends it: wa personal messages send 100000000000001@lid "…". While serve runs, the send
goes through serve's connection (one connection per device); there it
cannot ask, so at permission level ask it needs --yes.
An MCP client asks you before each write if you leave wa_write unapproved in it.