lupa11y
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lupa11yaudit http://localhost:3000 for accessibility and suggest fixes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
LupA11y
Agentic Accessibility Auditing: Deterministic Precision meets Visual Intelligence.
Auditoría de accesibilidad que pulsa Tab. Recorre tu web con el teclado, mide el foco píxel a píxel y te da cada arreglo en código.
Pruébalo en directo en lupa11y.vercel.app →

El Acta Europea de Accesibilidad (Directiva (UE) 2019/882, Ley 11/2023 en España) se aplica desde el 28 de junio de 2025. LupA11y no certifica el cumplimiento: enseña la evidencia y los arreglos.
Qué detecta
Cuatro fases sobre un Chromium real. Primero se mide; el modelo solo entra donde ninguna regla puede decidir.
Fase | Qué comprueba | WCAG |
axe-core | Las reglas automáticas de WCAG dentro de Chromium (Playwright), con los mensajes en español. | 2.2 A y AA |
Zoom y espaciado | La página a 320 px de ancho (un zoom del 400 %) y con el espaciado de texto de WCAG. Mide qué bloques obligan a desplazarse en horizontal y qué textos quedan recortados. | 1.4.10, 1.4.12 |
Agente de teclado | Pulsa | 2.1.1, 2.1.2, 2.4.7, 2.4.11, 2.4.12, 2.4.13 |
Gemini Vision | Si el | 1.1.1, 2.4.7 |
Related MCP server: Navable MCP
Cada hallazgo, con su evidencia

Cada hallazgo dice de qué fase sale, qué criterio WCAG incumple y con qué severidad. Trae el selector, el fragmento de HTML, el recorte de la captura (la lupa lo señala sobre la página) y un diff de corrección listo para copiar. El informe se descarga en JSON o en SARIF y se copia en Markdown.
El agente no adivina si el foco se ve: lo mide. En la demo, los cuatro enlaces del menú cambian 0 píxeles al recibir el foco, cuando el primero necesitaba 236 px².
Cuatro formas de usarlo
Las cuatro llaman al mismo motor y devuelven el mismo contrato Zod.
En la web
Pega una URL pública en lupa11y.vercel.app. La captura y los hallazgos llegan fase a fase mientras se audita, en unos diez segundos.
En tu CI, con la GitHub Action
- uses: Adriiiii24/LupA11y@v0
with:
url: http://localhost:3000
fail-on: high
sarif-path: lupa11y.sarif
comment-pr: true # necesita permissions: pull-requests: write
gemini-api-key: ${{ secrets.GEMINI_API_KEY }}
- uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: lupa11y.sarif # necesita permissions: security-events: writeFalla el check por encima de la severidad que elijas. Deja el resumen con los diffs en el job, anotaciones, un comentario en la pull request y SARIF para la pestaña de seguridad. Admite varias URL, un sitemap con max-pages, una baseline para fallar solo por lo que es nuevo o empeora, y level. Cachea Chromium entre ejecuciones y solo instala Node si el del job no sirve.
En tu editor, con el servidor MCP
claude mcp add lupa11y -e GEMINI_API_KEY=tu_clave -- node /ruta/a/LupA11y/packages/mcp/src/server.tsLa herramienta audit_url acepta localhost y devuelve Markdown con los diffs y un resumen estructurado (structuredContent). Está pensada para el bucle «audita, aplica, vuelve a auditar»: mantiene Chromium arrancado entre llamadas y la segunda auditoría de la misma URL dice qué se arregló, qué es nuevo y qué sigue igual. Funciona en Claude Code, Cursor y cualquier cliente MCP por stdio.
En la terminal, con la CLI
node packages/cli/src/main.ts https://www.tu-tienda.es --fail-on high --out informe.json --summary resumen.mdOpción | Para qué |
| Una o varias páginas, o las de un sitemap (con |
| Solo falla por lo que es nuevo o empeora respecto a ese informe. Las fases que no corrieron en los dos no se comparan. |
| SARIF 2.1.0 para el escaneo de código de GitHub, con huellas estables entre ejecuciones. |
| Páginas tras el login. Las cabeceras solo viajan al origen auditado, nunca a terceros. |
| Omiten una fase. |
Códigos de salida: 0 sin hallazgos por encima del umbral, 1 con hallazgos y 2 si alguna auditoría falló.
Cómo funciona
flowchart LR
accTitle: Arquitectura de LupA11y
accDescr: Una URL se abre en Chromium, pasa por cuatro fases y sale como un informe con el contrato Zod, que consumen la web, la GitHub Action, el servidor MCP y la CLI.
url([URL]) --> chromium[Chromium con Playwright]
chromium --> axe[axe-core]
chromium --> layout[Zoom y espaciado]
chromium --> keyboard[Agente de teclado]
chromium --> vision[Gemini Vision]
axe & layout & keyboard & vision --> report[[Informe con contrato Zod]]
report --> web[Web] & action[GitHub Action] & mcp[Servidor MCP] & cli[CLI]Un motor, un contrato.
packages/corehace la auditoría y la valida con un esquema Zod; las cuatro salidas solo cambian cómo la presentan.En directo. La API emite la auditoría como NDJSON: la consola de la web pinta eventos reales, no una animación.
Comparable. Cada nodo tiene una huella estable, así que dos auditorías se comparan hallazgo a hallazgo (línea base en la CI y memoria en el MCP).
La arquitectura completa (el algoritmo del agente, la medición del foco, la política de red, la comparación y las pruebas) está en docs/ARCHITECTURE.md.
Seguridad
La API pública solo audita hosts públicos. Se comprueban la URL, cada petición del navegador, cada WebSocket y cada salto de redirección.
En modo público, Chromium no resuelve DNS: sale por un proxy local que resuelve cada host una vez, lo valida y se conecta a esa misma IP. Así no cabe un DNS rebinding. WebRTC solo puede salir por el proxy.
La cuota solo se fía de la IP que declare un proxy de confianza; además hay un presupuesto global por proceso.
Los errores internos no llegan al cliente público: se registran en el servidor y el usuario ve un mensaje genérico.
El agente de teclado trabaja en modo de solo lectura: no envía formularios ni navega.
El contenido de la página llega a Gemini como dato delimitado, y la respuesta solo puede ser el JSON del esquema.
Desarrollo
Requisitos: Node 24.11 o superior.
npm install
npx playwright install chromium
npm run dev # http://localhost:3000La fase de visión se activa con GEMINI_API_KEY en apps/web/.env.local. Sin ella, todo lo demás funciona y el informe marca la visión como omitida. Con una clave gratuita de Google AI Studio también funciona: el motor respeta sus límites por minuto, reintenta si el modelo está saturado y puede seguir con un modelo de reserva cuando el principal agota su cuota diaria (unas 20 consultas al día por modelo; cada auditoría hace hasta 14). Las demás variables (cuota, IP de confianza, enlaces permanentes) están explicadas en apps/web/.env.example.
Comando | Qué hace |
| Tests unitarios y de extremo a extremo del motor, la CLI, el MCP y la lógica de la web, con |
| La web de verdad (necesita |
|
|
| ESLint de la web |
| Build de producción de la web |
| La CLI |
| Regenera la auditoría de muestra de la landing a partir de |
| Compila los paquetes a JavaScript, los empaqueta y comprueba que se instalan y arrancan |
En Vercel (plan gratuito) basta con importar el repositorio: vercel.json declara un único servicio, la web de apps/web, instalada desde la raíz del monorepo. La landing se sirve estática y la API usa el Chromium de @sparticuz/chromium. Allí los enlaces permanentes quedan desactivados, porque el disco no persiste.
El Dockerfile construye la web con su Chromium para un contenedor de larga vida (Fly.io, Cloud Run, un VPS…), en modo public-only y con un volumen en /data para los enlaces permanentes.
npm run pack:packages deja en .pack/ los tres paquetes compilados (@lupa11y/core, @lupa11y/cli con el binario lupa11y, @lupa11y/mcp con lupa11y-mcp) y verifica que se instalan desde sus tarballs y arrancan. Publicarlos es npm publish .pack/<paquete>.
Los cambios de cada versión están en CHANGELOG.md. La Action se usa por su etiqueta mayor, @v0, que se mueve a cada versión 0.x:
git tag vX.Y.Z && git push origin vX.Y.Z
git tag -f v0 vX.Y.Z && git push -f origin v0packages/core motor + contrato Zod (schema.ts) + textos (format.ts) + comparación (compare.ts) + SARIF (sarif.ts)
packages/cli CLI y base de la GitHub Action
packages/mcp servidor MCP (stdio)
apps/web landing y visor en Next.js 16, API de streaming NDJSON, informes compartidos, demo rota a propósito
action.yml GitHub Action compuesta
scripts/ empaquetado para npm
docs/ ARCHITECTURE.md y las capturas de este READMEArquitectura · Producto · Cambios · Licencia MIT
Proyecto de portfolio de Adrián Martínez Panés.
This server cannot be deployed
Maintenance
Related MCP Connectors
Scan a web page for accessibility, security, privacy, quality and SEO issues, with fixes.
Scan URLs for WCAG 2.1 violations, generate AI fixes, and produce VPAT 2.5 compliance reports.
Scan a live web page for WCAG 2.1/2.2 AA issues with axe-core: score, grade, failing rules.
Scan URLs or HTML for WCAG 2.2 violations. 75-rule manifest, weighted score, shareable reports.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI agents to perform comprehensive accessibility audits on websites using Playwright and axe-core against WCAG standards. Provides detailed compliance reports with violation summaries and remediation guidance across multiple browsers.3-
- AlicenseAqualityDmaintenanceEnables AI coding agents to perform real-browser accessibility scanning of localhost pages using Playwright and axe-core, returning WCAG 2.1 violations with structured fix plans.365 npm1MIT
- AlicenseAqualityCmaintenanceEnables web accessibility audits using axe-core, allowing users to scan URLs, check WCAG compliance levels, and export reports. It uses an anti-detect browser to bypass Cloudflare and other bot protection.722 PyPIMIT
- AlicenseBqualityDmaintenanceAudits web pages for WCAG 2.2 AA accessibility aligned with the GOV.UK standard using axe-core and headless Chromium, returning structured JSON, markdown reports, and GDS compliance summaries.41MIT