Yandex Metrika
Cobertura completa da API do Yandex Metrika (Stat, Management, Logs) com definições de ferramentas geradas a partir da documentação oficial do Yandex. Dez ferramentas expostas por padrão para não sobrecarregar o contexto; nunca reescreve silenciosamente sua consulta.
Documentação
Servidor MCP Yandex Metrika
Servidor MCP para a API do Yandex Metrika. Todos os 108 métodos são cobertos; por padrão, são declarados dez — aqueles usados para análise. O restante é ativado por uma única variável.
mcp-name: io.github.artgas1/yandex-metrika-mcp-server
npx -y yandex-metrika-mcp-server
Fork de atomkraft/yandex-metrika-mcp (upstream — Vadim Bezymianyi, MIT). Desde a versão 2.0.0, as ferramentas não são escritas manualmente, mas geradas a partir da especificação, montada com base na documentação oficial.
Cobertura
| API | métodos | dos quais no perfil core | exemplos de ferramentas |
|---|---|---|---|
| Management | 95 (21 recursos) | 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 |
O nome da ferramenta é metrika_<ресурс>_<действие>, onde o recurso é retirado da URL da própria API sem renomeações.
Portanto, metrika_goal_list é mapeado de forma inequívoca para GET /management/v1/counter/{id}/goals
e para sua própria página de documentação.
Contrato
O servidor foi reescrito devido a duas falhas observadas: ele retornava algo diferente do solicitado e silenciosamente injetava um filtro. Daí quatro regras, cada uma coberta por teste.
- Sem substituição silenciosa. O que foi solicitado é exatamente o que vai para a API. O servidor não inventa dimensões, períodos ou filtros adicionais.
- Tudo o que o servidor adicionou por conta própria é visível na resposta. A resposta chega como
{"_meta": {...}, "data": {...}}, onde_meta.applied_by_serverlista o que foi adicionado, e_meta.notes— as decisões tomadas em nome do chamador. - Uma recusa continua sendo uma recusa. Um erro da API é retornado com
isError: truee o corpo da resposta do Metrika. A repetição é feita com base no status (429/500/502/503/504 e falhas de rede), não por substring no texto; para 429, oRetry-Afteré respeitado com um teto de 30 segundos. O número de tentativas é sempre visível em_meta.retries. - O corte da saída é visível. Em
_metavãorows_returned,rows_totaletruncated— o Metrika corta a resposta por padrão, e não se pode silenciar isso. Se o próprio servidor truncou a resposta devido ao limite de comprimento, isso é declarado separadamente em_meta.truncated_by_servercom o número de linhas descartadas. - Segredos não vão para a resposta.
metrika_measurement_deletetem o parâmetrotoken; no_meta.request_urlexibido, seu valor é substituído porREDACTED. O próprio token OAuth vai apenas no cabeçalho e nunca aparece na resposta.
Filtro de robôs
Nos relatórios da Stat API, por padrão, é aplicada a própria flag de robô do Metrika, e somente ela:
ym:s:isRobot=='no'
Ele é declarado: visível no esquema da ferramenta, desativado pelo parâmetro human_traffic_only: false
e sempre listado em _meta.applied_by_server. Se a solicitação contém métricas ym:ad: ou
ym:ev:, o filtro não é aplicado (o Metrika responde a essa combinação com 400) — e isso vai para
_meta.notes, em vez de permanecer uma exceção silenciosa.
Sua própria condição é definida pela variável METRIKA_TRAFFIC_FILTER — completamente, incluindo isRobot,
se necessário:
METRIKA_TRAFFIC_FILTER="ym:s:isRobot=='no' AND ym:s:browserName!='HeadlessChrome'"
Isso é um exemplo de formato, não uma recomendação. Qual corte é correto depende de quais bots visitam exatamente o seu site: o corte por país, por cabeçalho do navegador ou por sub-rede só faz sentido com seus próprios dados. Copiar a lista de outra pessoa é inútil e perigoso: ela cortará tráfego real.
A condição personalizada definida é anunciada pelo servidor no stderr na inicialização — ela altera os números em cada relatório, e não se pode silenciar isso.
Comparação de períodos: uma resposta que parece válida
Em metrika_stat_comparison e metrika_stat_comparison_drilldown, as datas dos períodos
são opcionais, e o Metrika não reclama da ausência delas. Ele insere sua própria janela
(última semana) em ambos os conjuntos e retorna a comparação do período consigo mesmo:
metrika_stat_comparison(ids, metrics) → totals a == b
query date1_a == date1_b
O servidor não recusará — a solicitação foi enviada exatamente como foi montada. Mas essa resposta
vem com uma marcação em _meta.notes: tanto quando as datas não são definidas quanto quando os períodos coincidem explicitamente.
Como a especificação é estruturada
O Metrika não tem um openapi.json público, mas cada página de método é gerada a partir do OpenAPI
pelo mecanismo Diplodoc e é entregue como text/markdown. A semântica (tipo, required, combinador,
asserção) está em classes CSS do tipo {.json-schema-property}, portanto a especificação é montada
por um scanner linha a linha baseado nas classes, não por um parser de 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 é commitado — é a composição da API no momento da compilação. Um teste de derivação compara
com llms.txt: se o Yandex adicionou ou removeu um método, o teste fica vermelho.
A análise está vinculada à versão do gerador (Diplodoc Platform v5.57.3): toda a semântica depende de suas
classes, portanto uma divergência de versão interrompe a compilação da especificação, em vez de corrompê-la silenciosamente.
Execução
Por padrão, dez ferramentas de 108 são declaradas — aquelas usadas para análise. O gerenciamento de contadores e metas, acessos e a Logs API são ativados pela variável
METRIKA_PROFILE; detalhes abaixo, na seção «Por que nem tudo por padrão».Também é possível perguntar ao próprio servidor: a ferramenta
metrika_catalog_listlista o que está declarado, o que está oculto e como ativar.
npm install
npm run build
YANDEX_API_KEY=<OAuth-токен с scope direct:api / metrika> npm start
O token é o OAuth do Yandex, o mesmo usado para Direct e Webmaster.
Por padrão, o servidor mantém o modo stdio. Para um único processo local, ao qual vários clientes MCP se conectam, ative o 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. Com bind em loopback, o servidor também
verifica Host, para que o endpoint local não possa ser chamado via DNS rebinding.
Conexão ao cliente
{
"mcpServers": {
"yandex-metrika-mcp": {
"command": "npx",
"args": ["-y", "yandex-metrika-mcp-server@3"],
"env": { "YANDEX_API_KEY": "..." }
}
}
}
A partir de uma compilação local — o mesmo, mas com "command": "node" e o caminho até build/index.js.
A versão principal na linha de execução é fixada intencionalmente: uma mudança de versão principal altera o conjunto de ferramentas padrão, e não se deve receber isso silenciosamente na inicialização do agente.
Variáveis de ambiente
| Variável | Padrão | O que faz |
|---|---|---|
YANDEX_API_KEY | — | Token OAuth. Sem ele, o servidor não inicia. |
MCP_TRANSPORT | stdio | Transporte: stdio ou stateless Streamable http. |
MCP_HOST | 127.0.0.1 | Endereço do listener HTTP. Usado apenas com MCP_TRANSPORT=http. |
MCP_PORT | 3000 | Porta do listener HTTP, inteiro de 1 a 65535. |
METRIKA_PROFILE | core | Qual parte do catálogo é declarada: core (10 ferramentas), read (todas as 51 de leitura), all (todas as 108). Um valor desconhecido derruba a inicialização. |
METRIKA_ALLOW_WRITES | não definida | 1 permite e declara 57 ferramentas que alteram dados. Enquanto não definida — elas não existem em tools/list de forma alguma. |
METRIKA_TOOLS | vazio | Seleção própria separada por vírgulas: seção (stat, logs, management), prefixo do nome (metrika_goal) ou nome exato. Se definida — vence o perfil. |
METRIKA_TRAFFIC_FILTER | ym:s:isRobot=='no' | Condição de segmentação adicionada aos relatórios Stat. Definida por completo. |
METRIKA_MAX_OUTPUT_CHARS | 120000 | Teto de comprimento da resposta de uma única chamada. A exportação da Logs API geralmente não cabe nele — um dia de visitas são centenas de milhares de caracteres; o corte é declarado em _meta.truncated_by_server. |
METRIKA_API_BASE | vazio | Substituição do endereço da API (proxy, stub em testes). O fato da substituição é impresso no stderr. |
Como descobrir o que está oculto sem abrir o README
A ferramenta metrika_catalog_list é declarada em qualquer perfil e responde a partir da especificação contida no
pacote — não precisa de token nem de rede:
{
"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 — …"]
}
Ela existe por um motivo simples: um servidor que ocultou algo deve ser capaz de dizer
o quê exatamente e como ativar. instructions vê o modelo, mas não o humano — elas não aparecem na interface do cliente;
a linha de inicialização no stderr também não é aberta por ninguém no trabalho normal. Sem
essa ferramenta, só seria possível descobrir sobre as outras 98 vindo até aqui.
A lista de ferramentas na resposta é construída a partir da mesma seleção usada para registrá-las — não há como divergir da realidade, e isso é verificado por teste.
Por que nem tudo por padrão
As descrições das ferramentas declaradas ficam no contexto do modelo quando o cliente as carrega. Esse é o
custo do servidor, pago pelo próprio fato da conexão, não pelas chamadas. Medição tools/list
(09.09.2026):
| Perfil | Ferramentas | tools/list | tokens |
|---|---|---|---|
core (padrão) | 10 + catálogo | 32 181 B | 14,8 mil |
read | 51 + catálogo | 68 074 B | ~31 mil — estimativa |
all + METRIKA_ALLOW_WRITES=1 | 108 + catálogo | 158 301 B | ~73 mil — estimativa |
Medição core — 14,5 mil antes do catálogo e 14,8 depois: a própria ferramenta custa cerca de
670 bytes de esquema, aproximadamente 2% do conjunto. Sua resposta não entra nesse custo — ela é paga apenas na
chamada.
Os bytes são exatos, qualquer um pode reproduzi-los: serialize a resposta de tools/list e calcule o comprimento.
Com tokens é mais complicado, e aqui vale ser direto.
⚠️ A medição é honesta apenas para core — foi fornecida pelo /context do cliente, que calcula
com seu próprio tokenizador. As outras duas linhas foram recalculadas de bytes pela calibração
2,17 bytes por token, obtida da mesma linha de core.
A heurística comum «4 caracteres por token» aqui erra quase pela metade: ela foi derivada de
texto em inglês, e as descrições deste servidor são em russo, e o cirílico na tokenização BPE
é aproximadamente duas vezes pior que o latim. A primeira edição desta tabela foi construída exatamente com ela e
chamava para core 7,9k em vez de 14,5k. Se você calcula o orçamento de contexto para um servidor com
descrições não-inglesas — use um tokenizador, não divisão por quatro.
A composição de core foi derivada da medição de uso real, não de gosto: seis relatórios Stat
mais diretórios, sem os quais o relatório não pode ser montado (metrika_counter_list, metrika_counter_get,
metrika_goal_list, metrika_segment_list). O limite de peso é protegido por teste — o manifesto não pode
ficar mais caro silenciosamente. O limite no teste é em bytes: eles não dependem nem do tokenizador, nem
do idioma das descrições.
Segurança
- Escrita desativada por padrão, e ferramentas que alteram dados não são declaradas de forma alguma. Entre os
métodos, há quatorze
DELETEe cinco de exclusãoPOST(.../measurement/delete,.../expense/delete,.../logrequest/{id}/cleanetc.). O custo de uma chamada errônea — um contador ou meta removido sem possibilidade de restaurar o histórico. O modelo não pode chamar o que não vê emtools/list; como ativar — está dito eminstructionsdo servidor. - Anotações estão presentes em todas as ferramentas (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint). O cliente distingue leitura de exclusão por elas: exclusão sob o verboPOSTé marcada como destrutiva,PUT— também, porque substitui a entidade por completo. - As respostas do Metrika são dados não confiáveis. Nos relatórios estão frases de busca, títulos
de páginas, referers e valores de UTM, ou seja, strings escritas pelos visitantes do site. Qualquer
pessoa pode acessar o site por um link com texto dentro e vê-lo no relatório. Todas as ferramentas têm
openWorldHint: true, e em_meta.notesde relatórios e exportações há um lembrete de que são dados, não instruções. - stdio continua sendo o transporte padrão. HTTP é ativado apenas explicitamente via
MCP_TRANSPORT=http; o padrão seguro escuta em127.0.0.1e verificaHost.
Política de privacidade
O servidor não coleta, não armazena e não transmite dados sobre você para lugar nenhum. Sem telemetria, sem análise, sem chamadas aos servidores do autor — elas não existem: nenhuma infraestrutura foi montada para este pacote.
O único destinatário de rede é https://api-metrika.yandex.net. O token é lido de
YANDEX_API_KEY para a memória do processo e não é escrito em lugar nenhum: nem em arquivo, nem em stdout, nem no corpo
da resposta. Os dados dos relatórios não são armazenados em cache no disco e não sobrevivem ao processo.
Os dados que você solicita são processados pelo Yandex como operador do Metrika — a isso se aplica a política dele, não esta.
Texto completo: PRIVACY.md.
Instalação em um único arquivo (MCPB)
Para Claude Desktop e outros clientes que entendem bundles MCP, existe um arquivo .mcpb — ele está nos
releases. Você abre o arquivo, insere o
token na janela de instalação — pronto.
O bundle é compilado a partir do mesmo código com a mesma tag (npm run mcpb), e seu manifesto é gerado
a partir de package.json e do perfil — não é escrito manualmente, portanto não há como divergir do servidor; isso
é verificado por teste.
⚠️ No bundle, não é possível habilitar a gravação. O custo de uma chamada equivocada é um contador ou objetivo removido sem possibilidade de recuperar o histórico, e não há o que alternar nesse interruptor na janela de instalação. Precisa de gravação? Instale o pacote via npm e habilite-a conscientemente, por variável de ambiente.
Sem MCP: skill e linha de comando
MCP não serve para todos nem sempre: o cliente pode não suportar MCP, e as descrições das ferramentas ocupam contexto constantemente — elas ficam nele enquanto o servidor está conectado, você as chame ou não.
Para esse caso, o mesmo servidor pode ser iniciado por comando:
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
Sobre isso, existe um skill — uma pasta com instruções para o agente, instalada com uma única linha:
npx skills add artgas1/yandex-metrika-mcp # в текущий проект
npx skills add artgas1/yandex-metrika-mcp -g # глобально, во все проекты
O skill não adiciona ferramentas ao cliente nem mantém nada no contexto: ele só é lido quando o assunto é Metrika. Dentro dele estão o mesmo comando, o guia de referência de todos os 108 métodos e o dicionário de dimensões.
Onde ele funciona. O instalador coloca uma instância em .agents/skills/yandex-metrika/
e cria symlinks para as pastas de agentes específicos. Verificado executando em dois:
| agente | detecção | como foi verificado |
|---|---|---|
| Claude Code | .claude/skills/ → symlink | /yandex-metrika responde com base no conteúdo do skill |
| Codex | .agents/skills/ diretamente | informa o caminho para SKILL.md; nenhuma linha em AGENTS.md, nem configuração em config.toml é necessária para isso |
O instalador declara suporte a cerca de vinte outros agentes pelo mesmo catálogo universal (Amp, Cline, Antigravity, Augment e outros) — nesses, não verificamos.
Por que isso não é uma segunda implementação. A CLI não faz nenhuma requisição própria: ela analisa
argumentos e chama executeMethod — a mesma função usada pelas ferramentas MCP. Daí as mesmas
garantias: filtro de robôs nos relatórios, teto de resposta com aviso de truncamento, limpeza de segredos
da URL exibida, repetição por status. Não há como divergirem, porque não há o que divergir.
O guia de referência de métodos dentro do skill é gerado a partir de spec/metrika-api.json — a mesma spec
que é atualizada diariamente pela documentação do Yandex. Um teste compara o arquivo commitado com o que
seria gerado agora, então "skill desatualizado em relação à API" aqui é algo visível, não imperceptível.
Duas diferenças conscientes do comando em relação ao MCP:
| MCP | comando | |
|---|---|---|
METRIKA_PROFILE | ativo, por padrão core | inativo — todos os 108 métodos disponíveis |
METRIKA_ALLOW_WRITES | necessário para operações que alteram dados | igualmente necessário |
O perfil existe para não pagar com contexto pelas descrições de ferramentas não chamadas; o comando no terminal não tem esse custo. O bloqueio de gravação é outra coisa: um objetivo remoto não tem como ser restaurado, e uma flexibilização aqui seria uma brecha contornando o servidor.
Verificações
Não é maquete — execute você mesmo
npm run demo
Tudo na gravação vem da resposta do servidor via JSON-RPC: a linha do filtro adicionado vem de _meta.applied_by_server, as linhas do relatório vêm do corpo da resposta. Sem token, sem rede: as requisições são direcionadas a um stub local, então a execução pode ser repetida em qualquer lugar, inclusive no CI. Para regravar — npm run demo:record.
npm test # 87 тестов: спека, схемы, протокол MCP, поверхность, бандл, демо
npm run protocol # только протокольные: stdio, tools/list, tools/call, отказы
npm run smoke # живые вызовы к API (нужен YANDEX_API_KEY)
Os testes de protocolo iniciam o servidor como subprocesso e falam com ele via JSON-RPC — da mesma
forma que um cliente faz. Rede não é necessária: METRIKA_API_BASE direciona as requisições
para um stub. Verifica-se inclusive o que não é visível internamente: que nada além de JSON-RPC
aparece no stdout, que uma falha da API chega como isError, e não como texto de sucesso, e que a
gravação está realmente bloqueada.
O que NÃO está nas verificações
Eval de seleção de ferramenta. Esta é a única verificação que nem o snapshot do schema nem o teste de protocolo substituem: as descrições podem estar sintaticamente impecáveis, mas o modelo ainda assim pode escolher a ferramenta errada. Os testes não enxergam isso por construção — eles chamam a ferramenta pelo nome, ou seja, a seleção já foi feita pelo modelo.
Aqui, isso é uma omissão consciente, não um item esquecido. O perfil padrão tem dez ferramentas, das quais seis relatórios Stat diferem pela forma da resposta, não pelo tema, e não há muito com o que o modelo possa confundir. O eval se torna necessário quando a superfície padrão se expande ou quando entram ferramentas com descrições sobrepostas — nesse caso, ele deve ser escrito antes da expansão, não depois.
O que mudou na 2.0.0
Foram removidas 26 ferramentas-wrapper sobre presets da Stat API (get_visits, sources_summary,
get_page_performance e outras). Elas cobriam uma pequena parte da API, fixavam dimensões e período
no código e não permitiam fazer uma consulta arbitrária. Elas são substituídas por metrika_stat_*, que aceitam
os parâmetros da Stat API como estão.
Surgiram métodos que não existiam: lista de contadores, objetivos, segmentos, filtros, permissões, gastos, conversões offline e todo o Logs API. Antes, o identificador do contador precisava ser conhecido de antemão — agora ele pode ser encontrado.
O que mudou na 2.1.0
O servidor foi levado a um estado em que não é arriscado deixá-lo com um agente.
- Anotações em todas as 108 ferramentas. Antes, o cliente não distinguia
metrika_counter_listdemetrika_counter_delete. - Gravação desativada por padrão (
METRIKA_ALLOW_WRITES). - Defeito de parsing da documentação encontrado e corrigido. As asserções eram marcadas por uma linha em que o valor vem depois do parêntese de fechamento da classe — o reconhecedor de propriedades estava ancorado no fim da linha e não correspondia a essas linhas. Como resultado, nenhum exemplo, valor padrão ou limite chegava à spec, e parte deles caía na descrição do campo vizinho. Agora a spec tem 288 exemplos, 69 valores padrão e 155 limites; os limites são transferidos para o schema da ferramenta, e exemplos e valores padrão — para as descrições dos parâmetros.
- Perda de obrigatoriedade encontrada e corrigida. Parâmetros do tipo "um de N tipos" (
goalna criação e edição de objetivo,grantna concessão de acesso) eram montados comoz.unknown(), que é opcional no zod — o campo obrigatório ia para o cliente como opcional. Agora é uma união das formas reais, e a obrigatoriedade está no lugar. - Referências a entidades são expandidas em um nível: em 23 parâmetros de corpo, em vez de um objeto livre, os campos reais ficam visíveis.
- Flexibilizações na entrada onde são inofensivas. Número como string, booleano como palavra, lista separada por vírgula na query string — são aceitos; no corpo da requisição, onde o JSON exato importa, não são aceitos.
- Teto de tamanho de resposta com truncamento declarado: uma exportação do Logs API pode ter centenas de megabytes.
- Limpeza de segredos do
request_urlexibido. - Repetição em 429 respeitando
Retry-After. - SDK atualizado para 1.30 — na 1.17 havia três vulnerabilidades publicadas, duas graves;
npm audit --audit-level=highagora faz parte do CI. - Job de drift no CI corrigido. Ela executava os testes via
| teesempipefail, então o código de retorno era obtido deteee o job permanecia verde em qualquer falha de teste.