使用说明
WhatsApp MCP流
围绕以下内容构建的WhatsApp MCP服务器 流式HTTP 运输,使用 百利甜酒 用于WhatsApp连接,具有web管理UI和双向媒体流(上传+下载)。
要点:
- 传输:可流式HTTP
/mcp - 发动机:Baileys
- 管理员界面:二维码、状态、注销、运行时设置、聊天历史查看器
- 媒体:上传端点+
/media主机+MCP下载工具
快速入门(Docker)
# build and run
docker compose build
docker compose up -d
服务器将在以下位置可用:
- 管理用户界面:
http://localhost:3003/admin - MCP端点:
http://localhost:3003/mcp - 媒体文件:
http://localhost:3003/media/<filename>
主机上的DNS --iptables=false
在某些NAS/强化主机上(例如Synology dockerd --iptables=false)Docker的嵌入式DNS代理(127.0.0.11)没有iptables DNAT规则,并拒绝容器内的连接。
修复:复制 resolv.conf.example 到 resolv.conf 并添加音量覆盖:
cp resolv.conf.example resolv.conf
然后添加到本地 docker-compose.override.yml (未承诺):
services:
mcp-whatsapp:
volumes:
- ./resolv.conf:/etc/resolv.conf:ro
docker compose up 自动拾取覆盖。
运行时设置
可以在管理UI中编辑设置,并将其持久化到 SETTINGS_PATH (默认为 MEDIA_DIR/settings.json).
管理用户界面
具有运行时设置、QR链接、聊天历史查看器、导出和状态的管理控制台。
支持的设置:
media_public_base_urlupload_max_mbupload_enabledmax_files_per_uploadrequire_upload_tokenupload_tokenauto_download_mediaauto_download_max_mb
认证
尚未实现内置身份验证。在生产环境中,使用强制认证的网关。这个项目进展顺利 authmcp-gateway:
https://github.com/loglux/authmcp-gateway
媒体上传API
Base64 JSON格式:
curl -X POST http://localhost:3003/api/upload \
-H "Content-Type: application/json" \
-d {filename:photo.jpg,mime_type:image/jpeg,data:<base64>}
多部分(建议用于大文件):
curl -X POST http://localhost:3003/api/upload-multipart \
-F "file=@/path/to/file.jpg"
两人都回来了 url 以及(如果已配置) publicUrl.
通过send_media发送本地文件
这 ./files/ 项目根目录中的目录被绑定挂载到容器中 /app/files.将任何文件放到那里并立即引用它——不需要重新启动容器:
# On host:
cp report.pdf /path/to/whatsapp-mcp-stream/files/
# In send_media:
media_path: /app/files/report.pdf
对于URL源,请传递 media_url 直接到 send_media 或 stage_media --服务器下载文件本身而不使用base64。
上传身份验证(可选)
如果 require_upload_token=true,使用以下任一方式提供令牌:
x-upload-token: <token>Authorization: Bearer <token>
MCP传输
服务器在以下位置公开Streamable HTTP /mcp.
典型流程:
POST /mcp使用JSON-RPCinitialize- 使用返回的
mcp-session-id后续请求的标头 POST /mcp用于工具调用
注意:客户必须发送 Accept: application/json, text/event-stream 上 initialize.
冒烟测试
MCP工具的快速回归烟雾:
npm run smoke:mcp
可选自定义目标:
MCP_BASE_URL=http://localhost:3003 npm run smoke:mcp
MCP工具
认证
| 工具 | 说明 |
|---|---|
get_qr_code |
获取最新的WhatsApp二维码作为图像进行身份验证。 |
check_auth_status |
检查WhatsApp客户端是否已通过身份验证并准备就绪。 |
logout |
退出WhatsApp并清除当前会话。 |
联系人
| 工具 | 说明 |
|---|---|
search_contacts |
按姓名或电话号码搜索联系人。 |
resolve_contact |
按姓名或电话号码解析联系人(最佳匹配)。 |
get_contact_by_id |
通过JID获取联系方式。 |
get_profile_pic |
获取JID的个人资料图片URL。 |
get_group_info |
按组JID获取组元数据和参与者。 |
聊天
| 工具 | 说明 |
|---|---|
list_chats |
列出带有元数据和可选最后一条消息的聊天记录。 |
get_chat_by_id |
通过JID获取聊天元数据。 |
list_groups |
仅列出群聊。 |
get_direct_chat_by_contact_number |
通过电话号码解决直接聊天JID。 |
get_chat_by_contact |
按姓名或电话号码解析联系人,并返回聊天元数据。 |
analyze_group_overlaps |
查找出现在多个组中的成员。 |
find_members_without_direct_chat |
查找没有直接聊天的群成员。 |
find_members_not_in_contacts |
查找联系人中缺少的组成员。 |
run_group_audit |
将组合组审核作为一项常规操作运行。 |
消息
| 工具 | 说明 |
|---|---|
list_messages |
从特定聊天中获取消息。 |
search_messages |
按文本搜索消息(可选范围为聊天)。 |
get_message_by_id |
按ID获取特定消息(jid:id). |
get_message_context |
获取特定消息的最新消息。 |
get_last_interaction |
获取JID的最新消息。 |
send_message |
向个人或组发送短信。支持可选 idempotency_key. |
媒体
| 工具 | 说明 |
|---|---|
send_media |
发送媒体(图像/视频/文档/音频)。接受 media_path, media_url,或 media_content (base64)。支持可选 idempotency_key. |
stage_media |
将文件保存到服务器的媒体目录并返回其本地路径。使用返回的 saved_path 在 send_media (media_path)--当源是URL时避免base64(服务器直接下载),或者允许将同一文件发送给多个收件人而无需重新上传。 |
download_media |
从邮件中下载媒体。 |
实用
| 工具 | 说明 |
|---|---|
ping |
健康检查工具。 |
恢复说明
此服务包含针对Baileys/WhatsApp会话状态损坏的有意恢复解决方法。
为什么存在:
- 在生产环境中,我们观察到容器仍然存活,MCP仍然应答,但WhatsApp会话功能中断。
- 最常见的指标是Baileys的错误,如
failed to find key ... to decode mutation和failed to sync state from version. - 在这种状态下,手动重启容器通常会恢复服务。
当前行为:
- 根据应用程序状态损坏信号,该服务首先尝试通过以下方式进行软恢复
forceResync(). - 如果同一类故障在一个时间窗口内重复出现,则升级为内部WhatsApp客户端重启。
- 在断开连接时,例如
Connection Terminated,该服务会安排一个断开连接监视器,如果套接字没有返回,则升级为内部重启open迟早 - 重新连接生命周期防止嵌套锁死锁,因此断开连接恢复可以在不需要手动重新启动容器的情况下完成。
- 最近的生产观察显示插座反复断开(
428 Connection Terminated,503 Stream Errored)正在自动恢复到open. - 一个专用
/healthz端点报告503只有当服务真正卡在允许的恢复窗口之外时。 - Docker健康检查使用
/healthz,因此只有在进程内恢复有机会工作后,容器才会重新启动。
这些恢复机制减少了运营商的干预,提高了对常见WhatsApp/Baileys会话故障的恢复能力。
许可证
麻省理工学院
坚持
聊天和消息被持久化到会话卷中存储的本地SQLite数据库中。
环境变量:
| 变量 | 默认值 | 描述 |
|---|---|---|
DB_PATH |
<SESSION_DIR>/store.sqlite |
用于聊天/消息持久化的SQLite数据库路径。 |
WA_EVENT_LOG |
0 |
启用详细的WhatsApp事件日志。 |
WA_EVENT_STREAM |
0 |
将原始Baileys事件流写入文件进行深度调试。 |
WA_EVENT_STREAM_PATH |
/app/logs/wa-events.log |
事件流日志的文件路径。 |
WA_RESYNC_RECONNECT |
1 |
强制重新同步后启用重新连接安全网。 |
WA_RESYNC_RECONNECT_DELAY_MS |
15000 |
强制重新同步后重新连接前的延迟(ms)。 |
WA_SYNC_RECOVERY_COOLDOWN_MS |
300000 |
自动应用程序状态恢复之间的最小延迟。 |
WA_SYNC_RECOVERY_WINDOW_MS |
900000 |
用于计算重复应用程序状态损坏失败的时间窗口。 |
WA_SYNC_SOFT_RECOVERY_LIMIT |
2 |
升级到内部重启之前的软恢复次数。 |
WA_READINESS_GRACE_MS |
180000 |
恢复/断开连接前的宽限期 /healthz 变得不健康。 |
WA_DISCONNECT_RECOVERY_DELAY_MS |
30000 |
插座关闭后等待多长时间,断开连接监视器才会强制重新连接/重新启动。 |
WA_DISCONNECT_RECOVERY_RESTART_CODES |
428 |
逗号分隔的断开状态代码应直接升级到内部重启监视器。 |
WA_SEND_DEDUP_WINDOW_MS |
45000 |
抑制完全重复 send_message 在此窗口内向同一JID发出请求。 |
WA_IDEMPOTENCY_TTL_MS |
86400000 |
完成多长时间 send_message 幂等性记录保留在SQLite中,以便安全重试。 |
WA_MESSAGE_INDEX_MAX |
20000 |
消息索引的最大内存条目数(jid:id ->原始消息)。 |
WA_MESSAGE_KEY_INDEX_MAX |
20000 |
消息键索引的最大内存条目数(id ->原始消息)。 |
WA_INITIALIZE_TIMEOUT_MS |
120000 |
让WhatsApp客户端在截止日期前进行初始化;着手 0 禁用。超时,因此恢复可以重试而不是挂起。 |
WA_AUTO_DOWNLOAD_CONCURRENCY |
3 |
最大并行自动下载。自动下载通过进程内有界队列运行,因此入站媒体的突发不会使I/O饱和 |
WA_AUTO_DOWNLOAD_QUEUE_MAX |
200 |
排队的自动下载作业最多。多余的FIFO(最旧的先)将被丢弃,并显示警告日志;最近的消息保持优先级。 |
MCP_HTTP_ENABLE_JSON_RESPONSE |
1 |
默认情况下,对可流式HTTP POST请求使用直接JSON响应。设置为 0 强制使用较旧的SSE风格POST响应处理。 |
其他运输诊断:
/mcpPOST请求现在将请求生命周期事件记录在logs/mcp-whatsapp.log- 这包括请求输入、传输调度、传输调度和传输调度,
transport.handleRequest完成和HTTPfinish/close - 使用这些日志来确定响应离开之前是否发生了延迟
whatsapp-mcp-stream或者之后在网关/客户端
聊天历史记录API
通过以下方式浏览存储的聊天记录和消息:
GET /api/chats?limit=50&offset=0&q=<search> --分页聊天列表,可选择按姓名过滤。
GET /api/chats/:jid/messages?limit=50&offset=0 --聊天消息分页(最新消息优先)。
这两个端点都由 聊天 管理UI中的选项卡。
出口
通过以下方式导出聊天(JSON+可选下载媒体):
GET /api/export/chat/:jid?include_media=true
如果 include_media=true,ZIP包括已通过下载的文件 download_media。它不会从WhatsApp获取丢失的媒体。
