Last9
официальныйБесшовно переносите контекст реальной производственной среды — логи, метрики и трейсы — в ваше локальное окружение, чтобы быстрее автоматически исправлять код.
Что можно делать с Last9 MCP?
- Расследуйте инциденты в продакшене — Попросите ассистента получить логи, трассировки, метрики, исключения и сработавшие оповещения для сервиса, чтобы он мог диагностировать причину сбоя.
- Сопоставляйте изменения с их последствиями — Проверьте развёртывания и изменения конфигурации, затем сравните сервис и вызывающие его компоненты до и после изменений, чтобы выяснить, не привело ли изменение к регрессии.
- Запрашивайте метрики Prometheus — Выполняйте диапазонные или мгновенные запросы PromQL и просматривайте значения меток, чтобы исследовать любую метрику в источнике данных.
- Проверяйте производительность баз данных — Находите базы данных, выявляйте медленные выполнения запросов и изучайте шаблоны запросов и метрики на стороне сервера по спанам OTel.
- Анализируйте трассировки и профили — Получайте водопад трассировки по ID, ранжируйте отклонения атрибутов между когортами или запрашивайте пламенную диаграмму и список наиболее часто вызываемых функций для сервиса.
- Управляйте оповещениями и дашбордами — Проверяйте охват и качество оповещений, создавайте правила оповещений или вносите в них изменения, а также просматривайте, проверяйте или редактируйте пользовательские дашборды.
Документация
Last9 MCP Server

Ваш AI-агент не знает, что сломалось в production. Это исправит ситуацию.
Last9 MCP Server напрямую подключает Claude, Cursor, Windsurf и любого другого AI-ассистента с поддержкой MCP к данным наблюдаемости production-среды — логам, метрикам, трассировкам, исключениям, запросам к базам данных, оповещениям и развёртываниям. Агент перестаёт гадать и начинает анализировать реальные сигналы.
Начало работы за 30 секунд (Hosted)
Не нужно устанавливать бинарный файл. Не нужно управлять токенами. Один URL, OAuth в браузере — и готово.
Найдите slug вашей организации в URL Last9: app.last9.io/<org_slug>/...
Claude Code
claude mcp add --transport http last9 https://app.last9.io/api/v4/organizations/<org_slug>/mcp
Введите /mcp, выберите last9 и пройдите аутентификацию. Готово.
Cursor
Settings > MCP > Add New MCP Server:
{
"mcpServers": {
"last9": {
"type": "http",
"url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
Нажмите Connect и завершите OAuth-аутентификацию.
VS Code
Требуется версия 1.99+. Откройте Command Palette → MCP: Add Server, вставьте URL и пройдите аутентификацию.
Или добавьте напрямую в settings.json:
{
"mcp": {
"servers": {
"last9": {
"type": "http",
"url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
}
Windsurf
Settings > Cascade > Open MCP Marketplace > значок шестерёнки (mcp_config.json):
{
"mcpServers": {
"last9": {
"serverUrl": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
Claude Web/Desktop
Settings > Connectors > Add custom connector. Назовите его last9, вставьте URL и пройдите аутентификацию.
Требуется доступ администратора к вашей организации Claude.
Self-Hosted (STDIO)
Используйте этот вариант, если ваш MCP-клиент не поддерживает HTTP-транспорт или сервер должен работать локально.
Установка
Homebrew:
brew install last9/tap/last9-mcp
NPM:
Требуется Node.js версии 22.23.4+, 24.22.1+ или 26.12.1+: более ранние выпуски принимают TLS-сертификаты скомпрометированных промежуточных центров сертификации eMudhra при загрузке бинарного файла установщиком.
npm install -g @last9/mcp-server@latest
# or directly:
npx -y @last9/mcp-server@latest
Бинарные выпуски (Windows / вручную):
Скачайте файл со страницы GitHub Releases:
| Платформа | Архив |
|---|---|
| Windows (x64) | last9-mcp-server_Windows_x86_64.zip |
| Windows (ARM64) | last9-mcp-server_Windows_arm64.zip |
| Linux (x64) | last9-mcp-server_Linux_x86_64.tar.gz |
| Linux (ARM64) | last9-mcp-server_Linux_arm64.tar.gz |
| macOS (x64) | last9-mcp-server_Darwin_x86_64.tar.gz |
| macOS (ARM64) | last9-mcp-server_Darwin_arm64.tar.gz |
Получение токена обновления
Создавать токены могут только администраторы.
- Перейдите в раздел API Access
- Нажмите Generate Token, выбрав разрешения на запись
- Скопируйте токен
Настройка клиента
Homebrew:
{
"mcpServers": {
"last9": {
"command": "/opt/homebrew/bin/last9-mcp",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
NPM:
{
"mcpServers": {
"last9": {
"command": "npx",
"args": ["-y", "@last9/mcp-server@latest"],
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
Куда вставить:
| Клиент | Расположение |
|---|---|
| Claude Web/Desktop | Settings > Developer > Edit Config (claude_desktop_config.json) |
| Cursor | Settings > Cursor Settings > MCP > Add New Global MCP Server |
| Windsurf | Settings > Cascade > MCP Marketplace > значок шестерёнки (mcp_config.json) |
| VS Code | Оберните в { "mcp": { "servers": { ... } } } в settings.json — подробности |
Конфигурация VS Code STDIO
{
"mcp": {
"servers": {
"last9": {
"type": "stdio",
"command": "/opt/homebrew/bin/last9-mcp",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
}
Для NPM: используйте "command": "npx" и добавьте "args": ["-y", "@last9/mcp-server@latest"].
Windows
После загрузки со страницы GitHub Releases распакуйте архив и укажите полный путь:
{
"mcpServers": {
"last9": {
"command": "C:\\Users\\<user>\\AppData\\Local\\Programs\\last9-mcp-server.exe",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
Вариант с NPM проще для Windows — не нужно управлять путями.
Переменные окружения
| Переменная | По умолчанию | Описание |
|---|---|---|
LAST9_REFRESH_TOKEN | (обязательно) | Токен обновления из раздела API Access |
LAST9_DATASOURCE | организация по умолчанию | Имя источника данных/кластера — полезно, если у вас несколько кластеров Levitate |
LAST9_FAKE_NOW_ISO | (не задано) | Только для evals/replays; никогда не задавайте в production. Момент времени в формате RFC3339 (например, 2026-01-02T15:04:05Z), который подменяет текущее время при вычислении относительных интервалов, таких как lookback_minutes, чтобы запуски были воспроизводимыми. Некорректное значение приводит к ошибке запуска. Тайм-ауты, кэши и срок действия токена по-прежнему используют реальное время |
LAST9_API_HOST | app.last9.io | Переопределяет хост API |
LAST9_TOOLSETS | все инструменты | Список наборов инструментов через запятую, которые нужно предоставить (logs, traces, metrics, alerts, dashboards, profiles, grafana, investigate, all). Псевдоним: LAST9_MCP_TOOLSETS |
LAST9_MCP_READ_ONLY | false | Задайте true, чтобы предоставлять только инструменты для чтения; см. раздел Режим только для чтения. Значение, не являющееся логическим, приводит к ошибке запуска. Псевдоним: LAST9_READ_ONLY |
LAST9_MCP_ALLOW_WRITE_TOOLS | — | Список через запятую инструментов записи, которые всё ещё предоставляются в режиме только для чтения. Псевдоним: LAST9_ALLOW_WRITE_TOOLS |
LAST9_MAX_GET_LOGS_ENTRIES | 5000 | Максимальное число записей для разбитых на части запросов get_logs |
LAST9_USE_LOG_SEARCH_API | false | Задайте true, чтобы обрабатывать get_logs и get_service_logs одним поисковым запросом на стороне сервера вместо разбиения на части на стороне клиента. На каждый запрос отводится 90 секунд, после чего возвращается рекомендация сузить интервал; ошибка 502 или 503 повторяется один раз в пределах этого времени |
LAST9_DEBUG_CHUNKING | false | Задайте true, чтобы записывать подробности планирования разбиения на части для get_logs, get_service_logs, get_traces |
LAST9_DISABLE_TELEMETRY | true | Задайте false, чтобы включить внутреннюю трассировку OTel |
OTEL_SDK_DISABLED | — | Стандартная переменная окружения OTel. Переопределяет LAST9_DISABLE_TELEMETRY |
OTEL_EXPORTER_OTLP_ENDPOINT | — | Конечная точка коллектора OTLP (только при включённой телеметрии) |
OTEL_EXPORTER_OTLP_HEADERS | — | Заголовки авторизации OTLP (только при включённой телеметрии) |
Время выполнения этапов инструмента
При включённой внутренней телеметрии в спанах инструментов указываются last9.phase.<phase>.duration_ms
(фактическое время в миллисекундах) и last9.phase.<phase>.failed (завершился ли этап
ошибкой). Те же поля записываются в отладочные журналы tool phase completed
вместе с tool и phase, если настроенный регистратор принимает записи уровня debug.
Эти замеры времени не добавляют входные данные, текст запросов, учётные данные или тела ошибок.
| Инструмент | Этапы |
|---|---|
get_log_patterns | sample: получение и декодирование выборки; mine: поиск шаблонов; deep_link: определение необязательного индекса и создание ссылки |
get_logs | fetch: получение, декодирование и объединение результатов, включая повторы и необязательные проверки согласованности количества; count_sanity: вложенная необязательная проверка; post_process: рекомендации, сводка и форматирование JSON; deep_link: определение индекса и создание ссылки |
get_service_profile | request: подготовка и отправка запроса через общий клиент API, а также чтение полного ответа до краткого форматирования |
Записываются только выполненные этапы, в том числе неудачные запросы. Необязательные вспомогательные функции, подавляющие ошибки, сохраняют это поведение; failed: false не подтверждает доступность необязательной ссылки или проверки количества. Длительность вложенного этапа count_sanity уже включена в fetch; не учитывайте её повторно. Время получения включает работу клиента, поэтому оно не измеряет только выполнение на стороне сервера. Прежде чем настраивать выборку или кэширование, сравнивайте эти этапы на эквивалентных интервалах и путях поиска.
Для расследования задержек повторите запрос с теми же службой, источником данных, индексом, интервалом и ограничениями в базовой и тестируемой сборках. Запишите SHA сборки, общее время инструмента, длительность этапов, last9.logs.search_path, атрибуты повторных попыток, если они есть, и флаги покрытия. Сравнивайте как медленные, так и типичные вызовы. Медленный запрос на получение данных или профиля указывает на сетевой этап/API, который следует исследовать; для отнесения задержки к серверной части нужны отдельные коррелированные данные. Одних этих диагностических данных недостаточно, чтобы подтвердить улучшение задержки.
Режим только для чтения
--read-only (или LAST9_MCP_READ_ONLY=true) предоставляет только инструменты с аннотацией readOnlyHint: true, поэтому ни один инструмент не может создавать, изменять или удалять правила оповещений, каналы уведомлений, дашборды или правила отбрасывания, подтверждать оповещения, менять ответственных или отключать группы. Инструмент без аннотаций считается инструментом записи и скрывается.
Чтобы оставить несколько инструментов записи, перечислите их в --allow-write-tools (или LAST9_MCP_ALLOW_WRITE_TOOLS):
last9-mcp --read-only --allow-write-tools=acknowledge_alert,mute_alert_group
- Сервер отказывается запускаться, если в списке указано имя, не являющееся инструментом записи (опечатка или имя инструмента чтения); в сообщении об ошибке перечислены допустимые инструменты записи.
--allow-write-toolsбез--read-onlyприводит к ошибке запуска, поскольку в этом случае предоставляются все инструменты записи.- Режим только для чтения сочетается с
--toolsets: инструмент предоставляется, только если удовлетворяет обоим условиям.--toolsets=alerts --read-only --allow-write-tools=mute_alert_groupпредоставляет инструменты чтения оповещений иmute_alert_group; разрешённый инструмент записи, не входящий в выбранные наборы инструментов, остаётся скрытым. - Режимы
--httpиdump-toolsучитывают те же флаги и переменные окружения:go run . dump-tools --read-onlyвыводит доступные инструменты только для чтения, а инструкции сервера, которые он предоставляет, — вinstructions. - В описаниях, схемах и результатах инструментов чтения, а также в инструкциях сервера никогда не упоминаются скрытые инструменты записи. Разрешённый инструмент записи всё же может упоминать скрытые связанные инструменты (
create_alertсоздаёт отключённое правило, которое включаетpatch_alert), поэтому разрешайте такие пары вместе.
Возможности
Обзор
get_workspace_overview— Рекомендуемый первый вызов, если в запросе не указана служба или инструмент (если указаны — сразу вызывайте соответствующий инструмент): окружения, сигналы (логи, трассировки, метрики), обнаруженные за последний час, количество служб и групп оповещений, активные оповещения и текущее время — всё за один недорогой вызов. Если сигнал не обнаружен за этот час, у него всё ещё могут быть более старые данные, поэтому его можно запрашивать. Если один из вложенных вызовов завершается ошибкой, его поле получает значениеnull, а в список добавляется записьerrors[]. Доступен во всех наборах инструментовget_current_time— Текущее время и абсолютные границы дляlast 2h,yesterdayилиsince yesterday 9am ISTв любом часовом поясе IANA или распространённом часовом поясе с буквенным обозначением. Доступен во всех наборах инструментов
Состояние служб
get_service_summary— Ранжированные строки(service, env)для всего парка: количество запросов за интервал, пропускная способность в запросах в минуту, количество ошибок HTTP 4xx/5xx и ошибок gRPCget_service_environments— Доступные окружения для ваших служб. Сначала выполните этот инструмент — другим инструментам APM требуется значениеenvиз его результатаget_service_performance_details— Полная разбивка: пропускная способность, частота ошибок, p50/p90/p95/среднее/максимум, apdex, доступность (по умолчанию — сводка; полный временной ряд — с помощьюinclude_series)get_service_operations_summary— Группировка операций по HTTP-конечным точкам, вызовам БД, обмену сообщениями и HTTP-клиентамget_service_dependency_graph— Карта зависимостей с пропускной способностью, задержкой и частотой ошибок для вышестоящих/нижестоящих компонентов и инфраструктурыget_apm_service_deviations— Сравнение текущего интервала с базовым интервалом той же длительности: ухудшения/улучшения, сверка Apdex и итоговый результат (для всего парка или отдельной службы)get_exceptions— Исключения на стороне сервера с фильтрами по службе и спану
Наблюдаемость баз данных
Четыре инструмента для непосредственного анализа производительности баз данных на основе спанов трассировок OpenTelemetry, а при отсутствии трассировок — инфраструктурных метрик, например CloudWatch. Дополнительная инструментация не нужна, если вы уже используете OTel.
get_databases— Обнаружение всех баз данных в вашей инфраструктуре: тип БД, хост, пропускная способность (запросов/мин), p95-задержка, частота ошибок, количество зависимых сервисов. Также обнаруживает базы данных по метрикам инфраструктуры, например CloudWatch, без необходимости инструментировать трассировки — в таких строках вместо метрик трассировок указано значение активностиget_database_slow_queries— Фактические самые медленные выполнения запросов, отсортированные по длительности, с идентификаторами трассировок для перехода к полным трассировкамget_database_queries— Шаблоны запросов и агрегаты: частота выполнения запроса, средняя длительность/p95-длительность, частота ошибокget_database_server_metrics— Метрики на стороне сервера, полученные непосредственно с хоста БД (ЦП, подключения, коэффициенты попаданий в буфер — зависят от системы БД)
Поддерживаются PostgreSQL, MySQL, MongoDB, Redis, Aerospike и любые другие системы, в трассировках OTel которых есть атрибут db_system, а также базы данных, обнаруженные по метрикам инфраструктуры, например CloudWatch. В строках таких баз вместо метрик трассировок указано значение активности.
Prometheus / PromQL
prometheus_range_query— Запросы диапазонов PromQL для любых метрикprometheus_instant_query— Мгновенные запросы; используйте функции свёртки, напримерavg_over_time,sum_over_timeprometheus_label_values— Значения меток для заданного рядаprometheus_labels— Все доступные метки для ряда
Чтобы направить запросы в источник данных/кластер, отличный от используемого по умолчанию, задайте LAST9_DATASOURCE или укажите его для отдельного вызова с помощью datasource. Если datasource не задан, используется источник по умолчанию; уникальное близкое совпадение, которое сопоставитель считает безопасным (например, вариант с другим регистром), заменяется ближайшим совпадением. Автоматическое разрешение для имени с пропущенной, лишней или переставленной буквой не гарантируется: даже при наличии одного кандидата может потребоваться подтверждение, если изменение способно затронуть код региона или среды. Менее точные или неоднозначные совпадения возвращают список кандидатов и не запускают запрос (это не ошибка); неизвестные имена приводят к ошибке. Если вы не указали имя источника данных в точности, дополнительный блок содержимого сообщает, какой источник был использован. get_metric_status, get_service_profile и get_apm_service_deviations разрешают datasource таким же образом.
Logs
get_logs— Запросы к журналам в формате полного JSON-конвейера (агрегации, фильтры, извлечение полей)get_service_logs— Строки журналов сервиса с фильтрацией по уровню важности и содержимому; сводка по 20 строкам, еслиresponse_modeне равноrawget_log_patterns— Строки журналов сервиса за временной интервал, сгруппированные по шаблонам сообщений, с количеством, временем первого/последнего появления, распределением по уровням важности и примеромget_emerging_log_patterns— Шаблоны журналов, которые появились, участились, стали встречаться реже или исчезли по сравнению с базовым временным интервалом; указано количество для обоих интерваловget_log_attributes— Глобальный каталог атрибутов схемы журналов за временной интервалget_log_attributes_for_pipeline— Фактически присутствующие поля журналов для выполняющегося конвейера (обнаружение в заданной области), каждое с точнымfilter_fieldget_drop_rules— Правила отбрасывания журналов из Last9 Control Planeadd_drop_rule— Создание нового правила отбрасывания для сокращения объёма журналов на источникеget_remapping_rules— Правила переназначения (logs_extract,logs_map,traces_map) из Last9 Control Planeadd_remapping_rule— Создание правила переназначения, которое извлекает или сопоставляет атрибуты журналов и трассировок при приёме данных
Traces
get_traces— Запросы к трассировкам в формате JSON-конвейера для широкого поиска и агрегацийget_service_traces— Трассировки по точному идентификатору трассировки или имени сервиса. Используйте этот инструмент, если у вас есть идентификатор трассировки: он работает быстрееget_trace_attributes— Глобальный каталог атрибутов схемы трассировокget_trace_attributes_for_pipeline— Фактически присутствующие атрибуты для выполняющегося конвейера (обнаружение в заданной области), каждый с точнымfilter_fieldget_trace_attribute_values— Уникальные значения атрибута трассировки, при необходимости с ограничением по конвейеруget_trace_attribute_deviations— Ранжирование значений атрибутов, различающихся между двумя ограниченными когортами спанов (медленные и быстрые, с ошибками и без ошибок или два временных интервала). Корреляция, а не причинаget_trace_waterfall— Одна точная трассировка в виде водопадной диаграммы родительских и дочерних спанов с собственным временем по объединению интервалов, самыми медленными спанами и предупреждениями о графе
События изменений и оповещения
get_change_events— Развёртывания, изменения конфигурации, откаты. Сопоставляйте инциденты с произошедшими изменениямиanalyze_change_impact— Не привело ли изменение к сбоям? Сравнивает сервис и его непосредственных вызывающих до и после изменения: ключевые сигналы, отклонения APM и атрибутов трассировок, новые сработавшие оповещения и вердикт (regression likely/no significant change/insufficient data)get_alert_groups— Настроенные группы оповещений Compass с метками метаданных, командой, уровнем и количеством правил — включая группы без правил и группы, в которых нет сработавших оповещенийget_alert_operations_summary— Состояние дежурства за временной интервал: созданные и подтверждённые оповещения, очередь, доставки и, при наличииinclude_rules, самые шумные, нестабильные и ненаправленные правила. Для каждого количества указано егоstatus(available/partial/unavailable)get_alert_coverage— Отсутствующие оповещения: непокрытые ключевые сигналы, полностью отключённые или ненаправленные группы оповещений и правила, заглушённые слишком надолго; для каждого предлагается инструмент исправления. Только чтение.get_alert_config— Конфигурации правил оповещений — поиск по имени, уровню важности, типу и тегамget_entity_kpis— Все KPI (идентификатор, имя, PromQL, единица измерения) одной группы оповещений, включая KPI, которые пока не используются ни одним правилом; нужны идентификаторыcreate_alertиvalidate_alert_expressioncreate_kpi— Создание KPI (PromQL + единица измерения) в группе оповещений, если ни один существующий KPI не подходит. Создайте его один раз и сохраните возвращённый идентификаторget_alerts— Оповещения, сработавшие в данный момент в пределах временного интервалаget_alert_rule_state— Историческое состояние срабатывания (1/0) для каждого правила оповещений за временной диапазон, сгруппированное поrule_id. Можно фильтровать по группе оповещений, имени правила, фильтрам меток и состоянию.get_alert_hygiene— Шумные, нестабильные, устаревшие и ненаправленные правила оповещений за 7 или 30 дней, отсортированные по рейтингу; для каждого указаны данные, обосновывающие вердикт, и предлагается исправление. Только чтение.get_notification_channels— Настроенные каналы уведомлений (Slack, PagerDuty, электронная почта и т. д.).scope=channelsперечисляет сами каналы (идентификаторы для привязки); по умолчаниюattachedперечисляет привязки для каждой группы оповещенийrecommend_alert_config— Рекомендации по проектированию только для чтения (жизненный цикл, этапы проверки, контекст для реагирующих) перед созданием правила оповещенийvalidate_alert_expression— Проверка выражения оповещения на KPI группы оповещений без сохранения измененийdescribe_alert_chart— Только чтение: сигналы, доступные для оповещений (ключ, единица измерения) на диаграмме Discover (discover-service,discover-exceptions)create_alert— Создание правила оповещений (статического или адаптивного черезadaptive_std_cmp) в существующей группе оповещений; правило всегда создаётся отключённым как черновик. Создайте его один раз, затем уточняйте с помощьюupdate_alert/patch_alertcreate_alert_from_chart— Создание правила оповещений со статическим порогом на диаграмме Discover за один вызов. Как и в случае сcreate_alert, правило создаётся отключённым как черновикupdate_alert— Полная замена конфигурации оценки правила (может вернуть новый идентификатор правила)patch_alert— Частичное изменение правила: включение/приостановка,mute_until, отвечающийproperties, еженедельныйrecurring_mute_schedule(илиclear_recurring_mute_schedule)delete_alert— Безвозвратное удаление правила оповещенийmute_alert_group— Заглушение (или снятие заглушения) всех правил в группе оповещений до указанного срокаacknowledge_alert— Взять на себя ответственность за сработавшее оповещение или снять еёreassign_alert— Передать уже подтверждённое оповещение другому пользователюcreate_notification_channel— Создание канала Slack, PagerDuty, Opsgenie, электронной почты или универсального веб-перехватчикаattach_notification_channel— Привязка существующего канала к группе оповещений дляbreach,threatили обоих типовdetach_notification_channel— Удаление одной привязки канала к группе оповещенийdelete_notification_channel— Безвозвратное удаление канала без привязок
Для инструментов записи оповещений (create_kpi, create_alert, update_alert, patch_alert, delete_alert, create_alert_from_chart, mute_alert_group, acknowledge_alert, reassign_alert, create_notification_channel, attach_notification_channel, detach_notification_channel, delete_notification_channel) нужен токен с областью действия записи; для delete_alert, detach_notification_channel и delete_notification_channel вместо этого нужна область действия удаления. Они доступны только в наборе инструментов alerts.
Правила, каналы и привязки, созданные этими инструментами, помечаются created_via: last9-mcp вместе с именем и версией клиента MCP (для правил — аннотации _l9_created_via_ и _l9_created_via_client_, которые сохраняют patch_alert и update_alert и которые вызывающие стороны не могут задавать). get_entity_alert_rules и get_notification_channels показывают эту метку, а delete_alert, detach_notification_channel и delete_notification_channel указывают агентам удалять только помеченные ресурсы, если пользователь не назвал конкретный ресурс.
Пользовательские дашборды
list_dashboards— Пользовательские дашборды с фильтрацией по имени и постраничной выдачей объёмом до 32 КБ: идентификаторы, имена, время последнего обновления, авторы и состояние блокировкиget_dashboard— Полное определение дашборда по идентификатору, включая панели и запросыpreview_dashboard— Предварительный просмотр несохранённого дашборда или исправления только для чтения: разрешённые запросы, ограниченные результаты для каждой панели и итоговая разница панелей; изменения не сохраняютсяvalidate_dashboard— Проверка линтером, выполнение и классификация только для чтения для сохранённого идентификатора дашборда или встроенногоdashboard_definitionза период ≤24 ч. Дашборды не создаются и не обновляютсяcreate_dashboard— Однократное создание нового пользовательского дашборда (панели, запросы, метаданные). После возврата идентификатора редактируйте панели с помощьюpatch_dashboard.update_dashboard— Изменение большей части существующего дашборда по идентификатору (полная замена; для системных дашбордов только для чтения возвращается ошибка). Для редактирования отдельных панелей используйтеpatch_dashboardpatch_dashboard— Точечное редактирование существующего дашборда по идентификатору (добавление/обновление/удаление/перемещение панели, изменение заголовка, настройка переменной); возвращается краткая разница, а не полный дашбордdelete_dashboard— Удаление пользовательского дашборда по идентификаторуset_dashboard_lock— Блокировка или разблокировка пользовательского дашборда по идентификатору (только автор или администратор организации); заблокированный дашборд нельзя обновить, изменить или удалитьlist_dashboard_snapshots— Зафиксированные снимки дашборда на определённый момент времени (только метаданные)get_dashboard_snapshot— Полный зафиксированный снимок, включая данные панелей, для RCA / представлений, которыми можно поделитьсяdelete_dashboard_snapshot— Удаление зафиксированного снимка по идентификатору
Создавать дашборды можно через MCP prompts/list и prompts/get, не устанавливая навык. Все три подсказки не принимают аргументов:
create_dashboard_guide— Обнаружение, компоновка и выбор панелей; проверка полного варианта и выполнение запроса каждой панели до утверждения, однократное создание, точечное исправление, затем чтение результата.dashboard_examples— Полный пример с RED-метриками сервиса, задержкой конечных точек, классами статусов, состоянием хостов, количеством журналов и панелями трассировок, а также зависимыми переменными.query_guide— Семантика счётчиков/датчиков/гистограмм и производных метрик трассировок, мгновенные запросы и запросы диапазонов, окна вычисления скорости, границы процентов и правила logjson/tracejson.
Тот же материал доступен по адресам last9://reference/create_dashboard_guide, last9://reference/dashboard_examples и last9://reference/query_guide. Подсказки и ресурсы доступны для обнаружения в каждом наборе инструментов; для выполнения рабочего процесса нужны соответствующие инструменты (для создания дашбордов со смешанными сигналами используйте --toolsets=dashboards,investigate, который также обслуживает list_datasources). Сеансы только для чтения позволяют подготовить и проверить дашборд, но не сохранить его. Перед выполнением шага проверьте доступность инструментов.
Сейчас для проверки панелей используются prometheus_range_query, prometheus_instant_query, get_logs и get_traces вместе с validate_dashboard. Неподдерживаемые типы запросов и упрощённые значения по умолчанию валидатора не гарантируют соответствия отображению. После выхода #475 отдельный этап проверки запросов будет переключён на query_panel.
Непрерывное профилирование
Для работы необходимо включить непрерывное профилирование в организации. Сначала обнаружьте сервисы с помощью get_profile_services, затем получите пламенную диаграмму или ранжированный список функций.
get_profile_services— Сервисы, для которых в выбранном временном окне есть данные профилирования (индекс перед запросом)get_flamegraph— Вложенное дерево flamegraph для одного сервиса (cpuпо умолчанию; такжеalloc,wall)get_top_functions— Рейтинг функций одного сервиса по собственным сэмплам, от самых горячихget_profile_summary— Краткий разбор профиля одного сервиса на естественном языке
Дашборды Grafana
Инструменты только для чтения, работающие с экземпляром Grafana организации (через прокси Grafana от Last9). Поля учетных данных никогда не возвращаются модели. Включите с помощью LAST9_TOOLSETS=grafana (или не задавайте наборы инструментов, чтобы использовать все инструменты).
grafana_search_dashboards— Поиск дашбордов по подстроке в названии (с постраничной выдачей;truncated: trueпри достижении лимита)grafana_get_dashboard— Сводка дашборда по uid (панели, переменные, цели PromQL);full_json=trueдля необработанного JSON Grafanagrafana_list_folders— Дерево папокgrafana_list_folder_dashboards— Дашборды в одной папке (с постраничной выдачей)grafana_list_datasources— Список источников данных без учетных данных
Нечеткое разрешение имен
did_you_mean— Если агент не уверен в имени сущности, этот инструмент возвращает наиболее близкие совпадения из вашего каталога (сервисы, окружения, хосты, базы данных, развертывания/пространства имен K8s, задания). До 3 вариантов с оценками сходства. Сервер автоматически вызывает этот инструмент перед большинством инструментов, если поиск по имени ничего не находит.
Профиль сервиса
get_service_profile— Показывает, как на самом деле выглядят данные телеметрии сервиса до выполнения запроса: какие сигналы доступны, язык и среда выполнения, окружения развертывания, структура журналов и рекомендуемое исправление сбора данных, если оно применимо. Позволяет агенту пропускать инструменты трассировок, если у сервиса нет трассировок, и извлекать уровень серьезности из тела журнала, когдаSeverityTextпуст, вместо фильтрации по нему, которая ничего не найдет.
Как это работает
Прямые ссылки в каждом ответе. Каждый инструмент возвращает поле deep_link — прямую ссылку на дашборд Last9 для конкретного запроса и временного диапазона. Агент может передать вам ссылку; вы нажимаете на нее — и оказываетесь на нужной странице.
Наборы инструментов. По умолчанию сервер предоставляет все инструменты. Хосты автоматизации, которым нужны только инструменты для расследования (журналы/трассировки/метрики/профили), могут задать LAST9_TOOLSETS=investigate (или передать --toolsets=investigate), чтобы tools/list оставался небольшим без массового отключения инструментов на стороне клиента. Именованные наборы: logs, traces, metrics, alerts, dashboards, profiles, grafana, investigate, all. Неизвестные имена приводят к немедленной ошибке. get_current_time и get_workspace_overview доступны во всех наборах инструментов. В режиме HTTP запрос может дополнительно сузить набор с помощью заголовка X-Last9-Toolsets (см. Наборы инструментов для каждого запроса). Набор alerts также предоставляет доступные только для чтения prometheus_range_query и get_dashboard, которые вызываются в подсказке author-alert. Один только набор metrics не включает list_datasources или did_you_mean — используйте investigate (или объедините наборы инструментов), если нужны эти вспомогательные инструменты для обнаружения.
Справочные ресурсы инструментов. Подробные руководства по logjson/tracejson/service-logs/metrics — это ресурсы MCP (last9://reference/logjson, last9://reference/tracejson, last9://reference/service_logs, last9://reference/metrics, last9://reference/investigation, last9://reference/alerting), а не постоянно включенный текст описания инструментов. Руководство по оповещениям описывает грамматику выражений оповещений, статические и адаптивные поля, единицы измерения, проверки, выполняемые validate_alert_expression, а также шаблоны правил для задержки / частоты ошибок / насыщения. Критически важные правила запросов остаются в описании инструмента, чтобы агенты, которые никогда не вызывают resources/read, все равно получали корректные инструкции по составлению запросов. Узнайте поля, специфичные для организации, с помощью get_log_attributes / get_log_attributes_for_pipeline (и эквивалентов для трассировок) — они не добавляются в описания.
Разбиение больших результатов на части. get_logs и get_traces обрабатывают большие наборы результатов, разбивая их на части, а не усекая. Лимит по умолчанию — 5000 записей для журналов; его можно настроить через LAST9_MAX_GET_LOGS_ENTRIES.
Разработка
Режим HTTP, тестирование с curl, сборка из исходного кода
Запуск в режиме HTTP
export LAST9_REFRESH_TOKEN="your_refresh_token"
export LAST9_HTTP=true
export LAST9_PORT=8080
./last9-mcp-server
Сервер запускается по адресу http://localhost:8080/mcp.
Тестирование с curl
Обработчик Streamable HTTP работает в stateless-режиме, поэтому каждый запрос обрабатывается независимо. Рукопожатие initialize и заголовок Mcp-Session-Id необязательны — клиенты, которые их отправляют, продолжают работать (заголовок принимается и игнорируется), а клиенты могут сразу перейти к tools/list / tools/call. Каждый инструмент выполняет независимый запрос и возвращает ответ; сервер не отправляет уведомления сервер→клиент, поэтому GET /mcp (поток SSE) возвращает 405.
# List tools — a session handshake is optional in stateless mode
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}'
# Call a tool
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_service_logs",
"arguments": {
"service_name": "your-service-name",
"lookback_minutes": 30,
"limit": 10
}
}
}'
Наборы инструментов для каждого запроса
В режиме HTTP запрос может сузить доступный набор инструментов с помощью заголовка X-Last9-Toolsets или параметра запроса toolsets для клиентов, которые не могут задавать заголовки (/mcp?toolsets=logs,traces). Если переданы оба значения, приоритет имеет непустой заголовок. Значение использует те же имена, разделенные запятыми, что и --toolsets. Запрос получает пересечение с набором --toolsets, заданным при запуске: его можно сузить, но не расширить; значение all или пустое значение сохраняет набор, заданный при запуске. Неизвестное имя приводит к ответу 400 с указанием этого имени. tools/list, tools/call и инструкции initialize соответствуют эффективному набору; get_current_time и get_workspace_overview остаются доступными во всех наборах.
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "X-Last9-Toolsets: logs,alerts" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}'
Каждый уникальный эффективный набор обслуживается собственным сервером, который создается при первом запросе (десятки миллисекунд) и сохраняется до завершения работы; запрос, повторно задающий набор запуска, использует уже запущенный сервер. Вытеснения нет: принимаются только именованные наборы инструментов, поэтому кэш содержит не более одного сервера для каждой их комбинации (сейчас 135; около 75 МБ используемой кучи в сумме; при тестировании полностью заполненный кэш стабилизировался примерно на 230 МБ резидентной памяти).
Сборка из исходного кода
git clone https://github.com/last9/last9-mcp-server.git
cd last9-mcp-server
go build -o last9-mcp-server
LAST9_HTTP=true ./last9-mcp-server
LAST9_HTTP=true предназначен для локальной разработки. Для реального использования проще воспользоваться размещенной конечной точкой HTTP.
Справочник по инструментам
Все параметры, стандарты ввода времени и подробности
Ввод времени
- Абсолютное время (
start_time_iso/end_time_isoилиtime_iso) имеет приоритет надlookback_minutes. - Для относительных временных окон используйте
lookback_minutes. - Для абсолютных временных окон используйте RFC3339/ISO8601 —
2026-02-09T15:04:05Z. - Устаревший параметр
YYYY-MM-DD HH:MM:SSпринимается только для совместимости. - Преобразуйте выражения вроде
since yesterday 9am ISTв границы RFC3339 с помощьюget_current_time.
get_workspace_overview
Параметров нет. Параллельно проверяет последние 60 минут; каждый подзапрос выполняется с коротким тайм-аутом. Возвращает current_time, lookback_minutes, environments, telemetry (логические значения logs/traces/metrics), service_count (ранги get_service_summary для уникальных сервисов, все окружения), alert_group_count, firing_alert_count и errors ([{field, error}]). Если подзапрос завершился ошибкой, соответствующее поле равно null (неизвестно), а не 0 или false. Проверки не ограничиваются --toolsets: наборы инструментов определяют, какие инструменты доступны, а область доступа сервера к данным задается API-токеном.
get_current_time
range(строка, необязательно):last 2h,past 30 minutes,last 7d(s, m, h, d = 24h, w = 7d; не более 366d);today;yesterday;since <point>;<point> to <point>. Точка времени задается в формате RFC3339 или какtoday/yesterday/ день недели (monday,mon: последнее наступление, включая сегодня) /YYYY-MM-DDс необязательным9am,9:30pmили14:30. Часовой пояс в конце переопределяетtimezoneдля обеих границ; часовой пояс в любом другом месте вызывает ошибку. Не указывайте параметр, если нужно толькоnow.timezone(строка, необязательно): имя или аббревиатура IANA (IST = Asia/Kolkata, PST/PDT, EST/EDT, UTC, GMT). По умолчанию UTC. Неизвестные часовые пояса вызывают ошибку, как и неоднозначное значениеCST(передайтеAmerica/ChicagoилиAsia/Shanghai).
Возвращает now (а также start/end с range) в формате {iso, epoch_seconds, local}; local присутствует только для часового пояса, отличного от UTC.
get_exceptions
limit(целое число, необязательно): Максимальное количество исключений. По умолчанию: 20.lookback_minutes(целое число, необязательно): По умолчанию: 60.start_time_iso/end_time_iso(строка, необязательно): Абсолютный временной диапазон.service_name(строка, необязательно): Фильтр по сервису.span_name(строка, необязательно): Фильтр по имени span.env(строка, необязательно): Фильтр по окружению.
get_service_summary
start_time_iso/end_time_iso(строка, необязательно)env(строка, необязательно): Регулярное выражение PromQL. По умолчанию.*. Для точного совпадения нужны якоря (например,^prod$).sort_by(строка, необязательно):request_count(по умолчанию),throughput_rpm,http_4xx_count,http_5xx_countилиgrpc_error_count.limit(целое число, необязательно): Максимальное количество строк в рейтинге. Если не указано или равно 0, используется 10; значения выше 100 ограничиваются 100.
get_service_environments
start_time_iso/end_time_iso(строка, необязательно)
Для всех остальных инструментов APM требуется значение
env. Если результат пуст, используйте"".
get_service_performance_details
По умолчанию возвращает сводку по каждому ряду: points, missing_points (интервалы доступности без трафика, исключенные из статистики), min, p50, p90, p99 (ближайший ранг), max, mean, last, baseline_mean (среднее значение первой половины допустимых точек, а не всего окна), delta_pct (вторая половина допустимых точек относительно базового уровня; отсутствует, если базовый уровень равен 0) и до 3 change_points (timestamp, before_mean, after_mean), максимум для 4 рядов на метрику и каждого квантиля времени ответа (сначала наибольшее среднее; series_omitted учитывает остальные). Ряд с points: 0 не содержит статистики; для baseline_mean/delta_pct требуется не менее 6 точек (по 3 на половину). full_series указывает, что исходные точки доступны через include_series.
service_name(строка, обязательно)lookback_minutes(целое число, необязательно): По умолчанию: 60.start_time_iso/end_time_iso(строка, необязательно)env(строка, необязательно): По умолчаниюprod.top_n(целое число, необязательно): Максимальное количество записей в каждом списке top-operations/top-errors. По умолчанию: 5 или 10 сinclude_series=true. Максимум 100.include_series(логическое значение, необязательно): Возвращать каждую точку каждого ряда вместо сводки. По умолчанию: false.
get_service_operations_summary
service_name(строка, обязательно)lookback_minutes(целое число, необязательно): По умолчанию: 60.start_time_iso/end_time_iso(строка, необязательно)env(строка, необязательно): По умолчаниюprod.
get_service_dependency_graph
service_name(строка, необязательно)lookback_minutes(целое число, необязательно): По умолчанию: 60.start_time_iso/end_time_iso(строка, необязательно)env(строка, необязательно): По умолчаниюprod.
get_apm_service_deviations
service_name(string, optional): Не указывайте для области действия «весь парк»; укажите для одной службы и связанных с ней операций.lookback_minutes(integer, optional): Текущее окно. По умолчанию: 60.start_time_iso/end_time_iso(string, optional): Явно заданное текущее окно.baseline_start_time_iso/baseline_end_time_iso(string, optional): Явно заданный базовый период. По умолчанию — непосредственно предшествующее окно такой же длительности.datasource(string, optional): Не указывайте для значения по умолчанию; приблизительные названия разрешаются так же, как в инструментах Prometheus. В ответе указывается использованное значение по умолчанию или ближайшее совпадение; при неоднозначных названиях возвращаются варианты без выполнения запроса.env(string, optional): По умолчанию —prod.max_services/max_operations(integer, optional): По умолчанию 10, максимум 10 для каждого.
get_databases
env(string, optional): Фильтр по среде. Принимает регулярное выражение. По умолчанию: все.lookback_minutes(integer, optional): По умолчанию: 60. Окно не может превышать 7 дней.start_time_iso/end_time_iso(string, optional)
get_database_slow_queries
db_system(string, optional): например,postgresql,mysql,mongodb,redis.host(string, optional): Хост базы данных (net_peer_name).service_name(string, optional): Имя вызывающей службы.env(string, optional)min_duration_ms(float, optional): Минимальная длительность запроса в мс.lookback_minutes(integer, optional): По умолчанию: 60.start_time_iso/end_time_iso(string, optional)limit(integer, optional): По умолчанию: 20.
get_database_queries
db_system(string, optional)host(string, optional)service_name(string, optional)env(string, optional)lookback_minutes(integer, optional): По умолчанию: 60.start_time_iso/end_time_iso(string, optional)limit(integer, optional): По умолчанию: 20.
get_database_server_metrics
db_system(string, required): например,postgresql,mysql,mongodb,redis,aerospike.host(string, optional)lookback_minutes(integer, optional): По умолчанию: 60.start_time_iso/end_time_iso(string, optional)
prometheus_range_query
query(string, required): Запрос PromQL.start_time_iso/end_time_iso(string, optional): По умолчанию — последние 60 мин.lookback_minutes(float, optional): По умолчанию: 60.
prometheus_instant_query
query(string, required)time_iso(string, optional): По умолчанию — текущее время.lookback_minutes(float, optional)
prometheus_label_values
match_query(string, optional): Фильтр PromQL.label(string, required): Имя метки.lookback_minutes(float, optional): По умолчанию: 60.start_time_iso/end_time_iso(string, optional)
Если окно не задано, а match_query указывает одну метрику (metric{...} или {__name__="metric"}), пустой результат за 60 минут запрашивается повторно один раз за период в 4 дня; во втором текстовом блоке указывается, за какое окно получен результат.
prometheus_labels
match_query(string, optional): Фильтр PromQL.lookback_minutes(float, optional): По умолчанию: 60.start_time_iso/end_time_iso(string, optional)
Повторно выполняет пустой поиск по одной метрике за период в 4 дня, как prometheus_label_values.
get_logs
logjson_query(array, required): Запрос конвейера в формате JSON.lookback_minutes(integer, optional): По умолчанию: 5.start_time_iso/end_time_iso(string, optional)limit(integer, optional): Значение по умолчанию на сервере: 5000.index(string, optional):physical_index:<name>илиrehydration_index:<block_name>.response_mode(string, optional):summary(по умолчанию; также дляnull) илиraw. Если результат с необработанными строками превышает 20 строк, он возвращается в видеsummary:lines_summarized,severity_counts(шесть наиболее частых меток, остальные — вother_severities),first_timestamp/last_timestamp, гистограммаhistogramиз 10 интервалов за окно запроса (по возвращённым строкам, сtruncated: true, если результат обрезан из-за ограничения), а также наиболее частыеpatterns(template,count, до двухsamples), остальные суммируются вother; максимум 4000 символов. Метаданные верхнего уровня, которые всё ещё не помещаются, отбрасываются и перечисляются вdropped_fields.rawвозвращает строки. Результаты агрегирования никогда не суммируются.
Для инвентаризации служб на основе журналов сначала запросите physical_index_service_count:
sum by (name, service_name, env) (physical_index_service_count{destination="logs"})
Используйте service_name как ServiceName, при наличии используйте env как среду, а name — как физическое имя индекса. Если name="default", не указывайте index; для выбранного пользователем физического индекса, отличного от значения по умолчанию, передайте index: "physical_index:<name>". Если серверная часть отклоняет явную фильтрацию по физическому индексу, повторите запрос без index и сообщите, что эта серверная часть не поддерживает явную фильтрацию по физическому индексу.
get_service_logs
service_name(string, required)lookback_minutes(integer, optional): По умолчанию: 60.limit(integer, optional): По умолчанию: 100 или 20 сresponse_mode: "raw".env(string, optional)severity_filters(array, optional): например,["error", "warn"]. Логика OR.body_filters(array, optional): например,["timeout", "failed"]. Логика OR.start_time_iso/end_time_iso(string, optional)index(string, optional)response_mode(string, optional):summary(по умолчанию; также дляnull) илиraw. Если строк больше 20,logsзаменяется тем жеsummary, что и вget_logs, остальные поля сохраняются;rawвозвращает записи.
Фильтры разных типов объединяются с помощью AND. Внутри каждого массива используется OR.
Сначала используйте get_logs для широкого подсчёта агрегированных данных; используйте get_service_logs только после сужения поиска до службы, среды и индекса, а также небольшого набора примеров.
get_log_patterns
service_name(string, required)env(string, optional)start_time_iso/end_time_iso(string, optional)lookback_minutes(integer, optional): По умолчанию: 60.severity_filters/body_filters(array, optional): Логика OR, как вget_service_logs. Указывайтеseverity_filtersтолько еслиget_service_profileсообщаетseverity_setall; приnoneилиpartialотбрасываются строки, в теле которых указана соответствующая степень серьёзности.index(string, optional)sample_size(integer, optional): Строки, выбранные из окна, начиная с самых новых. По умолчанию: 1000, максимум: 5000.top_n(integer, optional): Количество возвращаемых шаблонов. По умолчанию: 20, максимум: 100. Остальные суммируются вother.
Кластеризация выполняется на MCP-сервере по выбранным строкам, поэтому количество, first_seen и last_seen относятся к выборке; window.sample_limit_reached сообщает, если в выборке могут отсутствовать подходящие строки (она содержит sample_size строк, а API не сообщает точное значение total_matching_lines, равное этому числу, либо поиск был logs_truncated), и в таком случае включает только самые новые строки окна. Каждый template и sample обрезается до 500 символов и заканчивается на …, поэтому тело, которое не кластеризуется (например, JSON без поля message), не может заполнить ответ. Поиск с неудачными фрагментами приводит к ошибке инструмента; поиск с усечёнными или ограниченными результатами всё равно возвращает шаблоны с пометкой sample_limit_reached. Пустой список patterns означает, что совпадений нет, только если sample_limit_reached имеет значение false; если значение true, поиск завершился досрочно и мог пропустить подходящие строки.
get_emerging_log_patterns
Принимает все параметры get_log_patterns (диапазон времени — текущее окно), а также:
baseline_start_time_iso/baseline_end_time_iso(string, optional): Укажите оба параметра или ни одного. По умолчанию — окно такой же длительности, непосредственно предшествующее текущему.min_count(integer, optional): Минимальное количество строк, необходимое изменившемуся шаблону в окне, где его больше: текущем дляnew/increased, базовом дляdecreased/disappeared. По умолчанию: 3 (илиsample_size, если оно меньше), максимум:sample_size.change_factor(number, optional): Коэффициент частоты больше 1, которого должен достичь шаблон, встречающийся в обоих окнах (increased), или до обратного значения которого частота должна снизиться (decreased). По умолчанию: 2.
Оба пороговых условия должны выполняться, поэтому шаблон с большим количеством строк, частота которого не изменилась на change_factor, никогда не будет выведен. Возвращаются только изменившиеся шаблоны (new, increased, decreased, disappeared) с количеством current и baseline; unchanged_patterns показывает количество шаблонов, присутствующих в обоих окнах, частота которых изменилась меньше чем на change_factor, а below_min_count_patterns — количество изменений, исключённых из-за того, что в них было меньше min_count строк. Частоты сравниваются в расчёте на минуту, если обе выборки содержат все совпадающие строки; в расчёте на минуту, оценённом по точному значению total_matching_lines ограниченной выборки; в остальных случаях — как доли выборки, где increased/decreased описывают состав, а не частоту (comparison_basis). Пустой список patterns означает отсутствие изменений, превышающих оба порога, а не отсутствие изменений в журналах: более редкие изменения учитываются в below_min_count_patterns, а окно с sample_limit_reached сравнивает выборки, а не целые окна.
get_log_attributes
lookback_minutes(integer, optional): По умолчанию: 15.start_time_iso/end_time_iso(string, optional)region(string, optional)index(string, optional)
get_log_attributes_for_pipeline
pipeline(array, required): Предыдущие этапы фильтрации для ограничения области поиска атрибутов, например[{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}].lookback_minutes(integer, optional): По умолчанию: 15.start_time_iso/end_time_iso(string, optional)region(string, optional)index(string, optional)
get_drop_rules
Параметров нет. Выводит правила отбрасывания через GET /otel_settings/drop?region=....
add_drop_rule
name(string, required)filters(array, required): Каждый фильтр:key,value,operator(equals/not_equals),conjunction(and).- В ключах фильтров необходимо использовать
attributes["key_name"]илиresource.attributes["key_name"](требование Last9 API). - Создаёт правило через
POST /otel_settings/drop?region=...&cluster_id=....
get_remapping_rules
rule_type(string, required):logs_extract,logs_mapилиtraces_map.region(string, optional): По умолчанию — настроенный регион источника данных.- Выводит правила через
GET /otel_settings/remapping/{rule_type}?region=....
add_remapping_rule
Создаёт одно правило за вызов; для правил сопоставления требуется отдельный вызов для каждого target_attribute.
rule_type(строка, обязательный):logs_extract,logs_mapилиtraces_map.name(строка, обязательный)remap_keys(массив, обязательный): Поля источника.logs_extractсjson: имена полей тела; сpattern: ровно одно регулярное выражение с именованной группой захвата. Правила сопоставления: пути атрибутов, используется первое непустое значение.target_attribute(строка, обязательный):logs_extract:log_attributesилиresource_attributes.logs_map:service,severityилиresource_deployment.environment.traces_map:service.extract_type(строка, толькоlogs_extract, обязательно там):jsonилиpattern.action(строка, толькоlogs_extract):upsert(по умолчанию) илиinsert.prefix(строка, толькоlogs_extract)preconditions(массив, толькоlogs_extract): Не более одного{key, value, operator};operator— этоequals(по умолчанию),not_equalsилиlike(регулярное выражение).region(строка, необязательный): По умолчанию: настроенный регион источника данных.- Создаёт правило с помощью
POST /otel_settings/remapping/{rule_type}?region=.... Повторные попытки не выполняются; после тайм-аута проверьте с помощьюget_remapping_rules.
get_traces
Используйте для широкого поиска и агрегирования. Для поиска по точному идентификатору трассировки используйте get_service_traces.
tracejson_query(массив, обязательный)start_time_iso/end_time_iso(строка, необязательный)lookback_minutes(целое число, необязательный): По умолчанию: 60.limit(целое число, необязательный): По умолчанию: 5000.
get_service_traces
Требуется ровно один из параметров trace_id или service_name.
trace_id(строка, необязательный): По умолчанию глубина поиска: 72 часа.service_name(строка, необязательный): По умолчанию глубина поиска: 60 мин.lookback_minutes(целое число, необязательный)start_time_iso/end_time_iso(строка, необязательный)limit(целое число, необязательный): По умолчанию: 10.env(строка, необязательный)
get_trace_attributes
lookback_minutes(целое число, необязательный): По умолчанию: 15.start_time_iso/end_time_iso(строка, необязательный)region(строка, необязательный)
get_trace_attributes_for_pipeline
pipeline(массив, обязательный): Предыдущие этапы фильтрации для ограничения области поиска, например[{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}].lookback_minutes(целое число, необязательный): По умолчанию: 15.start_time_iso/end_time_iso(строка, необязательный)region(строка, необязательный)
get_trace_attribute_values
tag_name(строка, обязательный): Имя атрибута изget_trace_attributes(например,resource_departmentилиattributes['http.method']).pipeline(массив, необязательный): Предыдущие этапы фильтрации для ограничения области поиска значений; опустите параметр, чтобы получить глобальные значения.lookback_minutes(целое число, необязательный): По умолчанию: 15.start_time_iso/end_time_iso(строка, необязательный): Исторические границы RFC3339; имеют приоритет надlookback_minutes.region(строка, необязательный)
get_trace_attribute_deviations
comparison_mode(строка, обязательный):latency,errorsилиtime.service_name(строка, обязательный)environment(строка, обязательный): Точное значениеdeployment.environment.operation(строка, необязательный)filters(массив, необязательный): Условия фильтрации JSON трассировки.candidate_attributes(массив, необязательный): Максимум 8; опустите для ограниченного поиска.latency_threshold_ms(число, необязательный): Обязателен для режимаlatency; для других режимов не допускается.start_time_iso/end_time_iso(строка, необязательный)lookback_minutes(целое число, необязательный): По умолчанию: 15. Максимум: 15.baseline_start_time_iso/baseline_end_time_iso(строка, необязательный): Обязательны для режимаtime; интервалы не должны пересекаться и должны иметь ту же длительность, что и целевое окно.minimum_cohort_size(целое число, необязательный): По умолчанию: 100. Минимум: 20.minimum_value_support(целое число, необязательный): По умолчанию: 20. Минимум: 10.limit(целое число, необязательный): По умолчанию: 10. Максимум: 10.
Требуется включить соответствующую возможность серверной части.
get_trace_waterfall
trace_id(строка, обязательный)environment(строка, необязательный)start_time_iso/end_time_iso(строка, необязательный)lookback_minutes(целое число, необязательный): По умолчанию: 4320 (72 часа).selected_span_id(строка, необязательный): Возвращает атрибуты, события и ссылки только для этого спана.max_spans(целое число, необязательный): По умолчанию: 500. Максимум: 1000; политика редактирования данных организации может установить меньший предел.
Возвращает конверт investigation-evidence/v1 службы трассировки без изменений; водопад находится в data. Служба формирует водопад и применяет редактирование значений согласно политике организации (учётные данные, литералы запросов, URL-адреса, адреса электронной почты, IP-адреса, идентификаторы пользователей) до отправки данных из серверной части: sanitizer указывает применённую политику, а evidence.sanitization содержит количество отредактированных или усечённых значений. Если нужные данные отредактированы, попросите администратора организации изменить политику, а не обходите её. Инструмент отклоняет ответ, если в нём нет блока sanitizer, значение sanitizer.version не равно trace-evidence-sanitizer/v1, тело содержит повторяющийся ключ JSON или его размер превышает 512 КиБ (уменьшите max_spans). Требуется включить соответствующую возможность серверной части.
get_change_events
start_time_iso/end_time_iso(строка, необязательный)lookback_minutes(целое число, необязательный): По умолчанию: 60.service_name(строка, необязательный)env(строка, необязательный)event_name(строка, необязательный): Сначала вызовите без этого параметра, чтобы получитьavailable_event_names.
analyze_change_impact
Передайте ровно один из параметров change_event или service + timestamp.
change_event(объект, необязательный): Один элементget_change_eventschange_events[]без изменений. Используетmetric.service,metric.deployment_environmentи самый раннийvalues[].timestamp.service(строка, необязательный): Обязателен вместе сtimestamp, еслиchange_eventне указан.timestamp(строка, необязательный): RFC3339 или секунды Unix, округляется вниз до минуты.env(строка, необязательный): Точное окружение. По умолчанию: окружение события, иначе все окружения.baseline_minutes(целое число, необязательный): По умолчанию: 60. Ограничивается диапазоном 30..120.after_minutes(целое число, необязательный): По умолчанию:baseline_minutes. Ограничивается диапазоном 30..120 и текущим временем.
regression likely, если выполняется любое из условий: частота ошибок увеличилась как минимум на 1 процентный пункт, p95 вырос как минимум на 40% или пропускная способность (rpm) снизилась как минимум на 50% для службы или одного из 10 её основных вызывающих сервисов, ранжированных по пропускной способности за оба окна вместе (только при наличии не менее 100 запросов до изменения и, для пропускной способности, после него; p95 учитывает только запросы latency_env); для них начинает срабатывать оповещение после изменения и продолжает срабатывать до конца последующего окна (сопоставление без учёта регистра по имени группы оповещений или метке service, service_name или service.name, иначе по аннотации; никогда не по произвольному тексту, например сводке); при наличии env оповещения с меткой другого окружения отбрасываются без учёта регистра, а оповещения без метки помечаются как env_match: unlabelled; обнаружена регрессия по get_apm_service_deviations. insufficient data, если последующее окно короче 5 минут (включая изменение в будущем), у службы слишком мало запросов или не удалось получить золотые сигналы, сведения о прямых вызывающих сервисах, оповещения или get_apm_service_deviations — полностью или в любом запросе из списка deviations.apm.unavailable: отсутствие данных не приводит к no significant change, а при обнаружении регрессии указывается, что именно не удалось получить. no significant change — допустимый ответ, а не ошибка. Отклонения атрибутов трассировки анализируются только при наличии env, не более чем за 15 минут с каждой стороны; они поясняют вердикт, но не определяют его, поэтому их пропуск или ошибка при получении не меняют вердикт. В каждом списке не более 10 элементов; указывается количество отброшенных элементов. Ошибка вызова вышестоящего сервиса добавляет error только в соответствующий раздел. Задержка золотых сигналов берётся из одного окружения в обоих окнах, указанного в latency_env: если env не задан, используется самое загруженное окружение. Частота ошибок золотых сигналов учитывает ошибки 5xx и gRPC; deviations.apm также учитывает спаны со статусом ошибки и ответы 429. Сигналы вызывающего сервиса основаны на его собственных серверных спанах, поэтому для вызывающих сервисов, у которых есть только клиентские спаны, отображается 0 rpm.
regressions содержит по одной записи на каждый триггер, лежащий в основе regression likely, в порядке reason, и равен [] для остальных вердиктов. Каждая запись содержит service, role (changed или dependent), env, metric (ровно одно из error_rate_pct, latency_p95_ms, throughput_rpm, alert, apm_deviation) и baseline/after в единицах метрики (%, мс, rpm или собственное значение сигнала APM; null для alert). Запись alert дополнительно содержит rule_id и state — состояние экземпляра в самом новом срезе мониторинга оповещений за последующее окно, в котором он указан, всегда firing: оповещение, начавшее срабатывать после изменения, но разрешившееся до конца последующего окна, не является регрессией и поэтому не создаёт заявку; оно остаётся в alerts.started со своим state, а reason учитывает его. env — окружение, в котором измерялась метрика: запрошенное env; в противном случае частота ошибок и пропускная способность суммируются по всем окружениям (env: ""), а для p95 используется самое загруженное окружение, latency_env; оповещение использует собственную метку окружения, а отклонение APM — собственное окружение. Каждая регрессия относится ко всей службе, поэтому ни одна из них не указывает конечную точку.
get_alert_groups
Инвентаризация настроенных групп оповещений Compass для аудита changeboard / покрытия метками. Включает группы без правил и группы, для которых оповещения не срабатывают. PromQL не возвращается.
alert_group_name/alert_group_type/data_source_name(строка, необязательный): Поиск подстроки без учёта регистра.team/tier(строка, необязательный): Точное совпадение без учёта регистра по настроенным метаданным.label_key+label_value(строка, необязательный): Параметры необходимо задавать вместе. Точное совпадение без учёта регистра с одной паройmetadata.labels— и по ключу, и по значению.
Возвращает компактный JSON {"count":N,"groups":[...]} с id, name, type, entity_class, team, tier, metadata.labels и количеством правил. Пустые team / labels означают, что значение не задано.
get_alert_operations_summary
start_time_iso/end_time_iso(строка, обязательный): Окно RFC3339, не более 31 дня.timezone(строка, необязательный): Имя часового пояса IANA для границ дней. По умолчанию:UTC.severities/services(массив, необязательный): Ограничивает сводку.include_rules(логический, необязательный): Также возвращать данные о гигиене правил (20 лучших поfire_count, часто срабатывающие и не маршрутизируемые правила, а такжеtruncated, если API ограничил список правил). По умолчанию:false.
Возвращает JSON с alerts_raised, acknowledged, unacknowledged, current_backlog, delivered, notification_outcomes, top_rules, needs_attention и coverage. Каждая метрика — это {status, count?, reason?}; значение partial охватывает только часть окна и не является нижней границей.
get_alert_coverage
Отвечает на вопрос «на что у меня нет оповещений?» для службы, окружения, одной группы оповещений или всей организации, если область не указана. Только для чтения: ничего не создаёт, не изменяет и не включает звук. Также доступен в наборе инструментов investigate.
service(строка, необязательный): Имя службы.environment(строка, необязательный): Окружение развёртывания (например,prod).entity_id(строка, необязательный): UUID группы оповещений (сущности), возвращаемыйget_alert_groups.muted_days(целое число, необязательный): Целое число дней, от 1 до 3650. По умолчанию: 7; значение 0 означает значение по умолчанию. Правило, отключённое на срок дольше этого периода, считается пробелом в покрытииmuted_too_long. Значения обрезаются; пустые строки игнорируются. Типы пробелов: uncovered_signal (нет включённого правила для latency, error_rate, throughput или saturation; указывается отключённое правило, которое охватывало бы этот сигнал), all_rules_disabled (группа оповещений, в которой отключены все правила), no_notification_channel (правило, для уровня важности которого ни один канал группы оповещений не настроен), muted_too_long (отключено на неопределённый срок или более чем наmuted_days;muted_since— время последнего обновления правила, аmute_untilне указывается при отключении на неопределённый срок).
Возвращает компактный JSON {scope, generated_at, complete, summary, counts, groups}. В groups содержится по одной записи {kind, count, gaps, omitted} для каждого имеющегося типа с перечислением не более 10 пробелов на тип (omitted учитывает остальные; чтобы увидеть их, сузьте область поиска); каждый пробел содержит suggested_tool (create_alert, create_alert_from_chart, attach_notification_channel или patch_alert) и suggested_args, в котором указаны только входные данные, принимаемые этим инструментом (patch_alert: entity_id, id и is_disabled=false или mute_until=0; attach_notification_channel: alert_group_id и breach/threat severity; create_alert: entity_id; create_alert_from_chart: service_name); собственные entity_id, rule_id и signal пробела перечислены рядом. Вызывайте предложенный инструмент, только если он доступен в сеансе и пользователь подтвердил действие. Значение complete равно true только если API не перечисляет пробелов, все счётчики равны 0 и хотя бы одна группа оповещений соответствует области поиска (точные метки service_name / env, проверенные по списку get_alert_groups); если область поиска не соответствует ни одной группе, запрос завершился ошибкой или счётчики ненулевые, но пробелы не перечислены, проверка не считается завершённой; причина указана в summary.
get_alert_config
search_term(string, optional): Полнотекстовый поиск по названию, группе, источнику данных и тегам.rule_name(string, optional)severity(string, optional)rule_type(string, optional):staticилиanomaly.alert_group_name/alert_group_type/data_source_name(string, optional)tags(array, optional): Все условия должны совпадать (логика AND).
Для каждого правила перечислены Recent Evaluations: 5 одноминутных выборок, от самой новой к самой старой; каждая помечена минутой UTC, на которой она заканчивается. Самая новая выборка заканчивается за 1–2 минуты до вызова, поскольку монитор заполняет последнюю минуту с задержкой. firing; ok = монитор сообщил, что правило не срабатывает (обычное, разрешённое, ожидающее или пустое состояние, как указано в is_firing=0 в get_alert_rule_state); unknown = строка монитора для правила отсутствует (правило ещё не оценивалось либо поиск за эту минуту завершился ошибкой, о чём сообщается в начале ответа) или строка содержит состояние, отличное от firing, normal, resolved, pending или empty (например, no_data, silenced). Для отключённых правил отображается none. Если совпало более 25 включённых правил, история для всех них не включается, и ответ сообщает об этом.
get_entity_kpis
Только для чтения; доступен в наборах инструментов alerts и investigate. Перечисляет все KPI одной группы оповещений, включая KPI, которые пока не используются ни одним правилом оповещения. Используйте возвращённые идентификаторы в expression_args / indicators_used; не придумывайте их.
entity_id(string, required): UUID группы оповещений/сущности изget_alert_groupsилиget_alert_config.
Возвращает JSON {"entity_id","count","kpis":[{"id","name","description","query","unit"}]}, отсортированный по имени. unit — отображаемая метка: пороговые значения сравниваются с исходным значением запроса. Если подходящего KPI нет, создайте его с помощью create_kpi. Результат для пустой группы содержит create_kpi только в том случае, если сеанс его предоставляет; при использовании --read-only (кроме случая --allow-write-tools=create_kpi) или набора инструментов investigate сообщается, что для создания KPI требуется сеанс alerts с правами на запись.
create_kpi
Создаёт KPI в существующей группе оповещений; доступен только в наборе инструментов alerts. Используйте его, только если в get_entity_kpis нет KPI с нужным запросом. Сначала проверьте с помощью prometheus_range_query, что запрос возвращает данные: API отклоняет только запросы с синтаксическими ошибками и сохраняет корректный запрос, даже если соответствующая метрика не существует.
entity_id(string, required): UUID группы оповещений/сущности.name(string, required): Уникальное имя в пределах группы оповещений; повторное создание с тем же именем отклоняется из-за конфликта.query(string, required): PromQL. Чтобы настроить оповещение для панели дашборда, возьмите PromQL панели изget_dashboard.unit(string, required): Единица измерения исходного значения запроса, напримерseconds,ms,percent,ratio,count,req/s. Это только метка, она ничего не преобразует, поэтому пороговые значения сравниваются с исходным значением.description(string, optional)data_source_id(string, optional): По умолчанию используется источник данных группы оповещений.
Ни один инструмент MCP не удаляет и не редактирует KPI (используйте интерфейс Last9), поэтому перед созданием подтвердите имя, запрос и единицу измерения. Создайте KPI один раз и сохраните возвращённый идентификатор для expression_args / indicators_used; при конфликте имён используйте идентификатор существующего KPI из get_entity_kpis. При тайм-ауте или ошибке соединения создание могло выполниться, а могло и нет: перед повторной попыткой проверьте имя с помощью get_entity_kpis. Возвращает {"id","name","query","unit"}.
get_alerts
time_iso(string, optional): Время оценки в формате RFC3339.window(integer, optional): Интервал просмотра в секундах. По умолчанию: 900. Диапазон: 60–86400.lookback_minutes(integer, optional): Диапазон: 1–1440.
get_alert_rule_state
start_time(integer or string, required): Начало диапазона (включительно): секунды Unix epoch (1718000000) или RFC3339 (2024-06-10T06:13:20Z). Миллисекунды, микросекунды и наносекунды Unix epoch преобразуются в секунды; значения до 2000-01-01 отклоняются.end_time(integer or string, required): Конец диапазона (включительно), в тех же форматах.step(integer, required): Интервал в секундах между выборками. Количество выборок((end_time - start_time) / step + 1)ограничено 100. Каждая выборка — это один вызов вышестоящего сервиса, охватывающийmin(step, 3600)секунд до указанной временной метки включительно; выборки запрашиваются группами по 5. Если выполнение занимает более 60 секунд, инструмент возвращает ошибку с рекомендациями по повторной попытке.alert_group_id(string, optional): Фильтр по идентификатору группы оповещений.rule_name(string, optional): Фильтр по имени правила с использованием регулярного выражения.alert_group_name(string, optional): Фильтр по имени группы оповещений с использованием регулярного выражения.label_filters(string, optional): Фильтры метокkey=value, разделённые запятыми.state(string, optional): Фильтр по состоянию (например,firing).
Возвращает JSON-карту rule_id -> [{timestamp, is_firing}]. Если правило отсутствует в ответе вышестоящего сервиса для определённой временной метки, оно указывается как is_firing=0 — это означает «не наблюдалось срабатывания», а не подтверждённое нормальное состояние.
get_alert_hygiene
Аудит включённых правил оповещений только для чтения. Он ничего не меняет: каждое предложенное исправление — это рекомендация, которая применяется только после явного подтверждения пользователя с помощью update_alert (настройка), patch_alert (is_disabled), delete_alert или attach_notification_channel, если они доступны.
window(string, optional):7dили30d. По умолчанию:7d.limit(integer, optional): Максимальное количество возвращаемых правил с проблемами, начиная с наиболее критичных. По умолчанию: 20. Диапазон: 1–100.
Окно заканчивается сейчас. Категории (одно правило может относиться к нескольким): noisy (≥ 5 срабатываний в день при < 20% acked; with an unavailable ack_rate it is judged on fire rate alone and the reason says so; mute time is not reported), flapping (> 4 переключениях в день), stale (последнее срабатывание было до окна, а в самом окне срабатываний не было; либо настроенное включённое правило не имело эпизодов в окне, при этом жизненный цикл coverage завершён и список API не усечён), unrouted (ни одно срабатывание в окне не достигло канала, и сейчас к группе оповещений не подключён ни один канал; если сведения о подключённых каналах недоступны, правило учитывается в категории unavailable.routed). Каждая статистика — это {status, count|value, reason} или null: недоступное значение никогда не считается нулём и пропускает только проверку, которой оно требуется; unavailable учитывает включённые правила для каждого отсутствующего значения (fire_count, flap_count, ack_rate, routed, rule_config для правил, отсутствующих в списке правил оповещений, исправления для которых не содержат текущего значения, и activity для настроенных правил без эпизодов, тишину которых невозможно подтвердить по истории; такие правила не оцениваются). coverage указывает, какую часть окна охватывает история оповещений; частота рассчитывается по охваченному периоду длительностью не менее одного дня. Значение upstream_truncated равно true, если API вернул только 200 самых шумных правил, поэтому менее шумные правила не оценивались. Исправления формируются на основе конфигурации каждого правила из списка правил оповещений: увеличить bad_minutes (число N в count_true(result) >= N) или увеличить eval_window (максимум до 60 минут); для шумных статических порогов изменить порог в condition (expr > 100) или переключить выражение на adaptive_std_cmp(metric, sensitivity, window); подключить канал уведомлений; отключить или удалить устаревшие правила.
Возвращает компактный JSON {window, from, to, coverage, upstream_truncated, rules_evaluated, flagged_rules, truncated, omitted_for_size, unavailable, rules}, рассчитанный на размер до 32 KB: значение truncated равно true, если количество правил с проблемами превышает limit или этот лимит; omitted_for_size учитывает правила, исключённые из limit из-за ограничения размера (самое проблемное правило всегда сохраняется, поэтому если одно правило превышает 32 KB, оно возвращается отдельно и превышает лимит); каждое правило содержит findings (category, reason, suggested_fix, необязательное alternative_fix) и исходное значение stats.
get_notification_channels
scope(string, optional):attached(по умолчанию) возвращает по одной строке для каждого подключения к группе оповещений;id— это идентификатор подключения, используемый вdetach_notification_channel.channelsвозвращает каналы организации (id,name,type,send_resolved,created_via);id— это идентификатор канала, используемый вattach_notification_channel. Адресаты, заголовки и сертификаты никогда не возвращаются.
Возвращает настроенные каналы уведомлений (Slack, PagerDuty, электронная почта, вебхуки и т. д.) в виде таблицы TSV. В строках подключений (service_fqid задан) указано global false и services -; services перечисляет только устаревшие привязки служб. В строках подключений send_resolved — это сохранённое значение по умолчанию для строки, а не фактическое значение, используемое при доставке; уведомления о разрешении используют собственное значение send_resolved канала (scope=channels). Оба режима включают created_via (last9-mcp для строк, созданных агентом MCP, иначе -).
recommend_alert_config
Только для чтения. Возвращает рекомендации по жизненному циклу, условия проверки и требования к контексту для реагирования; сам по себе этот результат не является доказательством, поэтому обосновывайте пороговые значения с помощью инструментов телеметрии.
signal(string, required): Метрика или сигнал влияния на пользователей, включая единицу измерения и измерения.objective(string, required): Симптом или влияние на пользователей, которое нужно обнаружить.rule_type(string, optional):static(по умолчанию) илиanomaly.severity(string, optional):breach(по умолчанию) илиthreat.environment(string, optional): Среда и профиль трафика.
validate_alert_expression
Проверяет выражение без сохранения. Используйте перед create_alert / update_alert.
entity_id(string, required): UUID группы оповещений/сущности.expression(string, required): Арифметическое выражение с индикаторами, указанными по точным именам их KPI, напримерerrors / requests. Не более 3 индикаторов. Имена с пробелами, точками или дефисами записывайте без изменений (Test Alert / errors), точно так, как их сохраняетcreate_alert.indicators_used(object, required, non-empty): Сопоставление имени индикатора с UUID KPI, принадлежащегоentity_id; перечислите идентификаторы и имена KPI группы с помощьюget_entity_kpis. Используйте точное имя каждого KPI: эта проверка принимает любое имя, ноcreate_alertиupdate_alertотклоняют ключиexpression_args, не совпадающие с именем связанного KPI. Проверяется только арифметическое выражение (передайте внутреннее выражение метрики, а не обёрткуadaptive_std_cmp(...));condition/alert_conditionне проверяются. Проверка наличия хотя бы одного временного ряда выполняется только при использовании более одного индикатора.
Возвращает {"valid":true} или {"valid":false,"reason":"..."}; недопустимое выражение — это обычный результат, а не ошибка инструмента.
describe_alert_chart
Только для чтения. Перечисляет сигналы, для которых можно настроить оповещения (key, unit, eval_query, query_kind), на поддерживаемом графике Discover. Токены с ролью Viewer отклоняются.
surface(string, обязательный):discover-serviceилиdiscover-exceptions; любая другая поверхность, включая пользовательские дашборды, отклоняется до вызова API (вместо этого используйтеcreate_alertс KPI).chart_key(string, обязательный): например,apdex,error_rate,response_time,exception_count.service_name(string, обязательный)env(string, необязательный)attributes(object, необязательный): Дополнительные измерения идентификатора с использованием имён ключей, указанных этим инструментом.
create_alert
Создаёт правило в существующей группе оповещений, всегда отключённое (черновик, даже если передан is_disabled=false). Сначала вызовите recommend_alert_config, а затем активируйте с помощью patch_alert is_disabled=false только после подтверждения пользователя. Создайте правило один раз и сохраните возвращённый идентификатор. Если в группе оповещений уже используется rule_name (без учёта регистра), создание отклоняется; при этом ничего не создаётся, а в сообщении указывается идентификатор существующего правила.
entity_id(string, обязательный): UUID группы оповещений/сущности.alert_rule(object, обязательный): Полное типизированное тело правила, включаяprimary_indicatorиexpression_args, привязанные к реальным KPI сущности. Каждый ключexpression_argsдолжен точно совпадать с именем привязываемого KPI (не с заполнителем, напримерx), а вprimary_indicatorиexpressionдолжны использоваться эти имена. Для статических правил обязательныcondition,alert_conditionиeval_window(0–60 минут). Для адаптивных правил используетсяexpression=adaptive_std_cmp(<primary_indicator>, sensitivity, window); тогда три поля необязательны (значения по умолчанию:expr > 0,count_true(result) >= 1,1). Нельзя задаватьalgorithm. Контекст для ответственных указывается вproperties(описание, инструкция по эксплуатации, аннотации,query_mode).
Маршрутизация уведомлений настраивается для группы оповещений, а не для правила.
create_alert_from_chart
Создаёт правило со статическим порогом на основе графика, описанного с помощью describe_alert_chart. Как и в случае с create_alert, правило создаётся отключённым, как черновик, и не срабатывает; активируйте его с помощью patch_alert is_disabled=false только после подтверждения пользователя. API графиков создаёт правила включёнными, поэтому инструмент отключает правило сразу после создания; если это не удастся, результатом будет ошибка с идентификатором правила, которое может быть активным.
surface/chart_key/service_name/signal_key/name(string, обязательный)env(string, необязательный)attributes(object, необязательный)threshold(number, необязательный): В единицах сигнала; значение должно быть не меньше 0. Для сигналов в единицах оценки, например apdex, необходимо указать значение явно.threshold_operator(string, необязательный):>(по умолчанию),<,>=,<=,==,!=.eval_window(integer, необязательный): Минуты, 1–60. По умолчанию: 5.bad_minutes(integer, необязательный): 1–eval_window. По умолчанию: 3.severity(string, необязательный):breachилиthreat.description(string, необязательный)group_id(string, необязательный): Обычно не указывайте.
update_alert
Полная замена конфигурации оценки правила. Сначала получите правило с помощью get_alert_config или get_entity_alert_rules. Если правило не существует или принадлежит другой группе оповещений, операция отклоняется без каких-либо изменений. Правило может быть мягко удалено и создано заново, поэтому впоследствии используйте возвращённый идентификатор замены.
entity_id(string, обязательный)id(string, обязательный): UUID правила оповещения.alert_rule(object, обязательный): Полная конфигурация; та же структура, что уcreate_alert.
patch_alert
Частичное изменение, сохраняющее идентификатор правила. Необходимо указать хотя бы одно изменение. Если правило не существует или принадлежит другой группе оповещений, операция отклоняется без каких-либо изменений.
entity_id(string, обязательный)id(string, обязательный): UUID правила оповещения.is_disabled(boolean, необязательный):falseактивирует правило,trueприостанавливает его.mute_until(integer, необязательный): Срок действия в формате Unix epoch;0снимает отключение уведомлений.properties(object, необязательный):description,runbook,annotations,query_mode. Каждое переданное поле заменяет сохранённое; пропущенные или пустые поля сохраняют сохранённое значение.annotationsзаменяет всю карту, поэтому для сохранения значений передайте все ключи;{}очищает её.recurring_mute_schedule(object, необязательный): Заменяет недельное расписание:enabled(по умолчанию false),timezone(имя IANA, обязательное) иwindows(от 1 до 20 значенийweekdaysв форматеsun..sat,start_time/end_timeв формате 24-часового времениHH:MM). Если время окончания не позже времени начала, окончание переносится на следующий день. Для сохранения расписания передайте все интервалы.clear_recurring_mute_schedule(boolean, необязательный): Полностью удаляет расписание; нельзя использовать вместе сrecurring_mute_schedule. Отличается отenabled=false, который сохраняет интервалы.
Пользователи с ролью Viewer могут изменять только mute_until. Изменения отключения уведомлений на уровне правила отклоняются, если отключены уведомления для группы или сущности. Чтобы прочитать изменения, используйте get_entity_alert_rules; он показывает mute_until, recurring_mute_schedule и properties.
delete_alert
Безвозвратно удаляет правило. Сначала проверьте его с помощью get_alert_config и получите явное подтверждение пользователя. Если правило не существует или принадлежит другой группе оповещений, операция отклоняется без удаления.
entity_id(string, обязательный)id(string, обязательный): UUID правила оповещения.
mute_alert_group
Отключает уведомления для всех текущих и будущих правил в группе; чтобы отключить уведомления для одного правила, используйте patch_alert с mute_until. Требуется доступ редактора.
entity_id(string, обязательный): UUID группы оповещений/сущности.until(integer, обязательный): Время окончания отключения уведомлений в секундах Unix epoch.0снимает отключение; отрицательное значение, например-1, отключает уведомления бессрочно.
acknowledge_alert
Берёт на себя ответственность за сработавшее оповещение или снимает её. Не устраняет и не отключает оповещение. Подтверждение оповещения, за которое вы уже отвечаете, безопасно и ничего не меняет. ack отклоняет запрос без записи, если get_alerts не содержит именно это оповещение (все три идентификатора) за последний час.
alert_group_id/rule_id/rule_type(string, обязательный): Скопируйте из оповещения вget_alerts.action(string, необязательный):ack(по умолчанию) илиunack. Снять подтверждение может только владелец или администратор организации.mute_until(integer, необязательный): Толькоack. Записывает отключение уведомлений, которое вы уже применили с помощьюmute_alert_groupилиpatch_alert; ничего не отключает.
reassign_alert
Передаёт оповещение, у которого уже есть владелец, другому пользователю; если владельца нет, сначала подтвердите оповещение. Если переназначение не выполнено из-за отсутствия владельца, инструмент сообщает, содержит ли get_alerts это оповещение за последний час. Last9 не уведомляет нового владельца.
alert_group_id/rule_id/rule_type(string, обязательный): Скопируйте из оповещения вget_alerts.owner_email(string, необязательный): Предпочтительный вариант; поиск среди активных пользователей организации выполняется без учёта регистра.owner_user_id(string, необязательный): Укажите ровно одно из значений:owner_emailилиowner_user_id.
create_notification_channel
Создаёт канал; он ничего не маршрутизирует, пока его не подключат с помощью attach_notification_channel. Создайте канал один раз и сохраните его идентификатор; инструмента для обновления нет. Возвращает только id, name, type и send_resolved.
name(string, обязательный): Должно быть уникальным для каждого типа; двоеточие не допускается.type(string, обязательный):slack,pagerduty,opsgenie,emailилиgeneric_webhook.destination(string, обязательный): URL входящего вебхука Slack (или идентификатор канала сslack_app_mode), ключ маршрутизации PagerDuty, ключ API Opsgenie, адреса рабочих электронных почт через запятую на любом домене, не только домене организации (API отклоняет адреса личных почтовых сервисов, например Gmail; если организация использует личную учётную запись для входа, принимается только адрес её администратора), либо URL вебхука HTTPS.slack_app_mode(boolean, необязательный): Только для Slack. По умолчанию: false.mention_handles(string, необязательный): Значения через запятую, напримерuser|U123ABC|name,special|here,special|channel.webhook_headers(object, необязательный): Толькоgeneric_webhook.webhook_ca_certificate(string, необязательный): Толькоgeneric_webhook; один сертификат ЦС PEM размером до 64 КиБ.send_resolved(boolean, необязательный): По умолчанию: true.
attach_notification_channel
Направляет уведомления из существующего канала в одну группу оповещений. Операция идемпотентна. При подключении копируются настройки доставки канала (заголовки, сертификат, упоминания); если настройки канала изменятся позже, подключите его повторно.
channel_id(integer, обязательный): Идентификатор канала (get_notification_channelsсscope=channels), а не идентификатор подключения.alert_group_id(string, обязательный): Изget_alert_groups.severity(string, обязательный):breach,threatилиboth.bothсоздаёт два подключения; если второе не удастся, первое останется подключённым, а в сообщении об ошибке будет указана серьёзность, для которой нужно повторить попытку.
detach_notification_channel
Удаляет одно подключение. Требуется токен с областью действия delete; токен с областью действия write не позволяет отключать каналы.
attachment_id(integer, обязательный):idизget_notification_channelsсscope=attached. Идентификаторы каналов отклоняются.alert_group_id(string, необязательный): Запрос отклоняется, если подключение относится к другой группе.
delete_notification_channel
Безвозвратно удаляет канал, к которому не подключено ни одного получателя; сначала отключите все его подключения. Требуется токен с областью действия delete. Удаление подтверждается повторным получением списка каналов.
channel_id(integer, обязательный):idизget_notification_channelsсscope=channels. Идентификаторы подключений отклоняются.
did_you_mean
query(string, обязательный): Имя для поиска — частичное, с опечаткой или сокращённое.type(string, необязательный): Ограничить поиск типом сущности:service,environment,host,database,k8s_deployment,k8s_namespace,job.
Возвращает до 3 наиболее близких совпадений с оценками сходства. Используйте этот инструмент перед любым вызовом, если имя сущности вызывает сомнения. Если предыдущий вызов вернул пустой результат, попробуйте этот инструмент перед повторной попыткой.
get_service_profile
service_name(string, обязательный): Сервис, для которого нужно определить профиль телеметрии.datasource(string, необязательный): Имя источника данных. Не указывайте для источника по умолчанию; приблизительное имя разрешается так же, как в инструментах Prometheus. Возвращает краткую сводку расследования, а затем полный профиль в виде необработанного JSON: наличие сигналов (logs/traces/metricsкакpresent,absentилиunknown), язык и среда выполнения, среды развертывания,signal_shapeжурналов (log_format,severity_set,level_field,trace_context_in_logs) и рекомендуемое исправление ingest, если оно применимо. Когда бэкенд сообщаетfreshness, в сводку добавляется строкаlast seenсfreshness.logs.last_seenиfreshness.traces.last_seen(RFC3339 илиnone, если значение равно null), а также предупреждениеtraces stale, еслиfreshness.traces_staleравноtrue: сбор spans прекратился, а журналы продолжили поступать, поэтому следует искать регрессию околоfreshness.traces.last_seen, а не отсутствие настройки. Данные получены из вышестоящего источника и кэшируются с TTL около 15 минут.
Вызывайте этот инструмент перед любым расследованием в контексте сервиса, чтобы выбор инструментов соответствовал фактической телеметрии сервиса: пропускайте инструменты трассировки, если traces равно absent, а если severity_set равно none или partial, определяйте уровень серьезности по level_field в теле журнала, а не используя severity_filters. metrics всегда равно unknown, а dependencies в v1 не заполняется. Если logs и traces оба равны absent, прежде чем заключать, что мониторинг сервиса не ведется, проверьте его имя с помощью did_you_mean.
list_dashboards
name(string, необязательный): подстрока в названии дашборда без учета регистра. Сужает список иtotal.limit(integer, необязательный): количество дашбордов на странице, 1–200. По умолчанию: 100.cursor(string, необязательный):next_cursorпредыдущей страницы; передавайте вместе с ним тот жеname.
Возвращает {"dashboards": [{"id", "name", "updated_at", "created_by", "locked"}], "total", "next_cursor"}, сначала недавно обновленные. Если created_by пуст, он не включается; locked не включается, если API не сообщает readonly. updated_at — это секунды с начала эпохи Unix в виде строки. Страница может завершиться раньше, чтобы не превышать 32 KB; на последней странице next_cursor отсутствует.
get_dashboard
id(string, обязательный): UUID дашборда.region(string, необязательный): регион для заполнения запросов панелей. По умолчанию используется настроенный регион источника данных.
Результат дополняется полями верхнего уровня locked (false, если API его не возвращает) и created_by (идентификатор пользователя — автора дашборда).
Чтобы настроить оповещение для панели, см. last9://reference/alerting.
validate_dashboard
Только чтение. Дашборды не создаются и не обновляются. Укажите ровно один из параметров: dashboard_id или dashboard_definition.
dashboard_id(string, необязательный): UUID сохраненного дашборда для проверки.dashboard_definition(object, необязательный): тело несохраненного дашборда, передаваемое напрямую (настоящий пробный запуск). Обертка создания{dashboard, metadata}разворачивается до объектаdashboard.start_time_iso/end_time_iso(string, необязательный): интервал проверки (RFC3339). Не более 24h.region(string, необязательный): регион для выполнения запросов панелей.
Возвращает dashboard_validation/v1: классификацию lint-проверки и выполнения для каждой панели (data / no_data / invalid / error). Пустые результаты в первый день классифицируются как valid_no_data без диагностических проб. Дашборд без панелей возвращает success: false с error: "no_panels". Поля панелей из других форматов (Grafana gridPos, title, type и targets для панелей, которым нужны запросы), а также поля неверного типа перечисляются для каждой панели в shape_problems, учитываются в summary.panels_invalid_shape и приводят к тому, что overall становится fail.
preview_dashboard
Предварительный просмотр только для чтения на стороне клиента. Передайте либо dashboard (объект несохраненного дашборда из запроса на создание), либо id вместе с ops (тот же упорядоченный набор операций, что и в patch_dashboard). Обязательные параметры start_time_iso и end_time_iso — временные метки RFC3339 с интервалом не более 24 часов. Необязательный параметр variables содержит скалярные переопределения; в противном случае используются значения дашборда и встроенные значения по умолчанию.
{
"id": "dashboard-id",
"ops": [{"op": "update_panel", "panel_id": "panel-id", "fields": {"name": "Request latency"}}],
"start_time_iso": "2026-10-01T08:00:00Z",
"end_time_iso": "2026-10-01T09:00:00Z"
}
Возвращает saved: false, сводку определения/запроса validation (включая definition_error при несовпадении со схемой создания) и panels со статусом ok / empty / error, разрешенными запросами и диагностикой целей. Запросы PromQL и LogJSON выполняются; неподдерживаемые типы запросов и неразрешенные переменные приводят к ошибке панели. Корректные панели без запросов имеют статус ok; некорректные определения панелей — error. Патч diff включает итоговые panels_added, panels_changed (в том числе перемещения) и panels_removed, а также изменения упорядоченных операций. Панели идентифицируются по ID и индексам, отсчитываемым с нуля; индексы удаленных панелей относятся к исходному дашборду. У сохраненных панелей должны быть непустые уникальные ID.
Ограничения: 50 панелей, 100 запросов, 100 операций, 65536 байт JSON для каждого из входных данных и дашборда-кандидата, а также 60 секунд на выполнение. Разрешенные запросы размером более 65536 байт JSON отклоняются до выполнения. Для каждой цели сохраняется не более трех образцов и 1024 байт JSON; если образцы опущены, указывается truncated: true. Если размер JSON-отчета превышает 262144 байта, операция завершается ошибкой с рекомендацией уменьшить входные данные.
Дашборд не создается и не обновляется. Эта проверка сопоставляет кандидата со схемой создания и выполняет запросы с помощью существующего валидатора; она не гарантирует принятие бэкендом или корректное отображение. Назначенные бэкендом ID, значения по умолчанию, отброшенные поля или параллельные изменения могут повлиять на сохраненный результат. Предварительный просмотр использует те же локальные операции патча и значения по умолчанию для версий панелей, что и запись.
create_dashboard
Только для создания нового дашборда. После того как этот вызов вернет dashboard.id, редактируйте панели с помощью patch_dashboard (или изменяйте структуру с помощью update_dashboard) — не создавайте дашборд повторно, чтобы добавить, удалить или исправить панели.
dashboard(object, обязательный): определение дашборда сnameиpanels[]. Для каждой панели обязательныname,version,layout(x,y,w,h),visualization.typeиqueries[].metadata(object, необязательный): метаданные дашборда — поля_categoryи_type(например,{"_category":"custom","_type":"metrics"}).
update_dashboard
Используйте только для изменения структуры большей части дашборда; чтобы добавлять, редактировать, удалять или перемещать отдельные панели, используйте patch_dashboard. Полная замена по ID (то же тело, что и при создании): необходимо повторно передать все панели без изменений.
id(string, обязательный): UUID дашборда для обновления.dashboard(object, обязательный): полное тело дашборда для замены (та же структура, что и при создании).metadata(object, необязательный): метаданные для замены. Для системных дашбордов только для чтения возвращается восстанавливаемая ошибка инструмента.
patch_dashboard
Для небольших изменений предпочтительнее, чем update_dashboard: неизмененные панели не передаются повторно. Инструмент считывает дашборд, последовательно применяет ops и записывает результат, поэтому изменения, внесенные кем-то еще между чтением и записью, будут перезаписаны. Возвращает {dashboard_id, changes[]}; операции, которым дашборд уже соответствует, исключаются, а если ни одна операция ничего не меняет, запись не выполняется. После записи различия проверяются повторным чтением: в fields панелей отображаются сохраненные значения, в not_stored перечислены ключи, отброшенные API, а в not_removed — ключи, сохраненные им вопреки null. Значения различий длиной более 200 символов сокращаются на месте с сохранением типа JSON.
id(string, обязательный): UUID дашборда для изменения.ops(array, обязательный): операции, применяемые по порядку; если какая-либо операция недопустима, запись не выполняется, а ошибка указывает ее какops[i].add_panel:panel(полный объект панели; дляversionпо умолчанию используется 1), необязательный параметрindex(позиция вставки, отсчитываемая с нуля; по умолчанию — в конец).update_panel:panel_id,fields(ключи верхнего уровня панели для замены;nullудаляет ключ;idнельзя изменить).remove_panel:panel_id.move_panel:panel_id,index(позиция после перемещения, отсчитываемая с нуля).set_title:title(название дашборда).set_variable:variable; заменяет переменную с тем жеtarget, иначе добавляет ее.
delete_dashboard
id(string, обязательный): UUID дашборда для удаления. Системные дашборды только для чтения удалить нельзя.
set_dashboard_lock
id(string, обязательный): UUID дашборда.locked(boolean, обязательный):trueблокирует дашборд,falseснимает блокировку.
Инструмент записи; вызывайте его только по прямой просьбе пользователя. Заблокировать или разблокировать дашборд может только его автор или администратор организации; встроенные дашборды всегда доступны только для чтения. Возвращает {"id", "locked"} с итоговым состоянием. Пока дашборд заблокирован, вызовы update_dashboard, patch_dashboard и delete_dashboard не выполняют запись и возвращают восстанавливаемую ошибку инструмента, начинающуюся с dashboard is locked, в которой указан автор и предлагается снять блокировку или скопировать дашборд с помощью create_dashboard.
list_dashboard_snapshots
dashboard_id(string, обязательный): UUID дашборда, снимки которого нужно перечислить.
Возвращает только метаданные (id, name, expires_at и т. д.). Для получения зафиксированных данных панелей используйте get_dashboard_snapshot.
get_dashboard_snapshot
id(string, обязательный): UUID снимка.
Возвращает полный зафиксированный снимок, включая dashboard_definition, panel_data, time_range и variables.
delete_dashboard_snapshot
id(string, обязательный): UUID снимка для удаления.
get_profile_services
lookback_minutes/start_time_iso/end_time_iso(необязательные): временной интервал; предпочтительно использовать lookback или явные границы ISO (по умолчанию 60m).region(string, необязательный): переопределение региона.
Возвращает сервисы, для которых в указанном интервале есть данные профилирования. Вызывайте перед get_flamegraph / get_top_functions / get_profile_summary.
get_flamegraph
service(string, обязательный): имя сервиса изget_profile_services.profile_type(string, необязательный):cpu(по умолчанию),allocилиwall. При сравнении интервалов зафиксируйте тип.env/cluster/namespace/runtime(string, необязательные): фильтры области действия.limit(number, необязательный): максимальное количество агрегированных строк стека (по умолчанию 1000, максимум 10000).lookback_minutes/start_time_iso/end_time_iso/region(необязательные).
Возвращает вложенное дерево flamegraph (name / value / self / children). truncated: true означает, что достигнут лимит строк API.
get_top_functions
Те же фильтры, что и у get_flamegraph. Возвращает рейтинг самых горячих функций по собственным образцам. Результат может быть усечен; проверьте truncated.
get_profile_summary
Те же фильтры, что и у get_flamegraph. Возвращает краткий разбор профиля сервиса на естественном языке.
grafana_search_dashboards
query(string, необязательный): подстрока заголовка. Пустое значение возвращает широкий список (с учетом ограничения в 5,000 строк).
Возвращает {"dashboards":[…], "truncated":bool} с uid, title, uri, url, type, tags. Используйте uid с grafana_get_dashboard.
grafana_get_dashboard
uid(string, обязательный): uid дашборда Grafana.full_json(boolean, необязательный): если значение true, возвращает необработанный JSON Grafana вместо отфильтрованной сводки.
Сводка по умолчанию: версия, теги, переменные шаблона и тип/источник данных/gridPos/цели promQL для каждой панели. Неизвестные типы панелей плагинов отображаются в unsupportedPanelTypes.
grafana_list_folders
Параметров нет. Возвращает дерево папок.
grafana_list_folder_dashboards
folder_uid(string, обязательный): uid папки Grafana.
Возвращает {"dashboards":[…], "truncated":bool} для дашбордов в этой папке (с постраничной разбивкой, до 5 000).
grafana_list_datasources
Без параметров. Возвращает безопасное представление источников данных (без полей с учетными данными).
Тестирование
Запустите анализатор горутин тестов, не выполняя тесты приложения:
make lint-test
Он запускает анализатор Go testinggoroutine для всех пакетов, включая их
файлы *_test.go, и проверяет его на небезопасных и безопасных фикстурах. Оба рабочих процесса тестирования CI запускают go vet -testinggoroutine ./... отдельным шагом, поэтому кэшированные результаты тестирования пакетов не могут обойти проверку линтером.
Корневой пакет также запускает анализатор как тест. Используйте go test -count=1 ./...
для полного набора тестов с отключенным кэшированием этой проверки: кэш тестов Go не отслеживает исходные файлы внутренних пакетов, которые читает подпроцесс анализатора. Обычный
go test ./... может повторно использовать успешный результат теста корневого пакета после изменения этих файлов.
Fatal, Fatalf и FailNow в testing.T или testing.B должны выполняться в родительской горутине теста. Рабочие горутины должны передавать ошибки обратно, чтобы родительская горутина могла их проверить:
errs := make(chan error, 1)
go func() { errs <- doWork() }()
if err := <-errs; err != nil {
t.Fatal(err)
}
Анализатор обнаруживает прямые вызовы в замыканиях go func; это не универсальная межпроцедурная проверка утверждений, скрытых за произвольными вызовами вспомогательных функций.
Интеграционные тесты пропускаются, если не задана переменная TEST_REFRESH_TOKEN.
