Skip to main content
2026-04-304 min readnavable Team
MCP ServerPa11yHTMLCSWCAG 2.1Accessibility TestingDual-Engineaxe-coreAI Developer ToolsOpen SourceBFSG

navable MCP v0.2: Dual-Engine Scanning with Pa11y and HTMLCS

One scan engine is good. Two engines confirming the same issue? That's confidence you can put in a compliance report.


What's New in v0.2

Version 0.2 of @navable/mcp introduces Pa11y/HTMLCS as an optional second accessibility scan engine alongside axe-core. When enabled, both engines run in parallel against the same page, and their findings are deduplicated server-side before reaching your AI agent.

The result: higher-confidence audits, cross-confirmed findings, and broader WCAG coverage — without doubling token cost or scan time.

Why Two Engines?

No single accessibility testing engine catches everything. axe-core and HTMLCS (the engine behind Pa11y) have different rule sets, different detection strategies, and different blind spots. When both engines flag the same element for the same WCAG success criterion, that's a cross-confirmed finding — high confidence that it's a real barrier, not a false positive. This matters for compliance sign-off where auditors expect evidence.

How It Works

Enable Pa11y

Per scan — pass engines to the tool call:

run_accessibility_scan({ url: "http://localhost:3000", engines: ["axe", "htmlcs"] })

Always on — add to .navable.json in your project root:

{
  "engines": ["axe", "htmlcs"]
}

By default, only axe-core runs. Pa11y is opt-in — you choose when to use it.

No Extra Downloads

Pa11y shares the same Chromium binary that Playwright already installed for axe-core scanning. There's no second browser download. The pa11y and puppeteer-core packages are bundled with @navable/mcp — just update to v0.2 and you're ready.

Server-Side Deduplication

When both engines run, the MCP server uses a conservative dedup strategy:

  1. Same WCAG success criterion + identical normalized CSS selector + matching HTML snippetmerged into one entry (axe version kept, tagged alsoFlaggedBy: ["htmlcs"])
  2. Ambiguous overlap → both entries kept as separate findings

This means you never lose a legitimate finding due to aggressive merging. The safety bias is: wrong merges are far worse than missed merges.

What Results Look Like

{
  "ruleId": "image-alt",
  "impact": "critical",
  "source": "axe",
  "alsoFlaggedBy": ["htmlcs"],
  "wcagCriteria": [{ "sc": "1.1.1", "en301549": "9.1.1.1" }],
  "selector": "img.hero-banner",
  "html": "<img class=\"hero-banner\" src=\"/hero.jpg\">"
}

Findings unique to HTMLCS include a helpUrl (link to the WCAG Understanding document) and a developerNote (one-sentence guidance for your agent):

{
  "ruleId": "WCAG2AA.Principle1.Guideline1_3.1_3_1.H49.AlignAttr",
  "impact": "moderate",
  "source": "htmlcs",
  "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",
  "developerNote": "Use semantic HTML to convey structure: headings for sections, <table> with <th> for data...",
  "wcagCriteria": [{ "sc": "1.3.1", "en301549": "9.1.3.1" }]
}

When to Use Each Mode

ScenarioRecommended enginesWhy
Iterative fix loops (scan → fix → re-scan)["axe"] (default)Fast (~3 s), low token cost, tight feedback loop
Compliance audit / BFSG sign-off["axe", "htmlcs"]Cross-confirms findings, broader coverage, audit-grade confidence
User asks for "thorough" or "full" scan["axe", "htmlcs"]Maximum detection coverage
CI pipeline quick-check["axe"]Speed matters, minimal output

The audit-page-structure agent skill enables dual-engine automatically. The scan-accessibility skill (used for fix workflows) keeps the axe-only default for faster iteration.

Controlling Token Cost with htmlcsIgnore

HTMLCS emits advisory "Check that…" warnings meant for human auditors. These inflate token cost without giving your agent actionable work. Suppress them in .navable.json:

{
  "engines": ["axe", "htmlcs"],
  "htmlcsIgnore": [
    "WCAG2AA.Principle1.Guideline1_3.1_3_1.H49.AlignAttr",
    "WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.1",
    "WCAG2AA.Principle1.Guideline1_3.1_3_1.H42.2"
  ]
}

Look for HTMLCS entries whose help text starts with "Check that…" in your scan output — those are candidates for suppression.

Upgrade

npm install @navable/mcp@latest

Or if you're using npx:

{
  "mcpServers": {
    "navable": {
      "command": "npx",
      "args": ["-y", "@navable/mcp@latest"]
    }
  }
}

No breaking changes. Existing workflows that don't pass engines continue to run axe-only — same behavior as before.

Updated Agent Skills

The navable agent skills are updated for v0.2:

  • scan-accessibility — now documents the engines parameter with guidance on when to use axe-only vs dual-engine. Remains axe-only by default for fast fix loops.
  • audit-page-structure — automatically enables ["axe", "htmlcs"] for structural audits where cross-confirmation adds value.
  • Both skills handle the new result fields (source, alsoFlaggedBy, helpUrl, developerNote) so your agent knows how to act on HTMLCS-only findings.

If you've already copied the skills into your project, pull the latest versions from the repository to get the updated descriptions and dual-engine handling.

What's Next

  • HTMLCS advisory filter presets — community-curated htmlcsIgnore lists for common frameworks
  • Per-engine timing in metadata — see exactly how long each engine took
  • Configurable dedup strictness — loosen or tighten the merge strategy for your use case