Skip to main content
Glama
zhuanghaixin

wechat-official-account

by zhuanghaixin
README.md
# 微信公众号 MCP Connector

通过本地 stdio MCP,将 WorkBuddy 等 MCP 客户端连接到微信公众号 API:检查连接、校验文章包、上传图片、创建和查询草稿。创建完成后由作者在公众号后台检查排版并手动发布。

## 功能

### 0.2:微信贴图

新增 `wechat_validate_tietu_bundle`(本地校验)和 `wechat_create_tietu_draft_from_bundle`(创建图片消息草稿)。原有长文章工具保留。更新后刷新 WorkBuddy MCP 或重启应用,工具列表应有 6 项。

专家追加指令见 [EXPERT-TIETU.md](./EXPERT-TIETU.md),格式样例见 [examples/tietu-demo/tietu-metadata.json](./examples/tietu-demo/tietu-metadata.json)。示例图片是测试占位图,ready_for_draft=false,默认禁止上传。

```bash
npm run validate:tietu
node validate-tietu.mjs /absolute/path/to/wechat-tietu-YYYY-MM-DD
```

准备好自己的图片和内容后,在 WorkBuddy 中先说:

> 调用 wechat_validate_tietu_bundle,bundle_path 为贴图包绝对路径,检查文案、图片和顺序。

需要上传时再说:

> 调用 wechat_create_tietu_draft_from_bundle,将这个贴图包创建为微信贴图草稿,返回 media_id 和核验结果,不正式发布。

贴图包读取 tietu-metadata.json:format 必须为 wechat_tietu,title 为 1–20 字;content 为纯文本,tags 最多 5 项,最终含标签文本最多 1000 字;images 为有序的 1–20 个本地相对路径,images_generated 必须为 true。ready_for_draft=false 可以校验,不能上传。这些长度是本版本的保守约束,不代表已核实微信所有端的最新上限。

贴图不需要 article.html 或独立封面。图片逐张上传为永久素材,请求中使用 article_type=newspic 与 image_info.image_list[].image_media_id;去重哈希包含类型及图片顺序。读回时核对类型、标题、文本和图片 ID 顺序;微信若规范化文本导致不一致,会返回 verified=false 供人工核对。

接口依据:[公开图片消息实现](https://github.com/JimLiu/baoyu-skills/blob/main/skills/baoyu-post-to-wechat/scripts/wechat-api.ts)以及微信文档索引。官方新增草稿文档本次无法直接抓取。贴图分支已通过模拟接口和本地 MCP 测试,**尚未进行真实贴图写入验收**;实际权限、字段兼容与视觉效果以微信返回及后台预览为准。

| 工具 | 功能 | 是否写入微信 |
| --- | --- | --- |
| `wechat_check_access` | 获取凭证并检查连接,不返回密钥或 token | 获取凭证 |
| `wechat_validate_article_bundle` | 校验文章包、预处理图片、生成内容哈希 | 否 |
| `wechat_create_draft_from_bundle` | 上传正文图和封面、创建草稿、读回核验标题 | 是 |
| `wechat_get_draft` | 按 `media_id` 读取草稿 | 否 |
| `wechat_validate_tietu_bundle` | 校验贴图文案和有序图片 | 否 |
| `wechat_create_tietu_draft_from_bundle` | 创建 newspic 贴图草稿并核验 | 是 |

不提供正式发布、群发、删除素材、删除草稿或覆盖已有草稿的工具。

## 从 0.1 升级到 0.2

在已有仓库目录执行:

```bash
git pull --ff-only
npm ci
npm test
npm run validate:tietu
```

保留本地 `.env` 与 `.state/`。刷新或重启 WorkBuddy,确认显示 6 个工具,然后把 [专家追加指令](./EXPERT-TIETU.md) 合并到已有专家 SOP 中。无需重新配置 AppSecret 或覆盖现有 MCP 配置。

0.2 新增贴图校验、创建及读回核验,长文章流程继续可用。16 项本地测试已通过;贴图真实写入及后台视觉效果仍需使用实际发布包验收。

## 准备条件

- Node.js 20.17 或更高版本(建议使用仍受支持的 LTS 版本)和 npm。
- 支持本地 stdio MCP 的客户端,例如 WorkBuddy。
- 微信公众号 AppID、AppSecret,及当前网络出口 IP 的 API 白名单。
- 对应公众号具有素材上传及草稿接口权限。Token 获取成功并不代表拥有全部接口权限。

密钥重置和管理员验证由账号管理员在微信开发者平台完成。不要将密钥发到聊天、Issue 或 Pull Request。

## 安装

```bash
git clone https://github.com/zhuanghaixin/wechat-official-mcp.git
cd wechat-official-mcp
npm ci
cp .env.example .env
chmod 600 .env
```

用本地编辑器填写 `.env`:

```dotenv
WECHAT_APP_ID=your_app_id
WECHAT_APP_SECRET=your_app_secret
```

`.env` 根据入口文件所在目录加载,不依赖客户端的工作目录。`.env.example` 只有占位符,不要将实际凭证填入示例文件。

运行连接检查:

```bash
npm run check
```

成功时会显示 `wechat_check_access` 和 `success: true`,并返回凭证剩余有效秒数。

## 接入 WorkBuddy

自动配置(会备份并保留已有 MCP 项目):

```bash
node configure-workbuddy.mjs
```

脚本写入 `~/.workbuddy/mcp.json`,自动使用当前 Node 和入口文件的绝对路径;若同名连接器已存在则停止,避免覆盖。之后刷新 MCP 或重启 WorkBuddy。

也可以手动合并以下配置。先运行 `command -v node` 获取 Node 路径,将示例路径替换为真实绝对路径:

```json
{
  "mcpServers": {
    "wechat-official-account": {
      "type": "stdio",
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/wechat-official-mcp/index.mjs"]
    }
  }
}
```

不要直接覆盖其他连接器。更新 Node 或移动项目后,也要更新启动路径。

在 WorkBuddy 对话中输入:

> 调用 wechat_check_access,检查微信公众号 API 连接,并展示实际工具返回结果。

## 文章包格式

文章目录必须位于**本项目的父目录之内**,包括本项目内的子目录。相对路径以项目父目录为基准;建议传绝对路径。真实路径检查也会限制符号链接,目录外文件不能被上传。

```text
workspace/
├── wechat-official-mcp/
└── my-article/
    ├── metadata.json
    ├── article.html
    ├── cover.jpg
    └── images/
        └── 01.jpg
```

`metadata.json`:

```json
{
  "title": "文章标题",
  "author": "作者",
  "summary": "文章摘要",
  "cover": { "file": "cover.jpg" }
}
```

`article.html` 使用本地图片相对路径:

```html
<section style="font-size:16px;line-height:1.8;">
  <h2>文章小标题</h2>
  <p>正文内容。</p>
  <img src="./images/01.jpg" alt="配图说明" />
</section>
```

字段与处理规则:

- 标题读取 `title`,兼容 `recommended_title`,最多 64 个字符;作者最多 8 个字符。
- 摘要读取 `digest`,兼容 `summary`,超过 120 个字符时截断并提示。
- 封面读取 `cover.file`,缺省为 `cover.png`。
- 正文图片从 HTML 的 `img src` 读取,不依赖 `inline_images` 字段;不下载远程图片。
- 图片在内存中转为 JPEG 并压缩至 1MB 以下,不改动源文件;透明背景变为白色。
- 移除脚本、外链样式和部分不适用的 HTML 属性。建议使用内联样式;此处理不是通用 HTML 安全净化器,应仅处理可信文章包。
- 正文过长会逐步精简装饰样式并返回警告;仍超过长度限制则停止。微信自身也可能调整排版,需要后台预览。

## 使用示例

先运行仓库自带的演示包校验(不联网、不上传):

```bash
node validate.mjs
```

校验自己的文章:

```bash
node validate.mjs /absolute/path/to/my-article
```

在 WorkBuddy 先校验:

> 调用 wechat_validate_article_bundle,bundle_path 为 /absolute/path/to/my-article,展示校验警告。

确认文章内容后创建草稿:

> 将 /absolute/path/to/my-article 上传到我的公众号草稿箱,调用 wechat_create_draft_from_bundle,返回 media_id 与核验结果,不正式发布。

然后查询:

> 调用 wechat_get_draft,media_id 为刚刚返回的草稿 ID。

创建工具会先查询草稿数量确认查询接口可用,再上传正文图片和永久封面素材、调用草稿创建接口,并读回核对标题。素材和创建权限最终以实际接口响应为准。

## 重试与状态记录

`.state/` 保存本地内容哈希、草稿 ID 和创建状态,按账号隔离,默认不提交到 Git。

- 相同文章内容再次调用会复用已有草稿 ID。
- 创建请求发出后若结果未知,会阻止自动重试;先到微信后台核对,避免重复生成。
- 进程异常退出可能留下 `.lock` 文件。确认没有运行中的请求且已核对远端结果后,再人工处理状态。
- 图片上传中断可能留下素材,不会自动删除。
- 修改文章会生成新哈希和新草稿,不会更新旧草稿。
- 不要把 `.state` 当作临时缓存随意清除,否则会失去去重记录。

## 故障排查

| 现象 | 排查方法 |
| --- | --- |
| `40164` | 把错误结果中的 `request_ip` 加入微信 API 白名单;换网络后可能需要更新 |
| `40125` | 核对本地 AppSecret |
| `40013` | 核对公众号 AppID |
| `48001` | 检查该公众号是否具有对应接口权限 |
| 网络超时 | 检查 Node 的网络出口;它可能与浏览器代理出口不同 |
| MCP 无法启动 | 检查 Node/入口文件绝对路径,并执行 `npm ci` |
| 工具列表仍只有旧工具 | 刷新 MCP 或重启客户端 |
| 文件路径超出允许目录 | 将文章移入项目父目录范围,并检查符号链接 |
| 草稿已创建但核验失败 | 按返回的 media_id 查询,不要立即再次创建 |

## 开发与测试

```bash
npm test
```

测试使用自带演示文章和模拟微信响应,不依赖个人文章或真实密钥,不创建远程草稿。覆盖凭证检查、错误脱敏、路径限制、multipart 上传、草稿创建流程、内容去重及结果未知时的重试保护。

```text
index.mjs               MCP 工具注册
access.mjs              连接检查
bundle.mjs              文章校验与图片预处理
wechat-api.mjs          微信 API 调用
drafts.mjs             长文章/贴图草稿流程与本地状态
tietu.mjs              贴图格式校验和图片预处理
validate-tietu.mjs     贴图 MCP 校验客户端
EXPERT-TIETU.md        WorkBuddy 专家追加指令
check.mjs               真实连接检查客户端
validate.mjs            本地文章校验客户端
configure-workbuddy.mjs  WorkBuddy 配置助手
examples/demo/          无私人内容的演示文章包
```

## 凭证与仓库内容

仓库仅包含源码、锁文件、测试、演示包与文档。不要提交 `.env`、`.state/`、本地 MCP 配置、真实文章素材、日志或配置备份;也不要使用 `git add -f` 绕过忽略规则。

## 参考

- [MCP TypeScript SDK](https://ts.sdk.modelcontextprotocol.io/server)
- [WorkBuddy 连接器](https://open.workbuddy.cn/docs/connector)
- [微信开发者平台](https://developers.weixin.qq.com/)

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation4/5

The four tools are distinct: checking credentials, validating content, creating drafts, and reading drafts. The only potential confusion is between validation and creation, but descriptions clarify that one is local/no upload and the other uploads/creates.

Naming Consistency3/5

All tools use the prefix 'wechat_' followed by a verb-noun structure (check_access, validate_article_bundle, create_draft_from_bundle, get_draft). However, the structure is not perfectly uniform: 'create_draft_from_bundle' is more verbose than 'get_draft', and the patterns vary slightly in noun phrases.

Tool Count4/5

With 4 tools, the server is lean and focused on the core workflow of creating drafts from article bundles. The count feels slightly thin for a fuller WeChat integration (e.g., missing publish or media management), but it's appropriate for the stated purpose.

Completeness3/5

The tools cover validation, creation, and retrieval of drafts, which is a reasonable lifecycle. However, obvious gaps include the ability to update/delete drafts or formal publish, and there's no tool for managing the article bundle beyond validation/creation.

Maintenance

ActivityMaintained
ResponsivenessNo issues