内容
# WhatsApp MCP 服务器
一个本地的模型上下文协议(MCP)服务器,将您的个人 WhatsApp 账户暴露为 Claude Desktop 或 Claude Code 的四个工具。
由 [Baileys](https://github.com/WhiskeySockets/Baileys) 支持 WhatsApp Web 协议,由 [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) 支持本地消息缓存。
单用户,本地,无云依赖。您只需扫描一次二维码,然后您的会话就会被保存,您无需再次扫描。
## 功能
四个 MCP 工具:
| 工具 | 功能 |
|---|---|
| `list_chats` | 最近的 WhatsApp 会话,最新的优先。可选的 JID 前缀过滤器(例如 `120363` 用于群组)。 |
| `read_messages` | 聊天中的最后 N 条消息。通过 `beforeTimestamp` 进行分页。可选的发送者过滤器。 |
| `search_messages` | 消息历史记录的全文搜索,支持相关性排名。支持 `pizza`、`pizza OR burger`、`piz*`、`"exact phrase"`。 |
| `send_message` | 通过 WhatsApp 发送文本消息。发送的消息也会被本地保存,以便后续读取/搜索。 |
## 架构
```
┌─────────────┐
│ Claude Code │ JSON-RPC over stdio
└──────┬──────┘
│
┌──────▼──────────────┐
│ src/index.ts │ MCP 服务器(注册 4 个工具)
│ src/db/queries.ts │ 读取侧:listChats, readMessages, searchMessages
│ src/wa/send.ts │ 写入侧:sendMessage
└──────┬──────────────┘
│
┌──────▼─────────────────┐
│ src/wa/persist.ts │ persistMessage, persistChat, attachPersistence
│ src/wa/socket.ts │ connectToWhatsApp (Baileys socket + QR)
│ src/wa/auth.ts │ loadAuthState
└──────┬─────────────────┘
│
┌──────▼──────────┐
│ data/history.db│ SQLite (chats + messages + FTS5)
│ auth/ │ Baileys 会话文件(gitignored)
└─────────────────┘
```
## 前置条件
- **Node.js 18+** (该项目使用 ESM 和现代 Node API)
- **手机上的 WhatsApp 账户** (您需要扫描一次二维码)
- **C/C++ 工具链** 用于 `better-sqlite3` 原生构建:
- macOS: Xcode 命令行工具 (`xcode-select --install`)
- Linux: `build-essential` + `python3`
- Windows: Visual Studio Build Tools with the "Desktop development with C++" workload
## 安装
该软件包位于 NPM 上,地址为
[`@muhammadmustafa18/whatsapp-mcp-server`](https://www.npmjs.com/package/@muhammadmustafa18/whatsapp-mcp-server)。

> ⚠️ **不要与 `whatsapp-mcp-server`(无作用域)混淆** — 这是 BitNex Technologies 的一个不同软件包,它与 WhatsApp Business Cloud API 而不是 WhatsApp Web 通信。始终使用带 `@muhammadmustafa18/` 作用域的名称。
### 选项 A:全局 npm 安装(推荐)
```bash
npm install -g @muhammadmustafa18/whatsapp-mcp-server
whatsapp-mcp
```


### 选项 B:从源代码(开发)
```bash
git clone https://github.com/MuhammadMustafa18/whatsapp-mcp-server.git
cd whatsapp-mcp-server
npm install
npm run build
npm start
```
`whatsapp-mcp` 包装器位于 `bin/cli.mjs` 中。它解析每个用户的存储位置(默认为 `~/.whatsapp-mcp/`,可通过 `WHATSAPP_MCP_HOME` 环境变量覆盖),然后启动捆绑的服务器。这样,您的身份验证数据和数据都随您而去,而不是安装位置。
## 首次运行
服务器启动时,WhatsApp 需要验证您。服务器将二维码打印到其 **stderr**(而非 stdout — stdout 保留用于 JSON-RPC)。
```bash
npm start # 选项 A
# 或
whatsapp-mcp # 选项 B(如果全局安装)
```
您将看到类似的内容:
```
[wa-mcp] 正在启动...
[wa-mcp] 数据库就绪,位于 .../data/history.db
[wa-mcp] 二维码(用 WhatsApp 扫描):
[此处显示二维码]
```

在手机上打开 WhatsApp → **设置 → 已连接设备 → 连接设备**,然后扫描二维码。会话被保存并在后续运行中重用 — 无需再次扫描,除非您注销。
当全局安装时,会话存储在 `~/.whatsapp-mcp/auth/` 中。当从源代码克隆运行时,会话存储在 `<project>/auth/` 中。可以通过 `WHATSAPP_MCP_HOME` 环境变量覆盖两者。
## 连接到 Claude
### Claude Code
```bash
# 源代码克隆
claude mcp add whatsapp-mcp -- node /path/to/whatsapp-mcp-server/bin/cli.mjs
# 全局安装
claude mcp add whatsapp-mcp -- whatsapp-mcp
```


### Claude Desktop
将以下内容添加到您的 Claude Desktop 配置文件中:
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"whatsapp": {
"command": "node",
"args": ["/path/to/whatsapp-mcp-server/bin/cli.mjs"]
}
}
}
```
重启 Claude Desktop。您应该在工具面板(左下角的锤子图标)中看到“whatsapp”。
## 使用示例
连接后,Claude 可以自然地使用这些工具。一些示例:
- “列出我的最近 WhatsApp 聊天记录”
- “显示我与 Ali 的最后 20 条消息”
- “在我的消息中搜索‘pizza’”
- “给 Ali 发送消息:8 点吃午饭?"

工具的完整 JSON-Schema 输入定义对 Claude 来说是自动可见的。有关架构,请参见 `src/index.ts`。
## 消息存储方式
- 传入消息(`messages.upsert` 事件)被持久化到 `messages` 中,父 `chats` 行会被更新 `last_message_at` 和一个简短的 `last_message_preview`。
- 聊天元数据更改(`chats.update` — 名称、静音、存档)会更新 `chats` 行。
- 初始同步(`chats.upsert`)会初始化 `chats` 表。
- 发出消息也会被持久化,以便 `read_messages` 返回已发送和已接收的消息。
- 通过 SQLite 触发器保持 `messages.text` 上的 FTS5 同步。
## 故障排除
### `无法找到模块 '...dist/db/schema.sql'`
您忘记复制 SQL 资产了。运行 `npm run build`(而不仅仅是 `tsc`)。
### 二维码不显示
确保您正在查看 **stderr** 输出,而不是 stdout。stdout 是 JSON-RPC 流。如果您将两者重定向到相同的位置,QR 代码文本将损坏协议。
### `send_message` 返回“无法读取未定义的属性”
套接字实际上并未连接到 WhatsApp。这会在以下情况下发生:
- `auth/` 中的保存会话已过期(注销 + 再次登录)
- 手机在会话期间失去互联网连接
- WhatsApp Web 正在限制速率
重启服务器并在需要时重新扫描二维码。
### 首次运行错误,提示“无此文件或目录”
`auth/` 目录在首次运行时自动创建。如果您正在运行编译版本(`dist/index.js`),请确保您从项目根目录运行,而不是从 `dist/` 中运行。
## 卸载
软件包、身份验证会话和消息历史记录都是分开的。选择您要删除的内容:
```bash
# 删除全局 `whatsapp-mcp` 命令
npm uninstall -g @muhammadmustafa18/whatsapp-mcp-server
# 从 Claude Code 中删除 MCP 条目
claude mcp remove whatsapp-mcp
# 删除保存的 WhatsApp 会话(强制下次运行时的二维码扫描)
rm -rf ~/.whatsapp-mcp/auth
# 删除本地消息历史记录
rm -rf ~/.whatsapp-mcp/data
# 完全重置(以上所有 + 主目录本身)
rm -rf ~/.whatsapp-mcp
```
在 Windows PowerShell 上,请使用 `Remove-Item -Recurse -Force` 代替 `rm -rf`,使用 `$env:USERPROFILE\.whatsapp-mcp` 代替 `~/.whatsapp-mcp`。
如果您通过源代码克隆(使用 `npm link`)而不是全局 npm 安装进行安装,还请删除本地链接:
`npm unlink -g @muhammadmustafa18/whatsapp-mcp-server`.
## 开发
该项目是一次构建一个功能,每个功能对应一个提交。git 历史记录可以作为教程:
```bash
git log --oneline
```
### 项目结构
```
src/
├── index.ts # MCP 服务器入口点 + 4 个工具注册
├── db/
│ ├── index.ts # initDb
│ ├── queries.ts # listChats, readMessages, searchMessages
│ └── schema.sql # SQLite 架构(chats, messages, FTS5 + 触发器)
└── wa/
├── auth.ts # loadAuthState
├── socket.ts # connectToWhatsApp
├── persist.ts # persistMessage, persistChat, attachPersistence
└── send.ts # sendMessage
```
### 构建产物
```
dist/ # 编译的 JS + 复制的 schema.sql
data/history.db # SQLite(gitignored)
auth/ # Baileys 会话(gitignored)
```
### 设计笔记
- **语句缓存**:每个 `db.prepare` 都通过 `Symbol.for` 键缓存到数据库句柄上,该键限定为数据库的生命周期。参见 `persist.ts` 中的 `getOrPrepare`。
- **`attachPersistence` 中的 FK 竞赛**:Baileys 有时会在新建聊天时先传递 `messages.upsert` 而不是 `chats.upsert`。我们将批次包装在 `db.transaction(...)` 和 `persistChat` 中,以便 `messages.chat_jid` 的 FK 在提交时得到满足。
- **`persistChat` 中的动态 UPSERT**:按调用构建,以便 SET 子句仅影响调用者实际具有数据的字段。避免了 NOT-NULL 哨兵陷阱,该陷阱在我们第一次尝试时就出现了。
- **FTS5 内容少 + 触发器**:`messages_fts` 虚拟表通过 `messages` 上的 INSERT/UPDATE/DELETE 触发器保持同步,这样我们就无需手动更新搜索索引。
## 许可证
ISC