Перейти к содержимому
AISARAISAR

MCP-сервер

Подключите AI-агента к своей рабочей области AISAR по Model Context Protocol.

AISAR предоставляет сервер Model Context Protocol — это позволяет любому MCP-совместимому AI-клиенту (Claude Code, claude.ai, Cursor и другим) работать с вашей рабочей областью через самоописывающиеся инструменты (tools), без написания интеграции под каждый эндпоинт REST API вручную.

Эндпоинт и аутентификация

Сервер работает по протоколу Streamable HTTP:

text
POST https://mcp.aisar.app/mcp/company

Аутентификация — тем же API-токеном компании, который используется для REST API (создаётся в кабинете: Настройки → Системы → API, требует тарифа Business), в заголовке Authorization:

text
Authorization: Bearer 123|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Сервер принимает только токены сервисных аккаунтов — те же токены, что и REST API. Токены мобильных сессий, embed-виджета и сессии браузера отклоняются. Также требуется активная подписка компании.

Транспорт — только Bearer, без cookie-сессий и без OAuth-флоу. Запрос без валидного токена получает 401; токен не того класса — 401/403.

Подключение клиента

Claude Code

bash
claude mcp add --transport http aisar https://mcp.aisar.app/mcp/company \
  --header "Authorization: Bearer YOUR_API_TOKEN"

claude.ai

Settings → Connectors → Add custom connector, URL https://mcp.aisar.app/mcp/company, заголовок Authorization: Bearer YOUR_API_TOKEN.

Обобщённый MCP-клиент (например Cursor)

json
{
  "mcpServers": {
    "aisar": {
      "url": "https://mcp.aisar.app/mcp/company",
      "headers": {
        "Authorization": "Bearer YOUR_API_TOKEN"
      }
    }
  }
}

После подключения вызовите инструмент whoami первым запросом — он подтвердит, к какой компании привязан токен.

Инструменты сервера

Документация

Читают актуальную документацию платформы прямо с сервера — ответы всегда синхронизированы с последним деплоем.

ИнструментНазначение
list_docsСписок доступных документов
list_doc_sectionsЗаголовки разделов документа
get_docДокумент целиком или один раздел
search_docsПолнотекстовый поиск по документации
list_webhook_eventsКаталог событий вебхуков платформы
get_webhook_payload_specТочная схема payload одного события
lookup_error_codeРасшифровка кода ошибки WhatsApp Cloud (Meta), например 131047

Чтение

ИнструментАргументы
whoami
list_channelsstatus?, type?, page, per_page
list_funnels
list_dealsfunnel_id?, stage_id?, status?, search?, page
get_dealdeal_id
search_contactsquery, page
get_contactcontact_id
list_conversationsstatus?, channel_id?, assigned_to_me?, search?, page
get_conversationconversation_id
search_messagesq, conversation_id? (без него — по всей компании), per_page? (макс. 50), page? — ограничено по частоте
list_templateschannel_id?, language?, sendable_only?
list_broadcasts / get_broadcast—, broadcast_id
get_dashboard_summaryperiod? (today/7d/30d)

Каждый ответ содержит явный allow-list полей — учётные данные каналов, provider-ключи, секреты интеграций, токены и пароли никогда не возвращаются.

Запись

Каждый инструмент записи проверяет соответствующее разрешение, работает в рамках компании токена и логируется в аудит.

ИнструментАргументы
send_messageconversation_id, text
send_template_messagechannel_id, contact_id\|conversation_id, template_id, variables?
create_contact / update_contactполя контакта
add_internal_noteconversation_id, text
assign_conversationconversation_id, user_id\|team_id
close_conversationconversation_id
create_deal / update_dealполя сделки (stage_id должен принадлежать воронке)
move_deal_stagedeal_id, stage_id
create_deal_notedeal_id, text

Вебхуки — самообслуживание

ИнструментАргументы
list_integrations
create_webhook_integrationurl, events[], signing_secret?
test_webhookintegration_id\|url
get_webhook_deliveriesintegration_id

URL вебхука проходит тот же SSRF-гард, что и REST-эндпоинт создания интеграций (приватные/loopback/link-local/метаданные-адреса отклоняются, включая DNS-rebinding и закодированные формы IP); на компанию есть лимит числа интеграций; имена событий валидируются по каталогу платформы.

ИИ-агенты и голос

Управление ИИ-агентами компании (включая голосовой профиль) — та же функциональность, что доступна на вкладке «ИИ-агенты» в кабинете. list_ai_agents/get_ai_agent/create_ai_agent/update_ai_agent/activate_ai_agent/deactivate_ai_agent управляют текстовой/чат-стороной агента (промпт, включённые инструменты, guardrails, бюджеты); list_knowledge_documents/create_knowledge_document/delete_knowledge_document — его базой знаний; get_voice_agent/update_voice_agent — опциональным голосовым профилем. Как и у всех инструментов сервера, id компании нигде не передаётся аргументом — область действия всегда «своя компания» из токена.

ИнструментАргументы
list_ai_agentsstatus? (active\|inactive\|suspended)
get_ai_agentinstance_id
create_ai_agentname, provider, model, config (config.system_prompt обязателен), опц. template_id, description, api_key_id, лимиты бюджета
update_ai_agentinstance_id, те же поля, что и create_ai_agent, но частично — меняются только заданные, config сливается с текущим
activate_ai_agent / deactivate_ai_agentinstance_id
list_knowledge_documentsinstance_id?
create_knowledge_documentinstance_id, title, source_type (text\|url), content\|source_url (ограничено по частоте)
delete_knowledge_documentinstance_id, document_id
get_voice_agentinstance_id
update_voice_agentinstance_id + голосовые поля (язык, voice_id, приветствие, follow-up, эскалация, TTS-тюнинг, voice_tools) — меняются только заданные
Голосовые инструменты (get_voice_agent, update_voice_agent) проходят три проверки по порядку: компания состоит в пилоте голосового ИИ → есть право ai_agent.* → на тарифе включена фича voice_ai (Business и выше). Компания вне пилота получает текстовое сообщение об ошибке, а не данные — это ожидаемое поведение, а не сбой.

В update_voice_agent поле voice_tools отвечает только за голосовые-специфичные настройки без аналога в текстовом агенте — на сегодня единственный ключ history ({enabled: bool}, чтение хвоста переписки во время звонка). Любой другой инструмент для голосового агента (CRM, сообщения, передача на человека) включается тем же enabled_tools в update_ai_agent, что и для текстового агента того же instance_id.

Правка системного промпта (update_ai_agent) или базы знаний (create_knowledge_document/delete_knowledge_document) автоматически ставит в очередь ресинк с голосовым вендором для агентов с голосовым профилем — отдельного шага публикации не требуется.

Именованные внешние действия

Именованное внешнее действие — сохранённый «рецепт» вызова одной операции на одном внешнем HTTP API (хост, путь, метод, авторизация, обработка ответа) с типизированными параметрами, которые ИИ-агент заполняет сам при вызове действия по имени. create_external_action/update_external_action/list_external_actions/get_external_action/delete_external_action управляют самим действием; bind_external_action/unbind_external_action привязывают его к конкретному экземпляру агента — само по себе создание действия не даёт ни одному агенту права его вызывать; test_external_action отправляет один реальный тестовый вызов с образцами значений параметров. create_ai_agent_secret/list_ai_agent_secrets создают и перечисляют учётные данные для авторизации действия: значение секрета write-only и никогда никуда не возвращается, в ответе приходит только id (для secret_id) и маскированная подсказка — раньше создание секрета было доступно только через REST, теперь весь путь «секрет → действие → тест → привязка» проходит в MCP. update_ai_agent_secret меняет секрет на месте, сохраняя его id, — это и есть ротация: поле secret необязательное, если его передать, значение заменяется и маскированная подсказка пересчитывается, если не передать — меняются только название, header_name/query_param или allowed_domains, а значение по-прежнему никогда не возвращается; в ответе есть флаг rotated, показывающий, менялось ли оно на самом деле. delete_ai_agent_secret удаляет секрет, но отказывается, пока на него ссылается хотя бы одно действие, — и перечисляет их slug в тексте ошибки, потому что external_actions.secret_id — обычная ссылка, и удаление секрета из-под действия оставило бы его выглядящим настроенным, но падающим при вызове с ничего не объясняющей ошибкой аутентификации; сначала действия нужно переключить на другой секрет или удалить. На практике это значит, что скомпрометированный ключ меняют через update_ai_agent_secret, а не через удаление и пересоздание секрета, — привязки действий к нему при этом не рвутся. list_external_action_calls читает журнал вызовов с фильтрами по действию, исходу и транспорту — без него было невозможно понять, почему конкретный вызов у агента не сработал. Итого тринадцать инструментов. Признак «это операция записи» сервер выводит из HTTP-метода и нигде не принимает как входной параметр — force_write разрешено только поднять GET до уровня записи, понизить POST/PUT/PATCH/DELETE до чтения нельзя. Всё это требует права ai_action.manage, которое по умолчанию выдаётся только роли администратора компании, — оно ОТЛИЧАЕТСЯ от ai_agent.update, обладание одним не подразумевает другое. Функция недоступна компаниям на продукте Kids. Вызов действия работает в обоих транспортах — и в переписке, и в голосовом звонке (управляется полем available_in, см. таблицу ниже).

ИнструментАргументы
create_external_actionname, model_description (от 20 символов — по нему модель решает, КОГДА звать действие), method, base_url (только схема+хост, без {{...}}), опц. path_template/query_template/header_template, body_type+body_template, parameters[] (что заполняет модель), context_bindings[] (что подставляет сервер), secret_id+auth_type, response_config, timeout_ms, retries, available_in, force_write, log_response, опц. slug (неизменяем после создания)
update_external_actionid + любое подмножество полей create_external_action (частично — меняются только заданные), плюс status (draft\|active\|disabled); slug менять нельзя
list_external_actionsstatus? (draft\|active\|disabled)
get_external_actionid
delete_external_actionid (мягкое удаление — привязки к агентам снимаются, история вызовов сохраняется)
bind_external_actioninstance_id, external_action_id, enabled? (по умолчанию true), hint?, confirmation_required? (только для чата)
unbind_external_actioninstance_id, external_action_id
test_external_actionid, parameters? (образцы значений)
create_ai_agent_secretname, auth_type (bearer\|basic\|api_key_header\|api_key_query), secret (значение — write-only, не возвращается), header_name\|query_param (для api_key_*), allowed_domains[] (по факту обязателен — секрет с пустым списком не пройдёт валидацию ни у одного действия)
list_ai_agent_secrets— (только секреты своей компании; значение никогда не возвращается, только preview_hint)
update_ai_agent_secretid, опц. name, secret (новое значение — это и есть ротация; не передан → текущее значение не трогается), header_name\|query_param, allowed_domains[] (полностью заменяет текущий список)
delete_ai_agent_secretid (отказ, если секрет ещё используется хотя бы одним действием — их slug перечисляются в тексте ошибки)
list_external_action_callsaction_id?, outcome? (ok\|refused\|budget_exceeded\|rate_limited\|http_error\|timeout\|blocked), transport? (chat\|voice\|test), per_page?, page?

base_url — это только схема и хост, без {{...}} (адрес действия никогда не зависит от модели); path_template/query_template/header_template/body_template — шаблоны с подстановками {{name}}. У заголовков подстановки урезаны сильнее: header_template может ссылаться только на имена из context_bindings (то, что подставляет сервер), но не на parameters (то, что заполняет модель) — придуманное моделью значение физически не может попасть в HTTP-заголовок, а Authorization/Host/Cookie и ещё несколько имён вообще зарезервированы. Секрет, переданный как secret_id, обязан иметь непустой allowed_domains, покрывающий хост base_url, — это проверяется уже на create_external_action/update_external_action, а не только в момент вызова.

Жизненный цикл действия: create_external_action создаёт его в статусе drafttest_external_action проверяет вызов реальными образцами параметров (работает в любом статусе, включая draft) → update_external_action переводит в activebind_external_action привязывает к агенту. test_external_action ограничен по частоте вызовов (см. «Лимиты и поведение») и НИКОГДА не принимает и не возвращает сырое тело ответа — только model_sees (то, что увидела бы модель) и маскированный request_preview того, что было отправлено. Это намеренное решение: сохранённый base_url можно редактировать, значит он аудируем, но не доверен — возврат сырого тела воссоздал бы SSRF-оракул для чтения именно там, где эта функция защищается от такого класса угроз.

Лимиты и поведение

  • Лимиты частоты (на токен, на компанию): search_messages — 30/мин, send_message и send_template_message — 60/мин, create_webhook_integration — 10/мин, create_knowledge_document — 20/мин, вызовы именованных внешних действий (в переписке и в звонке вместе) — 60/мин на компанию, test_external_action — отдельно 10/мин, инструменты документации — 120/мин.
  • Потолки вызовов внешних действий (независимо от лимита частоты выше): не больше 3 вызовов за один ход диалога модели, не больше 20 за один диалог в час, не больше 5 за один голосовой звонок — так ограничивается ущерб от зацикленного вызова или удачной промпт-инъекции.
  • Пагинация: per_page ограничен максимумом 50.
  • Без массовой рассылки: инструменты отправки работают только с существующим диалогом или одним контактом — массовой отправки здесь нет (для рассылок используйте функцию «Рассылки» в кабинете).
  • Недоверенный контент: тексты сообщений, имена контактов и заметки, которые возвращают инструменты, — это данные третьих лиц, а не инструкции для модели.

Диагностика

СимптомПричина / решение
401 UnauthorizedТокен отсутствует или невалиден.
403 ForbiddenТокен не является токеном сервисного аккаунта (например, мобильный/embed-токен), либо подписка неактивна / фича api выключена.
Инструмент возвращает «не найдено» по существующему IDID принадлежит другой компании — принадлежность к компании токена проверяется на каждом аргументе.
«Rate limit exceeded»Превышен лимит конкретного инструмента (см. «Лимиты и поведение») — повторите чуть позже.