MCP 服务器
SupDesk 的 MCP(Model Context Protocol)服务器让 AI 助手和其他由 LLM 驱动的工具直接访问项目的帮助中心、反馈看板、更改日志、消息线程、Beta 计划和候补名单。
端点
https://mcp.supdesk.app/mcp认证
以 Bearer 令牌的形式传入 API 密钥:
Authorization: Bearer sd_live_...在 SupDesk 控制台的工作区设置 → API 密钥中生成密钥。
密钥决定了项目,因此没有任何工具接受 project_id 参数 — 模型不必猜测,也不会弄错。
您能得到什么
出现哪些工具取决于项目。在项目设置中关闭的功能,其工具完全不会出现在 tools/list 中,就像 REST API 对这些路由返回 404 一样。
| 分组 | 工具数 | 需要 |
|---|---|---|
| 帮助中心 | 10 | 已开启帮助中心 |
| 反馈看板 | 5 | 已开启反馈看板 |
| 更改日志 | 5 | 已开启更改日志 |
| 消息 | 5 | 已开启私信 |
| Beta 测试 | 8 | 已开启 Beta |
| 候补名单 | 4 | 已开启候补名单 |
| 总览 | 1 | 始终可用 |
读取在所有计划上都可用。写入需要付费计划 — 用只读密钥执行创建、更新或删除会返回 forbidden,而用同一把密钥读取则完全正常。
帮助中心
list_articles— 文章,按最近编辑排序。包含草稿和已归档的文章;用status筛选出客户实际能看到的内容。get_article— 按 id 获取一篇文章,包含其 Markdown 正文。search_articles— 对已发布文章的全文搜索,按相关度排序,附带片段。create_article— 创建草稿。发布是单独的调用,因此不会有内容意外送达客户。update_article— 修改任意字段;把status设为published或archived。delete_article— 永久删除;若想保留文章,请改为归档。list_article_categories、create_article_category、update_article_category、delete_article_category— 删除分类会保留其中的文章,只是变为不分类。
文章正文是 Markdown,不是 HTML。门户通过一个从不执行 HTML 的查看器渲染它们,因此 HTML 会以纯文本形式送达读者。
一旦计划的文章额度用尽,create_article 会以 limit_reached 失败 — 免费版 5 篇、专业版 50 篇、团队版无限。
反馈看板
list_feedback— 记录,按最新排序。除非用type收窄,否则涵盖全部三种类型(bug、feature、feedback)。get_feedback、create_feedback、update_feedback— 用update_feedback把记录沿backlog → open → planned → in_progress → done推进。delete_feedback— 删除记录及其投票和评论。
更改日志、消息、Beta 和候补名单
与 REST API 完全对等,走的是同一批查询:
- 更改日志 —
list_changelog、get_changelog_entry、create_changelog_entry、update_changelog_entry、delete_changelog_entry。条目默认为草稿,因为正是发布这一步会向订阅者发送公告邮件。 - 消息 —
list_threads、get_thread(含完整消息历史)、create_thread、reply_to_thread、update_thread。 - Beta 测试 —
list_beta_programs、get_beta_program、create_beta_program、update_beta_program、delete_beta_program、list_beta_testers、add_beta_tester、remove_beta_tester。add_beta_tester对邮箱是幂等的,并返回接受令牌;此服务器不发送邮件,因此投递邀请由调用方负责。 - 候补名单 —
list_waitlist、add_waitlist_signup(对邮箱幂等)、update_waitlist_signup、remove_waitlist_signup。
总览
project_stats 返回整个项目的计数 — 按状态分组的反馈记录、未关闭的线程、已发布和草稿状态的文章,以及这些文章收到的「有帮助 / 没帮助」票数。这样代理无需遍历四个分页列表就能回答「还有多少未处理」。
结构化输出
每个工具都声明了 outputSchema,并同时返回 structuredContent(带类型且已校验)和一个包含相同数据 JSON 的 content 文本块。您的客户端支持哪个就处理哪个。
const result = await mcpClient.callTool("get_article", { id: "8f7a..." });
result.structuredContent.article.title; // 带类型
JSON.parse(result.content[0].text); // 相同数据,作为回退注解
每个工具都带有注解,让客户端在调用之前就知道自己在调用什么:
| 注解 | 出现在 |
|---|---|
readOnlyHint: true | list_*、get_*、search_*、project_stats |
idempotentHint: true | 读取类和 update_* |
destructiveHint: true | delete_*、remove_* |
分页
列表类工具接受一个不透明的 cursor 并返回 next_cursor — 把它传回去获取下一页,直到它为 null 时停止。
let cursor;
do {
const page = await mcpClient.callTool("list_articles", { status: "published", cursor });
handle(page.structuredContent.data);
cursor = page.structuredContent.next_cursor;
} while (cursor);游标是令牌,不是算术 — 请把它当作不透明的值。格式错误的游标会返回 invalid_request,而不是悄悄从第一页重新开始;悄悄重启会让分页遍历永远循环下去。
请注意,这是各个工具自身参数结构中的约定。MCP 协议层面的游标适用于工具和资源的列举,而不是工具的返回值;下面的资源列举用的才是真正的协议机制。
资源
用于把项目内容作为上下文附加进来,而不必调用工具再粘贴结果:
| URI | 内容 |
|---|---|
supdesk://articles/{slug} | 一篇已发布的帮助文章,Markdown 格式。 |
supdesk://board | 项目中未关闭的反馈记录,JSON 格式。 |
文章列举是真正的协议层分页,并且只包含已发布的文章 — 资源是客户端可能原样呈现的内容,而草稿之所以未发布是有原因的。
提示词
两个连接到项目真实数据的起点:
draft_article_from_thread— 把一段已解决的支持对话变成帮助中心文章,让下一位有同样问题的客户直接找到答案,而不是新开一个线程。需要同时开启帮助中心和私信。triage_feedback— 评估一条记录并给出推荐状态及理由。它会先查search_articles,这样已有的答案会被指出来,而不是提出新的工作。
两者的参数都使用 MCP 的补全能力:当您输入分类时,服务器会返回项目中真实存在的分类短链接,不必猜测。
日志
多步骤的写入会通过 MCP 日志发送进度通知 — create_article 会检查计划额度、探测可用的短链接,然后插入,并在每一步给出说明。不支持日志的客户端不受影响;写入照常完成。
示例
Claude Desktop
添加到 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"sup-desk": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.supdesk.app/mcp",
"--header",
"Authorization: Bearer sd_live_..."
]
}
}
}回答问题,或者写下答案
// 先看看帮助中心是否已经覆盖了这个问题。
const hits = await mcpClient.callTool("search_articles", {
query: "重置密码",
limit: 5
});
if (hits.structuredContent.data.length === 0) {
// 还没有 — 那就写一篇。创建出来的是草稿。
const created = await mcpClient.callTool("create_article", {
title: "如何重置密码?",
body: "打开 **设置**,然后选择 *重置密码*。",
category_id: "3c2b..."
});
// 发布是有意为之的单独一步。
await mcpClient.callTool("update_article", {
id: created.structuredContent.article.id,
status: "published"
});
}整理看板
const open = await mcpClient.callTool("list_feedback", {
status: "open",
limit: 10
});
await mcpClient.callTool("update_feedback", {
id: open.structuredContent.data[0].id,
status: "planned"
});一次调用看完所有未处理项
const stats = await mcpClient.callTool("project_stats", {});
// { posts_by_status: { open: 12, planned: 3, ... }, open_threads: 4,
// articles_published: 18, articles_draft: 2,
// article_helpful: 240, article_not_helpful: 11 }限流
MCP 服务器与 REST API 共用限流规则:每个项目每 60 秒 120 次请求。参见限流与用量。
错误
失败的工具调用会返回 isError: true,使用与 REST API 相同的错误词汇:
{
"error": {
"code": "limit_reached",
"message": "Your plan allows 5 help-center articles."
}
}| 错误码 | 含义 |
|---|---|
unauthorized | API 密钥缺失、格式错误、已吊销或不存在。 |
forbidden | 密钥有效,但该计划没有 API 写入权限。 |
invalid_request | 参数有误 — 包括格式错误的 cursor。 |
not_found | 此项目中没有该 id。 |
limit_reached | 计划的某项额度已用尽(例如文章上限)。 |
rate_limited | 当前时间窗内请求过多。 |
internal_error | 我们这边出了问题。可以安全重试。 |
完整列表记录在错误中。