wa-agent
Manifest validDeepSeek Harness plugin: a wa_* tool family that lets the agent operate a WhatsApp account through a bundled Baileys bridge.
wa-agent
WhatsApp control for the DeepSeek Harness agent.
wa-agent adds a family of 46 wa_* tools that let an agent operate a
WhatsApp account: connection and pairing, chats and message history, text,
media, locations, contacts and polls, reactions, edits, deletes, groups,
contact book, profile and privacy, presence, and the event stream.
The tools talk to a long-lived wa-agent bridge that ships inside this
package. The bridge (bridge/bridge.mjs, built on
Baileys) owns the WhatsApp socket,
the auth state and the message store; it also exposes a loopback HTTP endpoint
for the human-facing QR code. The plugin speaks to it over JSON-lines RPC on
stdio or, when a service manages the bridge, over loopback HTTP.
Install
One command installs the plugin, the bridge and the bridge's npm dependencies:
npx @deepseek-ai/dsh plugin --profile web add github:songjongdevsecops/wa-agent
On pnpm 11 and newer, that command may stop once because pnpm blocks
dependency build scripts by default (ERR_PNPM_IGNORED_BUILDS). It names the
packages. Approve them in the profile's pnpm-workspace.yaml and re-run the
same command:
allowBuilds:
baileys: true # preinstall only checks the Node.js version
protobufjs: false # postinstall belongs to the protobufjs CLI, not the runtime
Restart the harness to load the bundle (the bundle layer is read at boot, not at install time):
npx @deepseek-ai/dsh web
The package declares dsh.bundle.patch, so the add command appends wa-agent
to dsh.profile.bundles in the profile manifest. That line is the only
activation.
Check the loaded line:
npx @deepseek-ai/dsh --profile web --dump-config | grep -A3 wa-agent
Expected shape:
- id: wa-agent
name: wa-agent
config: {}
No extra step is needed to run the bridge: the plugin spawns it on the first
tool call (autoStart, default true) and restarts it after a crash. The
first thing left to do is pair your WhatsApp account (next section).
Update and uninstall
# update: re-run the add command, then restart the harness
npx @deepseek-ai/dsh plugin --profile web remove wa-agent # uninstall, then restart
Requirements
- Node.js
^22.19.0 || >=24.0.0. - pnpm on
PATH(npm install -g pnpm); the harness manages profile plugins with it. - DeepSeek Harness itself, e.g.
npx @deepseek-ai/dsh web. - A WhatsApp account you control, paired by you (see below).
Pairing
On first run the bridge has no session and shows a QR. With the default
httpPort: 29141:
- Open http://127.0.0.1:29141/qr.png.
- In the phone, open WhatsApp > Linked devices > Link a device and scan the QR.
- Call
wa_status(or ask the agent) to confirm the phase and the paired account.
Alternative: ask the agent for wa_pair_sms_code with the full international
phone number. The phone receives a 6-digit code, typed in WhatsApp > Linked
devices > Link with phone number.
The session is stored by the bridge, never by this package. It is reused on
every reconnect until wa_logout is called. Pairing is per account; you pair
your own account.
Usage
Ask the agent in natural language:
- "What is the WhatsApp status?"
- "Show the last 20 messages from this chat."
- "Send this image to
<recipient>with the caption<caption>." - "Create a group named
<name>and add<participants>." - "Mark this chat as read."
Tool groups:
| Group | Tools |
|---|---|
| Connection | wa_status, wa_pair, wa_pair_sms_code, wa_restart, wa_logout |
| Chats and messages | wa_chats, wa_chat_messages, wa_send_text, wa_edit_message, wa_send_media, wa_send_location, wa_send_contact, wa_send_poll, wa_send_reaction, wa_pin_message, wa_delete_message, wa_forward_message, wa_download_media, wa_mark_read, wa_chat_modify |
| Groups | wa_groups, wa_group_info, wa_group_create, wa_group_join, wa_group_update, wa_group_participants, wa_group_settings, wa_group_invite, wa_group_approvals, wa_group_leave |
| Contacts | wa_contacts, wa_contacts_allow, wa_contacts_clear, wa_phone_check, wa_peer_info, wa_block_user, wa_blocklist, wa_save_contact |
| Account | wa_profile, wa_profile_update, wa_profile_picture, wa_privacy_get, wa_privacy_set, wa_status_post |
| Events | wa_events |
Sends are per recipient. The plugin adds no mass-messaging, scraping or follower-growth surface.
Bridge resolution
The plugin looks for the bridge in this order:
- an explicit deployment:
bridgeDirin the plugin config, or theWA_WORKSPACEenvironment variable. The directory may holdbridge.mjsdirectly, or a workspace that holdswa-agent/bridge.mjs. - the bridge bundled in this package:
bridge/bridge.mjs. - a historical standalone deployment under
~/wa-agent(bridge.mjsorwa-agent/bridge.mjs).
Set bridgeDir (or WA_WORKSPACE) to keep using a bridge you already run.
When it is set, it is authoritative: a missing file fails with
WA_BRIDGE_MISSING instead of silently starting the bundled bridge against a
different state directory. When it is not set, the bundled bridge is used, with
its runtime root at your home directory, so state lives in ~/wa-agent/.
Configuration
Every path is configurable; the defaults derive from your home directory. A patch replaces the whole config of the line, so restate every key you want to keep.
| Key | Environment | Default | Meaning |
|---|---|---|---|
bridgeDir | WA_WORKSPACE | bundled bridge | bridge deployment directory; also the runtime root for state |
dataDir | <root>/wa-agent/data | WhatsApp auth-state directory override | |
mediaDir | <root>/wa-agent/media | downloaded-media directory override | |
httpPort | 29141 | loopback port for QR, health and RPC; 0 disables HTTP | |
autoStart | true | spawn the bridge on demand and restart it after a crash | |
rpcTimeoutMs | 120000 | per-RPC timeout |
Profile patch example (~/.dsh/profiles/web/cordis.patch.yml):
- id: wa-agent
config:
bridgeDir: '/absolute/path/to/wa-agent'
httpPort: 29141
Use an absolute path in the config; ~ is not expanded by the harness. Leaving
bridgeDir out uses the bundled bridge.
The plugin adopts a bridge that is already listening on httpPort (for
example, one managed by a service) instead of spawning a duplicate. With
autoStart: false, start the bridge yourself before calling a tool:
WA_WORKSPACE="$HOME" WA_HTTP_PORT=29141 \
node "$HOME/.dsh/profiles/web/node_modules/wa-agent/bridge/bridge.mjs"
Troubleshooting
pnpm not found on PATH—npm install -g pnpm, then re-run the add command.ERR_PNPM_IGNORED_BUILDS— pnpm ≥ 11 blocked thebaileyspreinstall and theprotobufjspostinstall. Add theallowBuildsblock shown in Install to the profile'spnpm-workspace.yamland re-run the add command.WA_BRIDGE_MISSING— an explicitbridgeDir/WA_WORKSPACEdoes not containbridge.mjsorwa-agent/bridge.mjs. The error lists the paths it tried. Unset it to use the bundled bridge.- No QR — call
wa_status. The bridge may still be connecting, orhttpPortmay be0(HTTP disabled). - Pairing rejected on the phone — the announced WhatsApp Web version may be outdated. The bridge asks Baileys for the current version at every boot; if the link still fails, update the package and Baileys.
- Plugin installed but no tools appear — restart the harness; the bundle layer is read at boot.
Security and limits
- The WhatsApp session is a private key. The bridge stores it in its data
directory (
<root>/wa-agent/data,~/wa-agent/datawith the bundled bridge). Never commit it, paste it into a prompt, or copy it into a repository. This package ships the bridge code only: no session, no message store, no QR cache and no media. - The HTTP endpoint is loopback-only. Do not expose
httpPortto a network: anyone who reaches it can drive the account. - Baileys is an unofficial WhatsApp Web client. Automation may violate WhatsApp's Terms of Service and can put the account at risk. Use it on your own account, at your own judgment.
- The bridge runs alongside the harness. It is a child process of the
plugin, not a service: it stops when the harness stops, and the plugin
restarts it after a crash. A missing bridge is reported clearly
(
WA_BRIDGE_MISSINGorWA_BRIDGE_DOWN), never as a silent success. - Offline phone. Sending and receiving for known chats works while the phone is offline. First-time contacts and groups may need the phone online to distribute keys; long offline periods can unlink the device.
- Windows. The plugin and the bridge are plain Node.js; they run natively wherever Node can reach WhatsApp. Paths and the child process use Node's cross-platform APIs.
License
Comments
Loading…
Similar plugins
by 0lidaxiang
DeepSeek Harness is a plugin-based system for building AI agents. Everything, from tools and models to the web UI, can be added or replaced as a plugin.
★ 4
↓ 168/wk
MIT
JavaScript
Oct 7, 2026
dsh plugin --profile web add dsh-plugin-greetby KouzakiUmi
DeepSeek Harness 插件:按 Agent preset 限制每个 Agent 可见的工具,保留全局 provider 挂载;基于 agent/created 与 ctx.tools.restrict()。
★ 0
MIT
JavaScript
Oct 5, 2026
dsh plugin --profile web add dsh-preset-tool-guardby aaravarr
DeepSeek Harness (DSH) plugin — a subagent_with_model tool plus a live multi-panel subagent viewer.
★ 3
↓ 28/wk
MIT
JavaScript
Aug 20, 2026
dsh plugin --profile web add @aaravarr/dsh-subagent-maxby bihangchi9-creator
A native DeepSeek Harness (dsh) plugin bridging dsh coding agents to Feishu/Lark group chats — one group, one project directory.
★ 34
↓ 72/wk
NOASSERTION
TypeScript
Sep 18, 2026
dsh plugin --profile web add @bihangchi9/lark-agent-bridgeby extension-hunter
DeepSeek Harness plugin: a 'Connected Apps' settings section — a central platform where other DSH plugins surface themselves.
★ 0
MIT
JavaScript
Aug 15, 2026
dsh plugin --profile web add dsh-authorize-appby AGSQ11
A small DeepSeek Harness plugin that shows the actual provider/model used by a subagent directly inside the existing native subagent tool-call row.
★ 0
MIT
JavaScript
Aug 21, 2026
dsh plugin --profile web add dsh-subagent-model-visibility