ИИ-ассистенты
MCP Server
Подключите ИИ-ассистента к WebAsk через OAuth или API-ключ
Подключение к MCP-серверу
Два способа подключения
Адрес сервера: https://mcp.webask.io/mcp/v1.
WebAsk поддерживает OAuth 2.1 и API-ключ. Оба способа сохраняют права пользователя и ограничения тарифа.
| Способ | Что нужно | Область доступа |
|---|---|---|
| OAuth — кнопка «Разрешить» | Добавить адрес сервера в клиент с поддержкой авторизации MCP, войти в WebAsk и выбрать воркспейс | Только выбранный воркспейс; 159 инструментов из текущего реестра |
| API-ключ | Создать ключ в WebAsk и передать Authorization: Bearer <API_KEY> |
Все воркспейсы, к которым у пользователя есть доступ; полный реестр из 163 инструментов |
Фактический каталог подключения получите через tools/list. Полные параметры и ответы — в справочнике инструментов.
Подключение через OAuth
- Добавьте в клиенте удалённый MCP-сервер с адресом
https://mcp.webask.io/mcp/v1. - Клиент откроет WebAsk: войдите в аккаунт, выберите воркспейс и нажмите «Разрешить».
- Клиент получает токен и сам обновляет его. API-ключ вручную передавать не нужно.
Выбор воркспейса определяет доступ: user://me и workspace://list показывают только его. Запросы к опросам, папкам или workspace_id другого воркспейса получают отказ доступа. Права участника внутри выбранного воркспейса остаются такими же, как в кабинете.
Четыре инструмента уровня аккаунта требуют API-ключ и не входят в OAuth-каталог:
manage_user_sessions, update_user_profile, get_partner_program, manage_partner_source.
Попытка вызвать их с OAuth-токеном получает JSON-RPC -32602 «Инструмент не найден».
Токен действует только на /mcp/v1, со scope mcp. В REST API v1–v3 он не принимается. Тариф проверяется для выбранного воркспейса. Если доступ пользователя или тариф закончился, запросы получают отказ.
Обнаружение сервера авторизации
Клиент выполняет discovery автоматически. Для своей интеграции доступны:
| Метаданные | Адрес |
|---|---|
| Защищённый ресурс | https://mcp.webask.io/.well-known/oauth-protected-resource/mcp/v1 |
| Сервер авторизации | https://mcp.webask.io/.well-known/oauth-authorization-server |
| Страница согласия | https://api.webask.io/oauth/mcp/authorize |
| Регистрация публичного клиента | https://api.webask.io/oauth/mcp/register |
| Обмен кода и обновление токена | https://api.webask.io/oauth/mcp/token |
issuer — https://mcp.webask.io; адреса согласия, регистрации и обмена токена находятся на api.webask.io. Клиент использует адреса из метаданных.
Без токена или с просроченным OAuth-токеном сервер отвечает HTTP 401 и передаёт:
WWW-Authenticate: Bearer resource_metadata="https://mcp.webask.io/.well-known/oauth-protected-resource/mcp/v1", scope="mcp"Неверный API-ключ отвечает HTTP 403 без этого заголовка. При таком отказе исправьте ключ в конфигурации.
Регистрация и токены
Регистрация принимает JSON с обязательным непустым redirect_uris (до 10 адресов), необязательным client_name (до 190 символов) и token_endpoint_auth_method: "none". Клиент публичный, секрет не выдаётся. Разрешены HTTPS-адреса, HTTP для localhost/127.0.0.1/[::1] и собственные схемы приложений. Фрагменты #, запятые и схемы javascript:, data:, file:, vbscript: запрещены.
Ответ регистрации — HTTP 201, с client_id, redirect_uris, grant_types: ["authorization_code", "refresh_token"], token_endpoint_auth_method: "none", scope: "mcp". Лимит — 30 регистраций в час с одного IP, затем HTTP 429. Повторная регистрация создаёт новую запись.
Authorization Code использует PKCE S256. Код действует 10 минут; обмен требует code_verifier. Токен доступа живёт 1 сутки, refresh-токен — 1 год. Другой scope не принимается. При отказе пользователя клиент получает error=access_denied с исходным state.
redirect_uri должен совпадать с зарегистрированным; у HTTP loopback-адресов localhost/127.0.0.1/[::1] допускается другой порт. Воркспейсы без MCP в тарифе недоступны для выбора. Повторное «Разрешить» с другим воркспейсом меняет выбор для этой пары клиента и пользователя, в том числе для уже выданных токенов.
Подключение через API-ключ
- Войдите в WebAsk и откройте Настройки → API / MCP.
- Создайте API-ключ и скопируйте его — он показывается один раз.
- Передайте его в заголовке
Authorization: Bearer <API_KEY>.
Cursor
Файл ~/.cursor/mcp.json. Пример для подключения по API-ключу:
{
"mcpServers": {
"webask": {
"url": "https://mcp.webask.io/mcp/v1",
"headers": {"Authorization": "Bearer <API_KEY>"}
}
}
}Для OAuth в клиенте с поддержкой авторизации MCP оставьте только url, без фиксированного заголовка Authorization.
VS Code
Файл .vscode/mcp.json. Здесь верхний ключ — servers, а транспорт — http:
{
"servers": {
"webask": {
"type": "http",
"url": "https://mcp.webask.io/mcp/v1",
"headers": {"Authorization": "Bearer ${input:webask-api-key}"}
}
},
"inputs": [
{"type": "promptString", "id": "webask-api-key", "description": "API-ключ WebAsk", "password": true}
]
}Для OAuth уберите headers и inputs; клиент запросит авторизацию. См. настройку MCP в VS Code.
Claude Desktop через локальный мост
Если ваша версия клиента подключает удалённые серверы через stdio, можно использовать сторонний пакет mcp-remote. Пример claude_desktop_config.json для API-ключа:
{
"mcpServers": {
"webask": {
"command": "npx",
"args": [
"-y", "mcp-remote@latest", "https://mcp.webask.io/mcp/v1",
"--header", "Authorization:${WEBASK_AUTH}"
],
"env": {"WEBASK_AUTH": "Bearer <API_KEY>"}
}
}
}Нужен установленный Node.js. Если клиент умеет удалённые подключения и OAuth напрямую, добавьте адрес сервера в его интерфейсе. Пакет @modelcontextprotocol/server-fetch читает веб-страницы и не служит мостом к WebAsk MCP.
Адрес и лимиты
Адрес сервера — https://mcp.webask.io/mcp/v1.
Лимит — 180 запросов в минуту на пользователя. Ссылки на экспорт действуют 1 час. Дополнительные права и тарифные условия каждого инструмента описаны в справочнике.
Ресурсы: чтение данных аккаунта
Обнаружение ресурсов
resources/list возвращает 6 конкретных URI: user://me, workspace://list, folder://list, quiz://list, theme://list, promocode://list.
resources/templates/list возвращает 13 шаблонов URI:
| Шаблон | Назначение |
|---|---|
quiz://{id}/structure |
Структура опроса |
quiz://{id}/answers |
Ответы |
quiz://{id}/summary |
Сводка |
quiz://{id}/report |
Отчёт |
quiz://{id}/texts |
Стандартные надписи |
quiz://{id}/variables |
Скрытые переменные |
quiz://{id}/hidden_options |
Скрытые опции опроса |
quiz://{id}/widgets_hidden |
Скрытые опции вопросов |
quiz://{id}/report_filters |
Фильтры отчёта |
quiz://{id}/report/{report_uuid}/files |
Файлы вопроса в отчёте |
quiz://{id}/report/{report_uuid}/inputs |
Текстовые ответы вопроса |
theme://{id}/details |
Тема оформления |
promocode://{id}/codes |
Коды списка промокодов |
Перед resources/read замените подстановки реальными идентификаторами: например, quiz://123/structure. Буквальная строка с {id} не адресует конкретный опрос. Полный HTTP-запрос приведён в разделе протокола.
OAuth ограничивает все ресурсы выбранным воркспейсом; API-ключ учитывает все доступные пользователю воркспейсы. Отказ по доступу нельзя обходить повторением запроса.
Чтение и права
Ресурсы предназначены только для чтения данных. Для их вызова отправляется запрос resources/read с соответствующим URI.
Отказ по доступу. Ресурс отвечает объектом {"error": "<код>", "message": "<пояснение>"}. Коды: user_not_authenticated, quiz_not_found, quiz_in_trash, workspace_not_found, access_denied.
access_deniedозначает, что текущему подключению недоступен объект: нет доступа к воркспейсу, папке опроса или объект находится за границей выбранного через OAuth воркспейса. Доступные пространства показываетworkspace://list; доступ к папкам определяют права участника. Повтор того же запроса не выдаёт доступ: проверьте выбранное пространство и попросите владельца открыть нужную папку.quiz_in_trash— опрос в корзине своего пространства: читать и править нельзя, вернуть —restore_quiz. Чужой опрос в корзине остаётсяquiz_not_found, чтобы по коду ответа нельзя было узнать о чужих данных.
Инструменты на те же случаи отвечают текстом с тем же пояснением.
Отказ по праву участника. Ресурс отвечает {"error": "right_denied", "right": "<код права>", "right_value": "allowed|partially|forbidden|missing", "role": "<роль>", "blocked": null|"invite_not_accepted"|"email_not_confirmed"|"not_member", "message": "<пояснение>"}. В message — имя права, его значение у роли (partially над чужим объектом называется отдельно: «только свои, а этот создал другой участник»), отличие по папке, если оно есть, и кто может право выдать. Инструменты на тот же отказ отвечают этим же текстом. Полный набор своих прав — user://me, поле workspaces.
Если ваш клиент не поддерживает
resources/read, используйте соответствующийget_*инструмент. Его данные доступны JSON-текстом вcontent[0].
Ресурс Tool-эквивалент user://meget_user_meworkspace://listget_workspace_listfolder://listget_folder_listquiz://listget_quiz_listquiz://{id}/structureget_quiz_structurequiz://{id}/answersget_quiz_answersquiz://{id}/hidden_optionsget_quiz_hidden_optionsquiz://{id}/textsget_quiz_textsquiz://{id}/variablesget_quiz_variablesquiz://{id}/summaryget_quiz_summaryquiz://{id}/reportget_quiz_reportquiz://{id}/widgets_hiddenget_quiz_widgets_hiddenquiz://{id}/report_filtersget_quiz_report_filtersquiz://{id}/report/{uuid}/filesget_quiz_report_filesquiz://{id}/report/{uuid}/inputsget_quiz_report_inputstheme://listget_theme_listtheme://{id}/detailsget_theme_detailspromocode://listget_promocode_listpromocode://{id}/codesget_promocode_codes
Пользователь и воркспейсы
user://me
Возвращает базовую информацию о текущем авторизованном пользователе. Структура ответа:
| Поле | Тип | Описание |
|---|---|---|
id |
integer |
ID пользователя |
email |
string |
Почта пользователя |
language |
string |
Язык интерфейса |
workspace |
object |
Текущее рабочее пространство |
workspaces |
array |
Права пользователя по каждому рабочему пространству, где он владелец или принятый участник |
Элемент workspaces[]:
| Поле | Тип | Описание |
|---|---|---|
id, name |
integer, string |
Рабочее пространство |
is_owner |
boolean |
Владелец: право не проверяется, в access все значения allowed |
role, role_id |
string\|null, integer\|null |
Роль участника; у владельца null |
access |
object |
Имя права → allowed (разрешено), partially (только свои объекты), forbidden (запрещено). Право, которого в роли нет, считается запрещённым |
folder_access |
array |
Отличия по папкам: { folder_id, name, access }. В этих папках действуют эти значения, в остальных — access |
blocked |
string\|null |
invite_not_accepted — приглашение не принято, email_not_confirmed — почта не подтверждена. Пока причина не снята, права не действуют независимо от значений |
Ассистенту это стоит читать до действий, а не после отказа: по access видно, что разрешено, без пробных вызовов. Тот же расчёт применяет проверка права при вызове инструмента — расхождений между «сказано» и «сделано» нет.
workspace://list
Возвращает список доступных рабочих пространств. Для OAuth — только выбранное пространство, для API-ключа — все доступные пользователю. Структура ответа: Общий объект с ключами:
| Поле | Тип | Описание |
|---|---|---|
total |
integer |
Общее количество всех пространств |
owned |
array |
Массив ваших пространств (id, name, is_default) |
shared |
array |
Массив гостевых пространств (id, name, owner_id) |
Папки и опросы
folder://list
Список папок в области доступа текущего подключения. Структура ответа:
| Поле | Тип | Описание |
|---|---|---|
total |
integer |
Общее количество папок |
items |
array |
Массив папок: [{"id": 1, "name": "Название"}] |
quiz://list
Список опросов в области доступа подключения. Ресурс не применяет query-фильтры и возвращает total и items. Для фильтра type (regular/micro) и пагинации используйте get_quiz_list: при непустых аргументах инструмент также возвращает returned, количество элементов текущей выдачи.
Структура ответа:
| Поле | Тип | Описание |
|---|---|---|
total |
integer |
Общее количество подходящих опросов |
items |
array |
Массив опросов: [{"id": 1, "name": "Тест", "answer_count": 0, "url_shared": "..."}] |
Структура и конфигурация опроса
quiz://{id}/structure
Полная структура элементов и виджетов опроса. Это главный ресурс для работы с содержимым форм. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Структура ответа:
| Поле | Тип | Описание |
|---|---|---|
ids |
array |
Массив UUID виджетов, определяющий их порядок вывода |
entities |
object |
Полная конфигурация и настройки каждого виджета (ключ - UUID) |
options |
array |
Дополнительные внутренние опции |
access_limits |
object |
Ограничения прохождения, только на чтение (менять — update_quiz_settings) |
access_limits отвечает на два вопроса, которые по публичному ответу опроса не разобрать: почему опрос отвечает отказом и почему человек не проходит его второй раз.
| Поле | Тип | Что значит |
|---|---|---|
available_devices |
array |
Разрешённые типы устройств (desktop, mobile, tablet). Клиент, устройство которого не распознано — например запрос без обычного user-agent, — под фильтр не попадает и получает отказ «устройство не допущено» (blocked_by_device) |
session_check_method |
array |
Чем опрос узнаёт прежнего респондента (cookie и прочие) |
multiple_ip |
boolean |
Разрешено ли несколько прохождений с одного IP |
limit_answer_count_enabled, limit_answer_count_value, limit_answer_count_mode |
boolean, integer, string |
Общий предел числа ответов. Исчерпан — опрос закрывается для всех сразу, а не для конкретного человека |
ip_list_enabled |
boolean |
Включены ли белый и чёрный списки IP |
use_password |
boolean |
Вход по паролю |
show_captcha |
boolean |
Капча перед прохождением |
close_quiz_enabled |
boolean |
Опрос закрыт автором |
Версии опроса у поля нет: значения читаются из локальной версии, то есть показывают то, что применится после публикации. Локальной версии нет — приходит пустой объект.
quiz://{id}/texts
Пользовательские и стандартные надписи внутри опроса (например, текст "Далее", "Завершить"). Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Структура ответа: Массив объектов текста:
| Поле | Тип | Описание |
|---|---|---|
code |
string |
Системный код надписи (button_next, button_done и др.) |
text |
string |
Пользовательский текст надписи |
quiz://{id}/variables
Скрытые переменные опроса (extra fields). Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Структура ответа: Массив объектов скрытых переменных:
| Поле | Тип | Описание |
|---|---|---|
field_id |
string |
UUID скрытой переменной |
name |
string |
Имя переменной |
quiz://{id}/hidden_options
Служебные конфигурационные опции всего опроса в целом. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Структура ответа: Массив активных скрытых опций:
| Поле | Тип | Описание |
|---|---|---|
id |
integer |
Внутренний ID опции |
name |
string |
Ключ опции (например, redirect_url) |
value |
string |
Значение опции |
quiz://{id}/widgets_hidden
Скрытая мета-информация конкретных виджетов опроса. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Структура ответа: Массив опций, привязанных к виджетам:
| Поле | Тип | Описание |
|---|---|---|
id |
integer |
Внутренний ID опции |
widget_uuid |
string |
UUID виджета |
name |
string |
Ключ опции |
value |
string |
Значение опции |
Ответы и сводная аналитика
quiz://{id}/answers
Список всех ответов респондентов (submissions). Каждая запись содержит уникальный answer_id.
Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Query-параметры (пример: ?limit=50&is_complete=1):
| Параметр | Тип | Возможные значения | Описание |
|---|---|---|---|
limit |
integer |
от 1 до 100 |
Лимит записей (по умолчанию 20) |
offset |
integer |
любое число |
Сдвиг для пагинации (по умолчанию 0) |
date |
string |
Y-m-d |
Получить результаты только за конкретный день |
is_complete |
boolean |
1/0, true/false |
Фильтр по завершённости (true — завершённые) |
sort |
string |
date_end, date_start |
Поле сортировки (по дате старта или завершения) |
order |
string |
desc, asc |
Направление сортировки |
is_screenout |
boolean |
true/false |
Показать отсеянных логикой опроса (по умолчанию их в выдаче нет) |
is_deleted |
boolean |
true/false |
Выбрать мягко удалённые ответы из корзины (по умолчанию исключены); скрытие is_hide — отдельный признак |
unique_link_group_id |
integer |
ID набора | Только ответы набора уникальных ссылок (manage_quiz_unique_links), на любом тарифе |
unique_link_ids |
array |
JSON-массив или через запятую: [501,502], 501,502 |
Только ответы этих ссылок набора; без unique_link_group_id не учитывается |
Инструмент get_quiz_answers принимает те же параметры, включая is_screenout, is_deleted и срез по уникальным ссылкам. В проверенной реализации JSON is_complete: false этого инструмента теряется при преобразовании query и работает как отсутствие фильтра. Для незавершённых ответов используйте ресурс quiz://123/answers?is_complete=false; подробности — в справочнике чтения. У каждого ответа есть поле unique_link — {id, label, group_id, group_name} или null для основного адреса опроса.
Структура ответа: Объект с данными пагинации:
| Поле | Тип | Описание |
|---|---|---|
total |
integer |
Общее количество подходящих ответов |
offset |
integer |
Текущий сдвиг |
items |
array |
Массив детальных ответов респондента с answer_id |
quiz://{id}/summary
Сводная аналитика опроса (воронка конверсий, типы устройств, география).
У опроса на сайте (type = micro) форма ответа другая: quiz_type, is_connected, site_domain и воронка показов на чужой странице. Своей страницы у такого опроса нет, поэтому визитов тоже нет, и обычная сводка отдала бы нули. Состав полей — в описании get_quiz_summary, tools-read.md.
Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Развёрнутые отчёты (Reports)
quiz://{id}/report
Детальный отчёт по виджетам со статистикой. При наличии фильтров возвращает report_uuid.
Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
Параметры чтения отчёта зависят от сохранённых фильтров и статусов. is_complete не гарантирует отдельный срез незавершённых ответов: у отчёта приоритет имеют сохранённые statuses. Для явных параметров, дат и отбора вопросов используйте get_quiz_report и generate_filtered_report; условия формирования и сохранения фильтров описаны в инструментах отчётов.
quiz://{id}/report_filters
Возвращает сохранённые фильтры пользователя для отчётов этого опроса. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
quiz://{id}/report/{report_uuid}/inputs
Текстовые/числовые ответы респондентов на input-like виджеты (input, fio, email, phone, datetime, number). Для number поле result возвращается строкой.
Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
report_uuid |
string |
(Обязательный) UUID отчёта |
Query-параметры:
| Параметр | Тип | Описание |
|---|---|---|
widget_id |
string |
ID (UUID) виджета |
widget_hash |
string |
Hash виджета (из структуры) |
limit |
integer |
Лимит записей (по умолчанию 50) |
offset |
integer |
Сдвиг (пагинация, начиная с 0) |
quiz://{id}/report/{report_uuid}/files
Загруженные пользователями файлы (ответы на виджет загрузки файла). Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID опроса |
report_uuid |
string |
(Обязательный) UUID отчёта |
Query-параметры: Как у inputs (widget_id, widget_hash, limit, offset).
Темы оформления
theme://list
Список тем оформления (публичных и приватных из workspace). Структура ответа: Массив объектов тем:
| Поле | Тип | Описание |
|---|---|---|
id |
integer |
ID темы оформления (нужен для apply_quiz_theme) |
name |
string |
Название темы |
theme://{id}/details
Детальные настройки указанной темы: цвета фона, шрифты, закругления кнопок и т.д. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID темы |
Промокоды
promocode://list
Списки групп промокодов в рабочем пространстве. Query-параметры:
| Параметр | Тип | Описание |
|---|---|---|
workspace_id |
integer |
(Обязательный) ID рабочего пространства |
promocode://{id}/codes
Коды в конкретном списке. Параметры ресурса:
| Параметр | Тип | Описание |
|---|---|---|
id |
integer |
(Обязательный) ID списка промокодов |
Query-параметры:
| Параметр | Тип | Описание |
|---|---|---|
workspace_id |
integer |
(Обязательный) ID рабочего пространства |
quiz_id |
integer |
Только коды, выданные этим опросом. Не передан — коды всего списка |
search, used, sort, order, limit, offset |
— | Поиск и сортировка, как в инструменте get_promocode_codes |
Технические детали протокола
Транспорт и версии
Эндпоинт — POST https://mcp.webask.io/mcp/v1, транспорт HTTP, формат JSON-RPC 2.0. Для авторизации передайте OAuth-токен или API-ключ в заголовке Authorization: Bearer <ACCESS_TOKEN_OR_API_KEY>.
Поддерживаемые ревизии реализации WebAsk: 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05.
До 2025-11-25 включительно клиент начинает с initialize. Для 2026-07-28 клиент указывает версию в каждом запросе; initialize не требуется. server/discover возвращает поддерживаемые версии и возможности сервера. Примеры ниже описывают контракт WebAsk на 08.10.2026.
Методы
| Метод | Назначение |
|---|---|
server/discover |
Версии, возможности и описание сервера |
initialize |
Согласование подключения для прежних ревизий |
tools/list |
Инструменты, доступные текущему подключению |
tools/call |
Вызов инструмента с name и arguments |
resources/list |
6 ресурсов с конкретным URI |
resources/templates/list |
13 шаблонов URI с подстановками |
resources/read |
Чтение конкретного URI, шаблон нужно раскрыть |
prompts/list |
Список шаблонов запросов |
prompts/get |
Получение шаблона по имени |
Запросы ревизии 2026-07-28
Каждый запрос содержит совпадающую версию в заголовке MCP-Protocol-Version и params._meta["io.modelcontextprotocol/protocolVersion"], а метод — в заголовке Mcp-Method и поле method.
Для tools/call, resources/read и prompts/get требуется ещё Mcp-Name:
| Метод | Значение Mcp-Name должно совпадать с |
|---|---|
tools/call |
params.name — имя инструмента |
resources/read |
params.uri — полный URI ресурса |
prompts/get |
params.name — имя шаблона |
Для URI применяется именно Mcp-Name. Цель с символами, которые нельзя передать в заголовке напрямую, кодируется в виде =?base64?…?=.
Список инструментов
POST /mcp/v1 HTTP/1.1
Host: mcp.webask.io
Authorization: Bearer <ACCESS_TOKEN_OR_API_KEY>
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/list
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {"_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28"}}
}Вызов инструмента чтения
POST /mcp/v1 HTTP/1.1
Host: mcp.webask.io
Authorization: Bearer <ACCESS_TOKEN_OR_API_KEY>
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_quiz_structure
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_quiz_structure",
"arguments": {"quiz_id": 123},
"_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28"}
}
}Чтение ресурса
POST /mcp/v1 HTTP/1.1
Host: mcp.webask.io
Authorization: Bearer <ACCESS_TOKEN_OR_API_KEY>
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: resources/read
Mcp-Name: quiz://123/structure
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/read",
"params": {
"uri": "quiz://123/structure",
"_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28"}
}
}Успешный result этой ревизии содержит resultType: "complete". Подсказки кеширования:
| Ответ | ttlMs |
cacheScope |
|---|---|---|
| Списки инструментов, ресурсов, шаблонов ресурсов и prompts | 300000 |
private |
resources/read |
0 |
private |
server/discover |
3600000 |
public |
Эти поля относятся к новой ревизии. В старые ответы они не добавляются.
Запросы прежних ревизий
Пример согласования 2025-06-18:
POST /mcp/v1 HTTP/1.1
Host: mcp.webask.io
Authorization: Bearer <ACCESS_TOKEN_OR_API_KEY>
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "example-client", "version": "1.0"}
}
}После согласования пример тела запроса шаблонов ресурсов:
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/templates/list",
"params": {}
}Для новой ревизии добавьте _meta и совпадающие заголовки, как в примерах выше.
Данные в результате инструмента
tools/call возвращает результат в JSON-RPC result. У большинства инструментов content[0] — текст сообщения, а дополнительные данные продублированы JSON-текстом в content[1] и соседними ключами result. При отсутствии дополнительных данных второй блок отсутствует. Иллюстративный полный ответ прежней ревизии:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{"type": "text", "text": "Список получен"},
{"type": "text", "text": "{\"items\":[],\"total\":0}"}
],
"isError": false,
"items": [],
"total": 0
}
}Инструменты, которые читают ресурсы (например, get_quiz_structure), возвращают JSON данных текстом уже в content[0]. Поэтому клиент не должен считать, что данные всегда во втором блоке. resources/read использует отдельную оболочку result.contents с URI, MIME-типом и текстом ресурса.
В справочнике фрагменты с заголовком «Данные результата» или «Полезная нагрузка» показывают содержимое данных без всей оболочки. Клиент, который передаёт модели только content, должен сохранить все текстовые блоки.
Ошибки
Ошибка инструмента — result.isError: true. Сообщение лежит в content, а детали валидации при их наличии также повторяются JSON-текстом в следующем блоке. Это отличается от ошибки JSON-RPC, где верхнее поле error заменяет result.
{
"jsonrpc": "2.0",
"id": 4,
"error": {"code": -32602, "message": "Tool not found: nonexistent_tool"}
}| Код JSON-RPC | Причина | HTTP |
|---|---|---|
-32022 |
Ревизия не поддерживается; data сообщает запрошенную и поддерживаемые версии |
400 |
-32020 |
Обязательного заголовка нет или версия, метод, цель расходятся с телом | 400 |
-32601 |
Неизвестный метод | 404 для 2026-07-28, 200 для прежних |
-32602 |
Неверные параметры или недоступное имя инструмента | Зависит от обработчика запроса |
Если в примере tools/call заменить Mcp-Name: get_quiz_structure на другое имя или удалить этот заголовок, новая ревизия вернёт HTTP 400 / -32020. Если версия не поддерживается, используйте одну из версий из ответа -32022.
Типичные сценарии использования
1. Получить список опросов и структуру конкретного
1. Вызываем tool: get_quiz_list → получаем список опросов с ID
(или читаем ресурс: quiz://list — для клиентов с поддержкой resources/read)
2. Вызываем tool: get_quiz_structure(quiz_id) → получаем структуру виджетов
(или читаем ресурс: quiz://{id}/structure)2. Работа с ответами
1. Вызываем tool: get_quiz_answers(quiz_id) → получаем ответы (с answer_id)
(или читаем ресурс: quiz://{id}/answers)
2. Вызываем tool: tag_answer (добавить теги) или toggle_answer_visibility (скрыть/показать)3. Экспорт с фильтрацией
1. Вызываем tool: generate_filtered_report (quiz_id, dateFrom/dateTo в формате d.m.Y, фильтры)
→ получаем report_uuid фильтрованного отчёта
⚠ Формат дат здесь d.m.Y (например 01.01.2024), тогда как get_quiz_report использует Y-m-d
2. Вызываем tool: get_quiz_report_files(quiz_id, report_uuid, widget_id, widget_hash)
или get_quiz_report_inputs(quiz_id, report_uuid, widget_id, widget_hash) → детальные ответы по виджетам
(widget_id и widget_hash берутся из get_quiz_structure)
3. Вызываем tool: export_filtered_report_pdf (quiz_id) → получаем ссылку на PDF
⚠ Инструменты export_filtered_report_pdf и export_filtered_report_word принимают только quiz_id;
report_uuid передавать не нужно — экспорт строится по последнему состоянию отчёта опроса4. Добавление промокодов
1. Вызываем tool: create_promocode_group → создаём список с первыми кодами → получаем list_id
2. (при необходимости) Вызываем tool: add_promocodes → добавляем ещё коды в список
3. Вызываем tool: get_promocode_codes(list_id, workspace_id) → проверяем добавленные коды
(или читаем ресурс: promocode://{list_id}/codes)5. Применить тему и сразу получить структуру опроса
1. Вызываем tool: get_theme_list → получаем список доступных тем с ID
(или читаем ресурс: theme://list)
2. Вызываем tool: apply_quiz_theme (quiz_id, theme_id)
→ в ответе сразу доступно поле quiz с widgets, hidden_options и meta — дополнительный
вызов get_quiz_structure не нуженБезопасное изменение логики
- Прочитайте актуальную структуру через
get_quiz_structureи сохраните существующие карты условий. - Измените нужное правило в локальной копии полной карты. Значение
savedLogic[widget_uuid]— массив групп правил. - Передайте полную изменённую карту в
update_quiz_logic. Переданная карта заменяет прежнюю целиком; пропущенные карты сохраняются с очисткой ссылок на удалённые вопросы. Пустой объект{}очищает карту. - Прочитайте структуру повторно и проверьте результат. Требуется право
edit_quiz; изменения конструктора действуют для респондентов после публикации.
Пример полной структуры логики и условий — в разделе редактирования опроса.