WhatsApp MCP流

围绕以下内容构建的WhatsApp MCP服务器 可流式传输的HTTP 运输,使用 百利甜酒 用于WhatsApp连接,具有web管理UI和双向媒体流(上传+下载)。
要点:
- 传输:可流式HTTP
/mcp - 发动机:Baileys
- 管理UI:二维码、状态、注销、运行时设置
- 媒体:上传端点+
/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/
运行时设置
可以在管理UI中编辑设置,并将其持久化到 SETTINGS_PATH (默认为 MEDIA_DIR/settings.json).
管理用户界面
Admin UI *具有运行时设置、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:}多部分(建议用于大文件):
curl -X POST http://localhost:3003/api/upload-multipart \
-F "file=@/path/to/file.jpg"两人都回来了 url 以及(如果已配置) publicUrl.
上传身份验证(可选)
如果 require_upload_token=true,使用以下任一方式提供令牌:
x-upload-token:Authorization: Bearer
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:mcpMCP工具
认证
| 工具 | 说明 |
|---|---|
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 | 发送媒体(图像/视频/文档/音频)。支持可选 idempotency_key. |
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 | /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 ->原始消息)。 |
MCP_HTTP_ENABLE_JSON_RESPONSE | 1 | 默认情况下,对可流式HTTP POST请求使用直接JSON响应。设置为 0 强制使用较旧的SSE风格POST响应处理。 |
其他运输诊断:
/mcpPOST请求现在将请求生命周期事件记录在logs/mcp-whatsapp.log- 这包括请求输入、传输调度、传输调度和传输调度,
transport.handleRequest完成和HTTPfinish/close - 使用这些日志来确定响应离开之前是否发生了延迟
whatsapp-mcp-stream或者之后在网关/客户端
出口
通过以下方式导出聊天(JSON+可选下载媒体):
GET /api/export/chat/:jid?include_media=true
如果 include_media=true,ZIP包括已通过下载的文件 download_media。它不会从WhatsApp获取丢失的媒体。
