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
- Una cuenta de Gaffer con resultados de pruebas subidos
- 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 MCP | Qué hace |
|---|---|
execute_code | Ejecuta JavaScript contra codemode.<function>(). Máximo 20 llamadas de API, tiempo de espera de 30s. |
search_tools | Encuentra funciones disponibles por palabra clave. Una consulta vacía las lista todas. |
list_projects | Lista 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ón | Categoría | Descripción |
|---|---|---|
get_project_health | salud | Puntuación de salud, tasa de aprobación, recuento de flaky, tendencia |
get_test_history | pruebas | Historial de aprobación/fallo para una prueba específica |
get_flaky_tests | pruebas | Pruebas con altas tasas de cambio (aprobado↔fallo) |
list_test_runs | pruebas | Ejecuciones de pruebas recientes, filtrables por commit/rama/estado |
get_test_run_details | pruebas | Resultados individuales analizados para una ejecución |
get_failure_clusters | pruebas | Pruebas fallidas agrupadas por causa raíz |
get_slowest_tests | pruebas | Pruebas más lentas por duración P95 |
compare_test_metrics | pruebas | Compara el rendimiento de pruebas entre commits o ejecuciones |
search_failures | pruebas | Busca fallos por patrón de error o nombre de prueba, o lista todos los fallos recientes |
get_coverage_summary | cobertura | Métricas generales de cobertura y tendencia |
get_coverage_for_file | cobertura | Cobertura para archivos o rutas específicas |
get_untested_files | cobertura | Archivos por debajo de un umbral de cobertura |
find_uncovered_failure_areas | cobertura | Archivos con baja cobertura Y fallos de pruebas |
get_report | informes | URLs de archivos de informe para una ejecución de pruebas |
get_report_browser_url | informes | URL de informe navegable firmada (30 min) |
get_upload_status | subidas | Si los resultados de CI están subidos y procesados |
upload_test_results | subidas | Sube 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),testNameofilePath(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/afterCommitObeforeRunId/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 clavesgaf_),searchIn(opcional:errors/names/all, predeterminadoall),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
truncatedcuando 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 clavesgaf_),framework(obligatorio),tests(obligatorio),branch,commitSha,ciProvider,startedAt,finishedAt,coverage - Devuelve:
uploadSessionId, elrunIdgenerado, 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_statusen 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)
- Encuentra la ejecución de pruebas fallida
- Obtén detalles individuales de fallos con trazas de pila
- Agrupa fallos por causa raíz — a menudo 15 fallos son 2-3 errores
- Comprueba si cada fallo es nuevo (regresión) o recurrente
- 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)
- Comprueba si los resultados de un commit se han subido
- Espera a que el procesamiento se complete
- 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/")
- Encuentra archivos con baja cobertura y fallos de pruebas (mayor riesgo)
- Encuentra archivos sin cobertura alguna
- Profundiza en directorios específicos para análisis dirigido
Referencia rápida de funciones
| Pregunta del agente | Funció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_areaspara 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
- Obtén la línea base con
get_coverage_summary - Identifica objetivos con
get_coverage_for_fileen rutas críticas - Escribe pruebas para los archivos de mayor impacto
- Vuelve a verificar la cobertura después de que el CI suba nuevos resultados
- 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
| Variable | Requerido | Descripción |
|---|---|---|
GAFFER_API_KEY | Sí | Tu clave de API de Gaffer (comienza con gaf_) |
GAFFER_API_URL | No | URL 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