MCP server for web accessibility testing with WCAG compliance
npm install accessibility-server-mcp@modelcontextprotocol/sdk
json
{
"command": "npx",
"args": ["-y", "accessibility-mcp-server"],
"env": {
"MCP_MODE": "true"
}
}
`
#### For Local Development/Testing
`json
{
"command": "node",
"args": ["path/to/accessibility-mcp/dist/index.js"],
"env": {
"MCP_MODE": "true"
}
}
`
#### Simple Mode (faster startup, core features only)
`json
{
"command": "npx",
"args": ["-y", "accessibility-mcp-server", "--simple"],
"env": {
"MCP_MODE": "true"
}
}
`
> Note: The server will be published to NPM as accessibility-mcp-server for easy npx usage.
#### For Claude Desktop
1. Install the server:
`bash
npm install -g accessibility-mcp-server
`
2. Configure Claude Desktop by adding to your claude_desktop_config.json:
`json
{
"mcpServers": {
"accessibility": {
"command": "accessibility-mcp",
"args": []
}
}
}
`
3. Restart Claude Desktop and the accessibility tools will be available.
#### For Cline VS Code Extension
1. Install the server globally:
`bash
npm install -g accessibility-mcp-server
`
2. Configure in VS Code settings or Cline configuration:
`json
{
"mcpServers": {
"accessibility": {
"command": "accessibility-mcp",
"args": []
}
}
}
`
#### For Custom Applications
Install the package as a dependency:
`bash
npm install accessibility-mcp-server
`
Then integrate programmatically:
`javascript
import { AccessibilityMCPServer } from 'accessibility-mcp-server';
// Create and start the server
const server = new AccessibilityMCPServer({
mode: 'full', // or 'simple' for basic features only
enableLogging: true
});
await server.run();
`
๐ฆ Installation Options
$3
`bash
For global command-line usage
npm install -g accessibility-mcp-server
For local project integration
npm install accessibility-mcp-server
`
$3
`bash
Clone the repository
git clone https://github.com/nigamutkarsh/accessibility-mcp-server.git
cd AccessibilityMCP
Install dependencies
npm install
Build the project
npm run build
Install globally
npm install -g .
`
$3
`bash
Build Docker image
docker build -t accessibility-mcp .
Run container
docker run -d --name accessibility-mcp \
-p 3000:3000 \
accessibility-mcp
`
๏ฟฝ Multi-Standard Support
The server supports testing against multiple accessibility standards simultaneously:
$3
Quick presets for common standard combinations:
- wcag-a: WCAG 2.0/2.1/2.2 Level A
- wcag-aa: WCAG 2.0/2.1/2.2 Level AA (default)
- wcag-aaa: WCAG 2.0/2.1/2.2 Level AAA
- section508: Section 508 compliance tags
- ada: ADA Title III compliance (WCAG 2.1 AA + legal guidance)
- en301549: EN 301 549 European standard
- all-standards: Comprehensive testing across all standards
$3
Specify individual axe-core tags for fine-grained control (~150+ available):
WCAG Tags:
- wcag2a, wcag2aa, wcag2aaa - WCAG 2.0 levels
- wcag21a, wcag21aa, wcag21aaa - WCAG 2.1 levels
- wcag22aa - WCAG 2.2 Level AA
- wcag111, wcag131, wcag143, wcag244, etc. - Specific success criteria
Other Standards:
- section508, section508.22.a, section508.22.g - Section 508
- EN-301-549 - European accessibility standard
- TTv5 - Trusted Tester v5
- RGAAv4 - French accessibility standard
Category Tags:
- cat.color, cat.forms, cat.keyboard, cat.aria, cat.text-alternatives
- cat.name-role-value, cat.semantics, cat.language, etc.
$3
- AND Logic (default): Rules must match ALL specified standards (requireAll: true)
- OR Logic: Rules match ANY specified standard (requireAll: false)
$3
`json
// Test against multiple presets
{
"standardPresets": ["wcag-aa", "section508", "ada"]
}
// Test against specific tags with AND logic
{
"standards": ["wcag21aa", "wcag244", "section508.22.a"],
"requireAll": true
}
// Test against category tags with OR logic
{
"standards": ["cat.color", "cat.forms"],
"requireAll": false
}
`
๏ฟฝ๐ ๏ธ Available MCP Tools
The server provides four main tools for accessibility testing, with two operational modes:
$3
- test_accessibility - Test URLs or HTML content
- test_website_accessibility - Test entire websites (crawl multiple pages)
- check_color_contrast - Validate color combinations
$3
- test_accessibility - Test URLs or HTML content
- test_website_accessibility - Test entire websites (crawl multiple pages)
- check_color_contrast - Validate color combinations
- get_wcag_rules - Retrieve WCAG rule information
$3
#### 1. Test Accessibility
Test a website or HTML content for accessibility issues:
For URLs with standard presets:
`json
{
"name": "test_accessibility",
"arguments": {
"target": "https://example.com",
"type": "url",
"level": "basic",
"standardPresets": ["wcag-aa", "section508"]
}
}
`
For URLs with specific standard tags:
`json
{
"name": "test_accessibility",
"arguments": {
"target": "https://example.com",
"type": "url",
"level": "full",
"standards": ["wcag21aa", "wcag244", "section508.22.a", "EN-301-549"]
}
}
`
For HTML snippets (legacy wcagLevel still supported):
`json
{
"name": "test_accessibility",
"arguments": {
"target": "Content without proper contrast",
"type": "html",
"level": "full",
"wcagLevel": "AAA"
}
}
`
For ADA compliance testing:
`json
{
"name": "test_accessibility",
"arguments": {
"target": "https://example.com",
"type": "url",
"level": "full",
"standardPresets": ["ada"]
}
}
`
#### 2. Test Website Accessibility
Test entire websites by crawling multiple pages:
With standard presets:
`json
{
"name": "test_website_accessibility",
"arguments": {
"baseUrl": "https://example.com",
"standardPresets": ["wcag-aa", "section508"],
"maxPages": 20,
"maxDepth": 3,
"concurrency": 3,
"excludePatterns": ["/admin/", "/api/", ".pdf"],
"continueOnError": true,
"delay": 1000
}
}
`
With specific standard tags:
`json
{
"name": "test_website_accessibility",
"arguments": {
"baseUrl": "https://example.com",
"standards": ["wcag21aa", "wcag244", "EN-301-549"],
"maxPages": 10,
"maxDepth": 2
}
}
`
Legacy wcagLevel parameter (still supported):
`json
{
"name": "test_website_accessibility",
"arguments": {
"baseUrl": "https://example.com",
"wcagLevel": "AA",
"maxPages": 20,
"maxDepth": 3
}
}
`
Key Features of Website Testing:
- ๐ท๏ธ Automatic Crawling: Discovers pages by following links
- ๐ Site-wide Reports: Aggregated accessibility metrics across all pages
- ๐ฏ Configurable Scope: Control depth, page limits, and URL patterns
- โก Parallel Testing: Test multiple pages simultaneously
- ๐ Common Issues: Identifies violations that appear across multiple pages
> ๐ For detailed website testing documentation, see WEBSITE_TESTING.md
#### 3. Check Color Contrast
Validate color combinations for WCAG compliance:
`json
{
"name": "check_color_contrast",
"arguments": {
"foreground": "#333333",
"background": "#ffffff",
"fontSize": 16,
"isBold": false
}
}
`
#### 4. Get WCAG Rules (Full Mode Only)
Retrieve information about WCAG accessibility rules:
Query rules by standard presets:
`json
{
"name": "get_wcag_rules",
"arguments": {
"standardPresets": ["wcag-aa", "section508"],
"category": "color",
"search": "contrast",
"limit": 10
}
}
`
Query rules by specific standard tags:
`json
{
"name": "get_wcag_rules",
"arguments": {
"standards": ["wcag21aa", "wcag244", "EN-301-549"],
"requireAll": true,
"limit": 20
}
}
`
Legacy wcagLevel parameter (still supported):
`json
{
"name": "get_wcag_rules",
"arguments": {
"wcagLevel": "AA",
"category": "color",
"search": "contrast",
"limit": 10
}
}
`
๐ง MCP Client Integration
$3
`javascript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
async function setupAccessibilityTesting() {
// Create transport to the accessibility server
const transport = new StdioClientTransport({
command: 'accessibility-mcp',
args: []
});
// Create MCP client
const client = new Client({
name: 'my-accessibility-client',
version: '1.0.0'
}, {
capabilities: {}
});
// Connect to the server
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log('Available tools:', tools);
// Test a website
const result = await client.callTool('test_accessibility', {
target: 'https://example.com',
type: 'url',
level: 'basic',
wcagLevel: 'AA'
});
console.log('Accessibility test result:', result);
// Clean up
await client.close();
}
setupAccessibilityTesting().catch(console.error);
`
$3
`javascript
import { spawn } from 'child_process';
import { EventEmitter } from 'events';
class AccessibilityMCPClient extends EventEmitter {
constructor() {
super();
this.process = null;
this.requestId = 0;
}
async connect() {
// Start the accessibility MCP server
this.process = spawn('accessibility-mcp', [], {
stdio: ['pipe', 'pipe', 'pipe']
});
// Handle server responses
this.process.stdout.on('data', (data) => {
const responses = data.toString().split('\n').filter(Boolean);
responses.forEach(response => {
try {
const parsed = JSON.parse(response);
this.emit('response', parsed);
} catch (error) {
console.error('Failed to parse response:', error);
}
});
});
// Initialize the connection
await this.sendRequest('initialize', {
protocolVersion: '1.0.0',
capabilities: {},
clientInfo: {
name: 'custom-accessibility-client',
version: '1.0.0'
}
});
}
async sendRequest(method, params = {}) {
const request = {
jsonrpc: '2.0',
id: ++this.requestId,
method,
params
};
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('Request timeout'));
}, 30000);
const handler = (response) => {
if (response.id === request.id) {
clearTimeout(timeout);
this.removeListener('response', handler);
if (response.error) {
reject(new Error(response.error.message));
} else {
resolve(response.result);
}
}
};
this.on('response', handler);
this.process.stdin.write(JSON.stringify(request) + '\n');
});
}
async testAccessibility(target, options = {}) {
return this.sendRequest('tools/call', {
name: 'test_accessibility',
arguments: {
target,
type: options.type || 'url',
level: options.level || 'basic',
wcagLevel: options.wcagLevel || 'AA'
}
});
}
async checkColorContrast(foreground, background, options = {}) {
return this.sendRequest('tools/call', {
name: 'check_color_contrast',
arguments: {
foreground,
background,
fontSize: options.fontSize || 16,
isBold: options.isBold || false
}
});
}
async close() {
if (this.process) {
this.process.kill();
this.process = null;
}
}
}
`
โ๏ธ Configuration & Environment
$3
The server supports two operational modes:
Simple Mode:
- Basic accessibility testing
- Color contrast analysis
- Minimal resource usage
- Faster startup time
Full Mode (Default):
- Complete accessibility testing suite
- WCAG rules database access
- Advanced analysis features
- Comprehensive reporting
`bash
Start in simple mode
accessibility-mcp --simple
Start in full mode (default)
accessibility-mcp
`
$3
`bash
Server mode configuration
ACCESSIBILITY_MCP_MODE=full # or 'simple'
Disable logging when running as MCP server
MCP_MODE=true
Browser configuration
PUPPETEER_HEADLESS=true
PUPPETEER_TIMEOUT=30000
Performance settings
NODE_ENV=production
LOG_LEVEL=error
`
$3
Different host applications require different configuration approaches:
Claude Desktop (claude_desktop_config.json):
`json
{
"mcpServers": {
"accessibility": {
"command": "accessibility-mcp",
"args": ["--simple"]
}
}
}
`
Cline/MCP Configuration:
`json
{
"mcpServers": {
"accessibility-testing": {
"command": "accessibility-mcp",
"args": [],
"env": {
"ACCESSIBILITY_MCP_MODE": "full"
}
}
}
}
`
๐ Response Format
All tools return responses in a consistent format:
`typescript
interface ToolResponse {
success: boolean;
data?: T;
error?: {
type: string;
message: string;
details?: any;
};
processingTime: number;
timestamp: string;
}
`
$3
`json
{
"success": true,
"data": {
"target": "https://example.com",
"type": "url",
"wcagLevel": "AA",
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"description": "Elements must have sufficient color contrast",
"help": "Ensure the contrast ratio is at least 4.5:1",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.8/color-contrast",
"nodes": [
{
"html": "Low contrast text
",
"target": ["p"],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast"
}
]
}
],
"summary": {
"totalViolations": 1,
"violationsByImpact": {
"critical": 0,
"serious": 1,
"moderate": 0,
"minor": 0
},
"compliance": {
"A": false,
"AA": false,
"AAA": false
},
"score": 75
},
"metadata": {
"testDuration": 2500,
"pageTitle": "Example Website",
"viewport": { "width": 1920, "height": 1080 }
}
},
"processingTime": 2500,
"timestamp": "2024-12-01T10:30:00.000Z"
}
`
๐ Production Deployment
$3
1. Install as system service:
`bash
Install globally
npm install -g accessibility-mcp-server
Create systemd service (Linux)
sudo cat > /etc/systemd/system/accessibility-mcp.service << EOF
[Unit]
Description=Accessibility MCP Server
After=network.target
[Service]
Type=simple
User=accessibility
ExecStart=/usr/local/bin/accessibility-mcp
Restart=always
Environment=NODE_ENV=production
Environment=MCP_MODE=true
[Install]
WantedBy=multi-user.target
EOF
Enable and start service
sudo systemctl enable accessibility-mcp
sudo systemctl start accessibility-mcp
`
2. Docker Production Setup:
`bash
Production Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
COPY config/ ./config/
EXPOSE 3000
USER node
CMD ["node", "dist/index.js"]
`
3. CI/CD Integration:
`yaml
GitHub Actions example
name: Accessibility Testing
on: [push, pull_request]
jobs:
accessibility:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install Accessibility MCP Server
run: npm install -g accessibility-mcp-server
- name: Test Website Accessibility
run: |
# Note: CLI interface would need to be implemented for CI/CD
# This is a conceptual example
echo "Accessibility testing would run here"
`
๐ Security & Compliance
$3
- ๐ Local Processing: All accessibility testing happens locally - no external API calls
- ๐ก๏ธ Input Validation: All inputs validated using Zod schemas
- ๐งน Resource Management: Automatic cleanup of browser instances and memory
- ๐ฆ Sandboxed Execution: Puppeteer runs in sandboxed mode
- ๐ซ No Data Transmission: Zero data leaves the customer environment
$3
- GDPR Compliant: No personal data processing or storage
- SOC 2 Ready: Designed for enterprise security requirements
- Zero Trust: No external dependencies or data transmission
- Audit Trail: Comprehensive logging for security auditing
๐ Troubleshooting
$3
Issue: MCP server not starting
`bash
Check if Node.js version is compatible
node --version # Should be 18.0.0 or higher
Verify installation
accessibility-mcp --version
Check for conflicting processes
ps aux | grep accessibility-mcp
`
Issue: Tools not appearing in host application
`bash
Verify MCP server is properly configured
cat ~/.config/claude-desktop/claude_desktop_config.json
Test server manually
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | accessibility-mcp
`
Issue: Browser automation failures
`bash
Install required dependencies (Linux)
sudo apt-get install -y chromium-browser
Check browser permissions
export PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
`
$3
For high-volume testing:
`bash
Set environment variables for better performance
export PUPPETEER_HEADLESS=true
export NODE_ENV=production
export ACCESSIBILITY_MCP_MODE=simple
`
Memory management:
`bash
Monitor memory usage
top -p $(pgrep -f accessibility-mcp)
Restart server if memory usage is high
sudo systemctl restart accessibility-mcp
`
๐ API Reference
$3
Tests websites or HTML content for accessibility violations.
Parameters:
- target (string, required): URL or HTML content to test
- type (enum): "url" | "html" (default: "url")
- level (enum): "basic" | "full" (default: "basic")
- wcagLevel (enum): "A" | "AA" | "AAA" (default: "AA")
$3
Analyzes color combinations for WCAG compliance.
Parameters:
- foreground (string, required): Foreground color (hex, rgb, hsl, or named)
- background (string, required): Background color (hex, rgb, hsl, or named)
- fontSize (number): Font size in pixels (default: 16)
- isBold (boolean): Whether text is bold (default: false)
$3
Retrieves WCAG accessibility rule information.
Parameters:
- wcagLevel (enum, optional): "A" | "AA" | "AAA"
- category (string, optional): Rule category filter
- search (string, optional): Search term for rules
- limit (number, optional): Maximum rules to return (1-50, default: 20)
๐ License
MIT License - see LICENSE file for details.
๐ค Support & Contributing
- Issues: GitHub Issues
- Documentation: Check the /docs` folder for additional guides