a11y-toolkit
a11y-toolkit is an MCP server that gives AI coding agents a full WCAG 2.2 accessibility toolkit — audit, fix, document, watch for regressions, test non-visually, and hand off verifiable evidence for human sign-off.
Audit websites or raw HTML statically and rendered pages via Playwright, with scored findings and concrete remediation.
Check contrast for color pairs, text over images, and live DOM elements; suggest nearest passing colors.
Run specialized tests for forms, keyboard traps, infinite scroll, 320px reflow, tooltip dismissibility, reduced motion, forced colors, screen-reader transcripts, and WebVTT caption quality.
Screen local PDFs and DOCX files for accessibility issues and validate HTML with W3C Nu.
Detect regressions by snapshotting pages and diffing before/after deploys or staging vs production.
Generate accessibility statements (EAA/RD 1112), VPAT 2.5 drafts, honest SVG badges, evidence packs, and WCAG criterion explanations.
Apply deterministic safe auto-fixes, re-verify findings to reject false positives, maintain a coverage ledger, and preview WCAG 3 draft groupings.
Support blindfold usability testing: an agent attempts real user journeys using only the accessibility tree and gets a scored journey verdict.
Provide 6 prompts/skill workflows for audits, contrast fixes, pre-deploy checks, EAA declarations, WCAG-EM evaluation, and blindfold testing.
Support behind-login auditing via Playwright auth state and multiple browser engines.
Generates SARIF reports for GitHub code scanning and supports accessibility regression workflows surfaced through GitHub pull requests.
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., "@a11y-toolkitcheck contrast for #1f2328 on #fbfaf7"
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.
a11y-toolkit — the accessibility layer for AI coding agents
32 MCP tools, 6 prompts and a skill covering the whole WCAG 2.2 loop: audit, fix, document, watch, hand off — and now blindfold usability testing, where the agent attempts real tasks perceiving only what a screen reader exposes. 51 of 55 A/AA criteria carry automated signals (93%), every finding ships with a concrete remediation your agent can apply, and the rendered tools run on whichever browser you have — Chromium, Firefox, WebKit, Chrome or Edge.
The European Accessibility Act is in force since June 2025, ADA suits keep landing, and AI agents now write most of the web. A scan is not a defence: the machine finds, the human signs.
This engine is in production at a11y.es — continuous WCAG 2.2 monitoring with hash-verifiable evidence packs and human-signed reports. En español. The service layer —panel, scheduling, the signing workflow, client operations— is NOT in this repository: cloning this engine is not cloning a11y.es.
What no other a11y tool gives an agent
Capability | axe-core / Lighthouse / pa11y | a11y-toolkit |
Text contrast over images and gradients (pixel sampling of the real background) | ✗ | ✓ |
VPAT 2.5 (WCAG) draft from the evidence pack — US/ADA counterpart of the EAA statement | ✗ | ✓ |
Form error testing: fills invalid data, really submits, judges what happens | ✗ | ✓ |
Keyboard traps: real Tab walk + Escape-release test, plus focus/input-triggered navigation | ✗ | ✓ |
Infinite-scroll audit: focus survival, announcements, feed end | ✗ | ✓ |
Reflow at 320px and the WCAG text-spacing override, measured | ✗ | ✓ |
Screen reader transcript: what a blind user hears, linearized | ✗ | ✓ |
Tooltips that ignore Escape caught by actually hovering (1.4.13) | ✗ | ✓ |
Legal statements for the EAA / RD 1112/2018, in Spanish and English | ✗ | ✓ |
An evidence pack a human can sign — hashes, matrix, empty signature block | ✗ | ✓ |
Runs with zero dependencies at core, speaks es/en, any browser you have | heavy runtimes | ✓ |
Related MCP server: Accessibility MCP Server
The tools (32)
Every tool, complete — description, arguments, and behavior annotations, generated from the server itself (server.TOOLS is the source of truth). All tools accept lang (en|es) unless noted; output is JSON unless noted.
Audit
a11y_audit_url
read-only · network
Express WCAG 2.2 audit of a URL or an HTML string: 20+ automated signals with a weighted 0-100 score — images without alt (1.1.1), controls without accessible names (4.1.2), form fields without labels (3.3.2), missing autocomplete on user-data fields (1.3.5), click handlers on non-interactive elements (2.1.1), unknown ARIA roles and broken aria-labelledby (4.1.2), duplicated unnamed landmarks, timed meta refresh (2.2.1), missing skip mechanism (2.4.1), lang/title (3.1.1, 2.4.2), heading structure (1.3.1), blocked zoom (1.4.4), captions (1.2.2), autoplay audio (1.4.2), generic/duplicated link text (2.4.4), target=_blank without warning (3.2.5), positive tabindex (2.4.3), aria-hidden on focusable elements, tables without th, duplicate ids, duplicate accesskeys. Each finding includes concrete remediation. Filter, not verdict: automation covers ~1/3 of WCAG; query a11y_criterion for what a criterion means. — Prefer a11y_audit_dom when JS renders the content or contrast/2.5.8/focus matter; use pages for light multi-page sampling. Returns JSON: {mode, url|file, score 0-100, findings [{criterion, severity, signal, issue, remediation}], summary {high, medium, low}, limits, score_note}.
Arguments
url: URL to fetch and audit.html: raw HTML to audit directly (overrides url).pages— range 1…20: light same-domain crawl: audit up to N pages, aggregated by score and recurring signals (default 1, max 20).lang— one of ['es', 'en']: output language (en default).timeout: fetch timeout seconds (30 default).
a11y_audit_dom
read-only · network
Deep RENDERED WCAG audit via local Playwright/Chromium: real computed text contrast against effective backgrounds with alpha compositing (1.4.3), pixel-sampled measurement of text sitting over images/gradients (background captured with the text transparent — no text pixels, no antialiasing bias), minimum target size 24×24 (2.5.8, new in WCAG 2.2), visible focus indicator heuristic (2.4.7), plus rendered versions of the static checks (alt, accessible names, labels, headings, lang/title, tabindex, aria-hidden, captions, tables). Findings include remediation. Requires playwright: pip install playwright && playwright install chromium. — Use instead of a11y_audit_url on JS-heavy pages; needs local Playwright. Returns JSON: {mode, url, score 0-100, findings [{criterion, severity, signal, issue, remediation}], summary, score_note} — same shape as the static audit.
Arguments
url(required): Page URL to load in Chromium (http/https or file:// for local fixtures).lang— one of ['es', 'en']: Output language for findings and remediation (default en).timeout: page load timeout seconds (45 default).auth_state: Path to a Playwright storage_state JSON (exported session) to audit behind login — local file, never uploaded.
a11y_forms
mutates state · not idempotent · network
Form error testing (3.3.1 Error Identification, 3.3.3 Error Suggestion) — the guided flow no competitor automates: fills every validatable field with INVALID data, really submits, and judges the post-submit DOM — are errors identified in text and associated with the field (aria-invalid + aria-describedby, error summary, role=alert), or does the form swallow them? Native browser validation counts as identification (unless the form has novalidate); forms that navigate on submit are honestly noted as not measurable in-page. Requires local Playwright. Returns JSON: per-field error judgments {field, submitted_value_class, error_identified, announced, suggestion_present} plus an overall 3.3.1/3.3.3 verdict. Use on test/staging forms, or forms you own: invalid data is REALLY submitted. Do not run against production forms that trigger real emails, orders or leads.
Arguments
url(required): Page URL with the form(s) to test.lang— one of ['es', 'en']: Output language (en default).timeout: Page load timeout seconds (45 default).auth_state: Path to a Playwright storage_state JSON to test forms behind login.
a11y_keyboard
read-only · network
Keyboard-trap detection (2.1.2) with REAL Tab walking in Chromium: up to 60 real tab stops, cycle detection (the modal pattern), then the decisive test — does ESCAPE release the cycle? A modal that cycles and releases on Escape is correct and NOT reported; a cycle Escape cannot leave is a trap (high severity). Returns the full tab stop list too. Requires local Playwright. — Scope: keyboard traps (2.1.2); focus visibility is part of a11y_audit_dom. Returns JSON: {tab_stops, trap_detected, escape_releases, findings}. Run on pages with modals, dialogs or embedded apps; a plain content page has nothing to trap.
Arguments
url(required): Page URL to Tab-walk (http/https or file://).lang— one of ['es', 'en']: Output language (default en).max_steps: max real Tab presses (60 default).auth_state: Path to a Playwright storage_state JSON (exported session) to Tab-walk behind login.
a11y_scroll
read-only · network
Infinite-scroll accessibility audit — the documented disaster nobody automates (Deque guidance + ARIA APG Feed pattern; criteria 2.4.3, 4.1.3, 2.2.2). Real scrolling batches in Chromium with a live-region observer: does the focused element SURVIVE each batch (re-render destroys it — the documented failure)? Is new content ANNOUNCED (aria-live/status receives text, role=feed)? Does the feed END or offer a load-more alternative (footer reachability)? APG feed pattern as positive signal. Honest guard: if no standard items are detected (login walls, non-standard markup) the unfounded signals are skipped with a note. Requires local Playwright. — For paginated feeds only; general page audit is a11y_audit_url/dom. Returns JSON: {mode, url, score, findings [{criterion, severity, signal, issue, remediation}], summary} — same shape as the audits.
Arguments
url(required): Feed URL to audit (best on feeds you own or can authenticate into).lang— one of ['es', 'en']: Output language (default en).max_batches: scroll batches (5 default).auth_state: Path to a Playwright storage_state JSON (exported session) to audit an authenticated feed.
a11y_reflow
read-only · network
Reflow check at 320px — criterion 1.4.10 (AA), the check axe and Lighthouse do not automate. Loads the URL at 1280px, then at 320px, and reports real horizontal scroll + the overflowing elements. Method note: browser zoom RE-LAYS OUT at 320 CSS px (that is the standard's own equivalence: 1280 @ 400% zoom = 320px), so the correct measurement is a 320px viewport. Requires local Playwright. — Scope: 320px reflow only (1.4.10); for the full rendered pass use a11y_audit_dom. Returns JSON: {url, viewport, horizontal_scroll, offenders [{selector, width}]}. Run once per template, not per page: fixed-width layouts are a property of the template.
Arguments
url(required): Page URL to test at 320px (http/https or file://).lang— one of ['es', 'en']: Output language (default en).timeout: Page load timeout in seconds (default 45).auth_state: Path to a Playwright storage_state JSON (exported session) to test behind login.
a11y_hover
read-only · network
Content on Hover or Focus (1.4.13): finds tooltip/overlay candidates, hovers each, and tests whether Escape dismisses the result — tooltips that do not dismiss are flagged. Requires local Playwright. — Scope: tooltips only; full audit is a11y_audit_dom, keyboard traps are a11y_keyboard. Returns JSON: {candidates, dismissed_on_escape, findings}.
Arguments
url(required): Page URL to test.lang— one of ['es', 'en']: Output language (en default).timeout: Page load timeout (45 default).
a11y_sr_transcript
read-only · network
Screen reader TRANSCRIPT: what a blind user HEARS on this page. Walks the accessibility tree linearly and returns the announcement text with roles, names and states — the linearized reading experience, as prose an agent can READ to understand the page from a blind user's perspective. — Read-only: for structure use a11y_snapshot, for keyboard traps use a11y_keyboard. Requires Playwright. Returns JSON: {url, total, announcements [{time, politeness, role, text}] — the linearized reading order}.
Arguments
url(required): Page URL to transcribe.lang— one of ['es', 'en']: Output language (en default).timeout: Page load timeout (45 default).
a11y_html_validate
read-only · network
The W3C's own parser as a toolkit mode: checks a URL or raw HTML against the Nu Html Checker (validator.w3.org/nu) — doctype, encoding, structural validity, plus alt/lang/role issues from the authoritative source, mapped to WCAG criteria where they overlap. PRIVACY: html mode POSTs the document to the W3C service (url mode shares only the URL, like a11y_audit_url); self-hosted vnu instances supported via base_url for sensitive content. Returns JSON: Nu validator messages mapped to WCAG criteria where they overlap.
Arguments
url: Page URL to validate (shares the URL with the W3C service).html: Raw HTML to validate — POSTs the content to validator.w3.org/nu; use url or a self-hosted instance for sensitive pages.base_url: Base URL of a self-hosted vnu instance (docker ghcr.io/validator/validator) instead of the public W3C service.lang— one of ['es', 'en']: Output language (en default).
Blindfold testing
a11y_journey_verdict
read-only
Blindfold journey verdict — the capability no other accessibility tool has: the agent attempted a REAL task (sign up, checkout, password reset) perceiving only the accessibility tree and acting by accessible name and keyboard; perceive via your browser accessibility snapshot (state-preserving). This turns its friction log into a deterministic scored verdict. Pass = task completable non-visually by the agent; friction items map to WCAG criteria and flow into the evidence pack (report:journey). Use with the blindfold-task prompt: act by accessible name, log friction per step, then call this. Task usability evidence, never conformance. Returns JSON: {verdict pass|partial|fail|blocked, score 0-100, findings [{criterion, severity, signal, issue, remediation, step}], summary, rules} — writes a file only when output_path is given. Run only after a real blindfold attempt (the blindfold-task prompt): the verdict prices the walk, it does not replace it.
Arguments
task(required): {"goal": what the agent attempted, "kind": sign-up|checkout|password-reset|search|custom}.steps(required): journey steps: {action, target (accessible name), perceived, friction?} — friction is {pattern: journey_* key} or {criterion, severity, issue, remediation?}.outcome(required): {"completed": bool, "gave_up": bool, "workaround_used": bool, "notes"}.url: page(s) where the journey ran.lang— one of ['en', 'es']: output language.output_path: write the full verdict JSON here instead of returning it inline.
Fix & contrast
a11y_autofix
read-only
DETERMINISTIC safe auto-fixes applied to HTML — the honest anti-overlay: a short closed list of fixes where the correct answer is unique (unblock viewport zoom 1.4.4, add the exact autocomplete token 1.3.5, fill missing html lang and empty title when provided). Everything requiring judgment (alt text, contrast, accessible names) is NOT touched — it returns not_applied with the reason and remediation instead. Returns fixed_html + applied + not_applied. — Only the closed allowlist of provably safe fixes; judgment fixes come back as not_applied with remediation. Returns JSON: {fixed_html, applied [{fix, …}], not_applied [{issue, remediation}]} — writes a file only when output_path is given.
Arguments
html(required): raw HTML to fix.lang: only if provided and lacks lang.title: only if provided and is empty.
a11y_contrast_pair
read-only
Exact WCAG contrast ratio for a color pair: per-criterion verdicts 1.4.3 (AA), 1.4.6 (AAA), 1.4.11 (non-text). Accepts #hex, rgb(), hsl(), CSS color names; rgba/hsl with alpha is composited over the background. If AA fails, suggests the nearest passing color. — For flat pairs; text over images needs a11y_contrast_image. Returns JSON: {text, background, ratio, verdicts [{criterion, level, threshold, passes}], aa_suggestion?}.
Arguments
fg(required): Foreground/text color: #hex, rgb(), hsl() or a CSS color name; alpha composites over bg.bg(required): Background color: same formats; alpha composites over white.lang— one of ['es', 'en']: output language (en default).
a11y_contrast_image
read-only
TEXT OVER IMAGE contrast: pixel-level sampling of the real background behind the text box → worst/median/p95 ratio, % of area passing AA, and automatic hostile-zone detection on a 3×3 grid (zona_peor). What pair-only checkers cannot do. region="x,y,w,h" recommended. — Use instead of a11y_contrast_pair whenever the background is a photo/gradient. Returns JSON: {worst_ratio, median_ratio, p95_ratio, area_passes_aa_normal_text_4_5, worst_zone, sampled_pixels}.
Arguments
path(required): Local path to the screenshot/image the text sits on (PNG/JPG/PPM).text_color(required): The text color as rendered over the image (must be opaque).region: Text bounding box as "x,y,width,height" in pixels (strongly recommended: defines what to sample).sample: Pixel step: 4 samples every 4px (auto-raised for huge regions).lang— one of ['es', 'en']: Output language (default en).
a11y_contrast_dom
read-only · network
REAL contrast of an element against whatever is behind it (image, gradient, video, photo): loads the page in Chromium, screenshots the element matched by selector with its text turned transparent — so only the real background is sampled, no text pixels, no antialiasing edges — and contrasts the pixels with the text color (computed from the element when not given). The automated version of a11y_contrast_image: no manual screenshot, no region math. Requires local Playwright. — Use instead of a11y_contrast_image when the text lives in a live page (captures and measures it automatically); for flat pairs use a11y_contrast_pair. Returns JSON: {url, selector, text_color, worst_ratio, median_ratio, p95_ratio, area_passes_aa_normal_text_4_5, worst_zone?, sampled_pixels, interpretation}.
Arguments
url(required): Page URL where the element lives (http/https or file://).selector(required): CSS selector of the text element to measure.text_color: Text color (default: computed from the element).sample: Pixel step (default 4).lang— one of ['es', 'en']: Output language (default en).timeout: Page load timeout seconds (default 45).auth_state: Path to a Playwright storage_state JSON to measure behind login — stays local.browser— one of ['auto', 'chromium', 'firefox', 'webkit', 'chrome', 'msedge']: Browser engine (auto = detect the first available).
a11y_vtt_check
read-only · network
WebVTT caption QUALITY (1.2.2) — the substance, not the presence. Everyone stops at " exists"; this downloads and parses the actual .vtt and judges what viewers get: malformed timing lines, empty cues, overlaps, impossible reading speed (>21 chars/second, BBC/Netflix standard) and coverage vs the media duration when given. Not a substitute for human review of accuracy or speaker identification. Returns JSON: {mode: "vtt", cues, characters, captioned_seconds, findings [{criterion, severity, signal, issue, remediation}], summary, limits}.
Arguments
url(required): URL of the .vtt caption file.duration: media duration in seconds — enables the coverage check (1.2.2 completeness) — range 1…∞.lang— one of ['en', 'es']: output language.
a11y_audit_pdf
read-only
PDF accessibility screening — the space nobody automated (axe, pa11y, Lighthouse: HTML only). Zero-dep structural first pass on a LOCAL file: tagged tree (/StructTreeRoot — the root failure), title, language, outline, /Alt entries, text layer (scanned detection), encryption. Full PDF/UA conformance needs a spec validator (veraPDF); this finds the failures that make full validation pointless. Use for enterprise document pipelines and PDFs linked from the audited site. Returns JSON: {mode: "pdf", pages, tagged, lang, title, images, alt_entries, findings, summary, limits}.
Arguments
path(required): local PDF file path (never fetched remotely — download it yourself first).lang— one of ['en', 'es']: output language.
a11y_docx_screen
read-only
DOCX accessibility screening — the other half of enterprise paperwork. Zero-dep structural pass on a LOCAL .docx: images with no alt text (docPr without descr), fake headings (bold+big paragraphs with no Heading style — invisible to the navigation pane and TOC), document language, tables without marked header row. Returns JSON: {mode: "docx", language, images, tables, findings, summary, limits}.
Arguments
path(required): local .docx file path.lang— one of ['en', 'es']: output language.
a11y_reduced_motion
read-only · network
Does the site HONOR prefers-reduced-motion? Loads the page normally, counts looping CSS animations (>0.15s infinite), then reloads emulating prefers-reduced-motion: reduce and counts again. If the number does not drop, the site ignores the user's preference (2.2.2; 2.3.3 AAA). Nobody else automates this. Covers CSS animations and video[autoplay]; JS/WebGL/scroll-parallax remain manual. Returns JSON: {mode, normal, reduced, respects, score, findings, limits}.
Arguments
url(required): page URL to test with and without prefers-reduced-motion.auth_state: path to a Playwright storage_state JSON — test behind login, stays local.browser— one of ['auto', 'chromium', 'firefox', 'webkit', 'chrome', 'msedge']: engine.lang— one of ['en', 'es']: output language.timeout: page load timeout seconds (45 default).
a11y_forced_colors
read-only · network
Does content survive forced-colors: active (Windows High Contrast)? Flags SVGs with hardcoded colored fills (they fall back to inherited and icons can vanish). Review-grade heuristic — the definitive check is visual on Windows HCM; this prepares it. Returns JSON: {mode, normal, forced, score, findings, limits}.
Arguments
url(required): page URL to test under forced-colors emulation.auth_state,browser,lang,timeout: as a11y_reduced_motion.
a11y_suggest_color
read-only
Nearest opaque color (RGB distance) to fg that reaches the target ratio against bg (4.5 default). Returns the color, its ratio and whether it lightens or darkens. — The fixer companion to a11y_contrast_pair failures. Returns JSON: {color, ratio, action} — the nearest opaque color reaching the target.
Arguments
fg(required): The failing foreground color to fix.bg(required): The background it must pass against.target: Ratio to reach: 4.5 normal text, 3.0 large text/UI, 7.0 AAA (default 4.5).
Document
a11y_generate_declaration
mutates state
Generates an Accessibility Statement in HTML: art. 10 RD 1112/2018 (Spanish public sector, marco="rd1112") or European Accessibility Act wording (Directive (EU) 2019/882 / Ley 11/2023, marco="eaa"; EN output uses Directive (EU) 2016/2102 / EAA wording). Every statement carries the EN 301 549 status note: v4.1.1 (September 2026) adopts WCAG 2.2 as the benchmark and adds the EAA mapping, but is not yet cited in the Official Journal — presumption of conformity stays with the already cited version (v3.2.1, WCAG 2.1 AA) until that citation. The generated document is itself accessible. Saves to output_path when given. — Legal statement generator; drive inaccessible_content from audit findings and a11y_evidence. Returns {html, summary} — the accessible legal statement; writes a file only when output_path is given.
Arguments
entity(required): Legal entity name as it should appear in the statement (company, body…).url(required): Website URL the statement covers.status(required) — one of ['full', 'partial', 'not_conformant']: Compliance state (partial is the honest default when findings exist). The pre-5.11 values plena | parcial | no_conforme still work as aliases.inaccessible_content: Non-accessible content list: one string per item, ideally criterion + reason + alternative.method: How conformance was evaluated (e.g. "self-evaluation: a11y-toolkit screening + manual review").evaluation_date: ISO date of the last evaluation (YYYY-MM-DD).review_date: ISO date of the next scheduled review.feedback: Contact channel for accessibility feedback (email or URL).complaints: Claim/complaint procedure URL or address (legally required in several jurisdictions).framework— one of ['rd1112', 'eaa']: Legal framework: rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector).alternative_format: Where to get the content in an alternative accessible format.output_path: save the HTML here (optional).lang— one of ['es', 'en']: Statement language (default en; es uses the Spanish legal wording).
a11y_generate_vpat
mutates state
Generates a VPAT 2.5 (WCAG edition) accessibility conformance report in accessible HTML from an a11y_evidence pack (or raw audit reports): the full 55-criterion WCAG 2.2 A/AA table with Remarks auto-filled from the pack (status, measured values, examples, remaining human effort) and every Conformance Level starting at Not Evaluated — automated fails force Does Not Support and a qualified human sets the final level via overrides (supports, partially_supports, does_not_support, not_applicable, not_evaluated). The document is a DRAFT until the signature block, which must reference the pack sha256, is completed. VPAT is the US/ADA counterpart of a11y_generate_declaration (EU/EAA): the machine fills Remarks, the human signs the claim. — The US/ADA counterpart of a11y_generate_declaration; feed it the a11y_evidence pack — levels stay Not Evaluated until a qualified human sets them. Returns {html, summary {level: count}, levels {code: level}, pack_sha256, draft} — the VPAT draft; writes a file only when output_path is given. Run after the audits you trust; a qualified human must set the final levels (overrides) and sign before publishing — the machine fills Remarks, never the claim.
Arguments
product(required): Product name as it must appear in the VPAT title and header.pack: a11y_evidence output (evidence pack); alternative to reports.reports: Audit report objects to bundle (when pack is not given, the pack is built here first).report_date: VPAT report date ISO (default: today).product_description: Product description paragraph.contact: Contact information for questions about this VPAT.methods: Evaluation methods used (default: honest automated-screening note).notes: Additional notes to include.overrides: Criterion → conformance level set by a qualified human: {"1.1.1": "supports", "1.2.2": "not_applicable", …}.reviewer: {"name":…, "credential":…, "review_date":…} to prefill the signature block.output_path: Local path to save the VPAT HTML (omit to receive it inline).lang— one of ['es', 'en']: Document language (default en).
a11y_badge
read-only
Returns an HONEST accessibility badge as accessible SVG: score, date and scope (automated screening ≈ 1/3 of WCAG), color-coded by score. Deliberately does NOT say "conformant" — the honest seal. Embed it in audited sites or statements. — Scope: the honest SVG seal for audited sites; the machine-readable bundle is a11y_evidence. Returns the honest SVG badge; writes a file only when output_path is given.
Arguments
score(required): 0-100 (from an audit result).fecha: ISO date (today by default).lang— one of ['es', 'en']: Badge language (default en).
a11y_criterion
read-only
Explains a WCAG 2.2 success criterion in plain language (es/en): what it requires, typical failures, and how to verify it with this toolkit (which tool automates which part). Codes like "1.4.3", "2.5.8", "4.1.2". Give a finding SIGNAL instead (e.g. img_no_alt, kbd_trap — the id in every audit finding) and it resolves to its criterion AND its published ACT rule(s) with official w3.org links. Use it whenever you need to explain WHY a finding matters or what the criterion actually says. — Knowledge lookup; does not fetch or audit anything. Returns JSON: {criterion, level, understanding, toolkit_signals, requires, typical_failures, how_to_check} or, in signal mode, adds {signal, act_rules [{id, name, status, url}]}; {error, …} for unknown codes.
Arguments
code: criterion number, e.g. 1.4.3 — or passsignalinstead.signal: engine signal id from any finding (e.g.kbd_trap): resolves its criterion and its published ACT rule(s) with w3.org links (proposed rules are labeled as such).lang— one of ['es', 'en']: Explanation language (default en).
Watch (regressions)
a11y_snapshot
read-only · network
Accessibility snapshot of a URL: interactive elements (tag, role, accessible name, href) in DOM order, the REAL tab focus order, and when Playwright ≥1.49 is available the computed ACCESSIBILITY TREE (aria snapshot — what a screen reader announces). Save it before a deploy and compare after with a11y_diff. Requires local Playwright. — Capture half of the watch loop; compare with a11y_diff (or a11y_diff_urls for two live URLs). Returns JSON: {url, ts, elements [{tag, role, name, ref…}], focus_order}.
Arguments
url(required): Page URL to snapshot (http/https or file://).auth_state: Path to a Playwright storage_state JSON (exported session) to snapshot behind login.
a11y_diff
read-only
Regression diff between two accessibility snapshots (before/after a deploy): added/removed/renamed interactives and focus-order changes. ok=false means a regression to review. Accepts inline JSON (starting with "{") or file paths. — Compares two existing snapshots; a11y_diff_urls snapshots both for you. Returns JSON: {ok, added, removed, renamed, focus_order_changed, first_differences} — ok:false means a regression to review.
Arguments
a(required): BEFORE snapshot (inline JSON or path).b(required): AFTER snapshot (inline JSON or path).
a11y_diff_urls
read-only · network
Snapshot two URLs and diff them in a single call (e.g. staging vs production). Requires local Playwright. — Convenience for staging-vs-production; manual control is snapshot + a11y_diff. Returns the same diff shape as a11y_diff, for two live URLs.
Arguments
url_a(required): First URL (usually staging).url_b(required): Second URL (usually production).
a11y_aria_live_snippet
read-only
Returns injectable JavaScript for an aria-live announcement monitor (bookmarklet or page.evaluate): logs every dynamic-region announcement with time, politeness, role and text — what a screen reader would say, visible on screen. — Diagnostics aid to inject in a browser; not an audit by itself. Returns the injectable JavaScript as text (bookmarklet or page.evaluate).
Arguments
lang— one of ['es', 'en']: monitor panel language (en default).
Hand off (evidence)
a11y_evidence
read-only
Builds the verifiable evidence pack: the machine→human handoff object for WCAG conformance work. Takes one or more audit reports (any mode — static, rendered, reflow, keyboard, scroll) and returns: the full 55-criterion A/AA matrix (automated-fail / automated-review / not-flagged — NOT pass / not-run / manual-only), each row priced with its human-effort class (MIN 1-3 / MED 5-10 / MAX 15-30 min of human review remaining) and total remaining minutes (the quote input for a review marketplace), every artifact SHA-256-hashed with timestamps, an empty signature block (name, credential, date) whose statement must reference the pack's own sha256, and the tamper-evidence rule stated. Vendor-neutral: any qualified human can review it. Evidence, never conformance. — The tier-3 handoff object; feed it every audit report you have. Returns the pack JSON (a11y-evidence-pack/2); writes a file only when output_path is given. Run after the audits you trust, and pass verified codes from the manual checklist — agent-verified never erases an automated-fail.
Arguments
reports(required): audit report objects (any mode).snapshot: a11y_snapshot output (optional).reviewer: {"name":…, "credential":…, "review_date":…} to prefill the signature block.verified: Criterion codes an agent/human verified against this sample (manual checklist protocol) — they become agent-verified in the matrix; automated-fail stays fail.
a11y_disprove
read-only · network
Disprover pattern (from Cloudflare's security-audit-skill): re-runs the audit against the live page and marks each finding confirmed or rejected — findings that don't reproduce are rejected with the reason. Catches false positives, race conditions, and page changes between audit and report. Returns a fresh score over confirmed findings only. — Run this before acting on any audit report. Returns JSON: {confirmed, rejected, score} — a fresh score over confirmed findings only.
Arguments
url(required): URL to re-verify against.report: existing audit report (optional; if absent, audits first).lang— one of ['es', 'en']: Output language (en default).timeout: Timeout seconds (30 default).
a11y_ledger
mutates state · not idempotent
Coverage ledger (from Cloudflare's security-audit-skill): persistent record of what has been audited, when, and with what result. Actions: record (add audit result), gaps (what has never been checked on a URL), summary (portfolio overview). Accumulates across runs — second audits show resolved findings. record returns the stored entry; gaps returns criteria never checked; summary returns {entries, active_signals, resolved, mean_score}. record after every audit run; gaps before planning the next pass. The ledger file accumulates across runs — give each project its own ledger_path.
Arguments
action(required) — one of ['record', 'gaps', 'summary']: What to do.url: URL (for record/gaps).report: audit report object (for record).ledger_path: ledger file path (default: a11y-ledger.json).
a11y_wcag3_preview
read-only
WCAG 3 demo — the view layer nobody ships: takes an audit report and re-groups its WCAG 2.2 findings under the outcomes of the WCAG 3 Working Draft (10 September 2026). Informative only: WCAG 3 is not a completed standard, the W3C has published no official WCAG 2 to WCAG 3 mapping (this one is curated and labeled as such), and NO score, tier or conformance claim is produced — the draft's tier thresholds are still TBD. Use it to show teams where today's 2.2 findings will land tomorrow; keep auditing against WCAG 2.2. Returns JSON: {mode, draft, disclaimer, mapping_note, no_score, conformance_model, outcomes [{outcome, draft_url, findings, severity, signals, criteria_22}], counts, unmapped} — never a score. Run after any audit when the team asks "what about WCAG 3?"; re-baseline on each W3C draft publication (roughly March/September).
Arguments
report(required): audit report object with a findings list (from a11y_audit_url, a11y_audit_dom, a11y_disprove, …).lang— one of ['es', 'en']: Output language (en default).
The 6 prompts
audit-page(url*,language): Full accessibility audit workflow for a URL: automated tools + what to verify manually (keyboard, screen reader, zoom). Every prompt exists in English and Spanish.fix-contrast(fg*,bg*,context): Guided contrast fix: verify the pair (or the text-over-image region), get the nearest passing color, apply it to the code. Every prompt exists in English and Spanish.pre-deploy-check(url*,baseline): Pre-deploy regression check: express audit of the URL plus snapshot diff against a baseline snapshot. Every prompt exists in English and Spanish.declaration-eaa(entity*,url*,status): Generate a European Accessibility Act / RD 1112/2018 accessibility statement, collecting any missing legal fields from the user. Every prompt exists in English and Spanish.conformance-wcagem(url*,tier,language): Guided WCAG-EM conformance ladder for a site: express screening → agent-verified guided evaluation on a representative sample → conformance report inputs. Every prompt exists in English and Spanish.blindfold-task(url*,goal*,kind,language): Blindfold usability test — the agent attempts a real task perceiving ONLY the accessibility tree and acting only by accessible name and keyboard, logging friction per step; closes with a11y_journey_verdict. The capability no other accessibility tool has: task-based non-visual testing where the agent IS the screen-reader user. Every prompt exists in English and Spanish.
Install
mcp-name: io.github.kinti/a11y-toolkit · PyPI: a11y-toolkit · Zenodo DOI:
10.5281/zenodo.22843722
Works with any MCP-capable client — Claude Code/Desktop, Cursor, Windsurf, VS Code, Codex CLI, OpenCode, ZCode, Zed, Cline, Continue, Kimi Code… See docs/clients.md for every verified config format.
claude mcp add a11y-toolkit -- uvx --from a11y-toolkit a11y-toolkit-mcpOr with JSON config:
{
"mcpServers": {
"a11y-toolkit": {
"command": "uvx",
"args": ["--from", "a11y-toolkit", "a11y-toolkit-mcp"],
"timeoutMs": 60000
}
}
}Rendered tools use Playwright if present and accept a browser parameter
(auto, chromium, firefox, webkit, chrome, msedge — auto-detects the first
available). Accept auth_state (Playwright storage_state path) to audit behind login.
Everything else works with zero dependencies.
The skill
git clone https://github.com/kinti/a11y-toolkit && cd a11y-toolkit
./skill/install-skill.sh # → ~/.zcode/skills and ~/.claude/skillsAgent hook — a11ytoolkit init
Agents that read AGENTS.md on their own get the
rule that matters — after any UI change, re-audit before calling the work
done — with the exact commands:
cd your-project
uvx --from a11y-toolkit a11ytoolkit init # writes/merges the AGENTS.md hook (idempotent)It also prints the MCP config block and the optional skill install step.
--check reports whether the hook is present (exit 1 if not — CI-friendly).
Languages — community locale packs
All user-facing messages (findings, remediations, legal wording) live in
locale packs — one JSON per language, es and en
ship today. Adding a language is a single-file PR: copy
_template.json, translate keeping the
{placeholders}, and python3 tests/test_locales.py validates it mechanically
(keys, placeholders, plural rule, completeness). Same community model as
axe-core's locales — with validation axe-core doesn't have. Guide:
docs/i18n.md. Downstream products can layer brand wording via
overlays without forking.
CLI — same engine, one command
a11ytoolkit audit --changed # ONLY what changed since HEAD (CI gate)
a11ytoolkit audit --changed --base origin/main # a branch's changes — exit 2 on high/medium
a11ytoolkit audit --url https://example.com --pages 5 # sitemap-first crawl
a11ytoolkit pair "#1f2328" "#fbfaf7" # contrast
a11ytoolkit image hero.jpg --text "#fff" --region 120,40,420,90
a11ytoolkit forms https://mysite/contact # form errors
a11ytoolkit kbd https://mysite # keyboard traps + 3.2.1/3.2.2
a11ytoolkit reflow https://mysite # 320px reflow
a11ytoolkit scroll https://medium.com/feed # infinite scroll
a11ytoolkit validate --url https://example.com # W3C Nu
a11ytoolkit hover https://mysite # tooltip dismissibility
a11ytoolkit fix --file page.html -o fixed.html # safe autofix
a11ytoolkit declaration --entity "Acme" --url https://… --status partial --framework eaa
a11ytoolkit snapshot https://mysite --out before.json # before deploy
a11ytoolkit diff before.json after.json # after deploy
a11ytoolkit evidence audit.json -o pack.json # verifiable evidence pack
a11ytoolkit disprove --url https://mysite # re-verify findings
a11ytoolkit budget --budget budget.json --audit audit.json # only NEW findings block
a11ytoolkit sarif --from-audit audit.json -o a11y.sarif # GitHub code scanning
a11ytoolkit badge --score 92 --out badge.svg # honest SVG
a11ytoolkit contrast-dom https://mysite --selector ".hero h1" # auto-region pixel sampling
a11ytoolkit vpat pack.json --product "Acme" -o vpat.html # VPAT 2.5 (WCAG) draft
a11ytoolkit earl --from-audit audit.json -o earl.json # ACT Rules / EARL export
a11ytoolkit wcag3 --from-audit audit.json # WCAG 3 draft preview (no score)Coverage: 51 of 55 WCAG 2.2 A/AA criteria (93%)
With automated signal | Manual-only (genuinely human) |
1.1.1, 1.2.2, 1.2.3, 1.2.5, 1.3.1–1.3.5, 1.4.1–1.4.5, 1.4.10–1.4.13, 2.1.1, 2.1.2, 2.1.4, 2.2.1, 2.2.2, 2.4.1–2.4.7, 2.4.11, 2.5.1–2.5.4, 2.5.7, 2.5.8, 3.1.1, 3.1.2, 3.2.1–3.2.4, 3.2.6, 3.3.1–3.3.4, 3.3.8, 4.1.2, 4.1.3 | 1.2.1 (audio transcripts), 1.2.4 (live captions), 2.3.1 (flash detection), 3.3.7 (redundant entry) |
The 4 manual-only criteria each have a knowledge entry (a11y_criterion) telling the
agent exactly how to verify them by hand. The boundary is printed on every report.
a11y.es — the engine in production
a11y.es runs this engine in production: continuous WCAG 2.2 monitoring with hash-verifiable evidence packs and human-signed reports, in Spanish, built for the European Accessibility Act / RD 1112/2012 market. Every report ends at the exact boundary where a qualified human begins — that boundary is the product.
Validated against real pages
Benchmarked against axe-core 4.10 on real pages monthly (methodology and results). Found a real WCAG failure on gov.uk that axe does not report (blue button at 3.91:1, manually verified). Drove out our own false positives (hidden skip links, honeypot fields, single-context generic links, image-alt accname — each with a regression fixture).
Why I built this
I have been auditing websites for accessibility since 2003. In twenty years the tools got faster and the failures stayed the same: the same missing alt text, the same keyboard traps, the same forms that swallow your work. When AI agents started writing most of the web, the audit gap stopped being a staffing problem and became an infrastructure one.
So I built the tool I always wanted next to me on an audit. Not another scanner — scanners exist. A toolkit that does half the work, says exactly where it stops, and packages the rest for the person who signs. The gov.uk failure you read about above is not a synthetic benchmark case: this engine found it, and I confirmed it with my own eyes before writing it down.
If it saves you an afternoon, leave a star — it genuinely helps the next auditor find it. If it doesn't, open an issue and tell me what is missing.
Honesty, built in
Every audit says: automation covers 93% of A/AA criteria; the rest needs a human.
The audit-page prompt and the skill have the agent check what it can (keyboard,
focus, zoom, announced errors) using the manual
checklist. A filter, not
a verdict. The remaining human work is priced per criterion — MIN 23 (read and
confirm), MED 19 (verify in the browser), MAX 13 (real interaction and judgment);
full table. And the evidence pack is the handoff object
for the person who signs, screen reader transcript included, so the reviewer sees
what a blind user hears.
Security & scope
A local tool: runs on your machine as your user. a11y_audit_url accepts
http/https only (no file:// — use --file/html for local HTML). a11y_html_validate
in html mode POSTs content to the W3C service (url mode shares only the URL;
self-hosted vnu supported). path/output_path read/write local paths — use it in
MCP clients you trust.
Development
python3 tests/test_contrast.py && python3 tests/test_audit.py && python3 tests/test_v32.py \
&& python3 tests/test_dom.py && python3 tests/test_cli.py && python3 tests/test_solido.py \
&& python3 tests/test_mcp.py && python3 tests/test_png.py && python3 tests/test_vpat.py \
&& python3 tests/test_act.pytests/test_dom.py self-skips without Playwright. tests/test_solido.py enforces the design
invariants (catalog parity, version alignment, count coverage, hostile-HTML fuzz).
Releases: make release V=X.Y.Z — bumps, gates, tags and pushes atomically.
Roadmap
Done recently: rendered audit with shadow DOM and state contrast, form error testing plus autofix, keyboard traps, infinite scroll, reflow, the W3C Nu integration, SARIF and error budgets, the evidence pack (spec published, self-verifying), sitemap crawling, behind-login auditing, browser auto-detection, the screen reader transcript, and per-criterion effort pricing. The full history lives in the changelog.
Next, roughly in this order:
Attestation interlock: let an external auditor's signature reference the evidence pack by hash (their schema, my side adapts)
Publish the monthly axe-core benchmark results from CI, run over real pages
Screen-reader transcript cross-checks against NVDA and VoiceOver output
More verified client configs (JetBrains AI, Gemini CLI), same treatment as docs/clients.md
Author
Jesús Quintana Fernández (jquin.net) — SEO/GEO consultant and web-accessibility practitioner since 2003. MIT © 2026.
Available Tools
32 toolsa11y_aria_live_snippeta11y-toolkit: aria-live monitor snippetARead-onlyIdempotent
Returns injectable JavaScript for an aria-live announcement monitor (bookmarklet or page.evaluate): logs every dynamic-region announcement with time, politeness, role and text — what a screen reader would say, visible on screen. — Diagnostics aid to inject in a browser; not an audit by itself. Returns the injectable JavaScript as text (bookmarklet or page.evaluate).
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | monitor panel language (en default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/idempotentHint already covering the safety profile, the description adds real context: it produces a text artifact usable as a bookmarklet or page.evaluate payload, and it is a diagnostic rather than an audit. It still doesn't say whether the injected monitor auto-expires or how its output is captured.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and readable, but it repeats itself: 'injectable JavaScript' and 'bookmarklet or page.evaluate' each appear twice across the description. Trimming the duplicated clause would make it tighter without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by explaining that the return value is injectable JavaScript text and what the monitor logs once injected. For a single optional parameter tool this is nearly complete, though a note on where announcements surface (console/panel) is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (the lang enum is documented as 'monitor panel language (en default)'), so the schema carries the parameter burden. The description adds no detail about the lang option or its effect on output, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: it returns injectable JavaScript that monitors aria-live dynamic-region announcements, logging time, politeness, role and text. That is a distinct capability from siblings like a11y_sr_transcript or a11y_audit_dom, and an agent can tell what artifact it produces without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the tool as a diagnostics aid to inject in a browser and warns that it is 'not an audit by itself', which tells the agent when this is and isn't the right pick. It does not name a specific alternative sibling to use instead, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_audit_doma11y-toolkit: Rendered WCAG auditARead-onlyIdempotent
Deep RENDERED WCAG audit via local Playwright/Chromium: real computed text contrast against effective backgrounds with alpha compositing (1.4.3), pixel-sampled measurement of text over images/gradients (background captured with the text transparent), minimum target size 24×24 (2.5.8, new in WCAG 2.2), visible focus indicator heuristic (2.4.7), plus rendered versions of the static checks (alt, accessible names, labels, headings, lang/title, tabindex, aria-hidden, captions, tables). Findings include remediation. Requires playwright: pip install playwright && playwright install chromium. — Use instead of a11y_audit_url on JS-heavy pages; needs local Playwright. Returns JSON: {mode, url, score 0-100, findings [{criterion, severity, signal, issue, remediation}], summary, score_note} — same shape as the static audit.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to load in Chromium (http/https or file:// for local fixtures) | |
| lang | No | Output language for findings and remediation (default en) | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | page load timeout seconds (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to audit behind login — local file, never uploaded | |
| color_scheme | No | Emulate prefers-color-scheme: run the contrast pass in dark mode too — dark themes fail where light passes (nobody audits both) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds substantial behavior beyond them: the Playwright/Chromium dependency and install step, local-only processing of the auth_state session ('local file, never uploaded'), and the exact rendering methodology (background captured with text transparent). This is exactly the kind of context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool does, then the dependency requirement, then the routing guidance, then the return shape — a sensible order. The opening sentence is a dense run-on enumerating checks, which costs some readability, but every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by spelling out the return shape ({mode, url, score 0-100, findings [{criterion, severity, signal, issue, remediation}], summary, score_note}) and noting it matches the static audit. For a six-parameter tool with a heavy runtime dependency, the definition is complete enough to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with six well-documented parameters, so the schema already does the heavy lifting and baseline 3 applies. The description adds no parameter-level detail (url, lang, browser, timeout, auth_state, color_scheme are all handled in the schema), so it neither compensates nor degrades.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — a rendered WCAG audit executed via local Playwright/Chromium — and enumerates the concrete checks (contrast with alpha compositing, target size, focus indicator, rendered static checks). It is clearly distinguished from the sibling a11y_audit_url, which it explicitly positions against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative and the condition that selects it: 'Use instead of a11y_audit_url on JS-heavy pages.' It also states the prerequisite ('Requires playwright: pip install playwright && playwright install chromium'), so the agent knows both when to pick this tool and what it needs to run.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_audit_pdfa11y-toolkit: PDF accessibility screeningARead-onlyIdempotent
PDF accessibility screening — the space nobody automated (axe, pa11y, Lighthouse: HTML only). Zero-dep structural first pass on a LOCAL file: tagged tree (/StructTreeRoot — the root failure), title, language, outline, /Alt entries, text layer (scanned detection), encryption. Full PDF/UA conformance needs a spec validator (veraPDF); this finds the failures that make full validation pointless. Use for enterprise document pipelines and PDFs linked from the audited site. Returns JSON: {mode: "pdf", pages, tagged, lang, title, images, alt_entries, findings, summary, limits}.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | output language | |
| path | Yes | local PDF file path (never fetched remotely — download it yourself first) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive and closed-world, so the bar is met; the description goes further by stating it is a zero-dep structural first pass, operates only on local files and never fetches remotely, and enumerates which failure classes it detects versus which it cannot. That is real behavioral context beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the differentiator and file-locality constraint come first, then the check list, then the output shape. The parenthetical comparisons with axe/pa11y/Lighthouse and veraPDF are justifiable boundary-setting, though the sentence is long enough to approach overload.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description names the returned JSON keys (mode, pages, tagged, lang, title, images, alt_entries, findings, summary, limits), so an agent knows what it gets back, and it clearly frames scope and limitations. Nothing needed to invoke or interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are documented in the schema; the description's only path-related guidance ('never fetched remotely — download it yourself first') duplicates the schema's own description nearly verbatim and adds nothing about the lang enum. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('PDF accessibility screening' on a LOCAL file) and enumerates the concrete checks performed (tagged tree, title, language, outline, /Alt, text layer, encryption). It explicitly separates itself from the HTML-only tools and from spec validators like veraPDF, so an agent can place it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context ('enterprise document pipelines and PDFs linked from the audited site') and a boundary condition — full PDF/UA conformance belongs to a spec validator, not this tool. It stops short of naming any sibling tool (e.g. a11y_audit_url vs a11y_audit_dom) as the alternative for HTML inputs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_audit_urla11y-toolkit: Express WCAG auditARead-onlyIdempotent
Express WCAG 2.2 audit of a URL or an HTML string: 20+ automated signals with a weighted 0-100 score — images without alt (1.1.1), controls without accessible names (4.1.2), form fields without labels (3.3.2), missing autocomplete on user-data fields (1.3.5), click handlers on non-interactive elements (2.1.1), unknown ARIA roles and broken aria-labelledby (4.1.2), duplicated unnamed landmarks, timed meta refresh (2.2.1), missing skip mechanism (2.4.1), lang/title (3.1.1, 2.4.2), heading structure (1.3.1), blocked zoom (1.4.4), captions (1.2.2), autoplay audio (1.4.2), generic/duplicated link text (2.4.4), target=_blank without warning (3.2.5), positive tabindex (2.4.3), aria-hidden on focusable elements, tables without th, duplicate ids, duplicate accesskeys. Each finding includes concrete remediation. Filter, not verdict: automation covers ~1/3 of WCAG; query a11y_criterion for what a criterion means. — Prefer a11y_audit_dom when JS renders the content or contrast/2.5.8/focus matter; use pages for light multi-page sampling. Static CANNOT measure class/var() CSS contrast (1.4.3): the report's not_measured says so — a 100 is never 'contrast is fine'. Returns JSON: {mode, url|file, score 0-100, findings [{criterion, severity, signal, issue, remediation}], summary {high, medium, low}, limits, score_note}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to fetch and audit | |
| html | No | raw HTML to audit directly (overrides url) | |
| lang | No | output language (en default) | |
| pages | No | light same-domain crawl: audit up to N pages, aggregated by score and recurring signals (default 1, max 20) | |
| timeout | No | fetch timeout seconds (30 default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, idempotent and non-destructive, so the safety profile is covered by structured data. The description still adds genuinely useful behavioral context beyond that: static analysis cannot measure class/var() CSS contrast, the report's not_measured field reflects this, and a score of 100 must not be read as "contrast is fine." That is meaningful disclosure, though it stops short of rate limits or fetch failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose, the sibling routing, and the caveat all appear before the long criterion enumeration, so the actionable content is front-loaded. The criterion list is dense but each entry pairs a signal with its WCAG success criterion, which is the detail an agent needs to match findings to a request.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing the return value and does so in detail ({mode, url|file, score, findings[{criterion, severity, signal, issue, remediation}], summary, limits, score_note}), plus explains the limits field's meaning. Minor gap: timeout and lang behavior are left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented, including that html overrides url and that pages is a light same-domain crawl. The description restates "URL or an HTML string" and clarifies pages is a sampling mode, but adds no syntax or format detail beyond the schema — baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Express WCAG 2.2 audit of a URL or an HTML string") plus concrete scope (20+ automated signals, weighted 0-100 score) and enumerates the checks it performs. It is immediately distinguishable from a11y_audit_dom and the multi-page siblings it names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes between alternatives: "Prefer a11y_audit_dom when JS renders the content or contrast/2.5.8/focus matter; use pages for light multi-page sampling," and points to a11y_criterion for criterion definitions. It also sets expectations on when this tool is insufficient ("automation covers ~1/3 of WCAG").
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_autofixa11y-toolkit: Deterministic safe auto-fixesARead-onlyIdempotent
DETERMINISTIC safe auto-fixes applied to HTML — the honest anti-overlay: a short closed list of fixes where the correct answer is unique (unblock viewport zoom 1.4.4, add the exact autocomplete token 1.3.5, fill missing html lang and empty title when provided). Everything requiring judgment (alt text, contrast, accessible names) is NOT touched — it returns not_applied with the reason and remediation instead. Returns fixed_html + applied + not_applied. — Only the closed allowlist of provably safe fixes; judgment fixes come back as not_applied with remediation. Returns JSON: {fixed_html, applied [{fix, …}], not_applied [{issue, remediation}]} — writes a file only when output_path is given.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL context for the report metadata (default: "(html)") | |
| html | Yes | raw HTML to fix | |
| lang | No | only if provided and <html> lacks lang | |
| title | No | only if provided and <title> is empty | |
| form_errors | No | inject the accessible form-error layer into forms without their own handling (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds genuinely useful behavior – the allowlist boundary, that rejections carry remediation text, and the {fixed_html, applied, not_applied} shape. However it claims it 'writes a file only when output_path is given' while no output_path parameter exists in the schema, and a file write would also sit awkwardly against readOnlyHint=true, so an agent could be misled about side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded, but the text repeats itself: 'Returns fixed_html + applied + not_applied' is immediately followed by a second 'Returns JSON: {fixed_html, applied, not_applied}' block, and the allowlist-only constraint is stated twice with an em-dash. Roughly a third of the text is duplication rather than new information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the return-shape burden and explains what appears in applied vs not_applied. For a 5-parameter mutator it is nearly complete, but the phantom output_path reference and the untouched default behavior of form_errors leave a small gap an agent would have to resolve from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; each parameter is already documented in the schema ('only if provided and <title> is empty', 'default: (html)'). The description restates the lang/title conditions and the default-true form-error layer without adding syntax, format, or interaction detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource combination (deterministic safe auto-fixes applied to HTML) and immediately bounds it: a closed allowlist of unique-answer fixes (1.4.4 zoom, 1.3.5 autocomplete, html lang, empty title). It implicitly distinguishes itself from the audit/check siblings by declaring judgment fixes out of scope, but never names a sibling tool explicitly, so the differentiation is inferential rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear when-to-use condition (only issues with a provably unique fix) and an explicit when-not (alt text, contrast, accessible names are NOT touched, returning not_applied with remediation). It does not route the agent to a specific sibling for the judgment cases, which keeps it below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_badgea11y-toolkit: Honest SVG badgeBRead-onlyIdempotent
Returns an HONEST accessibility badge as accessible SVG: score, date and scope (automated screening ≈ 1/3 of WCAG), color-coded by score. Deliberately does NOT say "conformant" — the honest seal. Embed it in audited sites or statements. — Scope: the honest SVG seal for audited sites; the machine-readable bundle is a11y_evidence. Returns the honest SVG badge; writes a file only when output_path is given.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ISO date (today by default) | |
| lang | No | Badge language (default en) | |
| score | Yes | 0-100 (from an audit result) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuine value with the disclosure that the badge deliberately avoids claiming 'conformant' and that scope is ~1/3 of WCAG. However, it says the tool 'writes a file only when output_path is given', which conflicts with readOnlyHint=true and references an output_path parameter that does not exist in the schema — a misleading behavioral claim on a read-only tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the essential fact (returns an SVG badge), but 'honest' appears five times and the return value is restated in the trailing sentence, so several clauses do not earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does explain the badge contents (score, date, scope, color coding), which is adequate. But the unsupported output_path claim leaves an agent unsure whether a file artifact is produced, and the 0-100 score constraint is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description introduces a phantom 'output_path' parameter that is absent from the schema, while saying nothing useful about score, date, or lang beyond what the schema documents. This actively misleads an agent about the callable surface instead of supplementing it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource: returns a color-coded accessibility SVG badge containing score, date and scope, and explicitly differentiates itself from the machine-readable sibling a11y_evidence. The core purpose is unmistakable, though the repeated 'honest' framing adds rhetoric rather than additional clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a use context ('embed it in audited sites or statements') and names the alternative explicitly ('the machine-readable bundle is a11y_evidence'), so an agent knows which sibling to pick. It lacks an explicit when-not condition (e.g., unaudited or partial audits).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_contrast_doma11y-toolkit: Live-element contrast samplingARead-onlyIdempotent
REAL contrast of an element against whatever is behind it (image, gradient, video, photo): loads the page in Chromium, screenshots the element matched by selector with its text turned transparent — so only the real background is sampled, no text pixels, no antialiasing edges — and contrasts the pixels with the text color (computed from the element when not given). The automated version of a11y_contrast_image: no manual screenshot, no region math. Requires local Playwright. — Use instead of a11y_contrast_image when the text lives in a live page (captures and measures it automatically); for flat pairs use a11y_contrast_pair. Returns JSON: {url, selector, text_color, worst_ratio, median_ratio, p95_ratio, area_passes_aa_normal_text_4_5, worst_zone?, sampled_pixels, interpretation}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL where the element lives (http/https or file://) | |
| lang | No | Output language (default en) | |
| sample | No | Pixel step (default 4) | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | Page load timeout seconds (default 45) | |
| selector | Yes | CSS selector of the text element to measure | |
| auth_state | No | Path to a Playwright storage_state JSON to measure behind login — stays local | |
| text_color | No | Text color (default: computed from the element) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent/non-destructive, and the description adds genuinely non-derivable context: it launches Chromium, hides the text (transparent) so only real background pixels are sampled, avoids antialiasing edges, and requires local Playwright. It stops short of mentioning runtime cost or browser-launch overhead, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then methodology, then sibling routing, then return shape. The em-dash parentheticals make it dense, but each segment earns its place and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the inline JSON return summary (worst/median/p95_ratio, pass flag, worst_zone, sampled_pixels, interpretation) is necessary and supplied. Combined with prerequisites, routing, and parameter coverage already in the schema, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all 8 parameters, so the schema already carries the semantics. The description only echoes a couple of schema facts (selector-matched element, text_color computed when not given) and adds no syntax or format detail beyond it — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource (measure the real contrast of an element against whatever renders behind it) and immediately scopes it against siblings by naming a11y_contrast_image and a11y_contrast_pair. An agent can tell exactly which contrast tool to pick without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'Use instead of a11y_contrast_image when the text lives in a live page' and 'for flat pairs use a11y_contrast_pair.' Alternatives and the conditions that select them are stated outright, plus the practical prerequisite of a local Playwright install.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_contrast_imagea11y-toolkit: Text-over-image contrastARead-onlyIdempotent
TEXT OVER IMAGE contrast: pixel-level sampling of the real background behind the text box → worst/median/p95 ratio, % of area passing AA, and automatic hostile-zone detection on a 3×3 grid (worst_zone). What pair-only checkers cannot do. region="x,y,w,h" recommended. — Use instead of a11y_contrast_pair whenever the background is a photo/gradient. Returns JSON: {worst_ratio, median_ratio, p95_ratio, area_passes_aa_normal_text_4_5, worst_zone, sampled_pixels}.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Output language (default en) | |
| path | Yes | Local path to the screenshot/image the text sits on (PNG/JPG/PPM) | |
| region | No | Text bounding box as "x,y,width,height" in pixels (strongly recommended: defines what to sample) | |
| sample | No | Pixel step: 4 samples every 4px (auto-raised for huge regions) | |
| text_color | Yes | The text color as rendered over the image (must be opaque) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/non-destructive, so safety is covered; the description instead adds behavioral substance — that sampling is pixel-level over the real rendered background, that a 3×3 hostile-zone grid is computed, and the shape of the result. It stops short of noting failure/edge behavior (e.g. what happens without region, or with translucent text_color), keeping it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the distinguishing capability and the sibling routing in the first two sentences; the return-field list is justified because no output schema exists. The telegraphic arrow/em-dash style is dense but readable, with only slight redundancy around region.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter, no-output-schema tool the description is essentially complete: capability, inlining of the return fields, and the sibling decision rule are all present. The remaining minor gap is that it doesn't say what happens when region is omitted despite the sampling depending on it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are already documented, and the description adds only the reminder that region is "x,y,w,h" and recommended — which restates the schema's own 'strongly recommended' note. Baseline 3 is correct when the schema does the semantic work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('TEXT OVER IMAGE contrast: pixel-level sampling of the real background behind the text box') and enumerates exactly what the tool produces (worst/median/p95 ratio, % area passing AA, worst_zone). It explicitly positions itself against a named sibling, so an agent can distinguish it from a11y_contrast_pair without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative outright — 'Use instead of a11y_contrast_pair whenever the background is a photo/gradient' — which is an explicit when/when-not rule with the selector condition stated. It also advises when to pass region ('recommended'), covering the main invocation choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_contrast_paira11y-toolkit: Contrast ratio + verdictsARead-onlyIdempotent
Exact WCAG contrast ratio for a color pair: per-criterion verdicts 1.4.3 (AA), 1.4.6 (AAA), 1.4.11 (non-text). Accepts #hex, rgb(), hsl(), CSS color names; rgba/hsl with alpha is composited over the background. If AA fails, suggests the nearest passing color. — For flat pairs; text over images needs a11y_contrast_image. Returns JSON: {text, background, ratio, verdicts [{criterion, level, threshold, passes}], aa_suggestion?}.
| Name | Required | Description | Default |
|---|---|---|---|
| bg | Yes | Background color: same formats; alpha composites over white | |
| fg | Yes | Foreground/text color: #hex, rgb(), hsl() or a CSS color name; alpha composites over bg | |
| lang | No | output language (en default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this as a safe, idempotent, closed-world read, so the remaining burden is behavioral detail — and the description supplies it: accepted color syntaxes, alpha compositing rules (over bg for fg, over white for bg), automatic nearest-passing-color suggestion when AA fails, and the shape of the returned JSON object despite there being no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then formats, then the sibling disclaimer and return shape — all sentences earn their place. Slightly dense with em-dash-separated clauses, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by documenting the returned JSON keys (text, background, ratio, verdicts, aa_suggestion). Combined with format acceptance, compositing behavior, and the sibling boundary, an agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the description's parameter content (accepted formats, alpha compositing) largely restates what the fg/bg schema entries already say. The lang enum parameter is not mentioned in the description at all. Baseline 3 is appropriate when the schema carries the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (exact WCAG contrast ratio for a color pair) and enumerates the verdict set it produces (1.4.3 AA, 1.4.6 AAA, 1.4.11 non-text). It explicitly distinguishes itself from the sibling a11y_contrast_image, so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives both the inclusion condition ('For flat pairs') and the exclusion with a named alternative ('text over images needs a11y_contrast_image'). This is explicit when/when-not/alternative guidance rather than implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_criteriona11y-toolkit: WCAG criterion explainedARead-onlyIdempotent
Explains a WCAG 2.2 success criterion in plain language (es/en): what it requires, typical failures, and how to verify it with this toolkit (which tool automates which part). Codes like "1.4.3", "2.5.8", "4.1.2". Give a finding SIGNAL instead (e.g. img_no_alt, kbd_trap — the id in every audit finding) and it resolves to its criterion AND its published ACT rule(s) with official w3.org links. Use it whenever you need to explain WHY a finding matters or what the criterion actually says. — Knowledge lookup; does not fetch or audit anything — includes the official Understanding WCAG 2.2 link for the criterion. Returns JSON: {criterion, level, understanding, toolkit_signals, requires, typical_failures, how_to_check} — signal mode adds {signal, act_rules [{id, name, status, url}]}; {error, …} for unknown codes.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | criterion number, e.g. 1.4.3 (or give signal) | |
| lang | No | Explanation language (default en) | |
| signal | No | engine signal id from a finding (e.g. img_no_alt, kbd_trap) — resolves criterion + ACT rules with w3.org links |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: it declares a pure knowledge lookup with no fetching/auditing, discloses the exact return shape including a signal mode that adds ACT rules with w3.org links, and documents the error shape for unknown codes. That goes well past readOnlyHint/idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and usage trigger, but the tail is dense — the return-shape sentence and the interleaved 'includes the official Understanding WCAG 2.2 link' aside sit awkwardly after the 'does not fetch' note. Slight restructuring would earn the fifth point; no sentence is truly wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating all returned fields plus the signal-mode additions and error case. With optional params (required: 0) fully explained, an agent has everything needed to call it correctly and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, but the description adds real meaning: it names the accepted code format ('1.4.3', '2.5.8', '4.1.2'), explains that signal ids are 'the id in every audit finding', and states the default language is English. The interaction between code and signal modes (signal resolves criterion AND ACT rules) is clarified beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb + resource: 'Explains a WCAG 2.2 success criterion in plain language' with the exact contents of the explanation (requirements, typical failures, verification). It also clearly distinguishes itself from the audit siblings by stating 'Knowledge lookup; does not fetch or audit anything.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit trigger: 'Use it whenever you need to explain WHY a finding matters or what the criterion actually says.' It also gives two concrete input routes (criterion codes like '1.4.3' or a finding signal like img_no_alt) and an explicit negative scope ('does not fetch or audit anything'), routing agents to the audit tools for those needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_diffa11y-toolkit: Snapshot regression diffARead-onlyIdempotent
Regression diff between two accessibility snapshots (before/after a deploy): added/removed/renamed interactives and focus-order changes. ok=false means a regression to review. Accepts inline JSON (starting with "{") or file paths. — Compares two existing snapshots; a11y_diff_urls snapshots both for you. Returns JSON: {ok, added, removed, renamed, focus_order_changed, first_differences} — ok:false means a regression to review.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | BEFORE snapshot (inline JSON or path) | |
| b | Yes | AFTER snapshot (inline JSON or path) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered; the description goes further by disclosing input handling (inline JSON starting with '{' or file paths) and the meaning of the ok flag. It stops short of noting failure modes (malformed/incompatible snapshot versions) or large-payload limits, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded well, but content is duplicated: 'ok=false means a regression to review' appears in the opening sentence and again in the trailing return-shape sentence (via 'ok:false means a regression to review'). Trimming one occurrence would tighten it without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return contract and does so reasonably (ok, added, removed, renamed, focus_order_changed, first_differences). It does not explain the element format inside added/removed or how renames are detected, which a caller consuming the diff might want, but the essentials for correct invocation are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already labels a/b as BEFORE/AFTER inline JSON or path, so baseline is 3. The description adds genuinely useful detail beyond the schema: the '{'-prefix heuristic for distinguishing inline JSON from a file path, which the schema does not state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Regression diff between two accessibility snapshots') and immediately scopes it ('before/after a deploy') with the concrete artifacts diffed (added/removed/renamed interactives, focus-order changes). It explicitly differentiates from the sibling a11y_diff_urls, so an agent can choose between them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the operative condition for this tool versus the alternative: 'Compares two existing snapshots; a11y_diff_urls snapshots both for you.' That is an explicit when-to-use/when-to-use-the-other split, plus interpretation guidance ('ok=false means a regression to review') that tells the agent what to do with the result.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_diff_urlsa11y-toolkit: Staging vs production diffARead-onlyIdempotent
Snapshot two URLs and diff them in a single call (e.g. staging vs production). Requires local Playwright. — Convenience for staging-vs-production; manual control is snapshot + a11y_diff. Returns the same diff shape as a11y_diff, for two live URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| url_a | Yes | First URL (usually staging) | |
| url_b | Yes | Second URL (usually production) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds useful non-annotation context: a hard dependency on local Playwright, that the auth_state session 'stays local', and that the return shape matches a11y_diff.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Short and front-loaded with the core action and example. The em-dash fragment ('Convenience for...; manual control is...') is slightly choppy but each piece carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by stating the return shape matches a11y_diff, and it discloses the Playwright prerequisite. Adequate for a 3-param tool, though it says nothing about failure behavior when a URL is unreachable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters. The description reinforces the 'two live URLs' and staging-vs-production framing but adds no format or constraint detail beyond the schema, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific compound verb+resource ('snapshot two URLs and diff them in a single call') and explicitly differentiates from the sibling path (a11y_snapshot + a11y_diff). An agent can tell exactly what this is without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative workflow and frames this as the convenience path for staging-vs-production. It gives clear context for selection but stops short of stating explicit when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_disprovea11y-toolkit: Disprover: re-verify findingsARead-onlyIdempotent
Disprover pattern (from Cloudflare's security-audit-skill): re-runs the audit against the live page and marks each finding confirmed or rejected — findings that don't reproduce are rejected with the reason. Catches false positives, race conditions, and page changes between audit and report. Returns a fresh score over confirmed findings only. — Run this before acting on any audit report. Returns JSON: {confirmed, rejected, score} — a fresh score over confirmed findings only.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to re-verify against | |
| lang | No | Output language (en default) | |
| report | No | existing audit report (optional; if absent, audits first) | |
| timeout | No | Timeout seconds (30 default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive). The description adds real value beyond that: it explains the purpose (catching false positives, race conditions, page-change drift) and that rejected findings carry a reason. It stops short of describing how re-verification is performed or any rate/timeout behavior beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and useful, but the closing sentence duplicates itself: 'Returns a fresh score over confirmed findings only' appears twice, and the stray em-dash separator adds clutter. The core content is tight, but the redundancy is avoidable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by stating the JSON return shape {confirmed, rejected, score}. Combined with the annotations covering the safety profile, an agent has enough to invoke this correctly, though the nested report payload is not elaborated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters, including the optional report object and its fallback-to-audit behavior. The description adds no syntax or format detail beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (re-runs the audit) and resource (findings), and describes exactly what it produces: each finding confirmed or rejected. This is clearly distinguishable from siblings like a11y_audit_url or a11y_diff, which do not re-verify prior findings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Run this before acting on any audit report,' giving a clear when-to-use trigger. It does not, however, name the specific sibling that generates the report it consumes or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_docx_screena11y-toolkit: DOCX accessibility screeningARead-onlyIdempotent
DOCX accessibility screening — the other half of enterprise paperwork. Zero-dep structural pass on a LOCAL .docx: images with no alt text (docPr without descr), fake headings (bold+big paragraphs with no Heading style — invisible to navigation pane and TOC), document language, tables without marked header row. Full review needs a human; this finds what makes it pointless. Returns JSON: {mode: "docx", language, images, tables, findings, summary, limits}.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | output language | |
| path | Yes | local .docx file path |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so safety is covered. The description adds real value beyond them: it is a zero-dependency *structural* pass only, it cannot replace a human review, and it advertises a `limits` field in the response so the agent knows the output self-documents its blind spots.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the concrete checks, and the return-shape sentence at the end is useful. Minor flourish ("the other half of enterprise paperwork", "finds what makes it pointless") costs a little density but the substance is all present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by listing the returned JSON keys (mode, language, images, tables, findings, summary, limits). Combined with the enumerated checks and the explicit human-review caveat, an agent has enough to call it correctly; only per-parameter behavior of `lang` is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so `path` and the `lang` enum are already fully documented in the schema. The description reinforces the local-file constraint for `path` but says nothing about what `lang` changes in the output (finding text localization). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (.docx) and enumerates exactly what the pass checks: missing alt text (docPr without descr), fake headings, document language, and tables without a header row. This makes it trivially distinguishable from the PDF/DOM/URL audit siblings, which operate on different inputs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"LOCAL .docx" implies a file-path precondition and "Full review needs a human" signals this is a screening step, not a verdict. However, no sibling is named as the alternative (e.g., a11y_audit_pdf for PDFs, a11y_autofix for remediation), so routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_evidencea11y-toolkit: Evidence pack (verifiable handoff)ARead-onlyIdempotent
Builds the verifiable evidence pack: the machine→human handoff object for WCAG conformance work. Takes one or more audit reports (any mode — static, rendered, reflow, keyboard, scroll) and returns: the full 55-criterion A/AA matrix (automated-fail / automated-review / not-flagged — NOT pass / not-run / manual-only), each row priced with its human-effort class (MIN 1-3 / MED 5-10 / MAX 15-30 min of human review remaining) and total remaining minutes every artifact SHA-256-hashed with timestamps, an empty signature block (name, credential, date) whose statement must reference the pack's own sha256, and the tamper-evidence rule stated. Vendor-neutral: any qualified human can review it. Evidence, never conformance. — The tier-3 handoff object; feed it every audit report you have. Returns the pack JSON (a11y-evidence-pack/2); writes a file only when output_path is given. Run after the audits you trust, and pass verified codes from the manual checklist — agent-verified never erases an automated-fail.
| Name | Required | Description | Default |
|---|---|---|---|
| reports | Yes | audit report objects (any mode) | |
| reviewer | No | {"name":…, "credential":…, "review_date":…} to prefill the signature block | |
| snapshot | No | a11y_snapshot output (optional) | |
| verified | No | Criterion codes an agent/human verified against this sample (manual checklist protocol) — they become agent-verified in the matrix; automated-fail stays fail |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses the exact output contract (a11y-evidence-pack/2), that a file is written only when output_path is given, digest/timestamp stamping, an empty human-signature block, and the matrix's tri-state semantics (automated-fail / automated-review / not-flagged, explicitly NOT pass/not-run/manual-only). It also states the substantive rule that agent-verified codes never erase an automated-fail, which no annotation conveys. The one tension is that readOnlyHint=true while the tool can write a file, but the description surfaces that write condition explicitly rather than hiding it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, but the middle is a single ~90-word run-on of em-dash-separated fragments (effort classes, hashes, signature block, tamper rule) that is hard to parse quickly. Information density is high and little is pure filler, yet the compressed telegraphic style ('Evidence, never conformance.', caps-locked MIN/MED/MAX) costs readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing the return value and does so thoroughly: JSON shape, schema version, matrix states, effort pricing, signature block, tamper rule. The only real gap is the optional 'snapshot' input, whose role relative to 'reports' is never explained in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces 'reports' by urging the agent to pass every report and clarifies that 'verified' codes are promoted to agent-verified while automated-fail stands, but it says nothing about 'snapshot' and only alludes to 'reviewer' via the signature-block mention.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a concrete verb and resource: 'Builds the verifiable evidence pack: the machine→human handoff object for WCAG conformance work', and the payload contents are enumerated (55-criterion matrix, effort classes, SHA-256 hashes, signature block). It is unmistakably distinct from audit siblings like a11y_audit_url or a11y_reflow, though it never names a sibling or an alternative tool explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Run after the audits you trust' and 'feed it every audit report you have' establish clear sequencing and input breadth, and 'pass verified codes from the manual checklist' tells the agent what else to supply. The when-to-use context is solid, but no explicit exclusions or named alternatives (e.g. vs. a11y_generate_vpat or a11y_generate_declaration) are given for an agent choosing between report-producing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_forced_colorsa11y-toolkit: forced-colors survival heuristicARead-onlyIdempotent
Does content survive forced-colors: active (Windows High Contrast)? Loads the page normally, flags SVGs with hardcoded colored fills (they fall back to inherited and icons can vanish), then emulates forced-colors and compares. Review-grade heuristic — the definitive check is visual on Windows HCM; this prepares it. Heuristic rev 1: SVG fills only, images queued for the next rev. Returns JSON: {mode, normal, forced, score, findings, limits}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to test | |
| lang | No | output language | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | page load timeout seconds (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to test behind login — stays local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly/idempotent/non-destructive/openWorld), and the description adds substantial context beyond them: the exact two-phase procedure, the finding that hardcoded SVG fills fall back to inherited and icons can vanish, the heuristic-vs-definitive caveat, and the revision-1 scope limit. It also notes auth_state stays local, useful for a login-gated test.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core question the tool answers, then the mechanism, then the caveat, then the return shape. Every sentence earns its place; the revision-1 scoping note prevents a false expectation of image coverage and the inline JSON return list compensates for the absent output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape ({mode, normal, forced, score, findings, limits}). Combined with the disclosed scope limits, the heuristic-vs-definitive framing, and annotations covering safety, an agent has everything needed to decide to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents url, lang, browser, timeout, and auth_state. The description only loosely gestures at url ('loads the page') and auth ('behind login') without adding syntax, defaults, or format detail beyond what the schema provides — the baseline 3 for schema-driven parameters applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: tests whether content survives forced-colors: active (Windows High Contrast), and details the mechanism (load normally, flag hardcoded SVG fills, emulate forced-colors, compare). This is a uniquely identifiable function among the siblings — no other tool covers forced-colors, so differentiation is inherent and the scope is precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly frames the tool's place: 'Review-grade heuristic — the definitive check is visual on Windows HCM; this prepares it,' which tells the agent when the result is sufficient and when it is not. It also states current coverage limits (SVG fills only, images deferred). It stops short of naming sibling tools for adjacent checks (e.g. contrast tools), so it is strong but not exhaustive on alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_formsa11y-toolkit: Form error testingADestructive
Form error testing (3.3.1 Error Identification, 3.3.3 Error Suggestion) — the guided flow no competitor automates: fills every validatable field with INVALID data, really submits, and judges the post-submit DOM — are errors identified in text and associated with the field (aria-invalid + aria-describedby, error summary, role=alert), or does the form swallow them? Native browser validation counts as identification (unless the form has novalidate); forms that navigate on submit are honestly noted as not measurable in-page. Requires local Playwright. Returns JSON: per-field error judgments {field, submitted_value_class, error_identified, announced, suggestion_present} plus an overall 3.3.1/3.3.3 verdict. Use on test/staging forms, or forms you own: invalid data is REALLY submitted. Do not run against production forms that trigger real emails, orders or leads.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL with the form(s) to test | |
| lang | No | Output language (en default) | |
| timeout | No | Page load timeout seconds (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON to test forms behind login |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that invalid data is REALLY submitted (matching destructiveHint/openWorldHint), that local Playwright is required, what gets checked in the DOM (aria-invalid, aria-describedby, role=alert), and what is not measurable. The safety-critical warning about production forms is exactly the kind of context annotations alone cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, followed by mechanism, requirements, return shape and the safety caveat. It is information-dense but somewhat long and parenthetical, trading some readability for thoroughness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, destructive, output-bearing tool with no output schema, the description covers the mechanism, the return JSON shape, the prerequisites (local Playwright), the edge cases and the safety constraint. Nothing an agent needs to invoke it safely and correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter (url, lang, timeout, auth_state) is already documented in the schema. The description adds behavioral context rather than parameter-level detail — it implies forms behind login (auth_state) are supported but doesn't enrich the parameter syntax beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: it fills validatable fields with invalid data, really submits, and judges the post-submit DOM for WCAG 3.3.1/3.3.3 error identification and suggestion. This is clearly distinguishable from sibling audit tools like a11y_audit_url or a11y_audit_dom because it is the only one that actively submits a form and reads the resulting DOM.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use (test/staging forms or forms you own) and when-not-to-use (do not run against production forms that trigger real emails, orders or leads). It also defines edge-case handling: native browser validation counts unless the form has novalidate, and forms that navigate on submit are honestly marked as not measurable in-page.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_generate_declarationa11y-toolkit: Accessibility statement (EAA/RD 1112)ADestructiveIdempotent
Generates an Accessibility Statement in HTML: art. 10 RD 1112/2018 (Spanish public sector, framework="rd1112") or European Accessibility Act wording (Directive (EU) 2019/882 / Ley 11/2023, framework="eaa"; EN output uses Directive (EU) 2016/2102 / EAA wording). The generated document is itself accessible. Saves to output_path when given. — Legal statement generator; drive inaccessible_content from audit findings and a11y_evidence. Returns {html, summary} — the accessible legal statement; writes a file only when output_path is given.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Website URL the statement covers | |
| lang | No | Statement language (default en; es uses the Spanish legal wording) | |
| entity | Yes | Legal entity name as it should appear in the statement | |
| method | No | How conformance was evaluated (e.g. "self-evaluation: a11y-toolkit screening + manual review") | |
| status | Yes | Compliance state: full | partial | not_conformant (plena | parcial | no_conforme, pre-5.11, still accepted as aliases) | |
| feedback | No | Contact channel for accessibility feedback (email or URL) | |
| framework | No | rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector) | |
| complaints | No | Claim/complaint procedure URL or address (legally required in several jurisdictions) | |
| output_path | No | save the HTML here (optional) | |
| review_date | No | ISO date of the next scheduled review | |
| evaluation_date | No | ISO date of the last evaluation (YYYY-MM-DD) | |
| alternative_format | No | Where to get the content in an alternative accessible format | |
| inaccessible_content | No | Non-accessible content list: one string per item, ideally criterion + reason + alternative |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, which could alarm an agent given this is a document generator; the description resolves that by stating a file is written only when output_path is given, and that it returns {html, summary}. It also notes the generated document is itself accessible, a non-obvious quality guarantee. It doesn't say whether an existing file at output_path is overwritten.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and the framework fork in the first clause, and the emitter-style tagline at the end is useful rather than filler. It is dense with parenthetical legal citations, which costs a little readability but each clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter generator with no output schema, the description supplies the return shape ({html, summary}), the conditional side effect, and the legal/input sourcing guidance. What's missing is minor: overwrite semantics for output_path and how status/partial maps into the generated text.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all 13 parameters are already documented, and the description mostly restates them (framework values, output_path behavior, lang). It adds light legal context — EN wording falls under Directive (EU) 2016/2102 / EAA — but gives no guidance on the required triple (entity/url/status) or how status interacts with inaccessible_content. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and artifact — generates an Accessibility Statement in HTML — and pins down the two legal frameworks (rd1112 vs eaa) with the exact directives behind each. The trailing tagline 'Legal statement generator' separates it from the sibling audit tools and from a11y_generate_vpat without the agent needing to open a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete workflow guidance: populate inaccessible_content from audit findings and a11y_evidence, and pick framework=rd1112 for Spanish public sector vs eaa for private sector. It stops short of naming an explicit alternative for when a different statement format (e.g. VPAT) is wanted, so no exclusion rule is stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_generate_vpata11y-toolkit: VPAT 2.5 report (WCAG edition)ADestructiveIdempotent
Generates a VPAT 2.5 (WCAG edition) accessibility conformance report in accessible HTML from an a11y_evidence pack (or raw audit reports): the full 55-criterion WCAG 2.2 A/AA table with Remarks auto-filled from the pack (status, measured values, examples, remaining human effort) and every Conformance Level starting at Not Evaluated — automated fails force Does Not Support and a qualified human sets the final level via overrides (supports, partially_supports, does_not_support, not_applicable, not_evaluated). The document is a DRAFT until the signature block, which must reference the pack sha256, is completed. VPAT is the US/ADA counterpart of a11y_generate_declaration (EU/EAA): the machine fills Remarks, the human signs the claim. — The US/ADA counterpart of a11y_generate_declaration; feed it the a11y_evidence pack — levels stay Not Evaluated until a qualified human sets them. Returns {html, summary {level: count}, levels {code: level}, pack_sha256, draft} — the VPAT draft; writes a file only when output_path is given. Run after the audits you trust; a qualified human must set the final levels (overrides) and sign before publishing — the machine fills Remarks, never the claim.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Document language (default en) | |
| pack | No | a11y_evidence output (evidence pack); alternative to reports | |
| notes | No | Additional notes to include | |
| contact | No | Contact information for questions about this VPAT | |
| methods | No | Evaluation methods used (default: honest automated-screening note) | |
| product | Yes | Product name as it must appear in the VPAT | |
| reports | No | Audit report objects to bundle (when pack is not given, the pack is built here first) | |
| reviewer | No | {"name":…, "credential":…, "review_date":…} to prefill the signature block | |
| overrides | No | Criterion → conformance level set by a qualified human: {"1.1.1": "supports", "1.2.2": "not_applicable", …} | |
| output_path | No | save the VPAT HTML here (optional) | |
| report_date | No | VPAT report date ISO (default: today) | |
| product_description | No | Product description paragraph |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly=false, destructive=true, idempotent=true, openWorld=false; the description adds substantial context beyond them: levels start at 'Not Evaluated', automated fails force 'Does Not Support', the document is a DRAFT until the signature block (referencing pack sha256) is completed, and a file is written only when output_path is given. This is exactly the behavioral disclosure a mutation tool needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and information-dense, but redundant: the a11y_generate_declaration counterpart relationship is stated twice, and 'the machine fills Remarks, the human signs the claim' plus the 'levels stay Not Evaluated until a qualified human sets them' point are repeated across the main text and the trailing recap.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, nested-object tool with no output schema, the description supplies the return shape ({html, summary, levels, pack_sha256, draft}), the draft/signature workflow, the override semantics, and the file-write condition. An agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds real semantics: it explains the pack-versus-reports relationship, that the pack is built from reports when absent, the accepted override level vocabulary, and the conditional file-writing behavior of output_path. It adds value over the schema without fully re-documenting every field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Generates a VPAT 2.5 (WCAG edition) accessibility conformance report in accessible HTML from an a11y_evidence pack'), including the exact artifact (55-criterion WCAG 2.2 A/AA table). It explicitly distinguishes itself from the sibling a11y_generate_declaration by positioning VPAT as the US/ADA counterpart versus the EU/EAA declaration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use context ('Run after the audits you trust'), names the required input source (the a11y_evidence pack, or raw reports), and routes the agent between this tool and a11y_generate_declaration by region/standard. The preconditions (qualified human must set levels and sign) are spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_hovera11y-toolkit: Hover dismissibility (1.4.13)ARead-onlyIdempotent
Content on Hover or Focus (1.4.13): finds tooltip/overlay candidates, hovers each, and tests whether Escape dismisses the result — tooltips that do not dismiss are flagged. Requires local Playwright. — Scope: tooltips only; full audit is a11y_audit_dom, keyboard traps are a11y_keyboard. Returns JSON: {candidates, dismissed_on_escape, findings}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to test | |
| lang | No | Output language (en default) | |
| timeout | No | Page load timeout (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open-world), so credit goes to added context: the description discloses the actual interaction performed (hovers elements, presses Escape), the local-Playwright dependency, and that non-dismissing tooltips are flagged. It doesn't discuss limits on candidate count or timing/pagination of the hover probing, but the operational disclosure is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose first, then the scope/alternative routing, then the return shape. Every clause carries information; the 'Returns JSON' sentence is justified because there is no output schema, though it is the least essential element.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the return keys (candidates, dismissed_on_escape, findings), and it covers the environment requirement and the auth path via the schema. For a focused single-criterion checker with annotated safety, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (url, lang, timeout, auth_state) is already documented in the schema, including the enum and defaults. The description adds no parameter-level syntax or format detail beyond that, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific criterion (1.4.13 Content on Hover or Focus) and a concrete verb sequence: finds tooltip/overlay candidates, hovers each, tests whether Escape dismisses. It explicitly distinguishes itself from siblings by naming a11y_audit_dom and a11y_keyboard, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit scope ('tooltips only'), names the alternative for full audits (a11y_audit_dom) and for keyboard traps (a11y_keyboard), and states the prerequisite (local Playwright). Nothing about when to pick this vs. a sibling is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_html_validatea11y-toolkit: W3C Nu validationARead-onlyIdempotent
The W3C's own parser as a toolkit mode: checks a URL or raw HTML against the Nu Html Checker (validator.w3.org/nu) — doctype, encoding, structural validity, plus alt/lang/role issues from the authoritative source, mapped to WCAG criteria where they overlap. PRIVACY: html mode POSTs the document to the W3C service (url mode shares only the URL, like a11y_audit_url); self-hosted vnu instances supported via base_url for sensitive content. Returns JSON: Nu validator messages mapped to WCAG criteria where they overlap.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Page URL to validate (shares the URL with the W3C service) | |
| html | No | Raw HTML to validate — POSTs the content to validator.w3.org/nu; use url or a self-hosted instance for sensitive pages | |
| lang | No | Output language (en default) | |
| base_url | No | Base URL of a self-hosted vnu instance (docker ghcr.io/validator/validator) instead of the public W3C service |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, openWorld), and the description adds genuinely non-derivable behavior: html mode POSTs the document to the third-party W3C service, url mode shares only the URL, and base_url enables a self-hosted vnu. It also states the return shape, disclosing network/privacy implications the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then privacy, then return shape — a logical order with little waste. Minor redundancy: 'mapped to WCAG criteria where they overlap' appears twice (opening and closing sentence).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the return-value burden ('Returns JSON: Nu validator messages mapped to WCAG criteria'), covers all four parameters' semantics, and discloses the third-party network behavior. An agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3, but the description adds real meaning beyond the schema by tying url/html to their privacy consequences (URL-only vs full document POST) and explaining base_url's self-hosted purpose. It does not add format or syntax detail for lang beyond the enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (checks a URL or raw HTML) against a named authoritative engine (Nu Html Checker) and enumerates the scope: doctype, encoding, structural validity, plus alt/lang/role issues. An agent can tell this apart from generic audits like a11y_audit_url because it names the specific checker and its WCAG mapping.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear selection context among its own modes (url for URL-only sharing, html POSTs content, base_url for sensitive content via self-hosted vnu) and contrasts privacy behavior with a11y_audit_url. However, it never explicitly states when to prefer this tool over sibling audits like a11y_audit_dom or a11y_audit_url for a given validation goal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_journey_verdicta11y-toolkit: Blindfold journey verdictARead-onlyIdempotent
Blindfold journey verdict — the capability no other accessibility tool has: the agent attempted a REAL task (sign up, checkout, password reset) perceiving only the accessibility tree and acting by accessible name and keyboard; perceive via your browser accessibility snapshot (state-preserving). This turns its friction log into a deterministic scored verdict. Pass = task completable non-visually by the agent; friction items map to WCAG criteria and flow into the evidence pack (report:journey). Use with the blindfold-task prompt: act by accessible name, log friction per step, then call this. Task usability evidence, never conformance. Returns JSON: {verdict pass|partial|fail|blocked, score 0-100, findings [{criterion, severity, signal, issue, remediation, step}], summary, rules} — writes a file only when output_path is given. Run only after a real blindfold attempt (the blindfold-task prompt): the verdict prices the walk, it does not replace it.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | page(s) where the journey ran | |
| lang | No | output language | |
| task | Yes | {"goal": what the agent attempted, "kind": sign-up|checkout|password-reset|search|custom} | |
| steps | Yes | journey steps: {action, target (accessible name), perceived, friction?} — friction is {pattern: journey_* key} or {criterion, severity, issue, remediation?} | |
| outcome | Yes | {"completed": bool, "gave_up": bool, "workaround_used": bool, "notes"} | |
| output_path | No | write the full verdict JSON here instead of returning it inline |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered; the description adds genuinely new behavior: deterministic scoring, the pass criterion definition, friction-to-WCAG mapping, the evidence-pack handoff, and the conditional file write. The one nuance it states ("writes a file only when output_path is given") sits in mild tension with readOnlyHint=true, though a new opt-in artifact is not destructive and is not a real contradiction. It does not discuss rate limits or failure modes when the journey input is malformed, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and the return shape, and most sentences carry distinct information. It loses a point for promotional framing ("the capability no other accessibility tool has") and for restating the blindfold-task prerequisite twice with slightly different phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description supplies the return contract inline (verdict enum, 0-100 score, findings field list, summary, rules) plus the file-write side effect. Combined with the stated preconditions and the WCAG-mapping behavior, an agent has everything needed to invoke it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes beyond it by explaining the relationship between parameters — steps carry per-step friction either as a journey_* pattern key or as {criterion, severity, issue, remediation}, and those map into the returned findings. It also clarifies output_path's effect (full verdict written to file instead of returned inline). It doesn't add format detail for url/lang/task beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and artifact: it converts a blindfold journey's friction log into a deterministic scored verdict with pass/partial/fail/blocked. It also explicitly differentiates itself from the rest of the toolkit ("the capability no other accessibility tool has") and from conformance-oriented siblings ("Task usability evidence, never conformance"). An agent can distinguish it from a11y_audit_url or a11y_keyboard without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit preconditions and sequencing: "Run only after a real blindfold attempt (the blindfold-task prompt)" and "act by accessible name, log friction per step, then call this." It names the companion prompt as the alternative workflow and draws the boundary against conformance tooling, so both when-to-use and when-not are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_keyboarda11y-toolkit: Keyboard-trap detectorARead-onlyIdempotent
Keyboard-trap detection (2.1.2) with REAL Tab walking in Chromium: up to 60 real tab stops, cycle detection (the modal pattern), then the decisive test — does ESCAPE release the cycle? A modal that cycles and releases on Escape is correct and NOT reported; a cycle Escape cannot leave is a trap (high severity). Returns the full tab stop list too. Requires local Playwright. — Scope: keyboard traps (2.1.2); focus visibility is part of a11y_audit_dom. Returns JSON: {tab_stops, trap_detected, escape_releases, findings}. Run on pages with modals, dialogs or embedded apps; a plain content page has nothing to trap.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to Tab-walk (http/https or file://) | |
| lang | No | Output language (default en) | |
| browser | No | Browser engine (auto = detect the first available) | |
| max_steps | No | max real Tab presses (60 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to Tab-walk behind login |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds substantive runtime context: requires local Playwright, a 60 tab-stop ceiling, and the exact trap-vs-modal decision rule. It also previews the return payload keys, which is more than the annotations give.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the criterion number and capability, then the decision rule, then scope. Dense and mostly earning its space, though phrases like 'the decisive test' add dramatic flourish that could be trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-param open-world tool with no output schema, the description supplies the prerequisite (local Playwright), the scope boundary against a sibling, the severity model, and the return shape. An agent has everything needed to decide whether to call it and how to interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter including url, lang, browser, max_steps and auth_state is already documented. The description mentions Chromium and the 60-stop bound, but that largely restates the schema's own 'max real Tab presses (60 default)' and browser engine entries. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (keyboard-trap detection / 2.1.2) plus the mechanism (real Tab walking in Chromium) and the decisive discriminator (Escape releases the cycle). It also names the bound: focus visibility belongs to a11y_audit_dom, so an agent can separate it from that sibling without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use (pages with modals, dialogs or embedded apps) and an explicit when-not (a plain content page has nothing to trap), plus the sibling routing for the adjacent concern. It also states the not-a-bug case — a cycle that Escape releases is correct and NOT reported — which prevents false-positive chasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_ledgera11y-toolkit: Coverage ledger (persistent)ADestructive
Coverage ledger (from Cloudflare's security-audit-skill): persistent record of what has been audited, when, and with what result. Actions: record (add audit result), gaps (what has never been checked on a URL), summary (portfolio overview). Accumulates across runs — second audits show resolved findings. record returns the stored entry; gaps returns criteria never checked; summary returns {entries, active_signals, resolved, mean_score}. record after every audit run; gaps before planning the next pass. The ledger file accumulates across runs — give each project its own ledger_path.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL (for record/gaps) | |
| action | Yes | What to do | |
| report | No | audit report object (for record) | |
| ledger_path | No | ledger file path (default: a11y-ledger.json) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and non-idempotency, so the mutation profile is covered. The description adds genuinely non-obvious behavior: the ledger accumulates across runs, prior findings show as resolved on re-audit, and each project should get its own ledger_path. It does not clarify whether record overwrites existing entries for the same URL, which is the one gap given destructiveHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded: the identity sentence comes first, actions next, return shapes and timing last. Nearly every clause carries information, though the parenthetical attribution to Cloudflare's skill is marginally expendable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, yet the description supplies the return shape for each action (stored entry, never-checked criteria, and the {entries, active_signals, resolved, mean_score} object). Combined with the persistence model and required-parameter guidance, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds real value beyond the schema by scoping url to record/gaps and by advising 'give each project its own ledger_path,' which explains the default file's cross-project collision risk rather than just restating the default value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (persistent coverage ledger) and enumerates its three actions (record, gaps, summary) with what each does. No sibling tool in the list provides persistent audit history, so the function is unambiguous without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit sequencing guidance: 'record after every audit run; gaps before planning the next pass,' which tells the agent when to invoke each action. It stops short of naming alternative sibling tools to use instead when persistence is not needed, so it is clear context rather than full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_reduced_motiona11y-toolkit: prefers-reduced-motion honored?ARead-onlyIdempotent
Does the site HONOR prefers-reduced-motion? Loads the page normally, counts looping CSS animations (>0.15s infinite), then reloads emulating prefers-reduced-motion: reduce and counts again. If the number does not drop, the site ignores the user's preference (2.2.2; 2.3.3 AAA). Nobody else automates this — axe leaves it as manual review. Covers CSS animations and video[autoplay]; JS/WebGL/scroll-parallax remain manual. Returns JSON: {mode, normal, reduced, respects, score, findings, limits}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to test | |
| lang | No | output language | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | page load timeout seconds (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to test behind login — stays local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/idempotentHint already declaring the safe-read profile, the description adds real behavioral detail: the two-pass reload methodology, the specific animation threshold (>0.15s infinite), the video[autoplay] coverage, and the honest limits. That is exactly the context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core question, then method, then scope limits, then return shape — a good information hierarchy. Mild deduction: 'Nobody else automates this' is marketing filler that does not help an agent invoke the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description enumerates the return keys ({mode, normal, reduced, respects, score, findings, limits}), covers the manual-review boundaries, and already reflects the safety annotations. An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so url, lang, browser, timeout, and auth_state are already documented in the schema, including that auth_state stays local. The description adds no syntax or format detail beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific, testable verb+resource: it checks whether a site HONORS prefers-reduced-motion, and spells out the exact method (load, count looping animations, reload with reduce, recount). This is unmistakably distinct from siblings like a11y_forced_colors or a11y_reflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context — WCAG 2.2.2 / 2.3.3 AAA — and explicitly notes the alternative gap ('axe leaves it as manual review'), plus what remains manual (JS/WebGL/scroll-parallax). It stops short of explicit when-not-to-use framing, but a caller can infer scope well.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_reflowa11y-toolkit: 320px reflow checkARead-onlyIdempotent
Reflow check at 320px — criterion 1.4.10 (AA), the check axe and Lighthouse do not automate. Loads the URL at 1280px, then at 320px, and reports real horizontal scroll + the overflowing elements. Method note: browser zoom RE-LAYS OUT at 320 CSS px (that is the standard's own equivalence: 1280 @ 400% zoom = 320px), so the correct measurement is a 320px viewport. Requires local Playwright. — Scope: 320px reflow only (1.4.10); for the full rendered pass use a11y_audit_dom. Returns JSON: {url, viewport, horizontal_scroll, offenders [{selector, width}]}. Run once per template, not per page: fixed-width layouts are a property of the template.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to test at 320px (http/https or file://) | |
| lang | No | Output language (default en) | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | Page load timeout in seconds (default 45) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to test behind login |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial context beyond them: the two-pass measurement method (1280px then 320px), the rationale that zoom re-layout is equivalent to a 320px viewport, the local Playwright dependency, and the exact JSON return shape. Nothing about the tool's runtime behavior is left to inference.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the check name and criterion, then method, scope, and return shape in a tight sequence. It is on the long side and dense with em-dash asides, but each sentence carries distinct operational value (dependency, method rationale, exclusion, cardinality rule).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the return object ({url, viewport, horizontal_scroll, offenders[{selector, width}]}). Combined with the method note, scope boundary, and environment requirement, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (url, lang, browser, timeout, auth_state) is already documented structurally; the description only reinforces the 320px viewport semantics of url. It adds no syntax, format, or interaction detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reflow check at 320px') tied to a named WCAG criterion (1.4.10, AA), and explicitly claims the niche axe/Lighthouse leave uncovered. It routes away from a sibling by name ('for the full rendered pass use a11y_audit_dom'), so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use (320px reflow / 1.4.10), an explicit alternative with its selecting condition (a11y_audit_dom for the full rendered pass), and a cardinality rule ('run once per template, not per page'). The prerequisite ('requires local Playwright') is also stated up front.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_scrolla11y-toolkit: Infinite-scroll auditARead-onlyIdempotent
Infinite-scroll accessibility audit — the documented disaster nobody automates (Deque guidance + ARIA APG Feed pattern; criteria 2.4.3, 4.1.3, 2.2.2). Real scrolling batches in Chromium with a live-region observer: does the focused element SURVIVE each batch (re-render destroys it — the documented failure)? Is new content ANNOUNCED (aria-live/status receives text, role=feed)? Does the feed END or offer a load-more alternative (footer reachability)? APG feed pattern as positive signal. Honest guard: if no standard items are detected (login walls, non-standard markup) the unfounded signals are skipped with a note. Requires local Playwright. — For paginated feeds only; general page audit is a11y_audit_url/dom. Returns JSON: {mode, url, score, findings [{criterion, severity, signal, issue, remediation}], summary} — same shape as the audits.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Feed URL to audit (best on feeds you own or can authenticate into) | |
| lang | No | Output language (default en) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to audit an authenticated feed | |
| max_batches | No | scroll batches (5 default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/idempotent/non-destructive, but the description adds substantive behavior the agent cannot infer: real scrolling batches in a live browser, a live-region observer, a per-batch focus-survival test, and an explicit degradation guard that skips unfounded signals. It also discloses the return payload shape inline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and dense with useful specifics, and the alternative-tool routing comes before the return-shape note. Some flourish ("the documented disaster nobody automates") and embedded criteria lists cost a little density, but nothing is redundant with structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description responsibly describes the returned JSON (mode, url, score, findings, summary) and the finding fields. Minor gap: the score scale and severity taxonomy are not defined, leaving an agent unsure how to read a low score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all four parameters are already documented; the baseline would be 3. The description still adds meaning by framing max_batches as real scroll batches in a browser (implying runtime cost) and by advising to audit feeds you own or can authenticate into, which motivates the auth_state parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource — an infinite-scroll accessibility audit with real Chromium scrolling — and enumerates the three concrete checks (focus survival, live-region announcement, feed termination). It explicitly demarcates itself from a11y_audit_url/a11y_audit_dom, so an agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit usage boundary ("For paginated feeds only; general page audit is a11y_audit_url/dom") and a prerequisite ("Requires local Playwright"). It also states a when-not condition via the honest guard for login walls / non-standard markup, so the agent knows when results will be degraded.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_snapshota11y-toolkit: A11y snapshot + tab orderARead-onlyIdempotent
Accessibility snapshot of a URL: interactive elements (tag, role, accessible name, href) in DOM order, the REAL tab focus order, and when Playwright ≥1.49 is available the computed ACCESSIBILITY TREE (aria snapshot — what a screen reader announces). Save it before a deploy and compare after with a11y_diff. Requires local Playwright. — Capture half of the watch loop; compare with a11y_diff (or a11y_diff_urls for two live URLs). Returns JSON: {url, ts, elements [{tag, role, name, ref…}], focus_order}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to snapshot (http/https or file://) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to snapshot behind login |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, openWorld. The description adds real behavioral context beyond them: it requires local Playwright, the accessibility tree only appears with Playwright ≥1.49, and it documents the return shape. Not full marks because the Playwright dependency is stated without failure semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded, but the single sentence sprawls with nested parentheticals, an em-dash clause, and a trailing fragment about the watch loop and JSON shape. It is information-dense rather than wasteful, yet the run-on structure hurts scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description compensates by sketching the return JSON ({url, ts, elements, focus_order}) and the Playwright version condition. Combined with annotations covering the safety profile, an agent has enough to invoke it correctly, though auth/login flow details remain thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (url, auth_state) are documented in the schema itself, so the baseline is 3. The description mentions login context only obliquely via the 'watch loop' framing and never explains auth_state's format, adding little beyond the structured field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource (accessibility snapshot of a URL) and enumerates exactly what it captures: interactive elements in DOM order, real tab focus order, and the computed accessibility tree. It names sibling tools (a11y_diff, a11y_diff_urls) so an agent can distinguish this capture tool from the comparison tools without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context ('Save it before a deploy and compare after with a11y_diff') and explicitly routes to a11y_diff_urls for two live URLs. It stops short of stating when NOT to use it (e.g., when you only have a DOM string, where a11y_audit_dom/a11y_keyboard might apply), so it is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_sr_transcripta11y-toolkit: Screen reader transcriptARead-onlyIdempotent
Screen reader TRANSCRIPT: what a blind user HEARS on this page. Walks the accessibility tree linearly and returns the announcement text with roles, names and states — the linearized reading experience, as prose an agent can READ to understand the page from a blind user's perspective. — Read-only: for structure use a11y_snapshot, for keyboard traps use a11y_keyboard. Requires Playwright. Returns JSON: {url, total, announcements [{time, politeness, role, text}] — the linearized reading order}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Page URL to transcribe | |
| lang | No | Output language (en default) | |
| browser | No | Browser engine (auto = detect the first available) | |
| timeout | No | Page load timeout (45 default) | |
| auth_state | No | Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds real context beyond that: the linearized walk behavior, the Playwright dependency, and the exact return shape. It does not cover auth/permission needs beyond the schema's own auth_state note.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core concept and well organized with em-dash-separated clauses. Slightly repetitive ('the linearized reading experience' and 'as prose an agent can READ... from a blind user's perspective' say overlapping things), but no wasted structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with no output schema, the description supplies the return contract ({url, total, announcements [{time, politeness, role, text}]}), the dependency, and the sibling routing — everything an agent needs to invoke and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters (url, lang, browser, timeout, auth_state). The description adds no parameter-level detail beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Screen reader TRANSCRIPT: what a blind user HEARS on this page') and explains the mechanism — walking the accessibility tree linearly. It explicitly distinguishes itself from siblings by naming a11y_snapshot and a11y_keyboard.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'for structure use a11y_snapshot, for keyboard traps use a11y_keyboard.' It also flags the required dependency ('Requires Playwright'), giving the agent the conditions under which the tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_suggest_colora11y-toolkit: Nearest passing colorARead-onlyIdempotent
Nearest opaque color (RGB distance) to fg that reaches the target ratio against bg (4.5 default). Returns the color, its ratio and whether it lightens or darkens. — The fixer companion to a11y_contrast_pair failures. Returns JSON: {color, ratio, action} — the nearest opaque color reaching the target.
| Name | Required | Description | Default |
|---|---|---|---|
| bg | Yes | The background it must pass against | |
| fg | Yes | The failing foreground color to fix | |
| target | No | Ratio to reach: 4.5 normal text, 3.0 large text/UI, 7.0 AAA (default 4.5) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds genuinely new behavioral detail: the matching is by RGB distance, results are constrained to opaque colors, and the returned action indicates whether the color lightens or darkens. It does not mention edge cases (e.g. when no passing color exists) or tie-breaking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The front-loaded first sentence is excellent, but the return-value information is stated twice — once as prose ('Returns the color, its ratio and whether it lightens or darkens') and again as 'Returns JSON: {color, ratio, action}' — and the trailing clause 'the nearest opaque color reaching the target' repeats the opening. Roughly a third of the text is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly steps in to document the return payload {color, ratio, action}, and all three parameters are documented in the schema. The only real gap is the undefined failure case when no opaque color reaches the target ratio, which matters for an agent deciding how to handle the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already carries a description, including the target's ratio semantics and default. The description reinforces 'opaque' and the 4.5 default but adds no syntax or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation (find the nearest opaque color to fg that reaches a target contrast ratio against bg) and even names the algorithm (RGB distance). It explicitly positions itself as 'the fixer companion to a11y_contrast_pair failures,' which separates it from the diagnostic sibling a11y_contrast_pair without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: this is the remediation step after a contrast-pair check fails, with a sensible default target of 4.5. However, it never states when NOT to use it — notably it does not distinguish itself from the sibling a11y_autofix, which an agent could reasonably confuse for the same fixer role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_vtt_checka11y-toolkit: WebVTT caption qualityARead-onlyIdempotent
WebVTT caption QUALITY (1.2.2) — the substance, not the presence. Everyone stops at " exists"; this downloads and parses the actual .vtt and judges what viewers get: malformed timing lines, empty cues, overlaps, impossible reading speed (>21 chars/second, BBC/Netflix standard) and coverage vs the media duration when given. Pass the .vtt URL (same http/https guard as the audits). Not a substitute for human review of accuracy or speaker identification. Returns JSON: {mode: "vtt", cues, characters, captioned_seconds, findings [{criterion, severity, signal, issue, remediation}], summary, limits}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL of the .vtt caption file | |
| lang | No | output language | |
| duration | No | media duration in seconds — enables the coverage check (1.2.2 completeness) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the read-only, idempotent, open-world, non-destructive profile, so the bar is lower. The description adds real behavioral context: it fetches and parses an external file, applies a concrete reading-speed standard (>21 chars/second, BBC/Netflix), and discloses a 'limits' field and the human-review boundary. It stops short of stating failure modes (e.g., unreachable URL, non-VTT content).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first clause, with detail following. It is dense and longer than typical, but nearly every sentence carries signal; the return-shape sentence is justified because there is no output schema. Slightly heavy parentheticals cost it the top mark.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by sketching the JSON return ({mode, cues, characters, captioned_seconds, findings, summary, limits}), states the analysis thresholds, the coverage condition, and the human-review limitation. An agent has everything needed to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so url, lang, and duration are already documented in the schema, including that duration enables the coverage check. The description's mention of the 21 chars/second threshold adds marginal color around the duration parameter but otherwise restates schema-provided meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource: it downloads and parses the actual .vtt and judges caption quality (WCAG 1.2.2), enumerating what it inspects (timing lines, empty cues, overlaps, reading speed, coverage). It explicitly carves out its scope against the naive '<track> exists' check, so an agent can tell it apart from a presence-checking sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context: pass the .vtt URL, and passing duration enables the coverage/completeness check, plus an explicit when-not ('not a substitute for human review of accuracy or speaker identification'). It never names a specific sibling tool as the alternative, so the routing is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
a11y_wcag3_previewa11y-toolkit: WCAG 3 draft preview (no score)ARead-onlyIdempotent
WCAG 3 demo — the view layer nobody ships: takes an audit report and re-groups its WCAG 2.2 findings under the outcomes of the WCAG 3 Working Draft (10 September 2026). Informative only: WCAG 3 is not a completed standard, the W3C has published no official WCAG 2 to WCAG 3 mapping (this one is curated and labeled as such), and NO score, tier or conformance claim is produced — the draft's tier thresholds are still TBD. Use it to show teams where today's 2.2 findings will land tomorrow; keep auditing against WCAG 2.2. Returns JSON: {mode, draft, disclaimer, mapping_note, no_score, conformance_model, outcomes [{outcome, draft_url, findings, severity, signals, criteria_22}], counts, unmapped} — never a score. Run after any audit when the team asks "what about WCAG 3?"; re-baseline on each W3C draft publication (roughly March/September).
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Output language (en default) | |
| report | Yes | audit report object with a findings list (from a11y_audit_url, a11y_audit_dom, a11y_disprove, …) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description goes well beyond them: it discloses the pinned draft date, that the mapping is curated not W3C-official, that no score/tier/conformance is produced because thresholds are TBD, and that output is JSON with a fixed key set. That is exactly the behavioral context an agent needs before quoting results to a team.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then the disclaimer, then the return shape and cadence — good ordering. The no-score point is made three times ('Informative only', 'NO score, tier or conformance claim', 'never a score'), which is defensible emphasis for a headline risk but is mild redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by enumerating the full return object including outcomes, counts, unmapped and the disclaimer fields. Combined with the draft pinning and non-conformance caveats, nothing an agent needs to call or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented, and the description correctly scopes the input as an audit report whose findings are WCAG 2.2. It adds the source tools the report can come from, but says nothing about the lang parameter or edge cases like what happens to unmapped criteria beyond the 'unmapped' key.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it takes an audit report and re-groups WCAG 2.2 findings under WCAG 3 Working Draft outcomes. The framing ('the view layer nobody ships') and the explicit negation of scoring clearly separate it from the audit siblings like a11y_audit_url and a11y_ledger.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('Run after any audit when the team asks "what about WCAG 3?"'), an explicit counter-instruction ('keep auditing against WCAG 2.2'), and a maintenance cadence ('re-baseline on each W3C draft publication, roughly March/September'). An agent knows both when to reach for it and when not to.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v5.14.0- Changed
a11y_badge2 fields changed- added
Input schema / properties / dateAdded value: +{ + "description": "ISO date (today by default)", + "type": "string" +} - removed
Input schema / properties / fechaRemoved value: -{ - "description": "ISO date (today by default)", - "type": "string" -}
- Changed
a11y_criterion3 fields changed- changed
Input schema / properties / code / descriptionPrevious value: -"criterion number, e.g. 1.4.3"New value: +"criterion number, e.g. 1.4.3 (or give signal)" - added
Input schema / properties / signalAdded value: +{ + "description": "engine signal id from a finding (e.g. img_no_alt, kbd_trap) — resolves criterion + ACT rules with w3.org links", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "code" -]New value: +[]
- Changed
a11y_generate_declaration12 fields changed- added
Input schema / properties / alternative_formatAdded value: +{ + "description": "Where to get the content in an alternative accessible format", + "type": "string" +} - added
Input schema / properties / complaintsAdded value: +{ + "description": "Claim/complaint procedure URL or address (legally required in several jurisdictions)", + "type": "string" +} - removed
Input schema / properties / disponibilidad_alternativaRemoved value: -{ - "description": "Where to get the content in an alternative accessible format", - "type": "string" -} - changed
Input schema / properties / entity / descriptionPrevious value: -"Legal entity name as it should appear in the statement (company, body…)"New value: +"Legal entity name as it should appear in the statement" - added
Input schema / properties / evaluation_dateAdded value: +{ + "description": "ISO date of the last evaluation (YYYY-MM-DD)", + "type": "string" +} - removed
Input schema / properties / fecha_evaluacionRemoved value: -{ - "description": "ISO date of the last evaluation (YYYY-MM-DD)", - "type": "string" -} - changed
Input schema / properties / framework / descriptionPrevious value: -"Legal framework: rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector)"New value: +"rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector)" - added
Input schema / properties / methodAdded value: +{ + "description": "How conformance was evaluated (e.g. \"self-evaluation: a11y-toolkit screening + manual review\")", + "type": "string" +} - removed
Input schema / properties / metodoRemoved value: -{ - "description": "How conformance was evaluated (e.g. \"self-evaluation: a11y-toolkit screening + manual review\")", - "type": "string" -} - removed
Input schema / properties / reclamacionRemoved value: -{ - "description": "Claim/complaint procedure URL or address (legally required in several jurisdictions)", - "type": "string" -} - changed
Input schema / properties / status / descriptionPrevious value: -"Compliance state: plena | parcial | no_conforme (parcial is the honest default when findings exist)"New value: +"Compliance state: full | partial | not_conformant (plena | parcial | no_conforme, pre-5.11, still accepted as aliases)" - changed
Input schema / properties / status / enumPrevious value: -[ - "plena", - "parcial", - "no_conforme" -]New value: +[ + "full", + "partial", + "not_conformant" +]
- Changed
a11y_keyboard2 fields changed- removed
Input schema / properties / max_pasosRemoved value: -{ - "description": "max real Tab presses (60 default)", - "type": "integer" -} - added
Input schema / properties / max_stepsAdded value: +{ + "description": "max real Tab presses (60 default)", + "type": "integer" +}
- Changed
a11y_scroll2 fields changed- added
Input schema / properties / max_batchesAdded value: +{ + "description": "scroll batches (5 default)", + "type": "integer" +} - removed
Input schema / properties / max_tandasRemoved value: -{ - "description": "scroll batches (5 default)", - "type": "integer" -}
- Added
a11y_wcag3_preview
3 tool updates
v5.9.0- Added
a11y_docx_screen - Added
a11y_forced_colors - Added
a11y_reduced_motion
3 tool updates
v5.8.0- Changed
a11y_audit_dom1 field changed- added
Input schema / properties / color_schemeAdded value: +{ + "description": "Emulate prefers-color-scheme: run the contrast pass in dark mode too — dark themes fail where light passes (nobody audits both)", + "enum": [ + "light", + "dark" + ], + "type": "string" +}
- Added
a11y_audit_pdf - Added
a11y_vtt_check
6 tool updates
v5.6.0- Changed
a11y_audit_dom1 field changed- removed
Input schema / browserRemoved value: -{ - "description": "Browser engine (auto = detect the first available)", - "enum": [ - "auto", - "chromium", - "firefox", - "webkit", - "chrome", - "msedge" - ], - "type": "string" -}
- Changed
a11y_autofix2 fields changed- added
Input schema / properties / form_errorsAdded value: +{ + "description": "inject the accessible form-error layer into forms without their own handling (default true)", + "type": "boolean" +} - added
Input schema / properties / urlAdded value: +{ + "description": "URL context for the report metadata (default: \"(html)\")", + "type": "string" +}
- Changed
a11y_forms1 field changed- removed
Input schema / browserRemoved value: -{ - "description": "Browser engine (auto = detect the first available)", - "enum": [ - "auto", - "chromium", - "firefox", - "webkit", - "chrome", - "msedge" - ], - "type": "string" -}
- Changed
a11y_keyboard1 field changed- removed
Input schema / browserRemoved value: -{ - "description": "Browser engine (auto = detect the first available)", - "enum": [ - "auto", - "chromium", - "firefox", - "webkit", - "chrome", - "msedge" - ], - "type": "string" -}
- Changed
a11y_reflow1 field changed- removed
Input schema / browserRemoved value: -{ - "description": "Browser engine (auto = detect the first available)", - "enum": [ - "auto", - "chromium", - "firefox", - "webkit", - "chrome", - "msedge" - ], - "type": "string" -}
- Changed
a11y_scroll1 field changed- removed
Input schema / browserRemoved value: -{ - "description": "Browser engine (auto = detect the first available)", - "enum": [ - "auto", - "chromium", - "firefox", - "webkit", - "chrome", - "msedge" - ], - "type": "string" -}
12 tool updates
v5.5.0- Changed
a11y_audit_dom1 field changed- added
Input schema / properties / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +}
- Changed
a11y_audit_url2 fields changed- added
Input schema / properties / pages / maximumAdded value: +20 - added
Input schema / properties / pages / minimumAdded value: +1
- Added
a11y_contrast_dom - Changed
a11y_diff_urls1 field changed- added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local", + "type": "string" +}
- Changed
a11y_disprove2 fields changed- removed
Input schema / properties / informeRemoved value: -{ - "description": "existing audit report (optional; if absent, audits first)", - "type": "object" -} - added
Input schema / properties / reportAdded value: +{ + "description": "existing audit report (optional; if absent, audits first)", + "type": "object" +}
- Added
a11y_generate_vpat - Changed
a11y_hover1 field changed- added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local", + "type": "string" +}
- Added
a11y_journey_verdict - Changed
a11y_keyboard1 field changed- added
Input schema / properties / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +}
- Changed
a11y_ledger2 fields changed- removed
Input schema / properties / informeRemoved value: -{ - "description": "audit report object (for record)", - "type": "object" -} - added
Input schema / properties / reportAdded value: +{ + "description": "audit report object (for record)", + "type": "object" +}
- Changed
a11y_reflow1 field changed- added
Input schema / properties / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +}
- Changed
a11y_sr_transcript2 fields changed- added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to audit behind login — stays local", + "type": "string" +} - added
Input schema / properties / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +}
2 tool updates
v5.0.0- Changed
a11y_evidence7 fields changed- removed
Input schema / properties / evaluadorRemoved value: -{ - "description": "{\"nombre\":…, \"credencial\":…, \"fecha_revision\":…} to prefill the signature block", - "type": "object" -} - removed
Input schema / properties / informesRemoved value: -{ - "description": "audit report objects (any mode)", - "items": { - "type": "object" - }, - "type": "array" -} - added
Input schema / properties / reportsAdded value: +{ + "description": "audit report objects (any mode)", + "items": { + "type": "object" + }, + "type": "array" +} - added
Input schema / properties / reviewerAdded value: +{ + "description": "{\"name\":…, \"credential\":…, \"review_date\":…} to prefill the signature block", + "type": "object" +} - removed
Input schema / properties / verificadosRemoved value: -{ - "description": "Criterion codes an agent/human verified against this sample (manual checklist protocol) — they become agent-verified in the matrix; automated-fail stays fail", - "items": { - "type": "string" - }, - "type": "array" -} - added
Input schema / properties / verifiedAdded value: +{ + "description": "Criterion codes an agent/human verified against this sample (manual checklist protocol) — they become agent-verified in the matrix; automated-fail stays fail", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / requiredPrevious value: -[ - "informes" -]New value: +[ + "reports" +]
- Changed
a11y_generate_declaration11 fields changed- removed
Input schema / properties / contenido_no_accesibleRemoved value: -{ - "description": "Non-accessible content list: one string per item, ideally criterion + reason + alternative", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Input schema / properties / entidadRemoved value: -{ - "description": "Legal entity name as it should appear in the statement (company, body…)", - "type": "string" -} - added
Input schema / properties / entityAdded value: +{ + "description": "Legal entity name as it should appear in the statement (company, body…)", + "type": "string" +} - removed
Input schema / properties / estadoRemoved value: -{ - "description": "Compliance state: plena | parcial | no_conforme (parcial is the honest default when findings exist)", - "enum": [ - "plena", - "parcial", - "no_conforme" - ], - "type": "string" -} - removed
Input schema / properties / fecha_revisionRemoved value: -{ - "description": "ISO date of the next scheduled review", - "type": "string" -} - added
Input schema / properties / frameworkAdded value: +{ + "description": "Legal framework: rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector)", + "enum": [ + "rd1112", + "eaa" + ], + "type": "string" +} - added
Input schema / properties / inaccessible_contentAdded value: +{ + "description": "Non-accessible content list: one string per item, ideally criterion + reason + alternative", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / marcoRemoved value: -{ - "description": "Legal framework: rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector)", - "enum": [ - "rd1112", - "eaa" - ], - "type": "string" -} - added
Input schema / properties / review_dateAdded value: +{ + "description": "ISO date of the next scheduled review", + "type": "string" +} - added
Input schema / properties / statusAdded value: +{ + "description": "Compliance state: plena | parcial | no_conforme (parcial is the honest default when findings exist)", + "enum": [ + "plena", + "parcial", + "no_conforme" + ], + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "entidad", - "url", - "estado" -]New value: +[ + "entity", + "url", + "status" +]
19 tool updates
v4.0.0- Changed
a11y_audit_dom4 fields changed- added
Input schema / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +} - added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to audit behind login — local file, never uploaded", + "type": "string" +} - added
Input schema / properties / lang / descriptionAdded value: +"Output language for findings and remediation (default en)" - added
Input schema / properties / url / descriptionAdded value: +"Page URL to load in Chromium (http/https or file:// for local fixtures)"
- Changed
a11y_badge1 field changed- added
Input schema / properties / lang / descriptionAdded value: +"Badge language (default en)"
- Changed
a11y_contrast_image5 fields changed- added
Input schema / properties / lang / descriptionAdded value: +"Output language (default en)" - added
Input schema / properties / path / descriptionAdded value: +"Local path to the screenshot/image the text sits on (PNG/JPG/PPM)" - added
Input schema / properties / region / descriptionAdded value: +"Text bounding box as \"x,y,width,height\" in pixels (strongly recommended: defines what to sample)" - added
Input schema / properties / sample / descriptionAdded value: +"Pixel step: 4 samples every 4px (auto-raised for huge regions)" - added
Input schema / properties / text_color / descriptionAdded value: +"The text color as rendered over the image (must be opaque)"
- Changed
a11y_contrast_pair2 fields changed- added
Input schema / properties / bg / descriptionAdded value: +"Background color: same formats; alpha composites over white" - added
Input schema / properties / fg / descriptionAdded value: +"Foreground/text color: #hex, rgb(), hsl() or a CSS color name; alpha composites over bg"
- Changed
a11y_criterion1 field changed- added
Input schema / properties / lang / descriptionAdded value: +"Explanation language (default en)"
- Changed
a11y_diff_urls2 fields changed- added
Input schema / properties / url_a / descriptionAdded value: +"First URL (usually staging)" - added
Input schema / properties / url_b / descriptionAdded value: +"Second URL (usually production)"
- Added
a11y_disprove - Changed
a11y_evidence1 field changed- added
Input schema / properties / verificadosAdded value: +{ + "description": "Criterion codes an agent/human verified against this sample (manual checklist protocol) — they become agent-verified in the matrix; automated-fail stays fail", + "items": { + "type": "string" + }, + "type": "array" +}
- Added
a11y_forms - Changed
a11y_generate_declaration12 fields changed- added
Input schema / properties / contenido_no_accesible / descriptionAdded value: +"Non-accessible content list: one string per item, ideally criterion + reason + alternative" - added
Input schema / properties / disponibilidad_alternativa / descriptionAdded value: +"Where to get the content in an alternative accessible format" - added
Input schema / properties / entidad / descriptionAdded value: +"Legal entity name as it should appear in the statement (company, body…)" - added
Input schema / properties / estado / descriptionAdded value: +"Compliance state: plena | parcial | no_conforme (parcial is the honest default when findings exist)" - added
Input schema / properties / fecha_evaluacion / descriptionAdded value: +"ISO date of the last evaluation (YYYY-MM-DD)" - added
Input schema / properties / fecha_revision / descriptionAdded value: +"ISO date of the next scheduled review" - added
Input schema / properties / feedback / descriptionAdded value: +"Contact channel for accessibility feedback (email or URL)" - added
Input schema / properties / lang / descriptionAdded value: +"Statement language (default en; es uses the Spanish legal wording)" - added
Input schema / properties / marco / descriptionAdded value: +"Legal framework: rd1112 (Spanish public sector, art. 10) or eaa (European Accessibility Act / private sector)" - added
Input schema / properties / metodo / descriptionAdded value: +"How conformance was evaluated (e.g. \"self-evaluation: a11y-toolkit screening + manual review\")" - added
Input schema / properties / reclamacion / descriptionAdded value: +"Claim/complaint procedure URL or address (legally required in several jurisdictions)" - added
Input schema / properties / url / descriptionAdded value: +"Website URL the statement covers"
- Added
a11y_hover - Added
a11y_html_validate - Changed
a11y_keyboard4 fields changed- added
Input schema / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +} - added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to Tab-walk behind login", + "type": "string" +} - added
Input schema / properties / lang / descriptionAdded value: +"Output language (default en)" - added
Input schema / properties / url / descriptionAdded value: +"Page URL to Tab-walk (http/https or file://)"
- Added
a11y_ledger - Changed
a11y_reflow5 fields changed- added
Input schema / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +} - added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to test behind login", + "type": "string" +} - added
Input schema / properties / lang / descriptionAdded value: +"Output language (default en)" - added
Input schema / properties / timeout / descriptionAdded value: +"Page load timeout in seconds (default 45)" - added
Input schema / properties / url / descriptionAdded value: +"Page URL to test at 320px (http/https or file://)"
- Changed
a11y_scroll4 fields changed- added
Input schema / browserAdded value: +{ + "description": "Browser engine (auto = detect the first available)", + "enum": [ + "auto", + "chromium", + "firefox", + "webkit", + "chrome", + "msedge" + ], + "type": "string" +} - added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to audit an authenticated feed", + "type": "string" +} - added
Input schema / properties / lang / descriptionAdded value: +"Output language (default en)" - added
Input schema / properties / url / descriptionAdded value: +"Feed URL to audit (best on feeds you own or can authenticate into)"
- Changed
a11y_snapshot2 fields changed- added
Input schema / properties / auth_stateAdded value: +{ + "description": "Path to a Playwright storage_state JSON (exported session) to snapshot behind login", + "type": "string" +} - added
Input schema / properties / url / descriptionAdded value: +"Page URL to snapshot (http/https or file://)"
- Added
a11y_sr_transcript - Changed
a11y_suggest_color3 fields changed- added
Input schema / properties / bg / descriptionAdded value: +"The background it must pass against" - added
Input schema / properties / fg / descriptionAdded value: +"The failing foreground color to fix" - added
Input schema / properties / target / descriptionAdded value: +"Ratio to reach: 4.5 normal text, 3.0 large text/UI, 7.0 AAA (default 4.5)"
4 tool updates
v3.12.0- Changed
a11y_aria_live_snippet1 field changed- changed
Input schema / properties / lang / descriptionPrevious value: -"monitor panel language (es default)"New value: +"monitor panel language (en default)"
- Changed
a11y_audit_url1 field changed- changed
Input schema / properties / lang / descriptionPrevious value: -"output language (es default)"New value: +"output language (en default)"
- Changed
a11y_contrast_pair1 field changed- changed
Input schema / properties / lang / descriptionPrevious value: -"output language (es default)"New value: +"output language (en default)"
- Added
a11y_evidence
12 tool updates
v3.3.0- Changed
a11y_aria_live_snippet1 field changed- changed
Input schema / properties / lang / descriptionPrevious value: -"Idioma del panel del monitor (es por defecto)"New value: +"monitor panel language (es default)"
- Added
a11y_audit_dom - Changed
a11y_audit_url6 fields changed- added
Input schema / properties / htmlAdded value: +{ + "description": "raw HTML to audit directly (overrides url)", + "type": "string" +} - added
Input schema / properties / lang / descriptionAdded value: +"output language (es default)" - added
Input schema / properties / pagesAdded value: +{ + "description": "light same-domain crawl: audit up to N pages, aggregated by score and recurring signals (default 1, max 20)", + "type": "integer" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "fetch timeout seconds (30 default)", + "type": "number" +} - added
Input schema / properties / url / descriptionAdded value: +"URL to fetch and audit" - removed
Input schema / requiredRemoved value: -[ - "url" -]
- Added
a11y_autofix - Added
a11y_badge - Changed
a11y_contrast_pair1 field changed- changed
Input schema / properties / lang / descriptionPrevious value: -"Idioma de la salida (es por defecto)"New value: +"output language (es default)"
- Added
a11y_criterion - Changed
a11y_diff2 fields changed- changed
Input schema / properties / a / descriptionPrevious value: -"Snapshot ANTES (JSON inline o ruta)"New value: +"BEFORE snapshot (inline JSON or path)" - changed
Input schema / properties / b / descriptionPrevious value: -"Snapshot DESPUÉS (JSON inline o ruta)"New value: +"AFTER snapshot (inline JSON or path)"
- Changed
a11y_generate_declaration2 fields changed- removed
Input schema / properties / lang / descriptionRemoved value: -"Idioma de la declaración (es por defecto; en = Directive (EU) 2016/2102 / EAA wording)" - changed
Input schema / properties / output_path / descriptionPrevious value: -"Guarda el HTML en esta ruta (opcional)"New value: +"save the HTML here (optional)"
- Added
a11y_keyboard - Added
a11y_reflow - Added
a11y_scroll
9 tool updates
v2.3.0- First observed
a11y_aria_live_snippet - First observed
a11y_audit_url - First observed
a11y_contrast_image - First observed
a11y_contrast_pair - First observed
a11y_diff - First observed
a11y_diff_urls - First observed
a11y_generate_declaration - First observed
a11y_snapshot - First observed
a11y_suggest_color
TDQS
Scored across 32 tools
Most tools target distinct resources or audit modalities, and descriptions explicitly route between near neighbors such as audit_url vs audit_dom, contrast_pair/image/dom, snapshot vs sr_transcript, and diff vs diff_urls. Some residual overlap remains among the general audit and contrast families, so it is not perfect.
All tools use the a11y_ prefix and snake_case, with predictable noun or action segments. However, the set mixes verb-led names like audit_url and generate_vpat with noun-led names like badge, evidence, and ledger, so it is not a strict verb_noun convention.
32 tools is well above the 3-15 well-scoped range and is heavy for an agent to navigate, even though many are specialized checks. Several could be consolidated or grouped under modes to reduce selection burden.
The surface spans static and rendered audits, specialized checks for keyboard, reflow, forms, motion, and contrast, document/PDF/DOCX/VTT screening, evidence/VPAT/declaration outputs, snapshots, diffs, and a coverage ledger. There are no obvious lifecycle dead ends for accessibility auditing and conformance evidence.
Maintenance
Related MCP Connectors
Accessibility compliance for AI coding tools. WCAG 2.2 reviews with shared evidence.
Scan URLs for WCAG 2.1 violations, generate AI fixes, and produce VPAT 2.5 compliance reports.
Run accessibility, contrast, and design token audits and file QA issues from your AI coding tool.
Free WCAG 2.2/ADA/508 accessibility MCP: scan, AI fixes, verify, vision audit, localhost tunnel
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables 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.3MIT
- AlicenseAqualityCmaintenanceProvides conversational, actionable accessibility testing for AI agents, including auditing, prioritization, and code-level fixes.225 npmMIT
- AlicenseAqualityDmaintenanceEnables AI agents to perform comprehensive web accessibility checks (WCAG 2.1/2.2) including color contrast analysis, ARIA validation, and full accessibility report generation without requiring any API key.822 PyPIMIT
- AlicenseNot gradedqualityDmaintenanceProvides AI agents with web accessibility analysis tools via MCP, enabling checks for alt text, heading hierarchy, color contrast, ARIA validation, and form accessibility.11 npmMIT