Personal Assistant Setup: OpenClaw WhatsApp Guide
Learn to configure OpenClaw as a personal assistant via a dedicated WhatsApp number, with safety cautions and a two-phone setup. Ideal for self-hosters seeking a round-the-clock AI helper.
Read this when
- Onboarding a new assistant instance
- Reviewing safety/permission implications
OpenClaw acts as a self-hosted gateway linking Discord, Google Chat, iMessage, Matrix, Microsoft Teams, Signal, Slack, Telegram, WhatsApp, Zalo, and other platforms to AI agents. The focus here is the "personal assistant" configuration: a dedicated WhatsApp number that functions as your round-the-clock AI helper.
Safety first
When an agent is assigned a channel, it gains the ability to execute commands on your system (subject to your tool policy), access and modify files within your workspace, and transmit messages outward through any linked channel. Begin with caution:
- Always configure
channels.whatsapp.allowFrom(avoid exposing your personal Mac to the open internet). - Reserve a separate WhatsApp number for the assistant.
- Heartbeats are set to fire every 30 minutes by default. Turn them off until you're comfortable with the setup using
agents.defaults.heartbeat.every: "0m".
Prerequisites
- OpenClaw installed and onboarded, refer to Getting Started if this step is incomplete
- An additional phone number (SIM/eSIM/prepaid) dedicated to the assistant
The two-phone setup (recommended)
Your target configuration looks like this:
flowchart TB
A["<b>Your Phone (personal)<br></b><br>Your WhatsApp<br>+1-555-YOU"] -- message --> B["<b>Second Phone (assistant)<br></b><br>Assistant WA<br>+1-555-ASSIST"]
B -- linked via QR --> C["<b>Your Mac (openclaw)<br></b><br>AI agent"]
Connecting your personal WhatsApp to OpenClaw turns every incoming message into "agent input." That outcome is usually undesirable.
5-minute quick start
- Pair WhatsApp Web (a QR code appears; scan it with the assistant phone):
openclaw channels login
- Launch the Gateway (keep it running):
openclaw gateway --port 18789
- Place a minimal configuration in
~/.openclaw/openclaw.json:
{
gateway: { mode: "local" },
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}
After that, send a message to the assistant number from your allowlisted phone.
Once onboarding completes, OpenClaw automatically opens the dashboard and displays a link without any token embedded. If the dashboard asks for authentication, enter the shared secret you configured into the Control UI settings. Onboarding defaults to token-based auth (gateway.auth.token), though password auth is available if you set gateway.auth.mode to password. To reopen it later: openclaw dashboard.
Give the agent a workspace (AGENTS)
OpenClaw pulls its operational instructions and "memory" from the workspace directory.
By default, ~/.openclaw/workspace serves as the agent workspace, and it gets created automatically (along with starter AGENTS.md, SOUL.md, IDENTITY.md, USER.md) during onboarding or the first agent run. Place environment-specific tool notes in the ## Tools section of AGENTS.md. BOOTSTRAP.md appears only for a freshly created workspace and should not reappear after you remove it. MEMORY.md is optional and never generated automatically; when it exists, it loads for standard sessions. Subagent sessions inject only AGENTS.md.
Tip
View this folder as OpenClaw's memory and initialize it as a git repository (ideally private) so your
AGENTS.mdand memory files stay backed up. With git installed, new workspaces get auto-initialized withgit init.
To set up the workspace and config folders without going through the full onboarding wizard:
openclaw setup --baseline
(Plain openclaw setup acts as an alias for openclaw onboard and triggers the complete interactive wizard.)
Complete workspace layout and backup details: Agent workspace Memory workflow: Memory
Optionally, pick a different workspace using agents.defaults.workspace (which supports ~).
{
agents: {
defaults: {
workspace: "~/.openclaw/workspace",
},
},
}
If you already bring your own workspace files from a repository, you can turn off bootstrap file creation entirely:
{
agents: {
defaults: {
skipBootstrap: true,
},
},
}
The config that turns it into "an assistant"
OpenClaw ships with a sensible assistant configuration, but you'll likely want to adjust:
- persona/instructions in
SOUL.md - thinking defaults (if you prefer)
- heartbeats (once you've gained confidence)
Example:
{
logging: { level: "info" },
agents: {
defaults: {
model: { primary: "anthropic/claude-opus-5" },
workspace: "~/.openclaw/workspace",
thinkingDefault: "high",
timeoutSeconds: 1800,
// Start with 0; enable later.
heartbeat: { every: "0m" },
},
entries: {
main: {
default: true,
groupChat: {
mentionPatterns: ["@openclaw", "openclaw"],
},
},
},
},
channels: {
whatsapp: {
allowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true },
},
},
},
session: {
scope: "per-sender",
resetTriggers: ["/new", "/reset"],
reset: {
mode: "daily",
atHour: 4,
idleMinutes: 10080,
},
},
}
Sessions and memory
- Session rows, transcript rows, and metadata (token usage, last route, etc.):
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Legacy/archive transcript artifacts:
~/.openclaw/agents/<agentId>/sessions/ - Legacy row migration source:
~/.openclaw/agents/<agentId>/sessions/sessions.json /newor/resetinitiates a new session for that chat (adjustable viasession.resetTriggers). Sent on its own, OpenClaw confirms the reset without calling the model./compact [instructions]condenses the session context and reports the remaining context budget.
Heartbeats (proactive mode)
By default, OpenClaw triggers a heartbeat every 30 minutes with the prompt:
Follow the heartbeat monitor scratch context when provided. Recurring tasks are automations; create or change their schedules with the automations tool, not heartbeat scratch. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.
Set agents.defaults.heartbeat.every: "0m" to turn this off. Heartbeat checklists reside in the monitor's cron scratch (see Heartbeat); openclaw doctor --fix migrates a legacy workspace HEARTBEAT.md into that location.
- If the monitor scratch exists but holds only whitespace, Markdown/HTML comments, Markdown headings like
# Heading, fence markers, or empty checklist stubs, OpenClaw skips the heartbeat run to conserve API calls. - With no scratch present, the heartbeat still executes and the model determines the action.
- If the agent responds with
HEARTBEAT_OK, optionally followed by up to 300 characters of text, OpenClaw withholds outbound delivery for that heartbeat. The 300-character cap is fixed. - By default, heartbeat delivery to DM-style
user:<id>targets is permitted. Setagents.defaults.heartbeat.directPolicy: "block"to block direct-target delivery while keeping heartbeat runs active. - Heartbeats execute full agent turns, so shorter intervals consume more tokens.
{
agents: {
defaults: {
heartbeat: { every: "30m" },
},
},
}
Media in and out
Templates let you expose incoming attachments, whether images, audio, or documents, to your command:
{{AttachmentPath}}(temporary file path on the local machine){{AttachmentUrl}}(provider reference or the original URL){{AttachmentContentType}}(MIME content type){{AttachmentDir}}(folder that holds the local path){{AttachmentIndex}}(zero-based index of the source fact){{Transcript}}(only when audio transcription is turned on)
The older names {{MediaPath}}, {{MediaUrl}}, {{MediaType}}, and {{MediaDir}}
still work, though they are kept around as deprecated compatibility aliases.
For outbound attachments, the agent relies on structured media fields carried by the message tool or reply payload, for instance media, mediaUrl, mediaUrls, path, or filePath. Here is an example of message-tool arguments:
{
"message": "Here's the screenshot.",
"mediaUrl": "https://example.com/screenshot.png"
}
Structured media accompanies the text when OpenClaw sends output. While legacy final assistant replies may still be normalized for compatibility, text is never parsed as attachment commands in tool output, browser output, streaming blocks, or message actions.
When a legacy final-reply MEDIA: line is unavoidable, place it as plain standalone
text. Markdown wrappers, code fences, and inline prose like
**MEDIA:/path.png**, `MEDIA:/path.png`, or
Here is the image: MEDIA:/path.png remain text and attach nothing. For details, check the
Rich output protocol.
Local-path handling follows the same file-read trust model used by the agent:
- With
tools.fs.workspaceOnlyset totrue, outbound local media paths are confined to the OpenClaw temp root, the media cache, agent workspace paths, and files produced by the sandbox. - With
tools.fs.workspaceOnlyset tofalse, outbound local media may draw on host-local files the agent is already permitted to read. - Local paths may be absolute, relative to the workspace, or relative to the home directory using
~/. - Host-local sends still permit only media and safe document types: images, audio, video, PDF, Office documents, and validated text documents like Markdown/MD, TXT, JSON, YAML, and YML. This extends the existing host-read trust boundary rather than acting as a secret scanner. If the agent can read a host-local
secret.txtorconfig.json, it can attach that file as long as the extension and content validation pass.
Store sensitive files outside the agent-readable filesystem, or keep tools.fs.workspaceOnly: true for stricter local-path sends.
Operations checklist
openclaw status # local status (creds, sessions, queued events)
openclaw status --all # full diagnosis (read-only, pasteable)
openclaw status --deep # probe channels (WhatsApp Web + Telegram + Discord + Slack + Signal)
openclaw health --json # gateway health snapshot over the WS connection
Logs are stored under /tmp/openclaw/: openclaw-YYYY-MM-DD.log applies to the default
profile, while openclaw-<profile>-YYYY-MM-DD.log is used for named profiles.
Next steps
- WebChat: WebChat
- Gateway ops: Gateway runbook
- Cron + wakeups: Cron jobs
- macOS menu bar companion: OpenClaw macOS app
- iOS node app: iOS app
- Android node app: Android app
- Windows Hub: Windows
- Linux status: Linux app
- Security: Security