mcpField
C
Creatif Space

Creatif Space

远程服务
creatif.space社交媒体0今天更新

关于 Creatif Space

Creatif Space 是用于通过 AI 客户端管理社交内容的远程 MCP 服务,涵盖起草、审批、发布和报告,并在发布操作前提供预览与确认。

主要功能

  1. 01查看频道、帖子和文件
  2. 02起草和编辑社交帖子
  3. 03创建并跟踪审批链接
  4. 04预览并确认发布
  5. 05查看洞察与报告

适用场景

  1. 01为营销活动准备社交帖子
  2. 02将草稿发送给客户审批
  3. 03安排或重试社交帖子
  4. 04分享表现报告

MCP 相关

它将 Creatif Space 账户、内容、审批、发布和洞察操作作为 MCP 工具提供。服务使用调用者的 bearer token 访问现有 V1 API。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.creatif.space/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

creatif.space MCP 服务

面向 creatif.space 的远程 MCP 服务。连接器 URL:https://mcp.creatif.space/mcp(也支持 /)。采用 Streamable HTTP、无状态,基于 Node 22 和 官方 @modelcontextprotocol/sdk。

它只是一个薄薄的接入层:每个工具都使用调用者自己的 Bearer 令牌调用现有的 V1 API,因此所有权、套餐、Credits 和验证都由 Laravel 负责。此处不包含业务逻辑。

60 秒上手(Claude)

  1. 在 Claude 中,打开 Settings → Connectors → Add custom connector,将其命名为 creatif.space,并粘贴连接器 URL: https://mcp.creatif.space/mcp
  2. 点击 Connect,登录 creatif.space 并授权访问。现在 Claude 可以看到 你的频道、草稿和审批链接。未经你同意,不会发布任何内容: 每次发送前都会先显示预览。
  3. 试着提出以下任一请求——每个请求都会运行一个现成的提示词(也可在 Claude 的 提示词菜单中找到):
    • “规划下周内容:为我们的冬季新品发布准备 5 条 Instagram 帖子。” → plan_week 会在你的频道中起草这些帖子。只会生成草稿,不会发布。
    • “把我的草稿发送给 [email protected] 审批。” → send_for_approval 会生成审批链接,供客户审批或提出修改意见。
    • “这周表现如何?给我一个可以发给客户的链接。” → weekly_results 会汇总过去 7 天的数据,并生成任何人都能打开的链接。
    • “为客户制作上个月的报告。” → monthly_report 会汇总整个月的数据,并生成同类链接。

端点

路径说明
POST /mcp(以及 POST /)MCP JSON-RPC(需要 Bearer 令牌)
GET /health存活状态检查,无需认证:{ok, name, version} — 与 serverInfo 中的版本相同(来自 package.json;参见 CHANGELOG.md)
GET /.well-known/glama.jsonGlama 连接器声明,无需认证(也支持 HEAD);相同文档也可通过 GET /mcp/.well-known/glama.json 访问
GET /.well-known/oauth-protected-resourceRFC 9728 元数据:resource: "https://mcp.creatif.space/mcp",authorization_servers: ["https://api.creatif.space"]
GET /.well-known/oauth-protected-resource/mcpRFC 9728 路径格式下的相同文档
POST /freeCreatif Space Free Tools — 独立的 MCP 服务,无需认证,每个 IP 每分钟 30 次调用

/mcp、/ 和 /free 上的 CORS(适用于浏览器客户端:MCP Inspector 网页版、Web IDE):OPTIONS → 204,并返回 Access-Control-Allow-Origin: *(不含凭据——仅通过 Bearer 请求头认证)、Allow-Methods: GET, POST, DELETE, OPTIONS、Allow-Headers: authorization, content-type, mcp-protocol-version, mcp-session-id, last-event-id、Expose-Headers: mcp-session-id, www-authenticate、Max-Age: 600。这些路径的所有响应(包括 401 和 429)都会包含相同的请求头。此功能由 Node 应用处理(src/cors.ts);nginx 会转发 OPTIONS 请求,且不得添加自己的 Access-Control-* 请求头。

缺少令牌或令牌无效 → 返回 401,并带有 WWW-Authenticate: Bearer resource_metadata="https://mcp.creatif.space/.well-known/oauth-protected-resource/mcp"(RFC 9728 路径格式,根据源站构建;根路径下的 well-known 端点提供相同文档)。

身份验证

令牌(Passport OAuth 2.1 访问令牌或 cs_live_… API 密钥)通过 POST {V1_API_URL}/oauth/introspect 进行检查,请求头为 X-MCP-Secret,请求体为 {token},返回 {active, user_ulid, scopes[], client_id, client_name, token_type, exp}。 检查结果会缓存 60 秒(不会超过 exp)。随后,同一 Bearer 令牌会转发到 V1 路由 (守卫 mcp,在 OAuth PR 中内置)。

作用域(scopes_supported):read、draft、approve、publish、approvals:decide——与 API 上 config/mcp.php 中的名称相同。每次 V1 调用都会携带 X-MCP-Tool 和 X-MCP-Client,供 API 的审计日志记录(不记录内容)。 速率限制:每个令牌每分钟 60 次请求(429 + Retry-After)。

客户端通过动态客户端注册(POST /oauth/register)或 OAuth 客户端 ID 元数据文档获取 client_id:client_id 是一个 https URL,提供 {client_id, client_name, redirect_uris, token_endpoint_auth_method: "none"}。API 会获取该文档 (仅限公共地址,不跟随重定向,≤ 5 KB,按照 Cache-Control 缓存 5 分钟至 24 小时),并声明 client_id_metadata_document_supported: true。

工具

工具范围V1 端点
list_channels — 需要重新连接的频道会附带 reconnect {reason, next_step},并列在 needs_reconnect 中读取GET /social-accounts
list_posts (status: draft, waiting, changes_requested, scheduled, published, failed, cancelled;from/to 可设为日期或时间;channel_id, limit) — waiting / changes_requested 会按 status=scheduled 读取,并按审批状态筛选帖子读取GET /social-posts?status&from&to&account_id&limit
list_failed_posts (limit, cursor) — 最近 30 天内的数据;按频道显示 failure_code + reason;部分发布的帖子仅列出发布失败的频道读取GET /social-posts?status=failed + ?status=published (from/to = 最近 30 天)
get_post读取GET /social-posts/{id}
list_files (search, type, folder_id, limit)读取GET /files
draft_post (caption, channel_ids, file_ids, media_urls, captions_by_channel, type)草稿POST /social-posts,并设置 draft: true
get_account_summary — 一次调用完成引导:套餐、已用/剩余限额、剩余 Credits、已连接/需要重新连接的频道、已用存储空间、failed_posts (最近 30 天)、approvals {waiting, changes_requested}、next_steps读取GET /credits, GET /social-accounts, GET /files/usage, GET /social-posts?status=failed + ?status=published (与 list_failed_posts 相同), GET /social-posts?status=scheduled
get_onboarding — “Get started” 检查清单(连接、起草、发送、发布),每项包含 {done, at},以及 next {step, tool, suggest}:建议的下一步读取GET /me/onboarding
get_credits — 套餐、限额、Credits;spend (本周期按操作分类:publish, reply, ai) 和 renewal (resets_at, days_until)读取GET /credits (limits.spend)
create_approval_link (post_ids — 或 Content Plan:date_from, date_to, timezone, channel_ids — approver_email(必填 — 客户端使用此邮箱登录并作出决定)、title, client_name, expires_in_hours) — 适用于所有套餐;Free:一位客户(按 approver_email 识别)、7 天窗口、最多 10 个排队帖子审批POST /social-approval-links (接受草稿)
create_content_plan (date_from, date_to, timezone, channel_ids, approver_email, title, client_name, expires_in_hours, confirm) — 先预览;confirm: true 会创建 Content Plan 并向审批人发送邮件审批GET /social-accounts, GET /social-posts?from&to (预览);confirm: true → POST /social-approval-links,并设置 notify_approver: true
check_approval_status (post_id | link_id)读取GET /social-posts/{id} 或 GET /social-approval-links/{id}
send_approval_reminder (link_id)审批POST /social-approval-links/{id}/remind (每个链接每 12 小时一次)
update_post (caption, scheduled_at, labels, file_ids | add_file_ids)草稿(仅限草稿和等待审批的帖子)PATCH /social-posts/{id}
schedule_posts (posts: [{post_id, scheduled_at}] 最多 10 个,confirm) — 一次预览所有帖子及 Credits 总额;confirm: true 会全部安排发布,否则全部不安排发布对每个帖子预览 GET /social-posts/{id}/send-preview;confirm: true → POST /social-posts/send-batch(先检查全部帖子;若有一个被拒绝,则撤回已发送的帖子)
schedule_post (post_id, scheduled_at, confirm)发布预览 GET /social-posts/{id}/send-preview;confirm: true → POST /social-posts/{id}/send
publish_post (post_id, confirm)发布相同,但立即发送
retry_post (post_id, confirm) — 再次发布帖子的失败频道;预览会显示各频道的 failure_code 和原因发布预览 GET /social-posts/{id}/retry-preview;confirm: true → POST /social-posts/{id}/retry
get_insight_summary (period: {month} | {from, to} ≤ 92 天, channel_ids) — Pro / Max;Free → plan_required读取GET /insight/summary?month | from&to&channel_ids
list_top_posts (period: {month} | {from, to} ≤ 92 天, channel_ids, limit, cursor) — Pro / Max;Free → plan_required读取GET /insight/top-posts?month | from&to&channel_ids
get_best_times (days 7–92, channel_ids) — Pro / Max;Free → plan_required读取GET /insight/best-times?days&channel_ids
get_insight_csv_link (from, to ≤ 366 天, channel_ids) — Pro / Max;Free → plan_required读取POST /insight/export-csv-link
get_insight_report_link (from, to ≤ 92 天, format onepage|deck|details, channel_ids, locale) — Insight PDF 的 15 分钟有效签名下载链接(单页、16:9 演示文稿或详细报告);Pro / Max读取POST /insight/export-link
create_insight_share_link (from, to ≤ 92 天, channel_ids, recipient_email) — Insight 报告的只读网页链接,无需账号即可访问,有效期 30 天;填写 recipient_email 后会向该邮箱发送一次邮件,对方也会在 list_shared_with_me 中看到报告审批POST /insight/share
revoke_insight_share_link (share_id) — 立即停用已分享的 Insight 链接审批DELETE /insight/share/{id}
request_media_upload (filename, mime, size_bytes, folder_id)草稿POST /files/presign → file_id + 预签名 PUT URL (15 分钟有效)
confirm_media_upload (file_id)草稿POST /files/{id}/complete (409 → GET /files/{id}:返回已就绪的文件)
list_conversations (type comment|dm, channel_id, unread_only, since, limit, cursor) — 在一个列表中显示 Engage 评论和私信,按最新优先排序读取GET /inbox/feed?type&account&unread&since&per_page&cursor
reply_to_conversation (conversation_id, text, confirm) — 在对话串中发送私信,或在评论下公开回复发布预览 GET /inbox/feed/{id};confirm: true → POST /inbox/feed/{id}/reply
get_storage_usage — 已用空间与配额(Free:总计 1 GB;付费套餐:Keep 配额)以及保留与自动删除文件(按最早日期排序),统计最新的 300 个文件读取GET /files/usage + GET /files?per_page=60&page=1..5
keep_file (file_id) — Pro/Max;Free → plan_required,配额已满 → storage_full,文件未就绪 (409) → file_not_ready草稿POST /files/{id}/keep
unkeep_file (file_id) — 恢复适用保留规则;返回 auto_delete_at草稿DELETE /files/{id}/keep
suggest_caption (brief, platform) — 按用户风格生成文案和标签;不保存任何内容。Pro/Max;AI_CAPTION_ENABLED 关闭时返回 404 → not_enabled(“请自行撰写文案”),Free → plan_required草稿POST /ai/caption
discard_draft (post_id, confirm) — 仅删除草稿;先预览,confirm: true 后删除;scheduled / published / failed → not_draft 并提供下一步草稿GET /social-posts/{id},然后 DELETE /social-posts/{id}/draft
list_approval_links (status active|expired|revoked|all, limit) — 状态、审批人邮箱、帖子数量、已批准/等待中/需修改数量读取GET /social-approval-links
revoke_approval_link (link_id, confirm) — 先预览,然后永久撤销链接;未获答复的帖子会退回给用户审批先 GET,然后 DELETE /social-approval-links/{id}
list_waiting_approvals — 其他用户发送给此用户审批的帖子approvals:decideGET /me/approvals/waiting
decide_approval (link, post_id, decision approve|revise, reason, confirm) — 审批人端;规则与审批页面相同,审计记录为 mcpapprovals:decide预览 GET /me/approvals/{post}/preview;confirm: true → POST /me/approvals/{post}/decision
list_spaces (status draft|published|archived, search, limit) — Pro/Max读取GET /spaces?tab&search
create_space_from_files (title, file_ids 1–100, view_mode) — 始终创建为 Draft+Private Space,不会发布;Pro/Max草稿POST /spaces,并传入 file_ids(创建前会先检查)
publish_space (space_id, confirm) — Pro/Max发布预览 GET /spaces/{id}/publish-preview;confirm: true → POST /spaces/{id}/publish
get_approval_history (post_id) — 某一帖子的所有决定,按时间从早到晚排列:审批人(邮箱已隐藏)、时间、决定、评论读取GET /social-posts/{id}/approval-audit
get_plan_calendar_link (link_id) — Content Plan 的 ICS 订阅源 URL(计划发布的帖子、文案的前 60 个字符);只读,URL 稳定读取GET /social-approval-links/{id}/calendar
get_approval_audit (link_id) — 用户某个链接下的所有决定:审批人、帖子、时间、决定、评论;支持表格和 CSV读取GET /social-approval-links/{id}/audit.csv
send_feedback (kind bug|idea|other, message, page) — 发送给 creatif.space 团队;不会公开显示,不消耗 Credits;每位用户每小时最多 10 条草稿POST /feedback
get_notification_settings — 用户会收到哪些邮件:post_missed_or_failed(“Post missed / failed”;除非 API 提供自己的键,否则对应 publish_failed 开关)、approval_decided、weekly_digest读取GET /me/notification-settings
update_notification_settings (post_missed_or_failed — 或旧名称 publish_failed —, approval_decided, weekly_digest: true/false;周一 08:00 摘要所用时区;至少启用一项)草稿PATCH /me/notification-settings
list_shared_with_me —“与您分享的报告”:其他用户分享给此用户邮箱的 Content Plans 和 Insight 报告approvals:decideGET /me/reports/shared
get_connect_link (network) — 应用的连接页面(https://creatif.space/social/connect?network=…)及相关步骤;响应中不含令牌;套餐已满时添加新网络 → plan_required读取GET /social-accounts + GET /credits(绝不调用 POST /social-accounts/auth-url)
媒体上传。 request_media_upload → 客户端将确切的字节 PUT 到
该 URL(Content-Type 和 Content-Length 都经过签名)→ confirm_media_upload
→ ID 会放入 draft_post / update_post 的 file_ids 中。预签名和
完成流程与应用相同,因此所有规则都由 Laravel 执行:Free 总容量 1 GB,Pro 25 GB
/ Max 50 GB Keep 配额、单文件上限、可接受的格式、魔数检查。
拒绝操作时会返回 storage_full(包含释放空间的 files_url + 升级链接
billing_url)、file_too_large、unsupported_format、upload_limit、
upload_incomplete(在 PUT 之前确认)、file_not_ready(帖子中包含未确认或
来自其他用户的 ID);其他工作区的 ID 会返回 not_found。

schedule_post / publish_post 若没有 confirm: true,只会返回预览 (渠道、Credit 花费、今日剩余发送次数,以及任何阻止发送的事项)。使用 bearer 令牌发送的次数上限为每位用户每天 20 次(UTC),由 Laravel (CapTokenSends,429 daily_send_cap)强制执行;应用的 Cookie 会话不受此限制。

confirm_token。 发送预览会返回由 API 签名的 confirm_token(使用应用密钥进行 HMAC;绑定用户、帖子、目标 ID 和 Credit 价格;有效期 10 分钟)。使用 bearer 令牌(MCP guard 或 API 密钥)发送时,必须将其一并传回:缺少令牌 → 422 confirm_token_required;令牌不匹配、已过期或伪造 → 409 preview_stale。暂存草稿以供审批以及应用的 Cookie 会话都不需要此令牌。本服务会在内存中 保存每位用户 + 每个帖子最近一次预览的令牌,并在 confirm: true 时将其发送——模型不会看到它。 没有可用的预览记录(从未显示、已过期、已使用或服务器重启)→ 重新生成预览,不会发送任何内容; 409 → 工具错误 preview_stale,并在 details.preview 中附上新预览。

审批和编辑遵循 API 规则。 需要由客户审批(或客户要求修改)的草稿,不会通过应用或令牌发送或 安排发送(409 approval_required);只能再次暂存给客户。令牌也不能跳过编辑者自己的审批步骤。 令牌只能编辑等待审批的草稿和帖子(409 not_editable)。

Spaces。 对已连接的应用仅限 Pro 和 Max:令牌可访问的每个 Spaces 路由都列在 config('mcp.route_features') 中,因此 Free 用户会在控制器运行前由 EnforceTokenScope 收到标准的 402 plan_required(feature: "spaces")响应——但应用仍会列出 Free 用户已有的 Spaces。publish_space 与 publish_post 的工作方式相同:预览会返回一个 confirm_token(对用户 + Space + 标题、地址、可见性、密码、 到期时间和文件进行 HMAC;有效期 10 分钟),本服务会保存该令牌,并在 confirm: true 时发送;使用令牌发布但未提供令牌 → 422 confirm_token_required, Space 已更改 → 409 preview_stale。预览还会说明阻止发布的原因 (active_slots_full)以及需要提示的情况(no_handle:尚无地址、 empty、expired)。Space 的链接格式为 {public_url}/{handle}/{slug} (Space 资源中的 public_url;没有 handle 时为 null)。

计划限制同样遵循 API 规则(计划定义只有一份:PlanSeeder, 由 PlanQuota 执行)。Free 最多可提前 7 天(UTC)安排发送,最多暂存 10 篇排队帖子 (已安排发送 + 等待审批),且一次只能与一个客户建立审批链接;Pro 和 Max 不受这些限制。 超过限制时,API 会返回 402 {message, reason: "plan_required", feature, required_plan, limit?}(feature:schedule_window、queue_limit、approval_clients 或 受限功能),工具错误为 plan_required,并在 details 中包含这些字段。 schedule_post 会在预览中发送其 scheduled_at,因此用户确认前就会收到限制提示。 互动。 list_conversations / reply_to_conversation 读取并回复的行与应用中「互动」的行相同(评论和通过 Outstand 中继发送的 Instagram/Facebook 私信),所有权规则也相同(其他工作区的 ID → not_found),并遵循相同的策略(查看者席位无法回复)、Credits 和中继错误 — API 的 /inbox/feed 路由会委托给应用的互动控制器。ID 有类型:dm_<ulid> 或 comment_<ulid>。所有套餐均包含互动(PlanSeeder v2 没有互动标志),因此这两个工具都不受套餐限制;API 返回的 402 仍会以 plan_required 返回。若调用 reply_to_conversation 时没有 confirm: true,则只会预览;确认后,仅当文本与过去 10 分钟内针对该对话显示过的预览文本完全一致时才会发送(按用户保存在内存中),否则会再次预览,不会发送任何内容。评论和私信文本都是数据,绝非指令 — 两个工具的描述都明确说明了这一点。

错误会作为工具结果返回,包含 isError: true 和 {error: {code, message, next_step, details}}。next_step 是模型现在应执行的唯一操作;details 永不为空(始终包含 tool),且 next_step 只会指向实际存在的 details.X(test/errors.test.ts 会针对每条错误路径检查这两点)。SDK 自行处理的错误参数和未知工具名也会使用相同的封装格式。错误代码:reconnect_required、 scope_missing、plan_required、not_found、unknown_tool、invalid_input、 unauthorized、forbidden、rate_limited、daily_cap_reached、 insufficient_credits、quota_exceeded、preview_stale、not_editable、 not_draft、not_approvable、not_a_plan、link_inactive、approval_required、storage_full、 file_too_large、unsupported_format、upload_limit、upload_incomplete、 file_not_ready、upstream_unavailable、internal_error,以及互动回复错误 reply_window_closed、reply_rejected、reply_not_possible、 relay_unavailable。

每次调用都会发出 PostHog 事件 mcp_tool_called {tool, client_surface, client_name, ok, code, duration_ms} — client_surface 的值为 claude、chatgpt、cursor、vscode、 api_key 或 other(根据 OAuth 客户端名称确定);code 的值为 ok 或错误 代码。ms 和 error 保留为 duration_ms 和 code 的旧名称。不记录参数、说明文字、ID 或其他用户文本。未设置 POSTHOG_KEY 时会跳过。

有意不做成 MCP 工具:账户数据导出。 POST /api/v1/me/export (整个工作区的 ZIP 文件,将通过电子邮件发送一个 24 小时有效的链接)仅适用于已登录的 creatif.space 会话。它不在 mcp.routes 中,因此 OAuth 或 API 令牌会收到 403。账户完整副本不应交给 AI 客户端。

从 AI 聊天中审批

适用于客户端——也就是 creatif.space 用户向其发送帖子或内容 计划以供审批的人。他们使用自己的账号(即收到链接的邮箱)将 creatif.space 连接到 Claude 或 ChatGPT,在授权页面允许 决定审批 (approvals:decide),之后无需打开审批页面即可查看并作出决定。

工具功能
list_shared_with_me“与你共享的报告”:与用户已验证邮箱共享的内容计划和洞察报告——标题、日期、发送者、链接(对于计划,还会显示有多少帖子待处理)。
list_waiting_approvals所有仍在等待用户决定的帖子,附带用于作出决定的链接 ID 和帖子 ID。
decide_approval批准,或说明原因并要求修改。始终先显示预览;仅在用户同意后,才使用 confirm: true 作出决定。

所有者一侧还有另外两个工具(权限范围 read):get_approval_audit——以行和 CSV 的形式显示某个自有链接的决定内容、决定者和时间;以及 get_approval_history——针对某个帖子,汇总其所在所有链接的相同信息,并遮蔽审批者的邮箱。

这些工具会遵守的规则(由 API 强制执行;工具仅作说明):

  • 仅限发给用户已验证邮箱的链接。其他人会收到 forbidden,并附上预期邮箱的提示;来自其他工作区的 ID 会返回 not_found。
  • 每次决定都分为两步:预览,然后确认。确认请求会携带一个签名令牌(有效期 10 分钟),该令牌绑定用户看到的确切帖子;如果帖子在此期间被编辑,系统会返回包含新预览的 preview_stale,且不会作出决定。令牌不会传递给模型。
  • 规则与审批页面相同:帖子必须在计划的日期范围和渠道内,且仍在等待审批;Free 发送者的计划仅允许决定未来 7 天内的帖子(返回 invalid_input,并附带 decidable_from)。
  • 每项决定都会记录审计信息,标记为 source: mcp;发送者收到的通知与通过页面作出决定时完全相同。
  • 第一篇待审批帖子发布前一天,审批者会收到一封提醒邮件(每个计划一次;他们可以通过邮件关闭提醒,所有者也可以使用 PATCH /social-approval-links/{id} {reminders: false} 关闭)。
对话示例

Rani: 这周有什么需要我审批的吗?

Claude 调用 list_shared_with_me 和 list_waiting_approvals。

Claude: Bro 与你共享了一份内容计划:12 月 (12 月 1 日至 31 日,Asia/Jakarta)。有两篇帖子在等你审批:

  1. “发布日——全场 8 折……”——Instagram,12 月 2 日周三 09:00
  2. “工作室幕后花絮”——Instagram,12 月 4 日周五 18:00

Rani: 批准第一篇。第二篇请他们换成有团队成员入镜的照片。

Claude 对第 1 篇帖子调用 decide_approval,参数为 decision: "approve";对第 2 篇调用该工具,参数为 decision: "revise"、reason: "Please use the photo with the team in it"——两次都不带 confirm,因此都会返回预览。

Claude: 我将这样处理:

  • 批准“发布日……”——它将在 12 月 2 日周三 09:00 发布到 Instagram。
  • 对“工作室幕后花絮……”要求修改,并告诉 Bro:“Please use the photo with the team in it.”

现在要继续吗?

Rani: 好。

Claude 再次对每篇帖子分别调用 decide_approval,使用相同参数并添加 confirm: true。

Claude: 已完成。“发布日……”已获批准,将于周三 09:00 发布;Bro 已收到你对“工作室幕后花絮……”的备注。没有其他待审批内容。

之后,在所有者一侧:

Bro: 谁审批了 12 月的发布帖子?什么时候审批的?

Claude 使用计划的链接 ID 调用 get_approval_audit。

Claude: Rani([email protected])于 12 月 1 日 03:10 UTC 要求修改“工作室幕后花絮……”(“Please use the photo with the team in it”),并于 03:10 UTC 批准了“发布日……”,两项决定均来自 AI 聊天。需要 CSV 吗?

工具注释

每个工具都有一个面向用户的 title,并将四个 MCP 提示显式设置为布尔值。list_*、get_* 和 check_* 工具的 readOnlyHint 为 true。任何会公开发布、删除、撤销或记录不可撤回决策的工具,其 destructiveHint 为 true:publish_post、schedule_post、schedule_posts、reply_to_conversation、retry_post、publish_space、discard_draft、unkeep_file、decide_approval、revoke_insight_share_link。只有会公开发布到社交网络或公共网络的工具,其 openWorldHint 为 true:publish_post、schedule_post、schedule_posts、reply_to_conversation、retry_post、publish_space。供目录审核表单使用的每个工具对应的一行说明见 docs/tool-justifications.md。test/annotations.test.ts 会检查这些规则和该文件,并在快照中固定每个工具的提示。完整参考文档列出了每个工具的范围、提示、描述和输入,见 docs/mcp-tools.md;该文档由服务返回的工具列表通过 npm run docs:tools 生成;如果内容过期,test/tools-doc.test.ts 会导致 CI 失败。

计划错误与 ChatGPT

任何工具描述都不会提及价格、计划层级或升级,无论客户端为何(test/no-upsell.test.ts)。当 OAuth 客户端为 ChatGPT 时——API 的 introspection 返回 client_surface: "chatgpt"(DCR 名称或 chatgpt.com / openai.com 重定向主机),或者客户端名称包含 ChatGPT / OpenAI——任何 402 或 plan_required 错误都会变为:

{ "error": { "code": "not_available_on_plan", "message": "This isn’t available on this account’s plan.", "next_step": "…no plan change or purchase…", "details": { "tool": "…" } } }

不包含升级链接或定价步骤;其他错误也会移除账单 / 充值链接。其他客户端会原样收到 API 的消息和链接(test/chatgpt-surface.test.ts)。

速率限制(429)

每个工具都会将 API 的 429 转换为相同的信封: {code: 'rate_limited', message, next_step, details: {retryable: true, retry_after_seconds}}。

  • **message:**API 自身的文本。
  • **retry_after_seconds:**取自响应正文中的 retry_after;如果没有,则取自 Retry-After 标头(EnforceTokenScope 的令牌限制只发送标头);如果仍没有,则为 60。

以下两种 429 会保留各自的代码:upload_limit(今日暂停上传)和 daily_cap_reached(已连接应用每日发送 20 次)。test/ratelimit.test.ts 会向每个工具发送 429。

幂等性(重复提交)

API 会在每位用户和每个键的范围内,对携带 Idempotency-Key 的 POST 请求执行一次,期限为 24 小时。重复请求会返回首次响应(带有 Idempotent-Replayed: true),且不会再次执行。这适用于发布 / 排期(/send)、/retry 和审批链接创建。服务端会为每次确认发送一个键:

  • publish_post、schedule_post 和 retry_post 会根据已确认预览的令牌生成键。重复发送确认只会发送一次,也只会扣费一次。
  • create_approval_link 会根据其参数在 10 分钟的时间窗口内生成键。重复请求同一个链接只会创建一次。

该键是哈希值:不会包含令牌或参数。只有 2xx 响应会被保留,因此修复导致确认被拒绝的原因后,可以重新发送该确认。

分页

每个 list_* 工具都使用相同的分页方式。它接受 limit 和 cursor,并返回 next_cursor(没有更多结果时为 null)。要请求下一页,请将 next_cursor 作为 cursor 传回,并使用相同的筛选条件。

  • **不透明游标:**其中包含工具、位置以及筛选条件的指纹。来自其他列表的游标,或与其他筛选条件一起重用的游标,会被拒绝为 invalid_input,下一步提示为“start again without cursor”。
  • **list_posts:**通过 GET /social-posts 使用 limit + offset 分页,并额外请求一行,以确定是否还有下一页。
  • **list_files:**遵循 API 的页码。游标会保留第一页的页面大小。
  • **list_conversations:**使用收件箱自身的游标。
  • **其他列表:**API 会返回全部结果,服务端负责分页。

src/tools/paging.ts;测试位于 test/pagination.test.ts。

结构化输出

list_channels、list_posts、get_post、get_credits、 list_waiting_approvals、check_approval_status、get_insight_summary、 list_files、list_spaces 和 get_storage_usage 声明了 outputSchema 并返回 structuredContent。为兼容旧客户端,文本块中仍包含相同的 JSON。架构(src/tools/outputs.ts)会为 Agent 所依赖的字段命名并指定类型,同时允许新增字段,因此 API 添加字段时不会导致调用失败。错误结果不包含 structuredContent;错误封装位于文本中。

提示词

prompts/list / prompts/get 提供三个现成的工作流。每个工作流都是一条用户消息,引导模型仅使用现有工具(每次发送仍须经过工具自身的预览和 confirm);用户输入的参数会加引号并标记为数据。定义于 src/prompts.ts。

提示词参数使用的工具
plan_week(“规划下周”)——为某个频道拟定一周的帖子(仅草稿)channel_id*、week_start、theme、posts(1–7)list_channels、list_posts、suggest_caption、draft_post
send_for_approval(“发送给客户以供审批”)——将草稿汇总到一个审批链接中approver_email*、post_ids(逗号分隔)、client_namelist_posts、get_post、create_approval_link、check_approval_status
weekly_results(“每周结果”)——汇总过去 7 天(或一个月)的数据 + 分享链接month(YYYY-MM;代替过去 7 天)、share(yes|no)get_insight_summary、create_insight_share_link
monthly_report(“月度报告”)——汇总一个月的数据 + 分享链接month(YYYY-MM,默认为上个月)、share(yes|no)get_insight_summary、create_insight_share_link

注册表元数据

  • mcp/server.json:官方 MCP 注册表条目(io.github.creatifren/creatif-space,远程地址为 https://mcp.creatif.space/mcp,条目版本为 1.2.2)。发布者提供的 _meta 列出了 OAuth 详情(授权服务器、受保护资源元数据、作用域)、所有工具、所有提示词以及服务版本。
  • mcp/free-tools/server.json:免费工具条目(io.github.creatifren/creatif-space-free-tools,远程地址为 https://mcp.creatif.space/free,无需身份验证,包含三个工具,条目版本为 1.1.0)。
  • glama.json(仓库根目录):Glama 维护者,与注册表命名空间中的所有者相同。
  • test/registry.test.ts 会确保这些信息与服务保持一致:工具、提示词、作用域和版本均相同;README 的 Tools 表格中的工具数量相同;仅包含架构字段。
  • 发布需手动完成,此处不会执行:.github/workflows/mcp-registry.yml 仅在 workflow_dispatch 时运行。发布是由 Rizal 执行的公开操作;两个条目的具体命令见 docs/registry-publish.md。

资源

resources/list 和 resources/read 提供两个只读 JSON 资源,作用域为 read。定义于 src/resources.ts。

URI内容数据结构与以下内容相同
creatif://channels已连接的频道,以及需要重新连接的频道list_channels(limit 100)
creatif://schedule/next-7-days从现在起至现在 + 7 天内安排的帖子(最多 100 条),按时间从近到远排列,并包含 {from, to, count}list_posts,状态为 scheduled
  • **错误:**缺少作用域或 API 错误会作为 JSON-RPC 错误返回,其 data 为常规的 {code, message, next_step, details} 封装。
  • **审计:**API 调用会携带 X-MCP-Tool: resource.channels / resource.schedule,因此会显示在审计日志和 mcp:usage 中。

免费工具(/free)

同一进程中的第二个无状态 MCP 服务:check_caption、 approval_request_template、connect_guide。无需登录,不存储用户数据; 每次调用都会发送 PostHog 事件 free_tool_called {tool, network}(不包含 文案文本),使用现有的 POSTHOG_KEY。文案和限制保存在 free-tools/*.json 中(caption-rules.json、按细分领域索引的 approval-templates.json、包含 file:line 证据的 connect-guides.json; 这些证据绝不会发送给调用方)。connect_guide 还会返回 account_type: 每个条目要么是 confirmed(引用代码作为依据),要么是 check in app (代码无法证实,因此不会猜测)。注册表条目 free-tools/server.json (io.github.creatifren/creatif-space-free-tools)不会由注册表工作流发布, 该工作流只发布 mcp/server.json。

环境

变量默认值说明
PORT3010
HOST127.0.0.1前置 nginx
V1_API_URLhttps://api.creatif.space/api/v1
MCP_RESOURCE_URLhttps://mcp.creatif.space/mcp精确的连接器 URL = 资源 ID;与 Laravel 的 MCP_RESOURCE_URL 值相同
MCP_AUTHORIZATION_SERVERhttps://api.creatif.space
MCP_INTROSPECT_SECRET—真实模式下必需;与 Laravel 中的值相同
MCP_AUTH_MODErealstub 仅用于测试,在 NODE_ENV=production 时会被拒绝(令牌格式为 stub:<user_ulid>:<scopes>)
POSTHOG_KEY—未设置 → 不进行分析
POSTHOG_HOSThttps://us.i.posthog.com
GLAMA_CLAIM已发布的声明在 GET /.well-known/glama.json 和 GET /mcp/.well-known/glama.json 提供(公开,必须保持已发布状态)
OPENAI_APPS_CHALLENGE—OpenAI Apps 域名验证令牌,在 GET /.well-known/openai-apps-challenge 以 text/plain 提供;未设置 → 404
MCP_PUBLIC_DISCOVERY关闭设为 true 后,initialize、notifications/initialized、ping 和 tools/list 无需令牌即可响应(注册表爬虫、客户端预览;每个 IP 每分钟 30 次)。tools/call 和其他所有请求仍会收到带有 WWW-Authenticate(resource_metadata)的 401 登录质询;携带令牌的请求始终采用正常的身份验证流程。请在 QA 验证前保持关闭。

开发

cd mcp
npm ci
npm run lint && npm run typecheck && npm test && npm run build
MCP_AUTH_MODE=stub npm start   # local only

部署检查清单(QA)

  1. 服务器已安装 Node 22 LTS(node -v → v22.x)和 nginx;DNS 将 mcp.creatif.space 指向此主机;TLS 证书已签发(certbot --nginx -d mcp.creatif.space)。
  2. 先部署 API 端:OAuth PR 已部署且迁移已运行;Laravel .env 中设有 MCP_INTROSPECT_SECRET 和 MCP_RESOURCE_URL=https://mcp.creatif.space/mcp。 两端的 MCP_RESOURCE_URL 都必须精确为 https://mcp.creatif.space/mcp(Laravel .env 和 /etc/creatif-mcp.env)——不能只填源站地址。
  3. /etc/creatif-mcp.env(权限模式 600,所有者为 root)中包含以下变量名: PORT、HOST、V1_API_URL、MCP_RESOURCE_URL、MCP_AUTHORIZATION_SERVER、 MCP_INTROSPECT_SECRET(与 Laravel 中的值相同)、MCP_AUTH_MODE(real,或不设置)、 POSTHOG_KEY、POSTHOG_HOST。切勿在此处设置 MCP_AUTH_MODE=stub。
  4. cd /var/www/creatif.space-api && git pull && cd mcp && npm ci && npm run build && npm prune --omit=dev
  5. 安装下面的 systemd 单元,执行 systemctl daemon-reload && systemctl enable --now creatif-mcp;后续部署时执行 systemctl restart creatif-mcp。
  6. 安装下面的 nginx 虚拟主机配置,执行 nginx -t && systemctl reload nginx。
  7. 冒烟测试:
    • curl -s https://mcp.creatif.space/health → {"ok":true,...}
    • curl -si -X POST https://mcp.creatif.space/mcp | grep -i www-authenticate → Bearer resource_metadata="https://mcp.creatif.space/.well-known/oauth-protected-resource/mcp"
    • curl -s https://mcp.creatif.space/.well-known/oauth-protected-resource/mcp → "resource":"https://mcp.creatif.space/mcp"
    • journalctl -u creatif-mcp -n 20 显示 listening on http://127.0.0.1:3010 (auth: real)
  8. 在 Claude 中:Settings → Connectors → Add custom connector → https://mcp.creatif.space/mcp,登录,然后运行 list_channels。

使用报告(每日启动检查)

在 API 主机上运行:php artisan mcp:usage --days=7(1–90;添加 --json 可获取机器可读版本)。数据来自 mcp_audit_logs:每个工具的 API 调用次数、错误(HTTP ≥ 400)、错误率以及最常见的错误代码(状态码映射为模型看到的 MCP 代码:402 → plan_required,404 → not_found,5xx → upstream_unavailable……)。仅包含汇总数据——不包含用户、令牌、IP 或客户端名称。统计的是 API 请求,而不是工具调用(一次工具调用可能产生多个请求);在此服务内部被拒绝的调用(参数错误、缺少作用域)不会到达 API,因此不在统计范围内。

延迟:过去 24 小时内每个工具的 p50 / p95(以及计时调用数和错误数),数据来自 mcp_audit_logs.duration_ms。这是 API 自身的响应时间,由 EnforceTokenScope 写入。该列出现之前的记录没有计时数据,因此会被排除。按 p95 从慢到快排序;在 --json 中,字段名为 latency_24h。

在生产环境中运行

每次部署构建一次:npm ci && npm run build(然后运行 npm prune --omit=dev)。

systemd — /etc/systemd/system/creatif-mcp.service
[Unit]
Description=creatif.space MCP server
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/creatif.space-api/mcp
EnvironmentFile=/etc/creatif-mcp.env
Environment=NODE_ENV=production
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=3
NoNewPrivileges=true
ProtectSystem=full

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now creatif-mcp
或使用 pm2 — mcp/ecosystem.config.cjs
module.exports = {
  apps: [{
    name: 'creatif-mcp',
    cwd: '/var/www/creatif.space-api/mcp',
    script: 'dist/index.js',
    env: { NODE_ENV: 'production', PORT: 3010 }, // secrets via the shell env / .env loader
    max_memory_restart: '300M',
  }],
};
nginx — mcp.creatif.space

兼容 SSE:禁用缓冲、延长读取超时时间,并使用 HTTP/1.1 连接上游。

server {
    listen 443 ssl http2;
    server_name mcp.creatif.space;

    ssl_certificate     /etc/letsencrypt/live/mcp.creatif.space/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mcp.creatif.space/privkey.pem;

    client_max_body_size 2m;

    location / {
        proxy_pass http://127.0.0.1:3010;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Streamable HTTP / SSE
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding on;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        add_header X-Accel-Buffering no;
    }
}

server {
    listen 80;
    server_name mcp.creatif.space;
    return 301 https://$host$request_uri;
}

检查:curl -s https://mcp.creatif.space/health 和 curl -si -X POST https://mcp.creatif.space/mcp | grep -i www-authenticate。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。