Gaffer.sh

Memória de CI para Agentes e Equipes

Documentação

@gaffer-sh/mcp

Servidor MCP (Model Context Protocol) para Gaffer - dê ao seu assistente de IA memória dos seus testes.

O que é isso?

Este servidor MCP conecta assistentes de codificação de IA como Claude Code e Cursor ao seu histórico de testes e dados de cobertura do Gaffer. Ele opera em modo de código: três ferramentas MCP sobre um namespace de 17 funções — 16 funções analíticas somente leitura mais upload_test_results. Ele permite que a IA:

  • Verifique a saúde dos testes do seu projeto (taxa de aprovação, testes instáveis, tendências)
  • Consulte o histórico de testes específicos para entender a estabilidade
  • Obtenha contexto sobre falhas de testes ao depurar
  • Analise a cobertura de código e identifique áreas não testadas
  • Navegue por todos os seus projetos (com chaves de API de usuário)
  • Acesse arquivos de relatórios de testes (relatórios HTML, cobertura, etc.)

Pré-requisitos

  1. Uma conta Gaffer com resultados de testes enviados
  2. Uma chave de API em Account Settings > API Keys

Configuração

Claude Code (CLI)

A maneira mais fácil de adicionar o servidor MCP do Gaffer é via CLI do Claude Code:

claude mcp add gaffer -e GAFFER_API_KEY=gaf_your_api_key_here -- npx -y @gaffer-sh/mcp

Claude Code (Manual)

Alternativamente, adicione às configurações do seu Claude Code (~/.claude.json ou projeto .claude/settings.json):

{
  "mcpServers": {
    "gaffer": {
      "command": "npx",
      "args": ["-y", "@gaffer-sh/mcp"],
      "env": {
        "GAFFER_API_KEY": "gaf_your_api_key_here"
      }
    }
  }
}

Cursor

Adicione a .cursor/mcp.json no seu projeto:

{
  "mcpServers": {
    "gaffer": {
      "command": "npx",
      "args": ["-y", "@gaffer-sh/mcp"],
      "env": {
        "GAFFER_API_KEY": "gaf_your_api_key_here"
      }
    }
  }
}

Como este servidor funciona

Este servidor usa modo de código. Em vez de expor uma ferramenta MCP por chamada de API, ele expõe três ferramentas mais um namespace codemode que você chama a partir de JavaScript. Menos definições de ferramentas ocupam a janela de contexto, e uma única execução pode encadear várias chamadas.

Ferramenta MCPO que faz
execute_codeExecute JavaScript contra codemode.<function>(). Máximo de 20 chamadas de API, timeout de 30s.
search_toolsEncontre funções disponíveis por palavra-chave. Uma consulta vazia lista todas.
list_projectsLista projetos. Registrada apenas quando o token é uma chave de API de usuário (gaf_).
const health = await codemode.get_project_health({ projectId: "proj_abc" });
if (health.flakyTestCount > 0) {
  const flaky = await codemode.get_flaky_tests({ projectId: "proj_abc" });
  return { health, flaky };
}
return { health };

Funções disponíveis via execute_code

FunçãoCategoriaDescrição
get_project_healthhealthPontuação de saúde, taxa de aprovação, contagem de instáveis, tendência
get_test_historytestingHistórico de aprovação/reprovação para um teste específico
get_flaky_teststestingTestes com altas taxas de alternância (aprovado↔reprovado)
list_test_runstestingExecuções de teste recentes, filtráveis por commit/branch/status
get_test_run_detailstestingResultados individuais analisados para uma execução
get_failure_clusterstestingTestes reprovados agrupados por causa raiz
get_slowest_teststestingTestes mais lentos por duração P95
compare_test_metricstestingCompare o desempenho de testes entre commits ou execuções
search_failurestestingPesquise falhas por padrão de erro ou nome de teste, ou liste todas as falhas recentes
get_coverage_summarycoverageMétricas gerais de cobertura e tendência
get_coverage_for_filecoverageCobertura para arquivos ou caminhos específicos
get_untested_filescoverageArquivos abaixo de um limite de cobertura
find_uncovered_failure_areascoverageArquivos com baixa cobertura E falhas de teste
get_reportreportsURLs de arquivos de relatório para uma execução de teste
get_report_browser_urlreportsURL de relatório assinada navegável no navegador (30 min)
get_upload_statusuploadsSe os resultados de CI foram enviados e processados
upload_test_resultsuploadsEnviar resultados de teste (gravação) — com limite de taxa e registro em log de auditoria

Toda função exceto upload_test_results é somente leitura.

Referência de Funções

list_projects

Lista todos os projetos aos quais você tem acesso.

  • Entrada: organizationId (opcional), limit (opcional, padrão: 50)
  • Retorna: Lista de projetos com IDs, nomes e informações da organização
  • Exemplo: "Quais projetos eu tenho no Gaffer?"

get_project_health

Obtém as métricas de saúde de um projeto.

  • Entrada: projectId (obrigatório), days (opcional, padrão: 30)
  • Retorna: Pontuação de saúde (0-100), taxa de aprovação, contagem de execuções de teste, contagem de testes instáveis, tendência
  • Exemplo: "Qual é a saúde da minha suíte de testes?"

get_test_history

Obtém o histórico de aprovação/reprovação de um teste específico.

  • Entrada: projectId (obrigatório), testName ou filePath (um obrigatório), limit (opcional)
  • Retorna: Histórico de execuções com status, duração, branch, commit, erros
  • Exemplo: "O teste de login é instável? Verifique o histórico dele"

get_flaky_tests

Obtém a lista de testes instáveis em um projeto.

  • Entrada: projectId (obrigatório), threshold (opcional, padrão: 0.1), days (opcional), limit (opcional)
  • Retorna: Lista de testes instáveis com taxas de alternância, contagens de transição, contagens de execução
  • Exemplo: "Quais testes são instáveis no meu projeto?"

list_test_runs

Lista execuções de teste recentes com filtragem opcional.

  • Entrada: projectId (obrigatório), commitSha (opcional), branch (opcional), status (opcional), limit (opcional)
  • Retorna: Lista de execuções de teste com contagens de aprovação/reprovação/pulados, informações de commit e branch
  • Exemplo: "Quais testes falharam no último commit?"

get_test_run_details

Obtém resultados de teste analisados para uma execução de teste específica.

  • Entrada: testRunId (obrigatório), projectId (obrigatório), status (filtro opcional), limit (opcional)
  • Retorna: Resultados individuais de teste com nome, status, duração, caminho do arquivo, erros
  • Exemplo: "Mostre-me todos os testes reprovados desta execução de teste"

get_report

Obtém URLs para arquivos de relatório enviados com uma execução de teste.

  • Entrada: testRunId (obrigatório)
  • Retorna: Lista de arquivos com nome do arquivo, tamanho, tipo de conteúdo, URL de download
  • Exemplo: "Obtenha o relatório do Playwright para a execução de teste mais recente"

get_report_browser_url

Obtém uma URL navegável no navegador para visualizar um relatório de teste.

  • Entrada: projectId (obrigatório), testRunId (obrigatório), filename (opcional)
  • Retorna: URL assinada válida por 30 minutos
  • Exemplo: "Dê-me um link para visualizar o relatório de teste"

get_slowest_tests

Obtém os testes mais lentos em um projeto, ordenados por duração P95.

  • Entrada: projectId (obrigatório), days (opcional), limit (opcional), framework (opcional), branch (opcional)
  • Retorna: Lista de testes com duração média e P95, contagem de execuções
  • Exemplo: "Quais testes estão deixando meu pipeline de CI mais lento?"

compare_test_metrics

Compara métricas de teste entre dois commits ou execuções de teste.

  • Entrada: projectId (obrigatório), testName (obrigatório), beforeCommit/afterCommit OU beforeRunId/afterRunId
  • Retorna: Métricas antes/depois com mudança de duração e porcentagem
  • Exemplo: "Minha correção tornou este teste mais rápido?"

get_coverage_summary

Obtém o resumo das métricas de cobertura de um projeto.

  • Entrada: projectId (obrigatório), days (opcional, padrão: 30)
  • Retorna: Porcentagens de cobertura de linha/ramo/função, tendência, contagem de relatórios, arquivos com menor cobertura
  • Exemplo: "Qual é a nossa cobertura de testes?"

get_coverage_for_file

Obtém métricas de cobertura para arquivos ou caminhos específicos.

  • Entrada: projectId (obrigatório), filePath (obrigatório - correspondência exata ou parcial)
  • Retorna: Lista de arquivos correspondentes com cobertura de linha/ramo/função
  • Exemplo: "Qual é a cobertura das nossas rotas de API?"

get_untested_files

Obtém arquivos com pouca ou nenhuma cobertura de teste.

  • Entrada: projectId (obrigatório), maxCoverage (opcional, padrão: 10%), limit (opcional)
  • Retorna: Lista de arquivos abaixo do limite ordenados por cobertura (menor primeiro)
  • Exemplo: "Quais arquivos não têm testes?"

find_uncovered_failure_areas

Encontra áreas de código com baixa cobertura E falhas de teste (alto risco).

  • Entrada: projectId (obrigatório), days (opcional), coverageThreshold (opcional, padrão: 80%)
  • Retorna: Áreas de risco classificadas por pontuação, com caminho do arquivo, % de cobertura, contagem de falhas
  • Exemplo: "Onde devemos concentrar nossos esforços de teste?"

get_failure_clusters

Agrupa testes reprovados por causa raiz usando similaridade de mensagens de erro.

  • Entrada: projectId (obrigatório), testRunId (obrigatório)
  • Retorna: Agrupamentos de testes reprovados agrupados por mensagens de erro semelhantes, com erro representativo e contagem de testes
  • Exemplo: "Essas 15 falhas são do mesmo bug?"

search_failures

Pesquisa falhas passadas por mensagem de erro, stack trace ou nome de teste — ou lista todas as falhas no período.

  • Entrada: query (opcional — omita para retornar todas as falhas), projectId (obrigatório para chaves gaf_), searchIn (opcional: errors/names/all, padrão all), days (opcional, padrão: 30), branch (opcional), limit (opcional, padrão: 20)
  • Retorna: Falhas correspondentes com nome do teste, mensagem de erro, contexto de execução e commit, além de truncated quando os limites de varredura encurtam a lista
  • Exemplo: "Já vimos este erro de conexão recusada antes?" / "O que falhou nos últimos 7 dias?"

get_upload_status

Verifica se os resultados de CI foram enviados e processados.

  • Entrada: projectId (obrigatório), sessionId (opcional), commitSha (opcional), branch (opcional)
  • Retorna: Sessão(ões) de envio com status de processamento, execuções de teste vinculadas e relatórios de cobertura
  • Exemplo: "Meus resultados de teste estão prontos para o commit abc123?"

upload_test_results

Envia resultados de teste estruturados. Esta é a única função que grava.

Use-a quando você tiver resultados em mãos — analisados da saída de CI ou do relatório JSON de um runner — e nenhuma CLI do Gaffer estiver disponível para enviá-los.

  • Entrada: projectId (obrigatório para chaves gaf_), framework (obrigatório), tests (obrigatório), branch, commitSha, ciProvider, startedAt, finishedAt, coverage
  • Retorna: uploadSessionId, o runId gerado e o resumo derivado de aprovação/reprovação/pulados
  • Exemplo: "Envie estes 42 resultados pytest analisados para que possamos rastreá-los"

runId, os carimbos de data/hora da execução e o resumo são derivados de tests — passe startedAt/finishedAt apenas se você souber a janela real de tempo de relógio.

Duas restrições que vale a pena conhecer:

  • Não é idempotente. Cada chamada cria uma nova execução, então uma nova tentativa após uma falha incerta produz uma duplicata. Verifique get_upload_status em vez de tentar novamente.
  • Com limite de taxa por projeto, e cada chamada é registrada no log de auditoria do projeto com o ID da credencial que a fez.

O processamento é assíncrono: os resultados levam alguns segundos para ficarem visíveis para as funções de leitura.

Fluxos de Trabalho de CI com Agentes

Estes fluxos de trabalho mostram como um agente de IA diagnostica falhas de CI, aguarda resultados e encontra lacunas de cobertura. Cada etapa é uma função codemode, então toda uma cadeia é executada dentro de uma única chamada execute_code em vez de uma ida e volta por etapa.

Fluxo de Trabalho: Diagnosticar Falhas de CI

list_test_runs(projectId, status="failed")
  → get_test_run_details(projectId, testRunId, status="failed")
  → get_failure_clusters(projectId, testRunId)
  → get_test_history(projectId, testName="...")
  → compare_test_metrics(projectId, testName, beforeCommit, afterCommit)
  1. Encontre a execução de teste reprovada
  2. Obtenha detalhes individuais de falhas com stack traces
  3. Agrupe falhas por causa raiz — frequentemente 15 falhas são 2-3 bugs
  4. Verifique se cada falha é nova (regressão) ou recorrente
  5. Verifique correções comparando antes/depois

Fluxo de Trabalho: Aguardar Resultados

get_upload_status(projectId, commitSha="abc123")
  → poll until processingStatus="completed"
  → get_test_run_details(projectId, testRunId)
  1. Verifique se os resultados de um commit foram enviados
  2. Aguarde o processamento ser concluído
  3. Use IDs de execução de teste vinculados para obter resultados

Fluxo de Trabalho: Encontrar Lacunas de Cobertura

find_uncovered_failure_areas(projectId)
  → get_untested_files(projectId)
  → get_coverage_for_file(projectId, filePath="src/critical/")
  1. Encontre arquivos com baixa cobertura e falhas de teste (maior risco)
  2. Encontre arquivos sem nenhuma cobertura
  3. Aprofunde-se em diretórios específicos para análise direcionada

Referência Rápida de Funções

Pergunta do AgenteFunção
"O que falhou?"get_test_run_details
"Mesma causa raiz?"get_failure_clusters
"Já viu este erro antes?"search_failures
"É instável?"get_flaky_tests
"É novo?"get_test_history
"Minha correção funcionou?"compare_test_metrics
"Os resultados estão prontos?"get_upload_status
"O que não foi testado?"find_uncovered_failure_areas
"O que está lento?"get_slowest_tests

Priorizando Melhorias de Cobertura

Ao usar ferramentas de cobertura para melhorar sua suíte de testes, combine dados de cobertura com exploração do código para obter os melhores resultados:

1. Entenda a Utilização do Código

Antes de focar em arquivos apenas pela porcentagem de cobertura, explore qual código é realmente crítico:

  • Encontre pontos de entrada: Procure definições de rotas, manipuladores de eventos, funções exportadas — isso revela qual código realmente executa em produção
  • Encontre arquivos muito importados: Arquivos importados por muitos outros são alvos de alto valor
  • Identifique lógica de negócios crítica: Procure arquivos que lidam com autenticação, pagamentos, mutações de dados ou lógica central do domínio

2. Priorize por Impacto

Baixa cobertura sozinha não indica prioridade. Considere:

  • Alta utilização + baixa cobertura = maior prioridade — Código que roda com frequência, mas carece de testes
  • Arquivos grandes com 0% de cobertura — Mais linhas descobertas significa maior impacto na cobertura geral
  • Arquivos com falhas e baixa cobertura — Use find_uncovered_failure_areas para isso

3. Use Consultas Baseadas em Caminhos

A ferramenta get_untested_files pode retornar muitos componentes de frontend. Para backend ou áreas específicas:

# Query specific paths with get_coverage_for_file
get_coverage_for_file(filePath="server/services")
get_coverage_for_file(filePath="src/api")
get_coverage_for_file(filePath="lib/core")

4. Melhoria Iterativa

  1. Obtenha a linha de base com get_coverage_summary
  2. Identifique alvos com get_coverage_for_file em caminhos críticos
  3. Escreva testes para os arquivos de maior impacto
  4. Verifique novamente a cobertura após o CI enviar novos resultados
  5. Repita

Autenticação

Chaves de API do Usuário (Recomendado)

As Chaves de API do Usuário (prefixo gaf_) fornecem acesso somente leitura a todos os projetos em suas organizações. Obtenha sua Chave de API em: Configurações da Conta > Chaves de API

Tokens de Projeto

Os Tokens de Projeto (prefixo gfr_) são projetados para enviar resultados de teste e fornecem acesso apenas a um único projeto. Ao usá-los, omita projectId — ele é resolvido automaticamente. As Chaves de API do Usuário são preferidas para o servidor MCP porque permitem list_projects e leitura entre projetos.

Variáveis de Ambiente

VariávelObrigatóriaDescrição
GAFFER_API_KEYSimSua Chave de API do Gaffer (começa com gaf_)
GAFFER_API_URLNãoURL base da API (padrão: https://app.gaffer.sh)

Desenvolvimento Local

pnpm install
pnpm build

Teste localmente com Claude Code (use caminho absoluto para o arquivo compilado):

{
  "mcpServers": {
    "gaffer": {
      "command": "node",
      "args": ["/absolute/path/to/dist/index.js"],
      "env": {
        "GAFFER_API_KEY": "gaf_..."
      }
    }
  }
}

Licença

MIT