Сервер MCP
Сервер MCP (Model Context Protocol) от SupDesk даёт ИИ-ассистентам и другим инструментам на базе LLM прямой доступ к центру помощи, доске обратной связи, журналу изменений, цепочкам сообщений, бета-программам и списку ожидания проекта.
Эндпоинт
https://mcp.supdesk.app/mcpАутентификация
Передайте API-ключ как Bearer-токен:
Authorization: Bearer sd_live_...Ключи создаются в консоли SupDesk в разделе Настройки рабочего пространства → API-ключи.
Проект определяется ключом, поэтому ни один инструмент не принимает аргумент project_id —
модели нечего угадывать и не в чем ошибиться.
Что вы получаете
Набор доступных инструментов зависит от проекта. Функция, отключённая в Настройках проекта,
вообще не показывает свои инструменты в tools/list — ровно так же, как REST API отвечает 404
на её маршрутах.
| Группа | Инструментов | Требуется |
|---|---|---|
| Центр помощи | 10 | Центр помощи включён |
| Доска обратной связи | 5 | Доска обратной связи включена |
| Журнал изменений | 5 | Журнал изменений включён |
| Сообщения | 5 | Приватные сообщения включены |
| Бета-тестирование | 8 | Бета включена |
| Список ожидания | 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, как только квота статей плана исчерпана —
Free 5, Pro 50, Team неограниченно.
Доска обратной связи
list_feedback— записи, сначала новые. Охватывает все три типа (bug,feature,feedback), если вы не сузите выборку черезtype.get_feedback,create_feedback,update_feedback— черезupdate_feedbackзапись движется по маршрутуbacklog → open → planned → in_progress → done.delete_feedback— удаляет запись, её голоса и комментарии.
Журнал изменений, сообщения, бета и список ожидания
Полное соответствие 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. - Бета-тестирование —
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 (типизированный
и проверенный), так и текстовый блок content с теми же данными в JSON. Обрабатывайте то, что
поддерживает ваш клиент.
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: 120 запросов за 60 секунд на проект. См. Лимиты запросов и использование.
Ошибки
Неудачный вызов инструмента возвращает 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 | Что-то сломалось на нашей стороне. Повтор безопасен. |
Полный список описан в разделе Ошибки.