AIQUAA Performance

MCP-сервер для анализа требований к производительности, генерации и расширения тестовых планов Apache JMeter, оценки результатов JTL, контроля пороговых значений и создания черновиков pull request.

Документация

AIQUAA Performance MCP Server

Servidor Model Context Protocol para convertir requisitos no funcionales, contratos de API, código y artefactos JMeter en automatización de rendimiento segura y trazable. Analiza cobertura, genera o amplía planes .jmx, evalúa .jtl, compara ejecuciones y prepara draft pull requests.

La capacidad no se infiere sólo desde el código. Todas las respuestas distinguen información observada, declarada, estimada y desconocida. Si falta carga suficiente, el servidor devuelve supuestos y una propuesta, nunca una carga “validada”.

Quick start

Requiere Node.js 20+. Java 11+ y Apache JMeter 5.6+ sólo son obligatorios para ejecutar pruebas.

npx -y aiquaa-performance-mcp-server

El servidor publica:

  • MCP Streamable HTTP: http://localhost:3000/mcp
  • Health: http://localhost:3000/health

Configuración de un cliente MCP:

{
  "mcpServers": {
    "aiquaa-performance": {
      "url": "http://localhost:3000/mcp"
    }
  }
}

Desarrollo local:

npm ci
npm run check
npm start

Arquitectura

MCP HTTP → schemas Zod → tools → dominio
                                ├─ análisis de requisito/repositorio
                                ├─ modelo de carga cerrado/abierto
                                ├─ parser/generador/validador/runner JMeter
                                ├─ JTL, thresholds y comparación
                                ├─ pipelines y GitHub draft PR
                                └─ adapters AIQUAA, CodeGraph y Engram

Las operaciones de lectura son puras. La generación devuelve archivos, pero no los escribe. perf_ejecutar y perf_pr concentran los efectos externos y están bloqueadas por defecto. La ejecución usa argumentos de proceso separados (shell: false); XML rechaza DOCTYPE/ENTITY; todas las rutas se normalizan y validan.

Tools

ToolResultado
perf_analizarEndpoints, flujos, auth, datos, riesgos, JMeter/CI existentes, faltantes y confianza
perf_requisitosPerformanceRequirement trazable desde NFR/SLA/SLO
perf_escenarioModelo cerrado u abierto y su justificación
perf_coberturacovered, partially_covered, uncovered, outdated, unsafe o blocked
perf_generarJMX, CSV ficticio, properties y thresholds en modos create, extend, modify
perf_validarXML, estructura, variables, CSV, plugins, listeners y secretos, sin ejecutar
perf_ejecutarvalidation_only, smoke o full, sujeto a autorización y límites
perf_resultadosMuestras, errores, throughput, P50/P90/P95/P99, bytes y veredictos
perf_compararMejora, degradación, cambio no significativo o no comparable
perf_pipelineGitHub Actions o Azure Pipelines headless con artifacts y thresholds
perf_cambiosPlan previo de archivos, cobertura estimada, riesgo y supuestos
perf_prPlan dry-run o rama + archivos + draft PR mediante Octokit
perf_monitoreoCaptura (Python + Selenium) evidencia de un dashboard de monitoreo externo (Grafana, Datadog, etc.) para adjuntar al informe
perf_informeInforme PDF (portada, veredicto, percentiles, comparación, detalle por sampler, evidencia de monitoreo opcional)

Todas aceptan response_format: json, markdown, files o patch, salvo perf_informe, que siempre devuelve el PDF embebido en base64 (resource con mimeType: application/pdf) junto a un resumen en texto; el cliente decide si lo persiste.

Modelos y presets

Un workload cerrado modela usuarios concurrentes que esperan una respuesta; uno abierto modela una tasa de llegada independiente. perf_escenario selecciona el segundo cuando el requisito declara arrivalRate o throughput y el primero cuando declara concurrencia.

Presets incluidos:

  • smoke: 1 thread, 1 loop, ramp-up 1 s.
  • baseline: 5 threads, 60 s, ramp-up 10 s.
  • load, stress, spike, endurance, soak, capacity, breakpoint, scalability, volume: se derivan del requisito; sin datos, comienzan como propuesta mínima con confianza baja.
  • aiquaa_stress: 1000 threads × 30 loops, ramp-up 0, think time 0. Está marcado como agresivo y nunca puede ejecutarse sin confirmación explícita.

JMeter y archivos generados

Los planes usan JMeter 5.6.3, HttpClient4, HTTP defaults, cookies, headers, CSV UTF-8, assertions y Simple Data Writer. Evitan BeanShell, secretos y listeners gráficos. La ampliación preserva el XML existente e inserta sólo samplers cuyos nombres todavía no existen.

tests/performance/
├── plans/P_<API>.jmx
├── data/D_<API>.csv
├── properties/<environment>.properties
├── thresholds/thresholds.json
└── README.md

test-results/performance/
├── R_<API>.jtl
├── dashboard/
├── summary.json
├── comparison.json
└── INFORME_PERF_<API>.pdf

Los CSV generados contienen valores ficticios. Configure recycle, stopThread y sharing mode según si los datos son reutilizables, únicos, consumibles o requieren cleanup. No versionar credenciales ni datos reales.

Thresholds y resultados

{
  "global": { "maxErrorRate": 1, "p95Ms": 1500 },
  "operations": {
    "POST /payments": { "maxErrorRate": 0.1, "p95Ms": 2000, "p99Ms": 3500 }
  }
}

Los veredictos son PASS, FAIL, INCONCLUSIVE y NOT_EXECUTED. Falta de thresholds, pocas muestras o ambiente inestable producen INCONCLUSIVE. La comparación devuelve not_comparable si difieren carga, duración, dataset, ambiente, infraestructura, versión o warm-up.

Un pipeline puede evaluar resultados con:

npx -y aiquaa-performance-mcp-server --evaluate test-results/performance/R_API.jtl tests/performance/thresholds/thresholds.json

O generar el mismo informe PDF que produce perf_informe, sin pasar por MCP:

npx -y aiquaa-performance-mcp-server --report test-results/performance/R_API.jtl tests/performance/thresholds/thresholds.json test-results/performance/INFORME_PERF_API.pdf \
  --api-name "Mi API" --test-type smoke --threads 1 --loops 1 \
  --baseline test-results/performance/R_BASELINE.jtl --api-version v1.2.0 --repo-url https://github.com/org/repo --author "Nombre" \
  --evidence-image test-results/performance/evidence/EVIDENCIA_MONITOREO.png --evidence-label "Dashboard de monitoreo" --evidence-url https://example.grafana.net/public-dashboards/xxx

Seguridad de ejecución

perf_ejecutar usa validation_only por defecto. Para una ejecución real se requieren simultáneamente:

  1. PERF_ALLOW_EXECUTION=true;
  2. host exacto en PERF_ALLOWED_HOSTS;
  3. authorized=true en la llamada;
  4. carga bajo los máximos configurados;
  5. confirmación adicional para producción, carga agresiva o pruebas destructivas.

Variables:

VariableUso
PORT, MCP_PATHServidor HTTP
JMETER_HOME, JAVA_HOMEEjecución local
PERF_ALLOWED_HOSTS, PERF_PRODUCTION_HOSTSAllowlist y protección de producción
PERF_MAX_THREADS, PERF_MAX_DURATION_SECONDS, PERF_MAX_ARRIVAL_RATELímites duros
PERF_ALLOW_EXECUTIONKill switch; false por defecto
PERF_MONITORING_PYTHON_BINBinario de Python para perf_monitoreo; python3 por defecto
PERF_MONITORING_ALLOWED_PRIVATE_HOSTSAllowlist de hosts privados/loopback para perf_monitoreo
GITHUB_TOKEN, GITHUB_API_URLDraft PR
AIQUAA_API_BASE_URL, AIQUAA_ACCESS_TOKENAdapter AIQUAA
CODEGRAPH_BIN, CODEGRAPH_ALLOWED_ROOTSContexto estructural opcional
ENGRAM_BIN, ENGRAM_PROJECT_PREFIXMemoria opcional por proyecto

La API HTTP limita cuerpos a 10 MB; los runners tienen timeout y cancelación. Tokens, passwords, API keys y secretos se redactan antes de producir archivos o PR. No se permite path traversal.

GitHub PR

perf_pr siempre usa rama test/performance/<requirement-or-flow>, título test(perf): add load coverage for <flow> y draft PR. dry_run=true es el default y devuelve el plan completo sin mutar GitHub. Con dry_run=false, Octokit crea la rama desde base, escribe cada archivo y abre el draft.

El body proporcionado debe documentar requisito, tipo/modelo, endpoints, carga, duración, ramp-up, dataset, thresholds, supuestos, riesgos, comandos, variables, impacto, ejecución y checklist de seguridad.

AIQUAA, CodeGraph y Engram

  • AIQUAA centraliza rutas para obtener requisitos y guardar planes, ejecuciones y vínculos de PR. El adapter es opcional y no registra contratos inventados más allá de esas rutas configurables.
  • CodeGraph puede construir contexto estructural sólo dentro de CODEGRAPH_ALLOWED_ROOTS; ejecute codegraph init -i en cada repositorio antes de usarlo.
  • Engram queda aislado mediante ENGRAM_PROJECT_PREFIX + projectId. Guardar únicamente thresholds, decisiones, ambientes y resultados curados; nunca credenciales o datasets sensibles.

Docker y CI

El Dockerfile construye TypeScript con Node 20 y ejecuta sobre Java 17 con JMeter 5.6.3. GitHub Actions valida lint, build, pruebas, cobertura mínima de 70%, paquete npm y build de imagen. La publicación npm se dispara desde releases, usa OIDC/trusted publishing y --provenance; no necesita un token npm persistente.

Evidencia de monitoreo (Python + Selenium)

perf_monitoreo automatiza, con Python + Selenium, lo que antes se armaba a mano: abrir un dashboard de monitoreo público (por ejemplo, Grafana) y capturarlo como evidencia dentro del informe PDF. Caso típico: un dashboard público de Grafana que muestra el estado de una base de datos durante la corrida (como el usado para mostrarles a los alumnos qué observar mientras corre una prueba de rendimiento).

Requiere Python 3 aparte del runtime Node del servidor:

pip install -r src/monitoring/python/requirements.txt

Selenium ≥4.6 resuelve el driver de Chrome por sí solo (Selenium Manager), sin webdriver-manager ni configuración manual; sólo hace falta tener Chrome/Chromium instalado. perf_monitoreo no ejecuta nada si el host del dashboard es privado/loopback, salvo que esté en PERF_MONITORING_ALLOWED_PRIVATE_HOSTS.

Flujo recomendado post-ejecución: perf_ejecutar → perf_resultados → (opcional) perf_monitoreo con la URL del dashboard → perf_informe pasando el resultado en monitoring_evidence. Un agente que orquesta este flujo debe preguntarle al usuario si necesita evidencia de monitoreo antes de invocar perf_monitoreo (así lo indica la descripción de la tool); si no la necesita, se salta directo a perf_informe.

El mismo adjunto se puede generar sin pasar por MCP con la CLI --report (ver más abajo), usando --evidence-image, --evidence-label, --evidence-url y --evidence-captured-at.

Ejemplo de flujo MCP

Analizá el repositorio y NFR-018. El requisito establece 150 usuarios concurrentes, P95 < 2 s y error rate < 0,5%. Revisá auth, JMX y baseline; no dupliques samplers. Planificá cambios, ampliá el plan, generá CSV ficticio, thresholds y diff. Después prepará el draft PR. No ejecutes la prueba.

Orden recomendado: perf_analizar → perf_requisitos → perf_escenario → perf_cobertura → perf_cambios → perf_generar → perf_validar → perf_pr.

Reutilización y diferencias respecto a las referencias

De aiquaa-labs/jmeter-skill se conservaron nombres P_, D_, R_, generación JMX/CSV, ejecución non-GUI, dashboard, CI, reparación y reporting. El cambio deliberado es que 1000×30 dejó de ser universal y pasó a aiquaa_stress con riesgo explícito. El diseño del informe PDF (perf_informe: portada, banda de estadísticas, percentiles, veredicto, comparación con línea base, detalle por sampler, top errores) reproduce el de reporter/jmeter_report.py de ese repo, mismo layout pero reimplementado en TypeScript con pdfkit para no requerir Python/pandas/reportlab en el servidor MCP.

De aiquaa-playwright-mcp-server se reutilizó el patrón de McpServer + Streamable HTTP sin estado, schemas Zod estrictos, adaptadores AIQUAA/CodeGraph/Engram, respuestas estructuradas y procesos sin shell. Performance agrega policy centralizada, análisis XML/JTL, comparabilidad y efectos externos bloqueados por defecto.

Limitaciones

  • El modelo abierto genera ArrivalsThreadGroup y requiere instalar JMeter Plugins Custom Thread Groups; perf_validar lo declara como dependencia antes de ejecutar.
  • El análisis estático local detecta señales, no capacidad real ni topología desplegada.
  • Los percentiles se calculan en memoria; aplique límites externos para JTL muy grandes.
  • perf_informe genera el PDF con pdfkit (sin dependencias de Python) a partir de lo que ya calcula perf_resultados/perf_comparar; el dashboard HTML de JMeter (-e -o) sigue siendo aparte, vía los pipelines de perf_pipeline.
  • La ampliación localizada usa nombres de sampler como clave de identidad; renombres manuales pueden requerir revisión.
  • perf_monitoreo requiere Python 3 + Selenium instalados por separado (src/monitoring/python/requirements.txt); no están incluidos en el Dockerfile de este servidor ni en las dependencias de npm, y sólo hacen falta si se usa esa tool.