跨平台、本地优先的微信 MCP 能力提供者(macOS / Windows)。
独立运行,无需安装 Local Bridge;目前也可由用户通过 Local Bridge 手动注册为本机 MCP Provider 并调用。微信聊天数据、实际发送和 UI 操作仍由本项目负责,Bridge 不内置微信业务逻辑。
| 功能 | 当前状态 |
|---|---|
| MCP stdio 10 个工具(含用户主动保存/移除的本地片段、微信合并转发 ZIP 原生导入) | ✅ 已实现 |
| 本地 SQLite / FTS5 文本索引 | ✅ 已实现;仅检索已读/导入的数据 |
| 发送任务记账 / 幂等键 / 单机 GUI 锁 | ✅ 已实现;RPA 调用在隔离子进程中,不污染 MCP stdio;不声称成功送达 |
| Windows 4.x GUI 适配 | 🔶 对接 pyweixin;需实机验证 |
| macOS GUI 适配 | ⏸ 登录保护暂停;实时读写在适配器入口阻断,已有索引可用 |
| 微信原生 SQLCipher 数据库解密与增量导入 | ❌ 尚未实现,放在独立后续任务 |
| Local Bridge 本机手动 MCP 接入 | ✅ 已提供,见 接入步骤;未通过真实微信 GUI 验收 |
| Local Bridge 自动注册 / 浏览器直接读写微信 | ❌ 尚未实现;MCP Server 可单独启动 |
重要:仓库提供可运行的软件骨架、SQLite 和 MCP 实现,但还没有完成真实微信账号的端到端发送验收。 微信 4.x 的可访问性树可随账号/版本变化,不能假设任意机器可用。
在 Python 3.10+ 的 Windows 或 macOS 上运行:
git clone https://github.com/eaopen/wechat-provider.git
cd wechat-provider
python -m venv .venv
# 激活 .venv 后
pip install -e .Windows 额外安装 pyweixin(上游包 pywechat127):
pip install -e ".[windows]"macOS 的旧 AX 后端依赖 wxauto-mac,但当前因登录保护暂停,安装依赖不会解除保护;无需为了索引读取反复调整权限:
pip install -e ".[macos]"以上两种后端均为可选运行时依赖,不复制/魔改上游项目。它们可能在部分微信 4.x 版本上失效,届时优先修复对应小型适配器,而非重写整个 Provider。
个人本机使用不需要 Apple Developer ID、Apple Development 或自签证书:
- 默认路径(无 FDA、无 Helper、无证书):本机索引、用户已授权的规范化 JSONL 导出、微信合并转发 ZIP 和手动片段,直接通过
wechat-provider serve(MCP stdio)或daemon+proxy使用。终端权限成功不代表桌面进程权限相同;缺权限时返回固定错误码,不会自动解密或复制微信数据库。 - 可选直读已授权微信数据库:在最终安装目录构建一次固定 ad-hoc Helper(
codesign --force --sign -,不是证书)。runtime 配置外置,Python/SDK/Reader 更新只改外部配置,不重编 Helper;Bridge 只经同用户 socket 代理访问,不需要 FDA。
# 固定安装一次(默认 ad-hoc,无需证书);不要放进 Bridge 开发构建目录
python3 macos/build_provider.py \
--runtime /absolute/private/helper-runtime.json \
--output "$HOME/Applications"
# 仅更新 Python/SDK/Reader 配置:只重写外部 runtime,不重编/重签 Helper
python3 macos/build_provider.py --configure-only \
--runtime /absolute/private/helper-runtime.json \
--output "$HOME/Applications"已安装 App 默认拒绝覆盖,必须显式 --force;脚本会警告代码身份变化、TCC 可能需要重新授权,且不承诺保留 FDA。由旧版脚本构建、runtime 仍内嵌在 bundle 的 App 需先 --force 重建一次,之后才能用 --configure-only 更新配置。ad-hoc 模式生成的 LaunchAgent 不含 AssociatedBundleIdentifiers(无 Team ID),不能据此假定 launchd/TCC 归属已正确。真实 TCC 归属(C)、Bridge/Python 更新后权限保持(D)、Helper 更新后是否需重授(E)均未验收,需要用户单独批准;不要重置 TCC、关闭 SIP、重签微信或重新登录。详见 macOS 独立 Provider。
wechat-provider status
wechat-provider serveserve 使用 MCP stdio 传输,适用于 Codex、Claude Code 等支持外部本地 MCP 的客户端。请把 MCP 客户端配置为调用当前虚拟环境中的 wechat-provider serve,不是 HTTP 接口。没有后台驻留/开放监听端口的要求。
提供十个工具:
wechat_statuswechat_list_chats(limit, source="desktop_ui")wechat_get_messages(chat_id, limit, source="desktop_ui")wechat_search(query, chat_id?, limit)wechat_send_message(chat_id, text, idempotency_key?)wechat_get_send_status(task_id)- wechat_save_excerpt(chat_title, text):仅显式点击后把用户复制的文字写入 Provider 自有 SQLite 索引
- wechat_forget_saved_excerpts(chat_title):只移除此名称下手动保存的片段,不删除微信数据或其他来源导入记录
wechat_native_export_preview(grant_token, timezone_offset_minutes?, offset?, limit?):校验一次性授权文件后,有界预览用户选择的微信合并转发 ZIP(不持久化聊天内容)wechat_native_export_save(grant_token, expected_fingerprint, timezone_offset_minutes?):用户显式点击后幂等写入本机索引(source=native_share);指纹不符则不导入;显式时区才保留带偏移时间戳
- 当前的
chat_id对应界面显示名称,不是微信不可变用户 ID。名称重复、模糊或群聊标题变化时可能选错对象;发给重要对象前要在界面核对。MVP 优先从文件传输助手/自己控制的测试对话进行人工验收。 - RPA 的返回
submitted仅表示底层 UI 自动化方法无异常返回,不表示验证了正确接收方或对方已收到。异常但可能已经点击发送的任务标为uncertain,不会盲目重发。 - 消息读取得自桌面 UI 可见范围,不是全量历史。获取 UI 消息后会索引文字;搜索只覆盖已读/导入的内容,结果带
complete=false。 - 当前不做自动群发、自动回复、批量好友操作、朋友圈及密钥内存扫描。未经明确授权不要把聊天数据发送给远程模型。
- 运行微信 UI RPA 需要本机登录、可交互图形桌面,以及当前微信版本的无障碍可访问性/屏幕状态。
如果有通过其他已获授权的工具导出的规范化 JSONL,可以只导入自己需要的记录:
wechat-provider import-jsonl /path/to/my_messages.jsonl每行示例(仅虚构数据;source_id 应尽量来自稳定原始消息 ID):
{"chat_id":"测试群","source_id":"example-001","text":"下周一起验收","sender":"甲","sent_at":"2026-10-27T10:00:00+08:00"}本项目只写自己的 SQLite,不写微信自有数据库。默认位置:macOS 在用户 ~/Library/Application Support/wechat-provider/wechat.db;Windows 在 %LOCALAPPDATA%/wechat-provider/wechat.db。可用 WECHAT_PROVIDER_DB 覆盖;WECHAT_PROVIDER_ACCOUNT 用于本机指定账号隔离(默认 default)。
- Windows:直接调用上游维护的
pyweixin.Messages会话列表、历史读取、发送方法。 - Mac:直接调用
wxauto-mac.WeChat的GetSessionList、GetChatHistory、SendToFriend。另参考 wechat-macos-automation 的发送校验经验;不把设备专属的硬编码坐标当默认逻辑。 - 数据库读取的下一阶段参考 robbin/wechat-exporter、Wechat-MCP 及 Windows 的 wechat-local-analytics;先验证不同微信版本的兼容性,再接入 只读离线快照,不直接嵌入未经确认的解密脚本。
- 不使用 OpenRPA 作为默认引擎;复杂 Windows 通用业务工作流有实际需求时再评估独立适配。
见 架构和完成条件、2026-10-28 微信 MCP 与发送方案横向调研、Local Bridge 当前实际接入命令与边界 及 开发要求。
PYTHONPATH=src python -m unittest discover -s tests -v
python -m compileall -q srcCI 只对 SQLite / MCP 无关核心 / 模拟 RPA 做跨平台验证,不会声称真实微信测试通过。
License: Apache-2.0. 第三方依赖遵循各自许可,不直接复制其源码。
wechat_status 返回 read_contract_version=1,区分可尝试读取与实机验收。source="local_index" 只读 Provider 自有 SQLite,不初始化 GUI 后端;source="desktop_ui" 尝试界面读取,失败时的索引降级仍标为 local_index / cached_fallback=true。所有结果均不完整,显示名不是稳定身份。
详见 读取验收 和 Mac 候选源码评审。
主读取方向是复用成熟的 SQLite / SQLCipher / WCDB 查询实现;GUI 负责操作,Vision OCR 仅作辅助。当前可执行入口是 wechat-provider import-jsonl <已授权规范化导出>,该导入入口不包含取钥、实时数据库读取或自动转换 GreenBubbles JSON。
- 每批最多 8 MiB / 10000 条;全部校验后单事务提交。格式/时间错误或 ID 内容冲突会整批回滚,错误不回显正文。
- 必需字段缺失的记录保持兼容地计入
skipped;重复计入duplicates;返回read/imported/skipped/duplicates,不能把退出成功理解为每条都已导入。 source_id应是同一来源下稳定且有命名空间的消息 ID;同一账号/会话/ID 内容不一致会报冲突,不静默覆盖。增量批次可重放,不需清空索引。sent_at若提供必须是带时区 ISO 时间,统一 UTC;最近片段按消息时间取,缺时间以入库时间兜底。旧记录保留原值,同一时刻的等价时区表示可重复导入。- 仍返回
source=local_index、live_read=false、complete=false。当前会话契约仍按显示名,不冒充已有稳定联系人 ID 支持。
本地验证:22 项 unittest 通过;真实 CLI 导入/重放到真实 MCP 读取通过(隔离虚构数据)。没有读取私人历史、初始化密钥或操作微信。详见 结构化导入验证。
已提供独立只读适配器:固定已安装 CLI + 用户明确绑定的 Profile/来源身份,通过原六工具的 source="structured_db" 读取会话、分页消息和搜索;不获取密钥、不初始化 GUI、不自动复制历史,不改变原有发送后端。structured_db_read 只表示已配置且可执行,verified=false,不代表实机已验收。
配置与字段边界见 GreenBubbles Reader。Bridge #47 已支持该来源;未配置时继续人工粘贴和已有索引。
已有逐数据库密钥及 Wechat-MCP SDK 时,可通过独立只读 Reader 直接分页读取当前数据库及 WAL,无需全量归档。配置、版本约束及有界搜索说明见 Wechat-MCP Reader。不执行取钥、登录或发送;与 GreenBubbles 二选一配置,共用现有 MCP 接口。
Companion 可以让用户明确给当前复制的聊天片段命名,并点击“保存本轮文字到本机”。 只保存到 WeChat Provider 自有本机索引,后续 local_index 可以选择这个标签并重新读取; 不是微信完整历史、真实联系人 ID、微信实时同步或自动持久化。可以按相同标签显式 移除所有手动保存片段,绝不会删除其他来源导入的记录。原始微信账号和数据库不参与操作。
wechat_status.capabilities.manual_excerpt_save=true 表示支持这个明确的写入动作; 创建、读取、删除均须前台用户动作或用户自行授权的 MCP 客户端调用。 工具正文是本地 MCP JSON 参数,不应放入命令行或诊断日志。 详情见 docs/COMPANION_LOCAL_EXCERPTS.md。
用户在 Companion 里明确选择一个微信「合并转发」导出的 .zip 后,Companion 会向 Provider 数据目录
写入一次性授权文件,再调用 wechat_native_export_preview 得到有界预览;用户勾选范围后交给 Agent
(仍由用户触发)。只有用户再次点击保存时,才会通过 wechat_native_export_save 把整份导出幂等写入
Provider 自有 SQLite(messages.source = "native_share" + 同库 native_exports 元数据表)。
- MCP 工具从不接受文件路径或文件字节,网页/Agent 无法借此读取任意本地文件;授权文件 0600、 TTL 600 秒、使用一次即删除。
- ZIP 校验 fail closed:24 MiB / 2000 条目 / 256 MiB 解压总量 / 32 MiB 单条目 / 压缩比 200 / 路径 512 字节;拒绝路径穿越、绝对路径、符号链接、加密、不支持压缩方法、ZIP64、多分卷、重名、 控制字符与坏 CRC。原文件绝不移动/改名/删除。
- 时区不静默转换:只有显式
timezone_offset_minutes才产生带偏移的sent_at;否则只保留本地时间并告警。 - 保存同样接受可选的
timezone_offset_minutes:提供时保存的行保留带偏移的sent_at,并记录到native_exports.timezone_offset_minutes;缺省时保存的sent_at为NULL(保存调用不假设时区)。 - 重复保存同一份导出(即使时区参数不同)只报告
already_imported,不会重写已存时间戳,也不会因 身份冲突而失败。 - 附件 P0 仅为元数据(不提取、不落盘)。
- 只验证微信 macOS 合并转发 TXT 格式;合成 ZIP 不等于真实微信分享已验证,也不读取微信数据库、 登录状态或权限。
详情(限制、字段、错误码、身份规则、CLI/验收):微信合并转发 ZIP 原生导入。