从一句话到全平台草稿:用 ChatGPT、MCP 与 OAuth 搭建 Sky Publisher
今天,我把一个一直想要的工作流真正跑通了:在 ChatGPT 对话中说一句“把这次聊天整理后发布到全平台草稿”,系统便会自动整理内容、检查各平台状态,并在小红书、知乎、微博和 X 中创建草稿。
这篇文章记录完整的设计与实现过程:为什么最初选择 WordPress REST API,后来为什么改用远程 MCP;怎样设计草稿和公开发布的安全边界;OAuth 2.1 联调中遇到了什么问题;以及最终如何验证整条链路。
一、我想解决什么问题
我经常在 ChatGPT 中进行很长的讨论。其中一些内容已经接近一篇完整文章,但从“有价值的对话”到“真正发布”之间还有大量机械工作:
- 整理对话,去掉重复内容;
- 补充标题、摘要和结构;
- 转换成适合不同平台的格式;
- 分别打开 WordPress、小红书、知乎、微博和 X;
- 复制、粘贴并保存草稿;
- 记录每个平台是否成功。
真正想要的体验很简单:
把这次聊天整理成教程,发布到我的全平台草稿。
ChatGPT 负责理解内容和意图,我自己的发布系统负责可靠、安全地执行。
二、第一步:先打通 WordPress
WordPress 是最容易接入的一站,因为它有成熟的 REST API。只要完成认证,ChatGPT 就可以创建文章、编辑现有文章、设置分类,并选择保存为草稿或公开发布。
这一阶段验证了最核心的可行性:大模型不仅能生成文章,也能调用外部工具完成真实操作。随后我增加了一个名为 AI Talk 的分类,专门收录由人和 AI 对话整理出的内容。
但 WordPress 只是一个平台。小红书、知乎、微博和 X 的接口能力、草稿机制与登录方式各不相同,仅靠一组普通 REST API 很难统一处理。
三、最终架构:ChatGPT + Remote MCP + Local Worker
最终采用的架构如下:
ChatGPT
│
│ OAuth 2.1 + MCP
▼
Sky Publisher Gateway
│
│ Job Queue / Status / Idempotency
▼
Local Worker on Mac
│
├── 小红书
├── 知乎
├── 微博
├── X
└── Facebook
其中每一层职责非常明确:
- ChatGPT:理解用户意图、整理文章、选择工具和目标平台;
- Remote MCP Gateway:负责认证、校验、权限、任务创建、幂等性和状态查询;
- Local Worker:运行在我自己的 Mac 上,通过已经登录的浏览器执行平台操作;
- 平台适配器:把统一的文章结构转换成各个平台能够接受的内容。
这样做的好处是,ChatGPT 不需要直接持有各个平台的账号密码;Gateway 也不需要模拟每个平台的复杂登录。真正的浏览器会话保留在我自己的设备上。
四、七个 MCP 工具
Sky Publisher 最终提供七个工具:
list_publish_targets:读取 Worker、平台登录状态以及草稿/公开发布能力;validate_publish_job:只校验,不产生副作用;create_draft_job:创建私有草稿;create_public_job:创建可能公开发布的任务;get_publish_job:查询任务及各平台结果;retry_publish_targets:重试指定的失败平台;cancel_publish_job:取消仍可取消的任务。
这里最重要的并不是工具数量,而是把“草稿”和“公开发布”拆成了两个完全不同的接口。
五、安全设计:草稿接口不能表达公开发布
最初的接口同时支持 draft 和 publish。这会带来一个问题:即使用户只想创建草稿,ChatGPT 也会因为接口具备公开发布能力而谨慎地重复确认。
最终的解决办法不是简单地把接口标记成“低风险”,而是从结构上消除风险:
create_draft_job的请求中根本没有mode字段;- 服务端强制所有目标使用
draft; - 即使调用方尝试注入
publish,Schema 也会直接拒绝; create_public_job单独保留,并继续要求明确确认;- 生产环境还有公开发布总开关,默认关闭。
这是一条很实用的 Agent 设计原则:不要只依赖 Prompt 约束危险行为,而要让低风险工具在数据结构层面无法表达高风险操作。
六、OAuth 2.1 与权限隔离
为了让 ChatGPT 网页版能够连接私人 MCP 服务,我为 Sky Publisher 增加了 OAuth 2.1,使用 Authorization Code Flow 和 PKCE S256。
权限被拆分为:
publisher.read:查看平台、校验任务和查询状态;publisher.draft:创建草稿;publisher.publish:公开发布;publisher.retry:重试任务;publisher.cancel:取消任务。
访问令牌采用短有效期,刷新令牌轮换;服务端验证签名、签发方、Audience、Resource、过期时间和 Scope。Owner 授权口令不会写入仓库,也不会出现在日志中。
这层 OAuth 不只是“能登录”,更重要的是把 ChatGPT 能做什么限制在可审计的权限集合中。
七、任务系统的可靠性设计
浏览器自动化不是同步 HTTP 请求:平台可能加载缓慢、要求重新登录,或者出现验证码。因此发布任务必须异步执行。
Gateway 创建 Job 后,Worker 获取任务并逐个平台处理。每个目标都有独立状态,例如:
queuedrunningdraft_createdneeds_loginneeds_captchafailed
系统还加入了幂等键。相同请求即使重复调用,也会返回同一个 Job,而不是在平台中生成多份重复草稿。
在创建任务前,ChatGPT 必须先调用 list_publish_targets 和 validate_publish_job。只有当 Worker 在线、Inventory 新鲜、平台已登录,并且校验结果为 valid=true、side_effects=false 时,才创建草稿。
八、今天遇到的几个真实问题
1. OpenAPI 工具数量不完整
最初远程 OpenAPI 中的路径参数使用了部分客户端不兼容的 $ref,导致 ChatGPT 没有识别全部 Action。把路径参数内联后,工具清单才完整加载。
2. Inventory 过期
浏览器更新重启后,Chrome 的调试端口消失,Worker 仍然保留旧的登录状态快照。后来增加了主动刷新机制:
- Inventory 超过阈值时,Gateway 请求 Worker 刷新;
- Worker 重连后立即刷新;
- Chrome/CDP 故障时返回新鲜的
available=false,而不是继续使用过期状态。
3. OAuth 页面本地能打开,云端却失败
OAuth 联调中还遇到了一个很典型的问题:本地浏览器可以打开授权页,但 ChatGPT 的云端浏览器收到 502 Bad Gateway 和 Connection refused。
这说明“我本地能访问”并不能证明公网所有访问路径都正常。需要同时检查 DNS、IPv4/IPv6、CDN 节点、反向代理配置和 upstream 监听端口。OAuth URL 中的 state 与 PKCE Challenge 还是一次性的,失败后不能反复复用旧链接,必须从 ChatGPT 重新发起连接。
九、最终生产验证
OAuth 修复并重新连接后,我通过 ChatGPT 发出了一条测试指令。系统完成了以下步骤:
- 读取平台状态;
- 排除不支持草稿的 Facebook;
- 验证小红书、知乎、微博和 X;
- 得到
valid=true和side_effects=false; - 调用专用草稿接口;
- 查询任务直到进入终态。
最终四个平台均返回 draft_created,实际模式全部是 draft,没有任何内容被公开发布。
十、最终使用体验
以后在任意支持该私人插件的 ChatGPT 会话中,只需要选择 Sky Publisher,然后说:
把这次聊天整理成一篇文章,保存到小红书、知乎、微博和 X 的草稿箱。不要公开发布。
如果要先发 WordPress,则可以说:
把这次聊天整理成一篇教程,发布到 WordPress,并归入 AI Talk 分类;同时生成一版适合短社交平台的摘要。
结语
这套系统表面上是“一键发布”,本质上是在建立一条由自然语言驱动、但具备严格权限和状态管理的内容流水线。
大模型负责理解和创作,MCP 负责标准化工具调用,OAuth 负责身份与授权,Gateway 负责任务与安全策略,本地 Worker 负责真实执行。把这些部分拆开之后,ChatGPT 就不再只是一个写作工具,而变成了我个人内容基础设施的统一入口。
最后更新于 2026年9月6日 by qlili