Справочник описывает текущий интерфейс каждого инструмента Альбато MCP, типичные сценарии использования и логику решений. Как подключить агента вы можете найти в статье Быстрый старт.
| Параметр | Значение |
|---|---|
| Эндпоинт | <MCP_SERVER_URL>/mcp |
| Авторизация | Authorization: Bearer <virtual_key> — виртуальный ключ вида mcp_vk_... (рекомендуется). Для обратной совместимости принимается и прямой токен Альбато. См. статью Виртуальные ключи. |
1. find_action
Находит сервис (партнёра), его подходящие действия и существующие подключения пользователя. Вызывается всегда первым. Всегда принимает массив queries — один вызов на весь сценарий.
Что видит агент
Найти сервисы, их действия и доступные подключения. Перед вызовом определите все сервисы и действия, которые нужны для всего сценария — передайте их одним вызовом.
Не вызывайте find_action несколько раз для разных шагов одного сценария. Для операций, создающих новый объект (заметку, задачу, звонок, письмо), который нужно связать с другим объектом (сделкой, контактом, компанией), включите в план отдельное действие связывания (например, actionQuery: "associate note").
Всегда передавайте массив queries — один элемент на нужный сервис/действие. Используйте этот инструмент перед get_action_schema и run_action_sync. Если по serviceQuery найдено несколько партнёров, статус — multiple_partners: вызовите снова с более точным serviceQuery.
Если connections пуст или у какого-то действия connected: false, используйте create_connection_link с partnerId, чтобы получить ссылку для подключения пользователя. Если connections содержит несколько элементов, спросите пользователя, какой использовать. Каждый элемент ответа содержит поле status: success, not_found, multiple_partners или error.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
queries | array | Да | Массив объектов { serviceQuery, actionQuery }. Передайте все нужные сервисы/действия одним вызовом — они выполняются параллельно. |
Поля объекта в queries:
| Поле | Тип | Описание |
|---|---|---|
serviceQuery | string | Название сервиса, например «HubSpot» |
actionQuery | string | Название действия, например «find deal» |
Ответ
Всегда массив — один элемент на каждый запрос:
[
{
"index": 0,
"status": "success",
"partnerId": 10001,
"partnerTitle": "HubSpot",
"actions": [
{
"triggerActionId": 20001,
"title": "Find deal",
"description": "...",
"hasCredentialWizard": false
}
],
"connections": [
{
"credentialId": 90001,
"title": "My HubSpot account",
"isDefault": false,
"createdAt": "2026-06-23 21:29:47"
}
]
},
{
"index": 1,
"status": "not_found",
"query": { "serviceQuery": "Unknown", "actionQuery": "..." }
}
]
Статусы элемента: success, not_found, multiple_partners, error. При multiple_partners — вызовите снова с более точным serviceQuery.
Партнёры с нативным адаптером (например, HubSpot, если для контракта включена нативная маршрутизация) возвращают другой формат:
- каждый элемент в
actionsвключаетconnected: <boolean>— есть ли у пользователя хотя бы одно подключение к адаптеру; connections— список{ connectionId, displayName, adapterId, source: "native" }вместоcredentialId;- если подключений нет —
actionsпуст, а в ответе есть_hint, указывающий наcreate_connection_link.
Почему так устроено
- Один запрос (партнёр + действия + подключения) вместо трёх отдельных — меньше обращений к модели. Каждое обращение стоит примерно 3–8 секунд.
- Всегда массив — единый интерфейс без переключения между одиночным и массовым режимом. Агент всегда знает формат ответа; один запрос покрывает весь сценарий вместо N последовательных вызовов.
hasCredentialWizardв ответе — признак того, что действию нуженget_credential_wizard_stepвместо обычногоcredentialId. Нужен сервисам с дополнительными параметрами подключения (например, Google Таблицы: аккаунт → таблица → лист).
2. get_action_schema
Возвращает схему входных полей действия. Должен вызываться перед run_action_sync. Всегда принимает массив actions.
Что видит агент
Получить схемы входных полей действий. Всегда передавайте массив actions — один элемент на действие. Для действий нативного адаптера (triggerActionId начинается с native:) credentialData не требуется — хаб сам определяет токен. Для обычных действий Альбато credentialData обязателен: используйте {"0": {"value": <credentialId>}}, где credentialId берётся из connections ответа find_action; для действий с мастером подключения передавайте полный currentCredentialData из завершённого мастера. С fieldFilter: возвращает подходящие поля и обязательные поля — этого достаточно для run_action_sync. Без fieldFilter: возвращает только обязательные поля. Если обязательных полей нет, возвращается пустой массив variables с подсказкой _hint — всегда делайте повторный запрос с fieldFilter. Каждый элемент ответа содержит поле status: success или error.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
actions | array | Да | Массив объектов — все запросы выполняются параллельно |
Поля объекта в actions:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
partnerId | number | Да | — |
triggerActionId | number | Да | — |
credentialData | object | Да* | Обычное подключение: {"0": {"value": <credentialId>}}. Действие с мастером: финальный currentCredentialData из завершённого мастера. *Не требуется для действий нативного адаптера (triggerActionId начинается с native:) — токен определяется автоматически |
fieldFilter | string[] | Нет | Отдельные слова для поиска полей по имени/подписи — ["note", "body", "text"], не фразы. Без фильтра — только обязательные поля |
useCache | boolean | Нет | По умолчанию true. Схемы кэшируются на 10 минут |
cacheTtl | number | Нет | Время жизни кэша в секундах, максимум 86400 |
Ответ
Всегда массив:
[
{
"index": 0,
"status": "success",
"variables": [
{ "name": "query", "label": "Search query", "type": "string", "isRequired": true, "isReadOnly": false },
{ "name": "hs_note_body", "label": "Text", "type": "string", "isRequired": false, "isReadOnly": false }
],
"rowSections": [...]
}
]
Статусы: success, error. Если полей нет и fieldFilter не передавался — variables пуст, а в ответе есть подсказка _hint добавить fieldFilter.
Почему так устроено
credentialData— единый параметр для обоих типов подключения действий Альбато. Обычное действие:{"0": {"value": credentialId}}. Действие с мастером: полный накопленныйcurrentCredentialData. Отдельного параметраcredentialIdнет — это упрощает интерфейс. Для действий нативного адаптера параметр не нужен — хаб сам определяет OAuth-токен пользователя.- Схема не возвращается целиком по умолчанию — у некоторых действий 50–200 полей. Без
fieldFilter— только обязательные поля. СfieldFilter— обязательные поля плюс совпадения по ключевым словам. fieldFilterиспользует отдельные слова, а не фразы — поиск подстроки по имени и подписи поля. Полеhs_note_body(подпись «Text») не найдётся по «note body» (пробел ≠ подчёркивание), но найдётся по «text». Если поле не нашлось с первой попытки — не пробуйте другие слова: действие просто его не поддерживает.
3. run_action_sync
Выполняет действие синхронно и возвращает результат.
Что видит агент
Выполнить действие синхронно. Всегда вызывайте get_action_schema перед этим инструментом — никогда не угадывайте имена полей. Используйте поле name каждой переменной как ключ в runnerData. Для действий нативного адаптера (triggerActionId начинается с native:) credentialData не требуется — хаб сам определяет токен. Если у пользователя несколько подключений к этому адаптеру, передайте connectionId из списка connections ответа find_action; если подключение одно, оно выбирается автоматически. Для обычных действий Альбато credentialData обязателен: используйте {"0": {"value": <credentialId>}}; для действий с мастером передавайте полный currentCredentialData из завершённого мастера.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
partnerId | number | Да | — |
triggerActionId | number | Да | — |
connectionId | string | Нет | Только для действий нативного адаптера с несколькими подключёнными аккаунтами — connectionId из списка connections ответа find_action. Если подключение одно, оно выбирается автоматически и параметр можно опустить |
credentialData | object | Да* | Обычное подключение: {"0": {"value": <credentialId>}}. Действие с мастером: финальный currentCredentialData. *Не нужен для действий нативного адаптера — для остальных действий без него запрос завершится ошибкой |
runnerData | object | Да | Данные для выполнения — поля из схемы get_action_schema |
useCache | boolean | Нет | По умолчанию false. Можно включить для действий только на чтение (получить сделку, получить контакт) |
cacheTtl | number | Нет | По умолчанию 60 секунд |
Ответ
{
"success": true,
"albatoResponse": {
"success": true,
"data": {
"eventData": [{
"data": {
"variables": [
{ "n": "Deal ID", "v": "500000000001" },
{ "n": "Deal Name", "v": "Cool deal" }
]
}
}]
}
}
}
Почему так устроено
- Всегда синхронно — Альбато поддерживает и асинхронный режим, но он неудобен для агентов: требует опроса статуса, что добавляет обращения к модели. Синхронный режим проще и быстрее для агента, даже несмотря на то, что держит HTTP-соединение открытым на всё время выполнения.
get_action_schemaобязателен перед этим вызовом — это явно указано в описании инструмента. Без схемы агент угадывает имена полей и получает ошибку валидации с последующим повтором, что добавляет 2 лишних обращения к модели.credentialDataунифицирован для действий Альбато — один параметр для обычных действий и действий с мастером. Для действий нативного адаптера он не нужен — вместо этого передаётсяconnectionId, когда аккаунтов несколько.useCacheдля запросов только на чтение — агент часто запрашивает одни и те же данные несколько раз за сессию (например, данные сделки на разных этапах). Кэширование избавляет от повторных обращений к API Альбато.
4. get_credential_wizard_step
Используется для действий с hasCredentialWizard=true. Пошагово собирает настройки подключения через многошаговый диалог.
Что видит агент
Используйте, когда у действия hasCredentialWizard=true. Пошагово собирает настройки подключения (например, аккаунт → таблица → лист). Порядок действий: 1) Если credentialId уже известен из find_action, начните сразу с {"0":{"value":<credentialId>}} — пропустите пустой первый вызов. Иначе вызовите с {}, чтобы получить варианты для шага 0. 2) Покажите варианты пользователю, получите его выбор. 3) Вызовите снова с currentCredentialData, собранным из выбранных значений: {"0":{"value":<выбор>}, ...}. 4) Повторяйте, пока не получите complete=true. 5) Передайте финальный currentCredentialData как credentialData в get_action_schema и run_action_sync.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
triggerActionId | number | Да | — |
currentCredentialData | object | Нет | Значения, накопленные к этому моменту: {"0":{"value":90002},"1":{"value":"40002"}}. Не передавайте или передайте {} для первого вызова |
Ответ
{
"complete": false,
"steps": [
{ "index": 0, "label": "Select account", "values": null },
{
"index": 1, "label": "Select spreadsheet",
"values": { "40001": "Test sheet for automation", "40002": "MCP demo spreadsheet" }
}
]
}
Когда все шаги заполнены — complete: true. Финальный currentCredentialData передаётся как credentialData в get_action_schema и run_action_sync.
Почему так устроено
- Некоторым сервисам недостаточно просто OAuth-подключения — нужно ещё выбрать конкретный объект внутри аккаунта: Google Таблицы (какая таблица?), Airtable (какая база?), Notion (какая страница?). Эти параметры нельзя зашить в схему заранее — они зависят от данных конкретного пользователя.
- Пошаговый подход, а не одна большая форма — потому что каждый шаг может зависеть от предыдущего. Список листов Google Таблиц нельзя получить, пока не выбрана таблица.
- Если
credentialIdуже известен (пришёл изfind_action) — первый шаг можно пропустить, передав его сразу. Это экономит один вызов.
5. create_connection_link
Создаёт ссылку для подключения аккаунта пользователя к сервису.
404, обратитесь к менеджеру Альбато.Что видит агент
Создать ссылку для авторизации сервиса пользователем. Для партнёров с нативным адаптером (например, HubSpot) возвращает oauthUrl и adapterId — откройте ссылку в браузере, затем вызовите check_connection_status с {"adapterId": "<adapterId>"}. Каждый вызов создаёт новое подключение (аккаунт) — вызывайте снова, чтобы добавить ещё один аккаунт того же сервиса. Для обычных партнёров Альбато возвращает sharingId и linkUrl — передайте пользователю, затем вызовите check_connection_status с {"sharingId": <sharingId>}.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
partnerId | number | Да | — |
title | string | Нет | Название подключения, которое увидит пользователь (только для режима Альбато) |
Ответ
Партнёр с нативным адаптером (например, HubSpot, PKCE OAuth):
{
"mode": "native_oauth",
"adapterId": "hubspot-native",
"oauthUrl": "https://app.hubspot.com/oauth/authorize?...",
"humanActionRequired": true,
"nextStep": "open_oauth_url_in_browser_then_call_check_connection_status",
"checkWith": "check_connection_status with {\"adapterId\": \"hubspot-native\"}"
}
Обычный партнёр Альбато:
{
"sharingId": 30001,
"linkUrl": "https://albato.com/connect/...",
"mode": "albato",
"status": "waiting",
"humanActionRequired": true,
"nextStep": "share_link_with_user_and_wait_confirmation"
}
Почему так устроено
Пользователь никогда не передаёт свои OAuth-учётные данные агенту напрямую — это было бы небезопасно. Для партнёров Альбато агент получает одноразовую ссылку, пользователь проходит стандартный OAuth-поток Альбато, а сервер получает credentialId по завершении. Для партнёров с нативным адаптером хаб сам управляет OAuth-потоком с провайдером (HubSpot и т.д.) через защищённый PKCE-поток — агент никогда не видит токены пользователя. Ссылка для OAuth действует 10 минут — если не завершить за это время, вызовите create_connection_link снова, чтобы получить новую.
Каждый вызов для нативного адаптера создаёт новое подключение (аккаунт) — повторный вызов позволяет добавить второй аккаунт того же сервиса, не заменяя первый.
6. check_connection_status
Проверяет статус подключения. Нативный адаптер — по adapterId, Альбато — по sharingId.
Что видит агент
Проверить статус подключения. Для подключений нативного адаптера: передайте {"adapterId": "<adapterId>"} (пришёл из create_connection_link) — вернётся список connections с connectionId и displayName для каждого авторизованного аккаунта. Для подключений Альбато: передайте {"sharingId": <sharingId>}. Попросите пользователя сначала завершить подключение, затем вызовите один раз для проверки — не опрашивайте автоматически.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
adapterId | string | Нет* | Поток нативного адаптера — из ответа create_connection_link |
sharingId | number | Нет* | Поток Альбато — из ответа create_connection_link |
*Передаётся ровно один из двух, в зависимости от того, какой поток вернул create_connection_link.
Ответ
Поток нативного адаптера:
{
"adapterId": "hubspot-native",
"connected": true,
"connections": [
{ "connectionId": "a1b2c3...", "displayName": "My Team" }
],
"humanActionRequired": false,
"nextStep": "continue_with_action"
}
Поток Альбато:
{ "status": "ready", "credentialId": 90001, "humanActionRequired": false, "nextStep": "continue_with_action" }
Статусы потока Альбато: waiting, ready, oauth_pending, revoked.
Почему так устроено
Агент вызывает инструмент один раз, после подтверждения пользователя — автоматического опроса нет. Это осознанное решение:
- Автоматический опрос — лишние обращения к модели, пока пользователь проходит OAuth.
- Гонка состояний: если агент проверит до завершения подключения, он получит
pending/waitingи может столкнуться с ошибкой авторизации. - Пользователь лучше знает, когда он нажал «Разрешить» — его подтверждение («готово») и есть сигнал.
7. disconnect_adapter
Удаляет одно или все подключения нативного адаптера (отзывает доступ).
404, обратитесь к менеджеру Альбато.Что видит агент
Удалить подключение нативного адаптера (отозвать доступ). Передайте adapterId и при необходимости connectionId, чтобы удалить конкретный аккаунт; без connectionId удаляются все аккаунты этого адаптера.
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
adapterId | string | Да | Например, «hubspot-native» |
connectionId | string | Нет | Конкретный аккаунт для удаления. Без него удаляются все подключения адаптера у пользователя |
Ответ
{ "disconnected": true, "adapterId": "hubspot-native", "connectionId": "a1b2c3..." }
Без connectionId: { "disconnected": true, "adapterId": "hubspot-native", "deletedCount": 2 }.
Почему так устроено
Применяется только к подключениям нативного адаптера, которые требуют авторизации виртуальным ключом (mcp_vk_...). Для подключений Альбато (обычные учётные данные) — см. disconnect_partner ниже. Явное разделение «один аккаунт» / «все аккаунты» защищает от случайного удаления лишних подключений, когда у пользователя несколько аккаунтов одного сервиса.
8. disconnect_partner
Удаляет одно подключение (учётные данные) Альбато к партнёру. Не затрагивает подключения нативного адаптера — для них используйте disconnect_adapter.
404, обратитесь к менеджеру Альбато.Что видит агент
Удалить подключение (учётные данные) Альбато к сервису партнёра. Требует partnerId и credentialId — оба берутся из списка connections ответа find_action или list_connections. Удаляет одну учётную запись; не затрагивает подключения нативного адаптера (для них — disconnect_adapter).
Параметры
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
partnerId | number | Да | Из find_action |
credentialId | number | Да | Из списка connections ответа find_action/list_connections (поле albatoConnections) |
Ответ
{ "disconnected": true, "partnerId": 10001, "credentialId": 90001 }
Ошибка для несуществующего или уже удалённого credentialId:
{
"error": {
"type": "partner_error",
"message": "Albato API request failed.",
"details": { "status": 400, "data": { "success": false, "errors": ["Invalid credential ID"] } }
}
}
Почему так устроено
Принимает только один credentialId за вызов — режима «удалить все подключения этого партнёра» нет. Чтобы удалить несколько учётных записей, вызывайте инструмент по одному разу на каждый credentialId.
9. list_connections
Возвращает все подключения текущего пользователя одним вызовом, без аргументов — и аккаунты нативного адаптера, и обычные учётные данные Альбато, по всем сервисам сразу.
Что видит агент
Получить список всех подключений текущего пользователя по всем сервисам — аргументы не нужны. Возвращает nativeConnections (аккаунты нативного адаптера, авторизованные через OAuth, например HubSpot) и albatoConnections (обычные учётные данные Альбато). Используйте, чтобы показать пользователю, что уже подключено, или чтобы найти connectionId/credentialId без вызова find_action.
Параметры
Нет — инструмент не принимает аргументов.
Ответ
{
"nativeConnections": [
{
"adapterId": "hubspot-native",
"adapterTitle": "HubSpot",
"connectionId": "a1b2c3...",
"displayName": "My Team",
"expiresAt": "2026-08-21 19:40:00",
"createdAt": "2026-07-01 10:00:00"
}
],
"albatoConnections": [
{
"credentialId": 90001,
"partnerId": 10001,
"partnerTitle": "HubSpot",
"title": "My HubSpot account",
"isDefault": false,
"environment": "albato",
"source": "albato",
"createdAt": "2026-06-23 21:29:47"
}
]
}
nativeConnections пуст, если подключения нативного адаптера не включены для вашего контракта, либо если вы авторизуетесь прямым токеном Альбато вместо виртуального ключа — инструмент не завершается ошибкой, а просто опускает эту часть.
Почему так устроено
find_actionуже возвращает подключения, но только для одного конкретного партнёра — чтобы узнать всё, что подключено, агенту пришлось бы перебирать сервисы наугад.list_connectionsдаёт полную картину одним вызовом.partnerTitleвalbatoConnections— необработанные учётные данные Альбато содержат толькоpartnerId, без человекочитаемого имени сервиса. Хаб подставляетpartnerTitleдля каждой записи — без этого ни агент, ни пользователь не поняли бы, к какому сервису относится подключение.- Инструмент всегда присутствует в
tools/list(в отличие отcreate_connection_link/check_connection_status/disconnect_adapter) — часть с Альбато работает независимо от того, включены ли подключения нативного адаптера для вашего контракта.
Типичные сценарии
1. Выполнить действие (существующее подключение)
find_action(queries: [{ serviceQuery: "HubSpot", actionQuery: "find deal" }])
→ [{ status:"success", partnerId, triggerActionId, connections:[{ credentialId:90001, ... }] }]
get_action_schema(actions: [{ partnerId, triggerActionId, credentialData: {"0":{"value":90001}}, fieldFilter: ["deal","name"] }])
→ [{ status:"success", variables:[...] }]
run_action_sync(partnerId, triggerActionId, credentialData: {"0":{"value":90001}}, runnerData)
→ result
2. Несколько сервисов
find_action(queries: [{ "HubSpot", "find deal" }, { "Slack", "send message" }])
→ [{ ...hubspot }, { ...slack }]
get_action_schema(actions: [{ hubspot params, credentialData:{"0":{"value":id1}} }, { slack params, credentialData:{"0":{"value":id2}} }])
→ [{ variables... }, { variables... }]
run_action_sync(hubspot, credentialData:{"0":{"value":id1}}) → deal data
run_action_sync(slack, credentialData:{"0":{"value":id2}}) → message sent
3. Действие с мастером (Google Таблицы)
find_action(queries: [{ "Google Sheets", "add row" }])
→ [{ hasCredentialWizard: true, connections:[{ credentialId: 90002, ... }] }]
get_credential_wizard_step(triggerActionId, { "0": { "value": 90002 } })
→ list of spreadsheets
get_credential_wizard_step(triggerActionId, { "0": { "value": 90002 }, "1": { "value": "40002" } })
→ list of sheets
get_credential_wizard_step(triggerActionId, { "0":{...}, "1":{...}, "2":{ "value": "Sheet1" } })
→ complete: true, final currentCredentialData
get_action_schema(actions: [{ partnerId, triggerActionId, credentialData: { "0":{...}, "1":{...}, "2":{...} } }])
→ variables
run_action_sync(partnerId, triggerActionId, credentialData: { "0":{...}, "1":{...}, "2":{...} }, runnerData)
→ result
4. Подключения ещё нет
find_action(queries: [{ "HubSpot", "create contact" }]) → [{ connections: [] }]
create_connection_link(partnerId) → linkUrl, sharingId
[агент отправляет linkUrl пользователю, ждёт подтверждения]
check_connection_status(sharingId) → credentialId: 90001
→ продолжить сценарием 1 (credentialData: {"0":{"value":90001}})
5. Нативный адаптер, несколько подключённых аккаунтов
find_action(queries: [{ "HubSpot", "find deal" }])
→ [{ triggerActionId: "native:...", connected: true,
connections: [{ connectionId: "acc-1", displayName: "My Team" }, { connectionId: "acc-2", displayName: "Sandbox" }] }]
[несколько подключений — спросить пользователя, какой аккаунт использовать]
get_action_schema(actions: [{ partnerId, triggerActionId }]) // credentialData не нужен
→ variables
run_action_sync(partnerId, triggerActionId, connectionId: "acc-2", runnerData)
→ result from the "Sandbox" account
Если у адаптера только одно подключение, connectionId можно не передавать — оно выбирается автоматически.
6. Что подключено / отключить аккаунт
list_connections()
→ { nativeConnections: [{ adapterId: "hubspot-native", connectionId: "acc-2", displayName: "Sandbox", ... }],
albatoConnections: [{ credentialId: 90001, partnerId: 10001, partnerTitle: "HubSpot", title: "My HubSpot account", ... }] }
[показать пользователю, что у него подключено]
disconnect_adapter({ adapterId: "hubspot-native", connectionId: "acc-2" })
→ { disconnected: true, adapterId: "hubspot-native", connectionId: "acc-2" }
disconnect_partner({ partnerId: 10001, credentialId: 90001 })
→ { disconnected: true, partnerId: 10001, credentialId: 90001 }
Архитектурные принципы
Минимизировать число вызовов
Каждый вызов инструмента стоит одно обращение к модели (примерно 3–8 секунд). Каждый инструмент устроен так, чтобы агент получал максимум нужной информации за один вызов. find_action объединяет три операции. Массовый режим объединяет N параллельных запросов.
Описания инструментов как единственная инструкция
Сервер работает с любым MCP-совместимым агентом. Нельзя рассчитывать, что клиент правильно настроил системный промпт. Поэтому каждое правило поведения (обязательный get_action_schema перед run_action_sync, отдельные слова в fieldFilter, проверка статуса только один раз) записано прямо в описаниях инструментов.
Авторизация через виртуальные ключи
При использовании mcp_vk_... настоящий токен Альбато пользователя хранится на сервере в зашифрованном виде и никогда его не покидает. Ваш MCP-клиент настроен с виртуальным ключом, который используется только как заголовок авторизации на уровне транспорта. Ни ваш MCP-клиент, ни модель агента никогда не видят настоящий токен Альбато.
Виртуальный ключ можно отозвать в любой момент, не меняя токен, стоящий за ним. Для обратной совместимости прямой токен Альбато по-прежнему принимается, и в этом случае сервер его не сохраняет — поведение остаётся прежним.