The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the A11Y Toolkit listing page.
16 MCP tools + 5 prompts + a skill that give any AI agent (Claude, Cursor, Windsurf, Codex…) the full WCAG 2.2 loop: audit → fix → document → watch. Zero dependencies at its core; every finding ships with a concrete remediation your agent can apply.
Accessibility is not optional anymore: the European Accessibility Act is in force since June 2025, ADA suits keep landing, and AI agents now write most of the web. This toolkit makes "is it accessible?" a one-question ask — and "then fix it" a one-command job.
| Capability | axe-core / Lighthouse / pa11y | a11y-toolkit |
|---|---|---|
| Text contrast over images/gradients (pixel sampling of the real background, hostile-zone grid) | ✗ | ✓ |
| Legal accessibility statements (EAA / RD 1112/2018), accessible HTML, es/en | ✗ | ✓ |
| Regression watch between builds: accessible names + real tab-order diff | ✗ | ✓ |
| Remediation text per finding, written for an agent to apply | ✗ | ✓ |
| Focus-order regression detection | ✗ | ✓ |
| Runs with zero dependencies (stdlib only; Playwright optional for the deep pass) | heavy runtimes | ✓ |
| Screen-reader aria-live announcement monitor | ✗ | ✓ |
| 0-100 score computed from weighted findings | ✓ (Lighthouse, subset of rules) | ✓ (fuller rule set) |
| Criterion explanations on demand for agents | ✗ | ✓ |
| Static core parity: ARIA validity, autocomplete 1.3.5, link purpose, list structure, duplicate ids | ✓ | ✓ |
| Output optimized for MCP/LLM consumption (JSON, severity-ranked, es/en) | ✗ | ✓ |
| Tool | What it does |
|---|---|
a11y_audit_url | Express static WCAG audit of a URL or raw HTML: 20+ signals with a weighted 0-100 score (alt, accessible names, labels, autocomplete 1.3.5, keyboard onclick, unknown ARIA roles, broken aria-labelledby, unnamed duplicated landmarks, meta refresh, skip mechanism, lang validity, title, headings, blocked zoom, captions, autoplay audio, generic/duplicated link text, target=_blank warnings, tabindex>0, aria-hidden-on-focusable, tables, duplicate ids, accesskeys). Per-finding remediation. |
a11y_audit_dom | Rendered audit (local Playwright/Chromium): real computed text contrast vs effective backgrounds with alpha compositing (1.4.3), minimum target size 24×24 (2.5.8 — new in WCAG 2.2), focus-indicator heuristic (2.4.7), :focus/:hover state contrast, open shadow DOM traversed — all static checks on the live DOM. |
a11y_contrast_pair | Exact ratio + verdicts 1.4.3/1.4.6/1.4.11. Accepts #hex, rgb(), hsl(), CSS color names; alpha composites over the background. Suggests the nearest passing color. |
a11y_contrast_image | Text over images: pixel-level sampling of the actual background → worst/median/p95 ratio, % area passing AA, hostile-zone detection on a 3×3 grid. |
| (rendered audit) | adds :focus/:hover state contrast (disabled exempt) and same-origin iframes |
a11y_suggest_color | Nearest opaque color (true RGB distance) reaching the target ratio (4.5 default). |
a11y_generate_declaration | Legal accessibility statement in HTML: RD 1112/2018 art. 10 (Spanish public sector) or European Accessibility Act wording (Directive (EU) 2019/882 / Ley 11/2023). es/en. The document is itself accessible. |
a11y_snapshot | Interactive elements (tag, role, accessible name, href) + real tab focus order + the computed accessibility tree (what a screen reader announces). Requires Playwright. |
a11y_diff | Regression diff between two snapshots: added/removed/renamed interactives, focus-order changes. |
a11y_diff_urls | Snapshot two URLs and diff in one call (staging vs production). |
a11y_aria_live_snippet | Injectable monitor logging every aria-live announcement (time, politeness, role, text) — what a screen reader would say, visible on screen. |
a11y_criterion | Explains any WCAG 2.2 criterion in plain language: what it requires, typical failures, and which toolkit tool verifies it. |
a11y_scroll | Infinite-scroll audit — the documented disaster nobody automates (Deque + APG Feed pattern): real scrolling batches, does focus SURVIVE, is new content ANNOUNCED, does the feed END or offer load-more. |
a11y_keyboard | Keyboard-trap detection (2.1.2) with REAL Tab walking: up to 60 stops, cycle detection, and the decisive test — does Escape release? Correct modals are not reported. |
a11y_autofix | Deterministic safe auto-fixes on HTML: unblock zoom (1.4.4), exact autocomplete tokens (1.3.5), missing lang, empty title. Everything requiring judgment is returned as no_aplicados with the reason — the honest anti-overlay. |
a11y_reflow | Reflow at 320px (1.4.10) — the check axe and Lighthouse don't automate: real horizontal scroll + overflowing elements at 320px viewport. |
a11y_badge | Returns an honest badge as accessible SVG: score, date, scope ("automated screening"), never "conformant" — the anti-overclaim seal. |
5 prompts (slash-commands in supporting clients): audit-page (full audit workflow +
what automation can't check), fix-contrast, pre-deploy-check (audit + diff → GO/NO-GO),
declaration-eaa (collects legal fields, generates), conformance-wcagem (the three-tier
WCAG-EM ladder).
Registry name:
mcp-name: io.github.kinti/a11y-toolkit· PyPI: a11y-toolkit
Claude Code (one command):
Any MCP client with JSON config (Claude Desktop, Cursor, Windsurf, VS Code…):
Or from the repo without publishing:
The rendered audit, snapshots and diffs use Playwright if present
(pip install playwright && playwright install chromium); everything else works with
zero dependencies.
Run from a clone with python3 a11y.py <subcommand>; from PyPI with uvx --from a11y-toolkit a11ytoolkit ….
examples/a11y-watch.yml turns this into a weekly scheduled check that fails
on regressions and publishes the SARIF to code scanning.
Before shipping the current rule set we benchmarked against axe-core 4.10 on real
pages (methodology and results) — same Chromium, same Playwright.
That pass caught a real WCAG failure on gov.uk that axe does not report (blue
button text at 3.91:1, manually verified) and drove out five of our own false
positives (hidden skip links reported as tiny targets, honeypot fields, non-tabbable
aria-hidden controls, single-context generic links). Every divergence has a
regression fixture.
Automation covers ~1/3 of WCAG — every audit says so. The audit-page prompt and the
bundled skill then have the agent check what it can (keyboard operability, focus
visibility, zoom reflow, announced errors) using
the manual checklist, and
recommend a screen-reader pass for the rest. A filter, not a verdict.
A local tool: runs on your machine as your user. path (image) and output_path
(statement) read/write local paths — use it in MCP clients you trust. Nothing leaves your
machine except the URL you explicitly audit.
test_dom.py self-skips without Playwright. Releases: tag vX.Y.Z → CI publishes to PyPI
(trusted publishing); server.json is the official MCP Registry manifest. Listed on
Smithery too. Contributions welcome — see
CONTRIBUTING.md (the golden rules: zero dependencies at the core,
es/en strings everywhere, honest scope notes).
a11ytoolkit sarif)a11y_badge)a11ytoolkit budget + examples/a11y-watch.yml)pages parameter)conformance-wcagem prompt + guided protocol)Jesús Quintana Fernández (jquin.net) — SEO/GEO consultant and web-accessibility practitioner since 2003. MIT © 2026.