Skip to main content
Glama

accessibility_audit

Run automated accessibility audits to detect WCAG 2.1 Level A and AA violations, providing severity-based issue reports with specific fix instructions for web pages.

Instructions

Run an automated accessibility audit using axe-core. Checks for WCAG 2.1 Level A and AA violations, reporting issues by severity with specific fix instructions.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesURL of the page to audit

Implementation Reference

  • The main handler function for the accessibility_audit tool, which orchestrates browser navigation, axe-core injection, and audit execution.
    export async function runAccessibilityAudit(
      url: string
    ): Promise<AccessibilityResult> {
      const page = await createPage(1440, 900);
    
      try {
        await navigateAndWait(page, url, 500);
    
        // Inject axe-core into the page
        const axeSource = await getAxeSource();
        await page.evaluate(axeSource);
    
        // Run the audit
        const rawResults = await page.evaluate(async () => {
          // @ts-expect-error axe is injected at runtime
          const results = await window.axe.run(document, {
            runOnly: {
              type: "tag",
              values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "best-practice"],
            },
          });
    
          return {
            violations: results.violations.map(
              (v: {
                id: string;
                impact: string;
                description: string;
                help: string;
                helpUrl: string;
                nodes: Array<{
                  target: string[];
                  html: string;
                  failureSummary: string;
                }>;
              }) => ({
                id: v.id,
                impact: v.impact,
                description: v.description,
                help: v.help,
                helpUrl: v.helpUrl,
                nodes: v.nodes.slice(0, 5).map(
                  (n: {
                    target: string[];
                    html: string;
                    failureSummary: string;
                  }) => ({
                    target: n.target,
                    html: n.html.slice(0, 200),
                    failureSummary: n.failureSummary,
                  })
                ),
              })
            ),
            passCount: results.passes.length,
            incompleteCount: results.incomplete.length,
            inapplicableCount: results.inapplicable.length,
          };
        });
    
        return {
          url,
          timestamp: new Date().toISOString(),
          violations: rawResults.violations as readonly AccessibilityViolation[],
          passes: rawResults.passCount,
          incomplete: rawResults.incompleteCount,
          inapplicable: rawResults.inapplicableCount,
        };
      } finally {
        await closePage(page);
      }
    }
  • Helper function to format the audit results into a readable Markdown report.
    export function formatAccessibilityReport(
      result: AccessibilityResult
    ): string {
      const lines: string[] = [
        `## Accessibility Audit Results`,
        ``,
        `**URL:** ${result.url}`,
        `**Scanned:** ${result.timestamp}`,
        `**Violations:** ${result.violations.length}`,
        `**Passes:** ${result.passes}`,
        `**Incomplete:** ${result.incomplete}`,
        ``,
      ];
    
      if (result.violations.length === 0) {
        lines.push("No accessibility violations found.");
        return lines.join("\n");
      }
    
      // Group by impact
      const byImpact = {
        critical: [] as AccessibilityViolation[],
        serious: [] as AccessibilityViolation[],
        moderate: [] as AccessibilityViolation[],
        minor: [] as AccessibilityViolation[],
      };
    
      for (const violation of result.violations) {
        const bucket = byImpact[violation.impact];
        if (bucket) {
          bucket.push(violation);
        }
      }
    
      for (const [impact, violations] of Object.entries(byImpact)) {
        if (violations.length === 0) continue;
    
        lines.push(`### ${impact.toUpperCase()} (${violations.length})`);
        lines.push(``);
    
        for (const v of violations) {
          lines.push(`- **${v.id}**: ${v.help}`);
          lines.push(`  ${v.description}`);
          lines.push(`  [Learn more](${v.helpUrl})`);
    
          for (const node of v.nodes.slice(0, 3)) {
            lines.push(`  - Element: \`${node.target.join(" > ")}\``);
            lines.push(`    Fix: ${node.failureSummary}`);
          }
    
          lines.push(``);
        }
      }
    
      return lines.join("\n");
    }

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prembobby39-gif/uimax-mcp'

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