AI-first multi-standard accessibility scanner. MCP-server-first design. Zero runtime dependencies. WCAG 2.2/2.1, Section 508, EN 301 549 out of the box.
ra11y (pronounced "rally") is built primarily for an AI coding agent calling its tools — not a human staring at a dashboard. Every response shape, noise-vs-signal decision, and per-finding hint is designed for one-shot agent triage: a scan returns ranked findings with WCAG citations, ready-to-paste suppression comments, primary fix paths, and a nextStep pointer so the loop closes in one round-trip.
That doesn't make it agent-only. ra11y ships a CLI with terminal output, multiple report formats, and precommit integration. It covers JSX/TSX, HTML, CSS, and SCSS across WCAG 2.2, WCAG 2.1, Section 508, and EN 301 549 — and a plugin API for adding more.
The rule engine, plugin API, multi-standard registry, output formatters, reports (coverage, checklist, VPAT, certification), and MCP server are all in tree and exercised by the test suite.
Known gaps the maintainers are tracking — none are silent failures, but worth knowing if you're integrating today:
checklist/coveragelack the minimum-honest-envelope fallback thatscan_projecthas. On large or bulk-vendor corpora these two surfaces can exceed the MCP host token cap and surface only a transport error. Workaround: scope down withpaths,restrictToPaths, or callscan_projectfirst to triage.bootstraptool'ssuggestedConfig.excludeis over-eager on bulk-template catalogs. Don't paste the suggested config blindly on corpora ≥1000 files; review the generatedexcludelist first. Fix in flight.scan_filereviewCandidates[].priority/.confidenceship asnullwhile the same candidates onchecklist.items[].candidates[]populate both. Usechecklistfor the ranked view.
The full backlog of in-flight shape-honesty work lives at .claude/backlog.md.
- AI-first MCP server. An agent-native tool surface — scan, checklist, suggest-fix, detect-native-wrappers — with responses shaped for one-shot triage (ranked fix paths, per-finding suppression pragmas,
nextStephints, scan-confidence telemetry, structured warnings the agent can act on). The full inventory ships viatools/list; current source-of-truth issrc/mcp/. - Zero runtime dependencies.
dependencies: {}is empty and enforced in CI viascripts/check-zero-deps.ts. Everything in-house — JSX/TSX parsing via the optional TypeScript peer dep, the rest is hand-rolled. - Multi-standard by architecture. Standards → Criteria → Rules. One rule satisfies WCAG 2.2, WCAG 2.1, Section 508, and EN 301 549 simultaneously via cross-standard
equivalentTomappings. Adding a new standard never touches rule code. - Surface, don't suppress. Doctrine documented at
docs/kb/architecture/ai-first-consumer.md. False positives are cheap for an agent to dismiss in one read; silent under-emission isn't reversible. The default everywhere is to surface honestly with enough context for the agent to triage, then let the agent suppress at the source via deterministic pragmas. - Network isolation.
src/never importsfetch/node:http/node:net/node:dns. Enforced byscripts/check-network-isolation.ts. A compliance tool scanning proprietary source has to be offline by construction. - Precommit-speed. Sub-second on typical commits. Performance budget in
scripts/bench.ts, enforced in CI; budgets and history atdocs/performance.md.
ra11y separates what to check (rules) from why it matters (criteria) from which framework cares (standards):
Standards (WCAG 2.2, 2.1, Section 508, EN 301 549)
└─ declares
Criteria (e.g. wcag22:1.4.3, section508:1194.22.c)
└─ satisfied by
Rules (e.g. contrast/minimum, alt-text/missing)
A scan with --standard section508 activates the same contrast/minimum rule and cites the Section 508 criterion ID in output — no rule changes needed. Adding a new standard is one file with criterion records + equivalentTo pointers into the existing standards.
Architecture deep-dive: docs/architecture.md. Rule authoring: docs/kb/patterns/writing-a-rule.md. Three-layer model: docs/kb/architecture/three-layer-model.md.
npm install --save-dev @ra11y/core
# or
bun add -d @ra11y/coreOr run without installing:
npx @ra11y/core src/ra11y src/ # Scan a directory
ra11y --changed # Scan only git-staged files (precommit)
ra11y --since main # Scan files changed since a git ref
ra11y --standard wcag22,section508 # Run multiple standards at once
ra11y --level AA # Enforce conformance level
ra11y --format sarif # GitHub code scanning output
ra11y --format json # Structured JSON for pipelines
ra11y --baseline=create # Freeze existing violations
ra11y --baseline=check # Only new violations fail the scan
ra11y --coverage # Per-standard coverage summary
ra11y --vpat # Generate VPAT-ready report
ra11y --certification # Generate readiness scorecard
ra11y --checklist # Manual review checklist
ra11y --explain contrast/minimum # Rule detail, spec quote, examples
ra11y --list-rules # All built-in rules
ra11y --list-standards # All built-in standardsFull reference: docs/cli.md.
ra11y ships a built-in MCP server so AI coding agents (Claude Code, Cursor, Zed, Continue) can scan, explain, and fix accessibility issues interactively.
Setup — add this to your project's .mcp.json:
The explicit --package=@ra11y/core ra11y form is required because the package name (@ra11y/core) doesn't match the bin name (ra11y); the shorter npx @ra11y/core --mcp form races on npx's bin-resolution cache and intermittently fails with command not found.
Or, from a clone: bun run src/cli.ts --mcp.
What the server exposes — a couple dozen tools spanning scan (scan_project, scan_file, scan_diff, scan), triage (checklist, coverage, review_candidates, suggest_fix, apply_fix, explain_rule, explain_standard), onboarding (bootstrap, detect_native_wrappers, propose_config, propose_baseline), conformance (vpat, attest, verdict_candidate, conformance_statement, draft_vpat_narrative, list_attestations, audit), and lifecycle (list_rules, list_suppressions, suppress, baseline, sessionConfigure). Canonical inventory: call tools/list on the server, or read src/mcp/.
Typical agent workflow:
scan_project → read findings + nextStep
↓
suggest_fix → apply deterministic edits
↓
scan_file → verify (cached AST, fast)
↓
checklist → manual-review candidates
↓
coverage → conformance scorecard
Full setup guide: docs/mcp/server-setup.md. Architecture: docs/kb/architecture/mcp-server.md.
First-run flags (for an agent meeting a new codebase):
// scan_project args
{
"cwd": "/abs/path/to/project",
"autoDetectWrappers": true, // auto-register PascalCase-with-onClick
// as nativeWrappers for this scan —
// closes the "47 opaque components"
// gap in one call.
"additionalPaths": ["dist/assets"], // bypass .gitignore + default build-dir
// skips to scan post-compile output.
"verboseMeta": true // expand analysisCoverage so agents can
// audit which rules ran on which files.
}ra11y.config.ts:
import { defineConfig } from "@ra11y/core";
export default defineConfig({
standards: ["wcag22", "section508"],
level: "AA",
exclude: ["node_modules", "dist", "**/*.test.tsx"],
overrides: [
{
files: ["src/legacy/**/*.tsx"],
rules: { "contrast/minimum": "warn" },
},
],
});Full reference: docs/configuration.md.
Scan only files staged in git, fail the commit on any error:
ra11y --changed --fail-on errorWith lefthook:
# lefthook.yml
pre-commit:
commands:
ra11y:
run: bunx ra11y --changed --fail-on errorOr use baseline mode to adopt on an existing codebase without fixing everything up front:
ra11y --baseline=create # freeze existing violations
ra11y --baseline=check # only new violations fail the scanExamples for CI and precommit tools: examples/.
Standards and rules are both pluggable. Adding a new accessibility framework is one file:
import { defineStandard } from "@ra11y/core/plugin";
export default defineStandard({
id: "coga",
name: "Cognitive Accessibility Guidelines",
version: "1.0",
publisher: "W3C WAI",
url: "https://www.w3.org/TR/coga-usable/",
levels: ["base"],
criteria: [
/* … */
],
});Rules declare coverage across every loaded standard:
import { defineRule } from "@ra11y/core/plugin";
export default defineRule({
id: "custom/no-placeholder-as-label",
satisfies: ["wcag22:3.3.2", "coga:clear-instructions"],
severity: "error",
// …
});Authoring guides: docs/plugins/authoring-a-rule.md, docs/plugins/authoring-a-standard.md, docs/plugins/authoring-a-formatter.md. End-to-end templates: examples/plugin-rule/, examples/plugin-standard/, examples/plugin-formatter/. Worked agent integrations: examples/ra11y-in-claude-code/, examples/ra11y-in-cursor/.
Bug reports + reproductions welcome via GitHub issues. Contribution norms — including the response-shape doctrine (docs/kb/architecture/ai-first-consumer.md) — live in CONTRIBUTING.md.
If you're using ra11y on a real codebase and the MCP responses surface something dishonest (counts that don't reconcile across surfaces, ambiguous-empty fields, oversize without an envelope, fix descriptions that contradict the rule's severity), open an issue with the response payload — those reports drive the doctrine work directly.
Apache-2.0 © ra11y contributors
{ "mcpServers": { "ra11y": { "command": "npx", "args": ["-y", "--package=@ra11y/core", "ra11y", "--mcp"] } } }