validate_accessibility_wave
Test website accessibility for WCAG compliance, identify errors, and detect contrast issues using WAVE analysis to ensure inclusive web experiences.
Instructions
Analyze website accessibility using WAVE. Tests WCAG compliance, errors, and contrast issues. Requires API key.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| apiKey | Yes | WAVE API key (required) | |
| reporttype | No | Detail level (1-4) |
Implementation Reference
- src/accessibility/wave.ts:68-129 (handler)The core handler function that performs the WAVE accessibility validation by calling the WAVE API, parsing the response, and returning structured results with error counts, contrast issues, alerts, and raw data.export async function analyzeWAVE( url: string, options: WAVEOptions ): Promise<WAVEResult> { try { if (!options.apiKey) { throw new Error('WAVE API key is required. Get one at https://wave.webaim.org/api/'); } // Build API URL const params = new URLSearchParams({ key: options.apiKey, url, }); if (options.reporttype) { params.set('reporttype', options.reporttype.toString()); } if (options.viewportwidth) { params.set('viewportwidth', options.viewportwidth.toString()); } const apiUrl = `https://wave.webaim.org/api/request?${params.toString()}`; const response = await fetch(apiUrl); if (!response.ok) { throw new Error(`WAVE API error: ${response.status} ${response.statusText}`); } const data: WAVEResponse = await response.json(); if (!data.status.success) { throw new Error(`WAVE analysis failed with HTTP status: ${data.status.httpstatuscode}`); } return { tool: 'wave', success: true, url, errors: data.categories.error.count, contrast_errors: data.categories.contrast.count, alerts: data.categories.alert.count, total_issues: data.categories.error.count + data.categories.contrast.count + data.categories.alert.count, wave_report_url: data.statistics.waveurl, credits_remaining: data.statistics.creditsremaining, raw: data, }; } catch (error) { return { tool: 'wave', success: false, url, errors: 0, contrast_errors: 0, alerts: 0, total_issues: 0, error: error instanceof Error ? error.message : String(error), }; } }
- index.ts:55-59 (schema)Zod schema used to validate the input arguments for the validate_accessibility_wave tool.const WAVEArgsSchema = z.object({ url: z.string().url(), apiKey: z.string(), reporttype: z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]).optional(), });
- index.ts:176-187 (registration)Tool registration definition including name, description, and input schema for the MCP server.name: 'validate_accessibility_wave', description: 'Analyze website accessibility using WAVE. Tests WCAG compliance, errors, and contrast issues. Requires API key.', inputSchema: { type: 'object', properties: { url: { type: 'string' }, apiKey: { type: 'string', description: 'WAVE API key (required)' }, reporttype: { type: 'number', enum: [1, 2, 3, 4], description: 'Detail level (1-4)' }, }, required: ['url', 'apiKey'], }, },
- index.ts:353-360 (handler)Dispatch handler in the main CallToolRequestSchema that validates args and calls the analyzeWAVE function.case 'validate_accessibility_wave': { const validatedArgs = WAVEArgsSchema.parse(args); const result = await analyzeWAVE(validatedArgs.url, { apiKey: validatedArgs.apiKey, reporttype: validatedArgs.reporttype, }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; }
- src/accessibility/wave.ts:7-62 (schema)TypeScript interfaces defining options, API response, and result structure for the WAVE tool.export interface WAVEOptions { /** API key (required - get from https://wave.webaim.org/api/) */ apiKey: string; /** Report type: 1=summary, 2=detailed, 3=very detailed, 4=all (default: 2) */ reporttype?: 1 | 2 | 3 | 4; /** Viewport width for testing (default: 1024) */ viewportwidth?: number; } export interface WAVEResponse { status: { success: boolean; httpstatuscode: number; }; statistics: { pagetitle: string; pageurl: string; time: number; creditsremaining: number; allitemcount: number; totalelements: number; waveurl: string; }; categories: { error: { description: string; count: number; items: Record<string, any>; }; contrast: { description: string; count: number; items: Record<string, any>; }; alert: { description: string; count: number; items: Record<string, any>; }; }; } export interface WAVEResult { tool: 'wave'; success: boolean; url: string; errors: number; contrast_errors: number; alerts: number; total_issues: number; wave_report_url?: string; credits_remaining?: number; error?: string; raw?: WAVEResponse; }