MCP 接入
工具参考
每次调用就是一个 POST。20 个工具按作用域分组,外加对所有调用都生效的硬规则。
请求的形状
POST https://popkit.loxily.com/api/mcp
Authorization: Bearer <token>
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: create_post
Accept: application/json, text/event-stream
Content-Type: application/json
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "create_post",
"arguments": {
"action": "schedule",
"scheduledAt": "2026-09-20T10:00:00+08:00",
"content": "…", "platforms": ["x", "youtube"],
"clientRequestId": "acme-2026-09-20-001"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "acme-scheduler", "version": "1.4.0" },
"io.modelcontextprotocol/clientCapabilities": {}
} } }- 2026 时代的客户端没有握手 —— 第一条消息就可以是
tools/list。2025 时代的客户端会先发initialize;同一个地址,服务端按它的方言应答。 Mcp-Method每次必带。tools/call与prompts/get另带Mcp-Name(=params.name),resources/read的Mcp-Name=params.uri。头体不一致回400 -32020。_meta信封必须有protocolVersion与clientCapabilities,两个键都带io.modelcontextprotocol/前缀;clientInfo可选但建议带 —— 它会出现在工作区的审计记录里。Accept要同时列application/json与text/event-stream:2026 的调用常态是纯 JSON,但 2025 时代的调用以 SSE 应答。- 工具结果在
structuredContent。业务失败仍是 HTTP 200 +isError: true,机器码在_meta["com.popkit/error"].code。
工具清单
工作区与账号
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| get_workspace_context | workspace:read | 读 | — | 我是谁 / 哪个工作区 / 角色 / 可用平台 / 配额余量 / 本凭证的 scope 与三档落点。起手必调。 |
| list_accounts | accounts:read | 读 | — | 已连接的社交账号、分组、授权状态与到期。 |
内容读取
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| list_posts | posts:read | 读 | — | 草稿 / 审批中 / 排期 / 已发布 / 失败的内容清单,游标分页,可按状态与平台筛。 |
| get_post | posts:read | 读 | — | 单条内容详情:正文、逐平台变体、媒体、逐账号投递结果。发布后用它轮询结果。 |
| check_publish_constraints | posts:read | 读 | — | 发布前预检(不写库):逐平台、逐账号的长度 / 媒体规格 / 授权 / 频控 / 必填项,口径与真实发布一致。 |
内容写入
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| create_post | posts:write schedule:write publish:execute | 写 / 发布(按 action) | publish 档必填 | 创建内容,action 三选一:draft / schedule(带 scheduledAt)/ publish。不传 targetAccountIds = 发给该平台全部可用账号(上限 20)。publish 档必须带 clientRequestId;A 类凭证还要走 confirm_publish 第二步。 |
| update_post | posts:write schedule:write publish:execute | 写 / 发布(按 action) | publish 档必填 | 改一条已有内容(正文 / 变体 / 媒体 / 落点),规则同 create_post。 |
| attach_media | posts:write | 写 | 可选(建议带) | 把媒体交给 popkit:mode=upload 拿一张 5 分钟有效的直传地址自己 PUT,或 mode=transload 给一个公网图片 URL 由我们代抓转存。返回的 mediaUrl 填进 create_post 的 media[].dataUrl。 |
| suggest_covers | posts:write | 写 | 可选(建议带) | 按内容的素材推荐封面:视频抽帧挑图(调两次:先触发、约 10–30 秒后取结果),图文在 2 张以上配图里挑首图,排好序并附理由。不扣 AI 配额。 |
| set_post_cover | posts:write | 写 | 可选(建议带) | 把一张推荐候选设为内容封面:视频内容写进封面(含 TikTok 封面帧),图文内容挪成第一张图。 |
| reschedule_post | schedule:write posts:write | 写 | 可选(建议带) | 改期,或把排期退回草稿。 |
| submit_for_approval | approvals:write | 写 | 可选(建议带) | 把草稿送进审批流(editor 角色凭证的正常终点)。 |
对外发布
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| confirm_publish | publish:execute | 发布 | 必填 | 两步确认的第二步:{ postId, confirmToken } → 真正对外发布。令牌一次性、10 分钟有效。 |
| publish_post | publish:execute schedule:write | 发布 | 必填 | 对已存在的内容执行发布或单账号重试。 |
评论互动
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| list_comments | comments:read | 读 | — | 已发布内容收到的评论(可只看未回复),每条带 canReply 与回不了的原因。 |
| reply_comment | comments:write | 发布 | 必填 | 以工作区的社交账号回复一条评论 —— 这是对外发声,按发布档限流,重复回复要显式 force,且同一条评论 24 小时内最多 3 条。 |
选题库
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| list_ideas | ideas:read | 读 | — | 选题库的分组与选题。 |
| create_idea | ideas:write | 写 | 可选(建议带) | 往选题库写一条选题,零对外副作用。 |
| update_idea | ideas:write | 写 | 可选(建议带) | 改一条既有选题;省略的字段保留原值,editor 只能改自己建的。 |
数据
| 工具 | scope(任一) | 档位 | 幂等键 | 说明 |
|---|---|---|---|---|
| get_analytics_summary | analytics:read | 读 | — | 指标概览与趋势(可按账号 / 时间范围)。 |
提示词与资源
提示词模板把 popkit 的运营套路打包好了 —— 数据现取、规矩内置,不用再教模型一遍。资源是可缓存的只读快照。两者都按 scope 裁剪,与工具一样。
| 提示词 | 需要的 scope | 做什么 |
|---|---|---|
| weekly_content_plan | accounts:read analytics:read posts:read | 按账号与近 30 天数据排本周内容计划。 |
| draft_from_idea | ideas:read posts:write accounts:read | 把一条选题展开成多平台草稿(ideaId 支持补全)。 |
| postmortem_last_campaign | posts:read analytics:read | 复盘最近一批已发布内容。 |
| comment_triage | comments:read | 评论分类与回复建议;有 comments:write 时才会建议动手回复。 |
| 资源 URI | 需要的 scope | 内容 |
|---|---|---|
| popkit://workspace/{workspaceId}/accounts | accounts:read | 账号清单 |
| popkit://analytics/{workspaceId}/summary | analytics:read | 30 天指标概览 |
| popkit://post/{postId} | posts:read | 单条内容详情(模板) |
对每次调用都生效的规则
- 发布是异步的 ——
create_post/confirm_publish立刻返回{ postId, status: "publishing", deepLink },逐账号结果用get_post轮询。卡住约 15 分钟自动判失败。 - 发给哪些号 —— 不传
targetAccountIds= 该平台下全部可用账号(过期号静默跳过),单次上限 20 个。要指定就显式传。update_post省略这个字段 = 保留原有选号。 - 幂等 —— 写工具带
clientRequestId(8–128 位[A-Za-z0-9_.:-])。24 小时内重放返回原结果并打上_meta["com.popkit/replayed"],发布档必填。键与入参绑定:同一个键换了入参会回invalid_input。 - 限流,三条各按不同维度计:读 60 / 写 10 / 发布 5 次每分钟,按每凭证 × 工作区 × 工具;每日外发 20 条,按每凭证 × 工作区;同账号两次外发间隔 600 秒,按每工作区 —— 这条是共享的,同一个账号被多枚凭证发就会互相挡。超过任一条 →
rate_limited,带retryAfterSec。 - 评论回复单独计。 每日外发上限与同账号间隔对它不适用 —— 批量回评是正常用法,不该被为发内容设计的额度掐断。真正生效的有两条:同一条评论 24 小时内最多接收 3 条我方回复(按平台评论计,跨工作区共享,给
force兜底);以及每日 500 条的总量上限(每凭证 × 工作区,给自动化兜底,正常用法碰不到)。超出 →rate_limited,带params.reason = "comment_reply_cap"。 - 手动渠道(抖音 / 小红书 / 公众号)没有平台接口:
publish只把内容记为已发布并提醒管理员去粘贴,不会自动发出去。 - 媒体不能用外链。先调
attach_media(直传或转存)拿到mediaUrl,再填进media[].dataUrl。