Gaffer.sh

Memoria de CI para Agentes y Equipos

Documentación

@gaffer-sh/mcp

Servidor MCP (Model Context Protocol) para Gaffer - dale a tu asistente de IA memoria de tus pruebas.

¿Qué es esto?

Este servidor MCP conecta asistentes de codificación con IA como Claude Code y Cursor a tu historial de pruebas y datos de cobertura de Gaffer. Funciona en modo código: tres herramientas MCP sobre un espacio de nombres de 17 funciones — 16 funciones analíticas de solo lectura más upload_test_results. Permite a la IA:

  • Verificar la salud de las pruebas de tu proyecto (tasa de aprobación, pruebas flaky, tendencias)
  • Consultar el historial de pruebas específicas para entender su estabilidad
  • Obtener contexto sobre fallos de pruebas al depurar
  • Analizar la cobertura de código e identificar áreas sin probar
  • Explorar todos tus proyectos (con claves de API de usuario)
  • Acceder a archivos de informes de pruebas (informes HTML, cobertura, etc.)

Requisitos previos

  1. Una cuenta de Gaffer con resultados de pruebas subidos
  2. Una clave de API desde Configuración de cuenta > Claves de API

Configuración

Claude Code (CLI)

La forma más fácil de añadir el servidor MCP de Gaffer es mediante la CLI de Claude Code:

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

Claude Code (Manual)

Alternativamente, añade a la configuración de Claude Code (~/.claude.json o proyecto .claude/settings.json):

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

Cursor

Añade a .cursor/mcp.json en tu proyecto:

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

Cómo funciona este servidor

Este servidor usa modo código. En lugar de exponer una herramienta MCP por llamada de API, expone tres herramientas más un espacio de nombres codemode que llamas desde JavaScript. Menos definiciones de herramientas ocupan la ventana de contexto, y una sola ejecución puede encadenar varias llamadas.

Herramienta MCPQué hace
execute_codeEjecuta JavaScript contra codemode.<function>(). Máximo 20 llamadas de API, tiempo de espera de 30s.
search_toolsEncuentra funciones disponibles por palabra clave. Una consulta vacía las lista todas.
list_projectsLista proyectos. Se registra solo cuando el token es una clave de API de usuario (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 };

Funciones disponibles vía execute_code

FunciónCategoríaDescripción
get_project_healthsaludPuntuación de salud, tasa de aprobación, recuento de flaky, tendencia
get_test_historypruebasHistorial de aprobación/fallo para una prueba específica
get_flaky_testspruebasPruebas con altas tasas de cambio (aprobado↔fallo)
list_test_runspruebasEjecuciones de pruebas recientes, filtrables por commit/rama/estado
get_test_run_detailspruebasResultados individuales analizados para una ejecución
get_failure_clusterspruebasPruebas fallidas agrupadas por causa raíz
get_slowest_testspruebasPruebas más lentas por duración P95
compare_test_metricspruebasCompara el rendimiento de pruebas entre commits o ejecuciones
search_failurespruebasBusca fallos por patrón de error o nombre de prueba, o lista todos los fallos recientes
get_coverage_summarycoberturaMétricas generales de cobertura y tendencia
get_coverage_for_filecoberturaCobertura para archivos o rutas específicas
get_untested_filescoberturaArchivos por debajo de un umbral de cobertura
find_uncovered_failure_areascoberturaArchivos con baja cobertura Y fallos de pruebas
get_reportinformesURLs de archivos de informe para una ejecución de pruebas
get_report_browser_urlinformesURL de informe navegable firmada (30 min)
get_upload_statussubidasSi los resultados de CI están subidos y procesados
upload_test_resultssubidasSube resultados de pruebas (escritura) — con límite de velocidad y registro de auditoría

Toda función excepto upload_test_results es de solo lectura.

Referencia de funciones

list_projects

Lista todos los proyectos a los que tienes acceso.

  • Entrada: organizationId (opcional), limit (opcional, predeterminado: 50)
  • Devuelve: Lista de proyectos con IDs, nombres e información de organización
  • Ejemplo: "¿Qué proyectos tengo en Gaffer?"

get_project_health

Obtén las métricas de salud de un proyecto.

  • Entrada: projectId (obligatorio), days (opcional, predeterminado: 30)
  • Devuelve: Puntuación de salud (0-100), tasa de aprobación, recuento de ejecuciones de pruebas, recuento de pruebas flaky, tendencia
  • Ejemplo: "¿Cuál es la salud de mi suite de pruebas?"

get_test_history

Obtén el historial de aprobación/fallo para una prueba específica.

  • Entrada: projectId (obligatorio), testName o filePath (uno obligatorio), limit (opcional)
  • Devuelve: Historial de ejecuciones con estado, duración, rama, commit, errores
  • Ejemplo: "¿Es flaky la prueba de inicio de sesión? Revisa su historial"

get_flaky_tests

Obtén la lista de pruebas flaky en un proyecto.

  • Entrada: projectId (obligatorio), threshold (opcional, predeterminado: 0.1), days (opcional), limit (opcional)
  • Devuelve: Lista de pruebas flaky con tasas de cambio, recuentos de transición, recuentos de ejecución
  • Ejemplo: "¿Qué pruebas son flaky en mi proyecto?"

list_test_runs

Lista ejecuciones de pruebas recientes con filtrado opcional.

  • Entrada: projectId (obligatorio), commitSha (opcional), branch (opcional), status (opcional), limit (opcional)
  • Devuelve: Lista de ejecuciones de pruebas con recuentos de aprobado/fallo/omitido, información de commit y rama
  • Ejemplo: "¿Qué pruebas fallaron en el último commit?"

get_test_run_details

Obtén resultados de pruebas analizados para una ejecución de pruebas específica.

  • Entrada: testRunId (obligatorio), projectId (obligatorio), status (filtro opcional), limit (opcional)
  • Devuelve: Resultados individuales de pruebas con nombre, estado, duración, ruta de archivo, errores
  • Ejemplo: "Muéstrame todas las pruebas fallidas de esta ejecución"

get_report

Obtén URLs para archivos de informe subidos con una ejecución de pruebas.

  • Entrada: testRunId (obligatorio)
  • Devuelve: Lista de archivos con nombre, tamaño, tipo de contenido, URL de descarga
  • Ejemplo: "Obtén el informe de Playwright para la última ejecución de pruebas"

get_report_browser_url

Obtén una URL navegable para ver un informe de pruebas.

  • Entrada: projectId (obligatorio), testRunId (obligatorio), filename (opcional)
  • Devuelve: URL firmada válida por 30 minutos
  • Ejemplo: "Dame un enlace para ver el informe de pruebas"

get_slowest_tests

Obtén las pruebas más lentas en un proyecto, ordenadas por duración P95.

  • Entrada: projectId (obligatorio), days (opcional), limit (opcional), framework (opcional), branch (opcional)
  • Devuelve: Lista de pruebas con duración promedio y P95, recuento de ejecuciones
  • Ejemplo: "¿Qué pruebas están ralentizando mi pipeline de CI?"

compare_test_metrics

Compara métricas de pruebas entre dos commits o ejecuciones de pruebas.

  • Entrada: projectId (obligatorio), testName (obligatorio), beforeCommit/afterCommit O beforeRunId/afterRunId
  • Devuelve: Métricas antes/después con cambio de duración y porcentaje
  • Ejemplo: "¿Mi corrección hizo esta prueba más rápida?"

get_coverage_summary

Obtén el resumen de métricas de cobertura para un proyecto.

  • Entrada: projectId (obligatorio), days (opcional, predeterminado: 30)
  • Devuelve: Porcentajes de cobertura de línea/rama/función, tendencia, recuento de informes, archivos con menor cobertura
  • Ejemplo: "¿Cuál es nuestra cobertura de pruebas?"

get_coverage_for_file

Obtén métricas de cobertura para archivos o rutas específicas.

  • Entrada: projectId (obligatorio), filePath (obligatorio - coincidencia exacta o parcial)
  • Devuelve: Lista de archivos coincidentes con cobertura de línea/rama/función
  • Ejemplo: "¿Cuál es la cobertura de nuestras rutas de API?"

get_untested_files

Obtén archivos con poca o ninguna cobertura de pruebas.

  • Entrada: projectId (obligatorio), maxCoverage (opcional, predeterminado: 10%), limit (opcional)
  • Devuelve: Lista de archivos por debajo del umbral ordenados por cobertura (menor primero)
  • Ejemplo: "¿Qué archivos no tienen pruebas?"

find_uncovered_failure_areas

Encuentra áreas de código con baja cobertura Y fallos de pruebas (alto riesgo).

  • Entrada: projectId (obligatorio), days (opcional), coverageThreshold (opcional, predeterminado: 80%)
  • Devuelve: Áreas de riesgo clasificadas por puntuación, con ruta de archivo, % de cobertura, recuento de fallos
  • Ejemplo: "¿Dónde deberíamos enfocar nuestros esfuerzos de pruebas?"

get_failure_clusters

Agrupa pruebas fallidas por causa raíz usando similitud de mensajes de error.

  • Entrada: projectId (obligatorio), testRunId (obligatorio)
  • Devuelve: Grupos de pruebas fallidas agrupadas por mensajes de error similares, con error representativo y recuento de pruebas
  • Ejemplo: "¿Son estos 15 fallos del mismo error?"

search_failures

Busca fallos pasados por mensaje de error, traza de pila o nombre de prueba — o lista cada fallo en la ventana.

  • Entrada: query (opcional — omítelo para devolver todos los fallos), projectId (obligatorio para claves gaf_), searchIn (opcional: errors/names/all, predeterminado all), days (opcional, predeterminado: 30), branch (opcional), limit (opcional, predeterminado: 20)
  • Devuelve: Fallos coincidentes con nombre de prueba, mensaje de error, contexto de ejecución y commit, más truncated cuando los límites de escaneo acortan la lista
  • Ejemplo: "¿Hemos visto este error de conexión rechazada antes?" / "¿Qué falló en los últimos 7 días?"

get_upload_status

Comprueba si los resultados de CI se han subido y procesado.

  • Entrada: projectId (obligatorio), sessionId (opcional), commitSha (opcional), branch (opcional)
  • Devuelve: Sesión(es) de subida con estado de procesamiento, ejecuciones de pruebas vinculadas e informes de cobertura
  • Ejemplo: "¿Están listos mis resultados de pruebas para el commit abc123?"

upload_test_results

Sube resultados de pruebas estructurados. Esta es la única función que escribe.

Úsala cuando tengas resultados en mano — analizados de la salida de CI o del informe JSON de un ejecutor — y no haya CLI de Gaffer disponible para subirlos.

  • Entrada: projectId (obligatorio para claves gaf_), framework (obligatorio), tests (obligatorio), branch, commitSha, ciProvider, startedAt, finishedAt, coverage
  • Devuelve: uploadSessionId, el runId generado, y el resumen derivado de aprobado/fallo/omitido
  • Ejemplo: "Sube estos 42 resultados de pytest analizados para que podamos rastrearlos"

runId, las marcas de tiempo de ejecución y el resumen se derivan de tests — pasa startedAt/finishedAt solo si conoces la ventana de tiempo real real.

Dos restricciones que vale la pena conocer:

  • No es idempotente. Cada llamada crea una nueva ejecución, por lo que un reintento después de un fallo incierto produce un duplicado. Comprueba get_upload_status en lugar de reintentar.
  • Con límite de velocidad por proyecto, y cada llamada se escribe en el registro de auditoría del proyecto con el ID de la credencial que la realizó.

El procesamiento es asíncrono: los resultados tardan unos segundos en hacerse visibles para las funciones de lectura.

Flujos de trabajo de CI agénticos

Estos flujos de trabajo muestran cómo un agente de IA diagnostica fallos de CI, espera resultados y encuentra brechas de cobertura. Cada paso es una función codemode, por lo que toda una cadena se ejecuta dentro de una sola llamada execute_code en lugar de un viaje de ida y vuelta por paso.

Flujo de trabajo: Diagnosticar fallos 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. Encuentra la ejecución de pruebas fallida
  2. Obtén detalles individuales de fallos con trazas de pila
  3. Agrupa fallos por causa raíz — a menudo 15 fallos son 2-3 errores
  4. Comprueba si cada fallo es nuevo (regresión) o recurrente
  5. Verifica correcciones comparando antes/después

Flujo de trabajo: Esperar resultados

get_upload_status(projectId, commitSha="abc123")
  → poll until processingStatus="completed"
  → get_test_run_details(projectId, testRunId)
  1. Comprueba si los resultados de un commit se han subido
  2. Espera a que el procesamiento se complete
  3. Usa IDs de ejecución de pruebas vinculados para obtener resultados

Flujo de trabajo: Encontrar brechas de cobertura

find_uncovered_failure_areas(projectId)
  → get_untested_files(projectId)
  → get_coverage_for_file(projectId, filePath="src/critical/")
  1. Encuentra archivos con baja cobertura y fallos de pruebas (mayor riesgo)
  2. Encuentra archivos sin cobertura alguna
  3. Profundiza en directorios específicos para análisis dirigido

Referencia rápida de funciones

Pregunta del agenteFunción
"¿Qué falló?"get_test_run_details
"¿Misma causa raíz?"get_failure_clusters
"¿Visto este error antes?"search_failures
"¿Es flaky?"get_flaky_tests
"¿Es nuevo?"get_test_history
"¿Funcionó mi corrección?"compare_test_metrics
"¿Están listos los resultados?"get_upload_status
"¿Qué no está probado?"find_uncovered_failure_areas
"¿Qué es lento?"get_slowest_tests

Priorizando mejoras de cobertura

Al usar herramientas de cobertura para mejorar tu suite de pruebas, combina los datos de cobertura con la exploración del código base para obtener mejores resultados:

1. Comprende la utilización del código

Antes de apuntar a archivos solo por el porcentaje de cobertura, explora qué código es realmente crítico:

  • Encuentra puntos de entrada: Busca definiciones de rutas, manejadores de eventos, funciones exportadas; estos revelan qué código se ejecuta realmente en producción
  • Encuentra archivos muy importados: Los archivos importados por muchos otros son objetivos de alto valor
  • Identifica la lógica de negocio crítica: Busca archivos que manejen autenticación, pagos, mutaciones de datos o lógica de dominio central

2. Prioriza por impacto

La baja cobertura por sí sola no indica prioridad. Considera:

  • Alta utilización + baja cobertura = máxima prioridad - Código que se ejecuta con frecuencia pero carece de pruebas
  • Archivos grandes con 0% de cobertura - Más líneas sin cubrir significa mayor impacto en la cobertura general
  • Archivos con fallos y baja cobertura - Usa find_uncovered_failure_areas para esto

3. Usa consultas basadas en rutas

La herramienta get_untested_files puede devolver muchos componentes de frontend. Para backend o á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. Mejora iterativa

  1. Obtén la línea base con get_coverage_summary
  2. Identifica objetivos con get_coverage_for_file en rutas críticas
  3. Escribe pruebas para los archivos de mayor impacto
  4. Vuelve a verificar la cobertura después de que el CI suba nuevos resultados
  5. Repite

Autenticación

Claves de API de usuario (Recomendado)

Las claves de API de usuario (prefijo gaf_) proporcionan acceso de solo lectura a todos los proyectos de tus organizaciones. Obtén tu clave de API desde: Configuración de la cuenta > Claves de API

Tokens de proyecto

Los tokens de proyecto (prefijo gfr_) están diseñados para subir resultados de pruebas y solo proporcionan acceso a un único proyecto. Cuando uses uno, omite projectId; se resuelve automáticamente. Las claves de API de usuario son preferidas para el servidor MCP porque habilitan list_projects y lectura entre proyectos.

Variables de entorno

VariableRequeridoDescripción
GAFFER_API_KEYSíTu clave de API de Gaffer (comienza con gaf_)
GAFFER_API_URLNoURL base de la API (por defecto: https://app.gaffer.sh)

Desarrollo local

pnpm install
pnpm build

Prueba localmente con Claude Code (usa la ruta absoluta al archivo compilado):

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

Licencia

MIT