关于 yandex-metrika-mcp-server
yandex-metrika-mcp-server 将 MCP 客户端连接到 Yandex Metrika API,用于报表、计数器管理和日志操作。其 108 个 API 方法的工具由文档规格生成,并可通过配置选择公开范围;写入工具默认关闭。
主要功能
- 01覆盖 Stat、Management 和 Logs API
- 02根据 API 规格生成工具
- 03按配置档选择公开的工具
- 04默认关闭写入工具
- 05报告重试次数和结果截断情况
- 06在响应中隐藏令牌值
适用场景
- 01查询 Yandex Metrika 报表
- 02启用写入工具后管理计数器和目标
- 03获取并下载 Logs API 数据
MCP 相关
该服务将 Yandex Metrika API 方法公开为 MCP 工具,默认使用 stdio,也可选择无状态 Streamable HTTP。工具公开范围由配置档和环境变量决定。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y yandex-metrika-mcp-serverYANDEX_API_KEY密钥OAuth-токен Яндекса с доступом к Метрике. Без него сервер не стартует.METRIKA_PROFILEКакая часть каталога объявляется: core (10 инструментов, умолчание), read (51 читающий), all (все 108).METRIKA_ALLOW_WRITES1 разрешает и объявляет 57 инструментов, меняющих данные. Пока не задана — их нет в tools/list вовсе.METRIKA_TOOLSСвоя выборка инструментов через запятую: раздел (stat, logs, management), префикс имени или точное имя. Задана — побеждает METRIKA_PROFILE.METRIKA_TRAFFIC_FILTERУсловие сегментации, которое добавляется к отчётам Stat. По умолчанию ym:s:isRobot=='no'.METRIKA_MAX_OUTPUT_CHARSПотолок длины ответа одного вызова в символах. По умолчанию 120000.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
11收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| field | string | 否 | 返回对象的一个或多个附加参数。附加参数名称以逗号分隔,可按任意顺序指定,且不含空格。例如:`field=goals,mirrors,grants,filters,operation,counter_flags,measurement_tokens`。 |
| callback | string | 否 | 处理 API 响应的回调函数。 |
| counterId | integer | 是 | 您希望获取其信息的计数器 ID。 |
详细介绍
Yandex Metrika MCP 服务
用于访问 Yandex Metrika API 的 MCP 服务。覆盖全部 108 个方法;默认公开十个—— 也就是常用的统计方法。其余方法可通过一个变量启用。
mcp-name: io.github.artgas1/yandex-metrika-mcp-server
npx -y yandex-metrika-mcp-server
Fork 自 atomkraft/yandex-metrika-mcp(上游项目由 Vadim Bezymianyi 维护,采用 MIT 许可证)。 从 2.0.0 版本开始,工具不再手动编写,而是根据从官方文档整理出的规范生成。
覆盖范围
| API | 方法数 | 其中 core 配置文件中的方法数 | 工具示例 |
|---|---|---|---|
| Management | 95(21 个资源) | 4 | metrika_counter_list、metrika_goal_create、metrika_segment_update |
| Logs | 7 | — | metrika_logs_create、metrika_logs_get、metrika_logs_download |
| Stat | 6 | 6 | metrika_stat_data、metrika_stat_bytime、metrika_stat_pivot |
工具名称的格式为 metrika_<资源>_<操作>,其中资源名称直接取自 API URL,不做改名。
因此,metrika_goal_list 可明确对应到 GET /management/v1/counter/{id}/goals
以及它对应的文档页面。
契约
由于观察到两种故障,服务器经过重写:返回内容与请求不符,并且悄悄添加了筛选条件。因此制定了四条规则,每条规则都有对应测试。
- 绝不悄悄替换请求内容。 请求什么,就向 API 发送什么。服务器不会自行补充 维度、时间段或筛选条件。
- 服务器自行添加的所有内容都会在响应中明确显示。 响应格式为
{"_meta": {...}, "data": {...}},其中_meta.applied_by_server列出服务器添加的内容,_meta.notes列出代替调用方做出的决定。 - 错误仍然是错误。 API 错误会连同 Metrika 响应正文一起返回,并设置
isError: true。 重试依据状态码(429/500/502/503/504 和网络故障),而非错误文本中的子字符串; 对 429 会遵循Retry-After,最长等待 30 秒。重试次数始终会显示在_meta.retries中。 - 返回结果被截断时会明确显示。
_meta中会提供rows_returned、rows_total和truncated—— Metrika 默认会截断响应,不能对此保持沉默。如果服务器自行按长度上限截断响应, 还会在_meta.truncated_by_server中单独说明,并列出被丢弃的行数。 - 响应中不会包含机密信息。
metrika_measurement_delete有一个token参数; 显示的_meta.request_url中,该参数的值会替换为REDACTED。OAuth 令牌只通过请求头发送, 永远不会出现在响应中。
Фильтр роботов
В отчётах Stat API по умолчанию применяется собственный флаг робота Метрики, и только он:
ym:s:isRobot=='no'
Он объявлен: виден в схеме инструмента, отключается параметром human_traffic_only: false
и всегда перечислен в _meta.applied_by_server. Если в запросе есть метрики ym:ad: или
ym:ev:, фильтр не применяется (Метрика отвечает на такое сочетание 400) — и это попадает
в _meta.notes, а не остаётся молчаливым исключением.
Своё условие задаётся переменной METRIKA_TRAFFIC_FILTER — целиком, включая isRobot,
если он нужен:
METRIKA_TRAFFIC_FILTER="ym:s:isRobot=='no' AND ym:s:browserName!='HeadlessChrome'"
Это образец формы, а не рекомендация. Какой рез верен — зависит от того, какие боты ходят именно к вам: отсечка по стране, по заголовку браузера или по подсети осмысленна только на своих данных. Копировать чужой список бессмысленно и опасно: он вырежет живой трафик.
Заданное своё условие сервер называет в stderr при старте — оно меняет числа в каждом отчёте, и молчать об этом нельзя.
Сравнение периодов: ответ, который выглядит валидным
У metrika_stat_comparison и metrika_stat_comparison_drilldown даты периодов
необязательны, и Метрика на их отсутствие не ругается. Она подставляет собственное окно
(последняя неделя) в оба набора и возвращает сравнение периода с самим собой:
metrika_stat_comparison(ids, metrics) → totals a == b
query date1_a == date1_b
Отказывать сервер не будет — запрос ушёл ровно тем, каким его собрали. Но такой ответ
приходит с пометкой в _meta.notes: и когда даты не заданы, и когда периоды совпали явно.
Как устроена спека
Публичного openapi.json у Метрики нет, но каждая страница метода сгенерирована из OpenAPI
движком Diplodoc и отдаётся как text/markdown. Семантика (тип, required, комбинатор,
ассертация) лежит в CSS-классах вида {.json-schema-property}, поэтому спека собирается
построчным сканером по классам, а не markdown-парсером.
npm run spec:fetch # скачать llms.txt и 108 страниц в .cache/docs/
npm run spec:build # разобрать их в spec/metrika-api.json
npm test # тесты спеки и схем инструментов
npm run smoke # живые вызовы к API (нужен YANDEX_API_KEY)
spec/metrika-api.json коммитится — это состав API на момент сборки. Тест на дрейф сверяет
его с llms.txt: Яндекс добавил или удалил метод — тест краснеет.
Разбор привязан к версии генератора (Diplodoc Platform v5.57.3): вся семантика висит на его
классах, поэтому расхождение версии останавливает сборку спеки, а не молча портит её.
Запуск
По умолчанию объявляются десять инструментов из 108 — те, которыми считают. Управление счётчиками и целями, доступы и Logs API включаются переменной
METRIKA_PROFILE; подробности ниже, в разделе «Почему по умолчанию не всё».Спросить у самого сервера тоже можно: инструмент
metrika_catalog_listперечисляет, что объявлено, что скрыто и как это включить.
npm install
npm run build
YANDEX_API_KEY=<OAuth-токен с scope direct:api / metrika> npm start
Токен — OAuth Яндекса, тот же, что используется для Директа и Вебмастера.
По умолчанию сервер сохраняет stdio-режим. Для одного локального процесса, к которому подключаются несколько MCP-клиентов, включите stateless Streamable HTTP:
YANDEX_API_KEY=<OAuth-токен> \
MCP_TRANSPORT=http MCP_HOST=127.0.0.1 MCP_PORT=13404 \
npm start
Endpoint — http://127.0.0.1:13404/mcp. При loopback-привязке сервер также
проверяет Host, чтобы локальный endpoint нельзя было вызвать через DNS rebinding.
Подключение к клиенту
{
"mcpServers": {
"yandex-metrika-mcp": {
"command": "npx",
"args": ["-y", "yandex-metrika-mcp-server@3"],
"env": { "YANDEX_API_KEY": "..." }
}
}
}
Из локальной сборки — то же самое, но "command": "node" и путь до build/index.js.
Мажор в строке запуска закреплён намеренно: смена мажорной версии меняет набор инструментов по умолчанию, и получать это молча при старте агента не нужно.
Переменные окружения
| Переменная | По умолчанию | Что делает |
|---|---|---|
YANDEX_API_KEY | — | OAuth-токен. Без него сервер не стартует. |
MCP_TRANSPORT | stdio | Транспорт: stdio или stateless Streamable http. |
MCP_HOST | 127.0.0.1 | Адрес HTTP listener. Используется только при MCP_TRANSPORT=http. |
MCP_PORT | 3000 | Порт HTTP listener, целое число от 1 до 65535. |
METRIKA_PROFILE | core | Какая часть каталога объявляется: core (10 инструментов), read (все 51 читающих), all (все 108). Неизвестное значение роняет старт. |
METRIKA_ALLOW_WRITES | не задана | 1 разрешает и объявляет 57 инструментов, меняющих данные. Пока не задана — их нет в tools/list вовсе. |
METRIKA_TOOLS | пусто | Своя выборка через запятую: раздел (stat, logs, management), префикс имени (metrika_goal) или точное имя. Задана — побеждает профиль. |
METRIKA_TRAFFIC_FILTER | ym:s:isRobot=='no' | Условие сегментации, добавляемое к отчётам Stat. Задаётся целиком. |
METRIKA_MAX_OUTPUT_CHARS | 120000 | Потолок длины ответа одного вызова. Выгрузка Logs API в него обычно не помещается — сутки визитов это сотни тысяч символов; урезание объявляется в _meta.truncated_by_server. |
METRIKA_API_BASE | пусто | Подмена адреса API (прокси, заглушка в тестах). Факт подмены печатается в stderr. |
Как узнать, что скрыто, не открывая README
Инструмент metrika_catalog_list объявлен в любом профиле и отвечает из спеки, лежащей в
пакете, — ни токена, ни сети ему не нужно:
{
"profile": "METRIKA_PROFILE=core",
"api_methods_total": 108,
"api_methods_declared": 10,
"api_methods_hidden": 98,
"writes_enabled": false,
"declared_tools": { "Stat API — отчёты": ["metrika_stat_data", "…"] },
"hidden_tools": { "Management API — …": ["metrika_goal_create", "…"] },
"how_to_widen": ["METRIKA_PROFILE=read — …", "METRIKA_PROFILE=all вместе с METRIKA_ALLOW_WRITES=1 — …"]
}
Он существует по простой причине: сервер, который что-то скрыл, обязан уметь сказать, что
именно и как это включить. instructions видит модель, но не человек — в интерфейс клиента
они не показываются; стартовую строку в stderr в обычной работе тоже никто не открывает. Без
этого инструмента узнать про остальные 98 можно было только придя сюда.
Список инструментов в ответе строится из того же отбора, по которому они регистрируются, — разойтись с реальностью ему негде, и это проверено тестом.
Почему по умолчанию не всё
Описания объявленных инструментов лежат в контексте модели, когда клиент их загрузил. Это
цена сервера, которую платят за сам факт подключения, а не за вызовы. Замер tools/list
(09.09.2026):
| Профиль | Инструментов | tools/list | токенов |
|---|---|---|---|
core (по умолчанию) | 10 + каталог | 32 181 Б | 14,8 тыс. |
read | 51 + каталог | 68 074 Б | ~31 тыс. — оценка |
all + METRIKA_ALLOW_WRITES=1 | 108 + каталог | 158 301 Б | ~73 тыс. — оценка |
Замер core — 14,5 тысячи до появления каталога и 14,8 после: сам инструмент стоит около
670 байт схемы, примерно 2% набора. Его ответ не входит в эту цену — он платится только при
вызове.
Байты точные, их воспроизведёт любой: сериализуй ответ tools/list и посчитай длину.
С токенами сложнее, и здесь стоит сказать прямо.
⚠️ Замер честный только у core — его дал /context клиента, который считает
собственным токенизатором. Две другие строки пересчитаны из байтов по калибровке
2,17 байта на токен, снятой с той же строки core.
Ходовая эвристика «4 символа на токен» здесь врёт почти вдвое: она выведена на
английском тексте, а описания у этого сервера русские, и кириллица в BPE токенизируется
примерно вдвое хуже латиницы. Первая редакция этой таблицы была построена именно на ней и
называла для core 7,9k вместо 14,5k. Если считаешь бюджет контекста для сервера с
не-английскими описаниями — считай токенизатором, а не делением на четыре.
Состав core выведен из замера реального использования, а не из вкуса: шесть отчётов Stat
плюс справочники, без которых отчёт не собрать (metrika_counter_list, metrika_counter_get,
metrika_goal_list, metrika_segment_list). Порог веса стоит тестом — манифест не может
подорожать молча. Порог в тесте стоит на байтах: они не зависят ни от токенизатора, ни
от языка описаний.
Безопасность
- Запись выключена по умолчанию, и меняющие инструменты не объявляются вовсе. Среди
методов четырнадцать
DELETEи пять удаляющихPOST(.../measurement/delete,.../expense/delete,.../logrequest/{id}/cleanи т. д.). Цена ошибочного вызова — удалённый счётчик или цель без возможности восстановить историю. Модель не может позвать то, чего не видит вtools/list; как включить — сказано вinstructionsсервера. - Аннотации проставлены на всех инструментах (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint). Клиент по ним отличает чтение от удаления: удаление под глаголомPOSTпомечено разрушающим,PUT— тоже, потому что заменяет сущность целиком. - Ответы Метрики — недоверенные данные. В отчётах лежат поисковые фразы, заголовки
страниц, реферера и значения UTM, то есть строки, которые пишут посетители сайта. Любой
может зайти на сайт по ссылке с текстом внутри и увидеть его в отчёте. У всех инструментов
openWorldHint: true, а в_meta.notesотчётов и выгрузок едет напоминание, что это данные, а не инструкции. - stdio остаётся транспортом по умолчанию. HTTP включается только явно через
MCP_TRANSPORT=http; безопасный дефолт слушает127.0.0.1и проверяетHost.
隐私政策
服务不会收集、存储或向任何地方传输您的数据。没有遥测、没有分析,也不会访问作者的服务器——因为根本不存在这些服务:没有为此软件包搭建任何基础设施。
唯一的网络地址是 https://api-metrika.yandex.net。令牌从 YANDEX_API_KEY 读取到进程内存中,不会写入任何地方:既不会写入文件,也不会写入 stdout 或响应正文。报告数据不会缓存到磁盘,也不会在进程结束后保留。
您请求的数据由 Yandex 作为 Metrika 的运营方处理——适用的是其政策,而不是本政策。
完整文本:PRIVACY.md。
单文件安装(MCPB)
Claude Desktop 和其他支持 MCP 捆绑包的客户端可以使用 .mcpb 文件——文件位于发布版本中。打开文件,在安装窗口中输入令牌即可。
捆绑包由同一份代码通过同一标签构建(npm run mcpb),其清单由 package.json 和配置文件生成,而不是手动编写,因此不会与服务不一致;测试会对此进行检查。
⚠️ 捆绑包中无法启用写入功能。 错误调用的代价可能是删除计数器或目标,且无法恢复历史记录,因此安装窗口里没有可切换的选项。需要写入功能?请通过 npm 安装软件包,并有意识地使用环境变量启用。
无需 MCP:技能与命令行
MCP 并非适合所有人,也并非适用于所有情况:客户端可能完全不支持 MCP,而工具描述会一直占用上下文——只要服务保持连接,无论您是否调用它们,这些描述都会留在上下文中。
在这种情况下,同一服务也可以通过命令运行:
npx -y yandex-metrika-mcp-server catalog --search goal
npx -y yandex-metrika-mcp-server describe metrika_stat_data
npx -y yandex-metrika-mcp-server call metrika_stat_data \
--ids <ID счётчика> --dimensions ym:s:trafficSource \
--metrics ym:s:visits,ym:s:users --date1 7daysAgo --date2 today
此外还提供技能——一个包含 Agent 指令的文件夹,只需一行命令即可安装:
npx skills add artgas1/yandex-metrika-mcp # в текущий проект
npx skills add artgas1/yandex-metrika-mcp -g # глобально, во все проекты
技能不会向客户端添加工具,也不会占用上下文:只有在提到 Metrika 时才会读取。技能中包含同一条命令、全部 108 种方法的参考手册,以及维度词典。
支持情况。 安装程序会将一个实例放入 .agents/skills/yandex-metrika/,并在各 Agent 的专用文件夹中创建符号链接。已通过启动测试验证两个 Agent:
| Agent | 发现方式 | 验证方式 |
|---|---|---|
| Claude Code | .claude/skills/ → 符号链接 | /yandex-metrika 根据技能内容作答 |
| Codex | 直接使用 .agents/skills/ | 会指出 SKILL.md 的路径;无需在 AGENTS.md 中添加任何内容,也无需在 config.toml 中进行设置 |
安装程序还会通过同一通用目录声明支持另外约二十种 Agent(Amp、Cline、Antigravity、Augment 等)——我们尚未在这些 Agent 上进行验证。
为什么这不是第二套实现。 CLI 不会发出任何独立请求:它解析参数并调用 executeMethod——也就是 MCP 工具所调用的同一函数。因此,两者的保障完全一致:报告中的机器人过滤、带有截断说明的响应上限、清除展示 URL 中的机密信息,以及按状态码重试。它们不可能出现差异,因为根本没有不同的实现。
技能内的方法参考手册由 spec/metrika-api.json 生成——这正是每日根据 Yandex 文档更新的规范文件。测试会将已提交的文件与当前生成的版本进行比对,因此“技能落后于 API”会明确报错,而不会悄然发生。
命令与 MCP 有两处有意设置的差异:
| MCP | 命令 | |
|---|---|---|
METRIKA_PROFILE | 生效,默认为 core | 不生效——可使用全部 108 种方法 |
METRIKA_ALLOW_WRITES | 执行数据变更操作时需要 | 同样需要 |
设置配置文件是为了避免未调用工具的描述占用上下文;在终端中运行命令则没有这项代价。写入限制则另有原因:远程目标一旦删除便无法恢复,在这里放宽限制就会成为绕过服务的漏洞。
检查
Не макет — запустите сами
npm run demo
Всё на записи приходит из ответа сервера по JSON-RPC: строка добавленного фильтра — из _meta.applied_by_server, строки отчёта — из тела ответа. Ни токена, ни сети: запросы уводятся на локальную заглушку, поэтому прогон повторяется где угодно, включая CI. Переснять запись — npm run demo:record.
npm test # 87 тестов: спека, схемы, протокол MCP, поверхность, бандл, демо
npm run protocol # только протокольные: stdio, tools/list, tools/call, отказы
npm run smoke # живые вызовы к API (нужен YANDEX_API_KEY)
Протокольные тесты поднимают сервер как подпроцесс и говорят с ним по JSON-RPC — тем же
способом, каким это делает клиент. Сеть при этом не нужна: METRIKA_API_BASE уводит запросы
на заглушку. Проверяется в том числе то, чего не видно изнутри: что в stdout не попадает
ничего, кроме JSON-RPC, что отказ API приезжает как isError, а не как успешный текст, и что
запись действительно заблокирована.
Чего в проверках НЕТ
Евала выбора инструмента. Это единственная проверка, которую не заменяют ни снапшот схемы, ни протокольный тест: описания могут быть синтаксически безупречны, а модель всё равно возьмёт не тот инструмент. Тесты этого не видят по построению — они зовут инструмент по имени, то есть выбор уже сделан за модель.
Здесь это осознанный пропуск, а не забытый пункт. Профиль по умолчанию — десять инструментов, из них шесть отчётов Stat различаются формой ответа, а не темой, и путать их модели особо не с чем. Евал становится нужен, когда поверхность по умолчанию расширяется или когда в неё попадают инструменты с пересекающимися описаниями, — тогда его надо писать до расширения, а не после.
Что изменилось в 2.0.0
Удалены 26 инструментов-обёрток над пресетами Stat API (get_visits, sources_summary,
get_page_performance и прочие). Они покрывали малую часть API, зашивали измерения и период
в код и не давали задать произвольный запрос. Их заменяют metrika_stat_*, принимающие
параметры Stat API как есть.
Появились методы, которых не было вовсе: список счётчиков, цели, сегменты, фильтры, разрешения, расходы, офлайн-конверсии и весь Logs API. Раньше идентификатор счётчика приходилось знать заранее — теперь его можно найти.
Что изменилось в 2.1.0
Сервер довели до состояния, в котором его не страшно оставить агенту.
- Аннотации на всех 108 инструментах. До этого клиент не отличал
metrika_counter_listотmetrika_counter_delete. - Запись выключена по умолчанию (
METRIKA_ALLOW_WRITES). - Найден и починен дефект разбора документации. Ассертации размечены строкой, где значение стоит после закрывающей скобки класса, — распознаватель свойств заякорен на конец строки и такие строки не матчил вовсе. В итоге до спеки не доезжало ни одного примера, значения по умолчанию или границы, а часть их падала в описание соседнего поля. Сейчас в спеке 288 примеров, 69 значений по умолчанию и 155 ограничений; ограничения переносятся в схему инструмента, примеры и значения по умолчанию — в описания параметров.
- Найдена и починена потеря обязательности. Параметры вида «один из N типов» (
goalу создания и правки цели,grantу выдачи доступа) собирались какz.unknown(), а он в zod необязателен, — обязательное поле уезжало клиенту как опциональное. Теперь это объединение реальных форм, и обязательность на месте. - Ссылки на сущности разворачиваются на один уровень: у 23 параметров тела вместо свободного объекта видны настоящие поля.
- Послабления на входе там, где они безвредны. Число строкой, булево словом, список через запятую в строке запроса — принимаются; в теле запроса, где важен точный JSON, не принимаются.
- Потолок длины ответа с объявленным урезанием: выгрузка Logs API бывает в сотни мегабайт.
- Вычистка секретов из показанного
request_url. - Повтор на 429 с соблюдением
Retry-After. - SDK обновлён до 1.30 — на 1.17 висели три опубликованных уязвимости, две высокие;
npm audit --audit-level=highтеперь часть CI. - Починена джоба дрейфа в CI. Она запускала тесты через
| teeбезpipefail, поэтому код возврата брался уteeи джоба оставалась зелёной при любом падении теста.
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。