Skip to main content
Glama

Tactual

Analizador de coste de navegación para lectores de pantalla. Mide lo difícil que es para los usuarios de tecnología asistiva descubrir, alcanzar y operar objetivos interactivos en la web.

Qué hace

Las herramientas de accesibilidad existentes comprueban la conformidad: ¿es correcto el ARIA? ¿Es suficiente la relación de contraste?

Tactual mide el coste de navegación: ¿cuántas acciones necesita un usuario de lector de pantalla para llegar al botón de pago? ¿Qué sucede si se pasan de largo? ¿Pueden siquiera descubrir que existe?

Funciona capturando instantáneas de accesibilidad de Playwright, construyendo un grafo de navegación y puntuando cada objetivo bajo un perfil de tecnología asistiva.

Instalación

# For CLI usage
npm install tactual playwright

# For MCP server usage (AI tools)
npm install tactual playwright @modelcontextprotocol/sdk

Playwright y @modelcontextprotocol/sdk son dependencias opcionales. Playwright es necesario para la CLI y el análisis de páginas. El SDK de MCP es necesario para ejecutar el servidor tactual-mcp. Ninguno es necesario si solo utilizas la API de la biblioteca con estados previamente capturados.

Inicio rápido

CLI

# Analyze a URL (default profile: generic-mobile-web-sr-v0)
tactual analyze-url https://example.com

# Analyze with a specific AT profile
tactual analyze-url https://example.com --profile voiceover-ios-v0

# Explore hidden UI (menus, tabs, dialogs, disclosures)
tactual analyze-url https://example.com --explore

# Output as JSON, Markdown, or SARIF
tactual analyze-url https://example.com --format json --output report.json
tactual analyze-url https://example.com --format sarif --output report.sarif

# Compare two analysis runs
tactual diff baseline.json candidate.json

# List available AT profiles
tactual profiles

# Run benchmark suite
tactual benchmark

# Initialize a tactual.json config file
tactual init

API de la biblioteca

import { analyze, getProfile } from "tactual";
import { captureState } from "tactual/playwright";
import { chromium } from "playwright";

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto("https://example.com");

const state = await captureState(page);
await browser.close();

const profile = getProfile("generic-mobile-web-sr-v0");
const result = analyze([state], profile);

for (const finding of result.findings) {
  console.log(finding.targetId, finding.scores.overall, finding.severity);
}

Servidor MCP

Tactual incluye un servidor MCP para el consumo por parte de agentes de IA:

# Start the MCP server (stdio transport — default)
tactual-mcp

# Start with HTTP transport (for hosted platforms, remote clients)
tactual-mcp --http              # listens on http://127.0.0.1:8787/mcp
tactual-mcp --http --port=3000  # custom port (or set PORT env var)
tactual-mcp --http --host=0.0.0.0  # bind to all interfaces (default: 127.0.0.1)

Herramientas MCP disponibles:

Herramienta

Descripción

analyze_url

Analiza una página web para determinar el coste de navegación con lector de pantalla. El formato predeterminado es sarif. Admite los parámetros waitForSelector, waitTime, minSeverity, focus, excludeSelector, exclude, maxFindings, summaryOnly, timeout, storageState. Los hallazgos incluyen selectores de localizador de Playwright. Pasa probe: true para pruebas de teclado. Pasa includeStates: true para obtener estados capturados para trace_path sin conexión.

trace_path

Rastrea la ruta de navegación paso a paso hasta un objetivo específico. Muestra cada acción, coste y anuncio de lector de pantalla modelado. Acepta ID de objetivo o patrón glob (p. ej., *search*). Pasa statesJson de un analyze_url previo para omitir el inicio del navegador. Admite storageState para páginas autenticadas.

list_profiles

Lista los perfiles de tecnología asistiva (AT) disponibles

diff_results

Compara dos resultados de análisis. Muestra penalizaciones resueltas/añadidas, cambios de gravedad y estado por objetivo.

suggest_remediations

Sugerencias de corrección clasificadas por impacto. Redundante para la salida SARIF (las correcciones están integradas).

save_auth

Autentícate con una aplicación web y guarda el estado de la sesión. Pasa la ruta del archivo de salida como storageState a otras herramientas para analizar contenido autenticado.

analyze_pages

Analiza varias páginas en una sola llamada con agregación a nivel de sitio. Devuelve ~200 bytes por página. Úsalo para el triaje del sitio antes de profundizar en páginas individuales.

Configuración mediante herramienta de IA

Primero instala los paquetes necesarios en tu proyecto:

npm install tactual playwright @modelcontextprotocol/sdk

Claude Code — añade a .mcp.json en la raíz de tu proyecto:

{
  "mcpServers": {
    "tactual": {
      "type": "stdio",
      "command": "npx",
      "args": ["tactual-mcp"]
    }
  }
}

GitHub Copilot — añade a .copilot/mcp.json o ~/.copilot/mcp-config.json:

{
  "mcpServers": {
    "tactual": {
      "type": "stdio",
      "command": "npx",
      "args": ["tactual-mcp"]
    }
  }
}

Cursor / Windsurf / Cline — mismo formato en la configuración MCP de tu editor:

{
  "mcpServers": {
    "tactual": {
      "command": "npx",
      "args": ["tactual-mcp"]
    }
  }
}

Directo (instalación global) — si prefieres no usar npx:

npm install -g tactual playwright
tactual-mcp  # starts the MCP server on stdio

GitHub Actions

Utiliza la acción compuesta del GitHub Actions Marketplace:

jobs:
  a11y:
    runs-on: ubuntu-latest
    steps:
      - name: Analyze accessibility
        uses: tactual-dev/tactual@v0.2.1
        with:
          url: https://your-app.com
          explore: "true"
          fail-below: "70"

La acción instala Tactual y Playwright, ejecuta el análisis, sube el SARIF a GitHub Code Scanning y hace fallar la compilación si la puntuación media está por debajo del umbral. Genera average-score y result-file para pasos posteriores.

O utiliza la CLI directamente para tener más control:

- name: Install Tactual
  run: npm install tactual playwright

- name: Install browsers
  run: npx playwright install chromium --with-deps

- name: Run accessibility analysis
  run: npx tactual analyze-url https://your-app.com --format sarif --output results.sarif --threshold 70

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Configuración

Flags de la CLI

Options:
  -p, --profile <id>              AT profile (default: generic-mobile-web-sr-v0)
  -f, --format <format>           json | markdown | console | sarif (default: console)
  -o, --output <path>             Write to file instead of stdout
  -d, --device <name>             Playwright device emulation
  -e, --explore                   Explore hidden branches
  --explore-depth <n>             Max exploration depth (default: 3)
  --explore-budget <n>            Max exploration actions (default: 50)
  --explore-max-targets <n>       Max accumulated targets before stopping (default: 2000)
  --exclude <patterns...>         Exclude targets by name/role glob
  --exclude-selector <css...>     Exclude elements by CSS selector
  --focus <landmarks...>          Only analyze within these landmarks
  --suppress <codes...>           Suppress diagnostic codes
  --top <n>                       Show only worst N findings
  --min-severity <level>          Minimum severity to report
  --threshold <n>                 Exit non-zero if avg score < N
  --config <path>                 Path to tactual.json
  --no-headless                   Headed browser (for bot-blocked sites)
  --timeout <ms>                  Page load timeout (default: 30000)
  --probe                         Run keyboard probes (focus, activation, Escape, Tab)
  --wait-for-selector <css>       Wait for selector before capturing (for SPAs)
  --wait-time <ms>                Additional wait after page load
  --storage-state <path>          Playwright storageState JSON for authenticated pages
  --summary-only                  Return only summary stats, no individual findings
  -q, --quiet                     Suppress info diagnostics

tactual.json

Créalo con tactual init o manualmente:

{
  "profile": "voiceover-ios-v0",
  "exclude": ["easter*", "admin*", "debug*"],
  "excludeSelectors": ["#easter-egg", ".admin-only", ".third-party-widget"],
  "focus": ["main"],
  "suppress": ["possible-cookie-wall"],
  "threshold": 70,
  "priority": {
    "checkout*": "critical",
    "footer*": "low",
    "analytics*": "ignore"
  }
}

La configuración se detecta automáticamente desde el directorio de trabajo (tactual.json o .tactualrc.json). Los flags de la CLI se fusionan y sobrescriben los ajustes de configuración.

Perfiles de tecnología asistiva (AT)

Perfil

Plataforma

Descripción

generic-mobile-web-sr-v0

Móvil

Primitivas de lector de pantalla móvil normalizadas (predeterminado)

voiceover-ios-v0

Móvil

VoiceOver en iOS Safari — navegación basada en rotor

talkback-android-v0

Móvil

TalkBack en Android Chrome — controles de lectura

nvda-desktop-v0

Escritorio

NVDA en Windows — teclas rápidas del modo exploración

jaws-desktop-v0

Escritorio

JAWS en Windows — cursor virtual con modo de formularios automático

Los perfiles definen el coste de cada acción de navegación, los pesos de las dimensiones de puntuación, costSensitivity (escala la curva de decaimiento de la alcanzabilidad) y modificadores dependientes del contexto. Consulta src/profiles/ para obtener detalles de implementación.

Puntuación

Cada objetivo recibe un vector de puntuación de 5 dimensiones:

Dimensión

Qué mide

Descubribilidad

¿Puede el usuario saber que el objetivo existe?

Alcanzabilidad

¿Cuál es el coste de navegación para llegar allí?

Operabilidad

¿El control se comporta de forma predecible?

Recuperación

¿Qué tan difícil es recuperarse de pasarse de largo?

Riesgo de interoperabilidad

¿Qué probabilidad hay de varianza en el soporte de AT/navegador? (penalización)

Los pesos de las dimensiones varían según el perfil:

Perfil

D

R

O

Rec

costSensitivity

generic-mobile-web-sr-v0

0.30

0.40

0.20

0.10

1.0

voiceover-ios-v0

0.30

0.35

0.20

0.15

1.1

talkback-android-v0

0.25

0.45

0.20

0.10

1.3

nvda-desktop-v0

0.35

0.25

0.30

0.10

0.7

jaws-desktop-v0

0.30

0.25

0.35

0.10

0.6

Compuesto: Media geométrica ponderada: overall = exp(sum(w_i * ln(score_i)) / sum(w_i)) - interopRisk. Cada dimensión se establece en un mínimo de 1 antes del logaritmo para evitar log(0). Esto significa que un cero en cualquier dimensión reduce drásticamente la puntuación general: no puedes operar lo que no puedes alcanzar.

Bandas de gravedad:

Puntuación

Banda

Significado

90-100

Fuerte

Poca preocupación

75-89

Aceptable

Mejorable

60-74

Moderado

Debe ser triado

40-59

Alto

Probable fricción significativa

0-39

Severo

Probable bloqueo

Diagnóstico

Tactual detecta e informa cuando el análisis puede no ser fiable:

Código

Nivel

Significado

blocked-by-bot-protection

error

Desafío de Cloudflare/bot detectado

empty-page

error

No se encontraron objetivos en absoluto

possibly-degraded-content

advertencia

Sospechosamente pocos objetivos para una página http

sparse-content

advertencia

Solo se encontraron 1-4 objetivos

possible-login-wall

advertencia

Contenido protegido por autenticación (detecta redirecciones de ruta /login, /signin, /auth)

possible-cookie-wall

info

El consentimiento de cookies puede ocultar contenido

redirect-detected

advertencia

Aterrizó en un dominio diferente

no-headings

advertencia

No se encontraron elementos de encabezado

no-landmarks

advertencia

No se encontraron regiones de puntos de referencia

Exploración

El flag --explore activa la exploración de ramas acotada:

  • Abre menús, pestañas, divulgaciones, acordeones y diálogos

  • Captura nuevos estados de accesibilidad de la interfaz de usuario oculta

  • Marca los objetivos descubiertos como requiresBranchOpen

  • Respeta los presupuestos de profundidad, recuento de acciones, recuento de objetivos y novedad

  • La política de acciones seguras bloquea las interacciones destructivas

La exploración es útil para páginas con una interfaz de usuario oculta significativa (p. ej., menús desplegables, interfaces con pestañas, diálogos modales).

Los candidatos a exploración se ordenan por una clave estable (rol + nombre) antes de iterar, por lo que el mismo contenido de página produce el mismo orden de exploración en todas las ejecuciones.

Presupuestos de exploración

Presupuesto

Flag de CLI

Predeterminado

Propósito

Profundidad

--explore-depth

3

Profundidad máxima de recursión

Acciones

--explore-budget

50

Presupuesto total de clics en todas las ramas

Objetivos

--explore-max-targets

2000

Detener si los objetivos acumulados superan esto

Tiempo

(solo biblioteca)

120s

Tiempo de espera global

Detección de framework SPA

Tactual detecta cuando el contenido SPA se ha renderizado antes de capturar el árbol de accesibilidad. Frameworks detectados: React, Next.js, Vue, Nuxt, Angular, Svelte y SvelteKit. También se comprueban las señales de contenido HTML5 genérico (puntos de referencia, encabezados, navegación, enlaces). Para SPAs no cubiertos por la detección automática, utiliza --wait-for-selector (CLI) o waitForSelector (MCP/API) para especificar un selector CSS que indique que tu aplicación se ha hidratado.

Después de la detección inicial del framework, Tactual utiliza el sondeo basado en convergencia —tomando instantáneas repetidamente del árbol de accesibilidad hasta que el recuento de objetivos se estabiliza—, lo que funciona independientemente del framework.

Riesgo de interoperabilidad

Tactual incluye una instantánea estática de datos de soporte de roles/atributos ARIA derivados de a11ysupport.io y el proyecto ARIA-AT. Los roles con brechas de soporte conocidas entre AT/navegador reciben una penalización por riesgo de interoperabilidad.

Rol

Riesgo

Nota

button, link, heading

0

Bien soportado

dialog

5

La gestión del foco varía

combobox

8

Patrón más problemático para la interoperabilidad

tree

10

Mal soportado fuera de JAWS

application

15

Peligroso si se usa mal

Recomendaciones de formato de salida

Formato

Tamaño típico

Mejor para

console

~8KB

Revisión humana en terminal

markdown

~11KB

PRs y comentarios de problemas

json

~18KB

Consumo programático

sarif

~4-40KB

GitHub Code Scanning / CI

Todos los formatos que no son SARIF emiten una salida resumida: estadísticas, problemas agrupados y peores hallazgos (limitado a 15). SARIF limita a 25 resultados. Cuando la salida se trunca, aparece una nota en la parte superior.

Para el uso de MCP, sarif es el formato predeterminado y recomendado. Usa summaryOnly: true para una comprobación de salud mínima (~835 bytes: estadísticas, recuentos de gravedad, 3 problemas principales).

Calibración

Tactual incluye un framework de calibración (src/calibration/, exportado como tactual/calibration) para ajustar los parámetros de puntuación frente a conjuntos de datos de verdad fundamental. Consulta docs/CALIBRATION.md para obtener más detalles.

Desarrollo

npm install                    # Install dependencies
npm run build                  # Build with tsup
npm run test                   # Run unit + integration tests
npm run test:benchmark         # Run benchmark suite
npm run typecheck              # TypeScript type checking
npm run lint                   # ESLint

Seguridad

Sandboxing del navegador

Tactual siempre ejecuta Playwright con el sandboxing de Chromium predeterminado habilitado. Nunca desactiva la seguridad web ni modifica el modelo de seguridad del navegador. Todas las interacciones de página ocurren dentro del sandbox del proceso estándar de Chromium.

Política de acciones seguras

Cuando la exploración está habilitada (--explore), Tactual clasifica los elementos interactivos en tres niveles antes de activarlos:

Nivel

Acción

Ejemplos

Seguro

Activado

Pestañas, elementos de menú, divulgaciones, acordeones, anclas de la misma página

Precaución

Activado con cuidado

Enlaces externos, botones ambiguos, botones de envío

Inseguro

Omitido

Eliminar, cerrar sesión, comprar, desplegar, cancelar suscripción

Esta es una heurística basada en palabras clave: no puede detectar el engaño semántico (p. ej., un botón "Guardar" que en realidad elimina datos) ni inspeccionar el comportamiento del lado del servidor. Para uso en producción, ejecuta siempre la exploración en entornos de confianza o aislados (sandboxed).

Validación de URL

Todas las URL se validan antes de la navegación. Los rangos de IP privados/internos y los esquemas que no son HTTP(S) se rechazan de forma predeterminada.

Licencia

Apache-2.0

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tactual-dev/tactual'

If you have feedback or need assistance with the MCP directory API, please join our Discord server