Playwright Accessibility Testing MCP Server
Supports CSS selectors for targeting specific elements during accessibility scans and interactive component testing.
Requires Node.js 18+ runtime environment to execute the MCP server for accessibility testing with Playwright and axe-core.
Uses npm for package management and installation of the accessibility testing server dependencies.
Implemented in TypeScript with comprehensive type definitions for scan results, configurations, and tool schemas.
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., "@Playwright Accessibility Testing MCP Server test the checkout form on https://example.com for accessibility issues"
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.
Playwright Accessibility Testing MCP Server
A production-ready Model Context Protocol (MCP) server for comprehensive accessibility testing using Playwright and axe-core. Test web applications for WCAG 2.0/2.1 compliance with ease.
Features
Comprehensive WCAG Testing: Tests WCAG 2.0/2.1 Level A/AA compliance plus best practices
Natural Language Testing: Find elements by visible text - no CSS selectors needed
Auto-Discovery: Automatically discover and test all interactive elements
Interactive Component Testing: Test across different states (dropdowns, modals, etc.)
Screenshot Capture: Visual documentation of tested areas
Predefined Prompts: Quick-start templates for common testing scenarios
Production-Ready: Modular architecture, TypeScript, comprehensive error handling
Related MCP server: Accessibility MCP Server
Installation
npm install
npm run buildConfiguration
Add to your MCP client configuration file:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"playwright-a11y": {
"command": "node",
"args": ["/absolute/path/to/playwright-axe-mcp/dist/server.js"]
}
}
}Claude Code (.claude/config.json in your project):
{
"mcpServers": {
"playwright-a11y": {
"command": "node",
"args": ["/absolute/path/to/playwright-axe-mcp/dist/server.js"]
}
}
}Restart your MCP client after configuration.
Quick Start
Using the Predefined Prompt (Easiest!)
The fastest way to test is with the comprehensive-a11y-test prompt:
Use comprehensive-a11y-test prompt:
- url: https://example.com
- block: Rewards account
- steps: open menu, select provider, input value, click applyParameters:
url(required): URL to testblock(optional): Section name (e.g., "Navigation", "User Profile")steps(optional): Comma-separated interaction steps
What it does:
Navigates to the URL
Runs full accessibility audit
Tests specified section with auto-discovery or custom steps
Generates human-readable report with:
Executive summary
Critical/serious/moderate/minor issues
Prioritized fix recommendations
Available Tools
1. a11y_scanUrl
Scan a URL for accessibility violations.
Parameters:
{
url: string; // Required: URL to scan
selector?: string; // Optional: CSS selector to scan specific element
waitForSelector?: string; // Optional: Wait for this element before scanning
captureScreenshot?: boolean; // Optional: Capture screenshot (default: false)
timeout?: number; // Optional: Navigation timeout in ms (default: 30000)
}Example:
{
"url": "https://example.com",
"selector": "header nav",
"captureScreenshot": true
}2. a11y_scanInteractiveByText
Test components using natural language - no CSS selectors needed!
Parameters:
{
url: string; // Required: URL to navigate to
containerText: string; // Required: Visible text to find section (e.g., "Rewards")
autoDiscover?: boolean; // Optional: Auto-discover interactions (default: true)
customInteractions?: Array<{
stateName: string; // Name for this interaction
elementText: string; // Visible text of element to interact with
action: "click" | "hover" | "focus";
waitAfter?: number; // Wait time in ms (default: 500)
}>;
captureScreenshots?: boolean; // Optional: Screenshot each state
timeout?: number; // Optional: Navigation timeout in ms
}Example: Auto-discover everything
{
"url": "https://example.com",
"containerText": "User Menu",
"autoDiscover": true,
"captureScreenshots": true
}Example: Custom interactions
{
"url": "https://example.com",
"containerText": "Rewards",
"customInteractions": [
{
"stateName": "After opening menu",
"elementText": "View Details",
"action": "click"
}
]
}Response Format
Scan Result
{
"url": "https://example.com",
"timestamp": "2025-01-28T...",
"summary": {
"violations": 3,
"passes": 12,
"incomplete": 1
},
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"description": "Elements must have sufficient color contrast",
"help": "Ensure contrast ratio is at least 4.5:1",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.4/color-contrast",
"tags": ["wcag2aa", "wcag21aa"],
"nodes": [
{
"html": "<button class=\"btn\">Submit</button>",
"target": [".btn"],
"failureSummary": "..."
}
]
}
],
"screenshotPath": "/path/to/screenshot.png"
}Interactive Scan Result
{
"url": "https://example.com",
"containerText": "Rewards",
"totalStates": 3,
"states": [
{
"stateName": "Initial State",
"summary": {"violations": 0, "passes": 5, "incomplete": 0},
"violations": []
},
{
"stateName": "After interacting with buttons: \"View Details\"",
"action": "click",
"elementText": "View Details",
"summary": {"violations": 2, "passes": 8, "incomplete": 1},
"violations": [...]
}
]
}Project Structure
server/
├── constants/ # Configuration and constants
│ ├── config.ts # Application configuration
│ ├── selectors.ts # Interactive element selectors
│ └── wcag-tags.ts # WCAG compliance tags
├── types/ # TypeScript type definitions
│ └── scan-result.ts # Scan result interfaces
├── utils/ # Utility functions
│ ├── axe-scanner.ts # Axe configuration and scanning
│ ├── browser.ts # Browser management
│ ├── container-finder.ts # Find elements by text
│ └── screenshot.ts # Screenshot utilities
├── tools/ # Tool implementations
│ ├── scan-url.ts # URL scanning tool
│ └── scan-interactive-by-text.ts # Interactive testing tool
├── prompts/ # Prompt templates
│ └── comprehensive-a11y-test.ts # Predefined test prompt
└── server.ts # Main MCP server entry pointWCAG Compliance
This server tests for:
WCAG 2.0 Level A (
wcag2a)WCAG 2.0 Level AA (
wcag2aa)WCAG 2.1 Level A (
wcag21a)WCAG 2.1 Level AA (
wcag21aa)Best Practices (
best-practice)
Impact Levels
Violations are categorized by severity:
Critical: Blocks access completely - fix immediately
Serious: Creates significant barriers - fix before release
Moderate: Noticeable issues - fix soon
Minor: Small improvements - can be backlogged
Output Files
All screenshots are saved to: ./accessibility-screenshots/
scan-{timestamp}.png- Full page screenshots{name}-{timestamp}.png- Named screenshots
Usage Examples
Test a simple page
User: "Check accessibility of https://example.com"
Claude: → Calls a11y_scanUrl
→ Returns: 3 violations (2 serious, 1 moderate)Test specific section by name
User: "Test the Navigation menu on https://example.com"
Claude: → Calls a11y_scanInteractiveByText with containerText="Navigation"
→ Auto-discovers all interactive elements
→ Returns: Issues found in different statesTest with custom interactions
User: "Test the Rewards section - click 'View Details' then 'Redeem'"
Claude: → Parses your request
→ Calls a11y_scanInteractiveByText with custom interactions
→ Returns: Accessibility analysis for each stateDevelopment
# Build TypeScript
npm run build
# Watch mode for development
npm run watch
# Start server directly (for testing)
npm startAdding New Tools
Create tool file in
server/tools/Define schema and execution function
Register in
server/server.ts
Adding New Utilities
Create utility file in
server/utils/Export functions
Import where needed
Best Practices
Always test with screenshots during initial development:
{"captureScreenshot": true}Wait for dynamic content on SPAs:
{"waitForSelector": ".content-loaded"}Test interactive components in different states:
Initial state
After user interaction
Error states
Success states
Use natural language testing when you don't know selectors:
{"containerText": "User Menu", "autoDiscover": true}
Troubleshooting
Server not starting
npm run build
# Check config path is absolute
# Restart MCP clientElement not found
Verify the text exists on the page
Try a shorter, more specific text
Check if content is loaded (use
waitForSelector)
Timeout errors
{"timeout": 60000} // Increase to 60 secondsRequirements
Node.js 18+
Playwright (browsers installed automatically)
License
ISC
Contributing
Follow the modular architecture
Add TypeScript types for new features
Document new tools in README
Update constants instead of hardcoding values
Built for production use with modular, maintainable architecture.
Available Tools
2 toolsa11y_scanInteractiveByTextA
Test accessibility of components by finding them using visible text/labels instead of CSS selectors. Automatically discovers and tests interactive elements. Perfect for natural language testing like 'test the Rewards section' or 'test the user menu'. Uses comprehensive WCAG 2.0, 2.1 Level A/AA and best-practice rules by default.
Inputs: url (required), containerText (required), autoDiscover, customInteractions, +2 more.
a11y_scanUrlA
Run accessibility scan on a URL or specific element using Playwright + axe-core. Supports full page or targeted section scanning with optional screenshots. Uses comprehensive WCAG 2.0, 2.1 Level A/AA and best-practice rules by default.
Inputs: url (required), selector, waitForSelector, captureScreenshot, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: a11y_scanInteractiveByText focuses on testing components via visible text/labels for natural language scenarios, while a11y_scanUrl handles URL-based or element-specific scanning. There is minor potential for confusion since both perform accessibility scans, but their different input methods (text vs. URL/element) and use cases (interactive components vs. general pages) make them mostly distinguishable.
Both tools follow a consistent naming pattern with the prefix 'a11y_scan' followed by descriptive suffixes (InteractiveByText and Url). They use snake_case uniformly, and the names clearly indicate their distinct functionalities, making them predictable and easy to understand.
With only two tools, the server feels thin for an accessibility testing domain, which might involve more operations like generating reports, filtering results, or testing specific WCAG criteria. However, the tools cover core scanning functionalities, so it's borderline but not severely lacking.
The server provides basic scanning capabilities for URLs and interactive components, but there are notable gaps. Missing operations include result analysis tools (e.g., summarize findings, export reports), configuration options (e.g., custom rule sets), and follow-up actions (e.g., retest after fixes). This limits agents to scanning without deeper workflow support.
Maintenance
Related MCP Connectors
Scan URLs or HTML for WCAG 2.2 violations. 75-rule manifest, weighted score, shareable reports.
Run WCAG accessibility scans on websites, list each issue with its element, and triage from chat.
Scan URLs for WCAG 2.1 violations, generate AI fixes, and produce VPAT 2.5 compliance reports.
Write, run and check natural-language browser tests of your web app from your AI assistant.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables automated web accessibility scans for WCAG compliance using Playwright and Axe-core, providing visual and JSON reports with remediation guidance.253,447 npm59MIT
- 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
- AlicenseAqualityDmaintenanceEnables accessibility testing of websites and HTML content using axe-core and IBM Equal Access engines. Supports WCAG compliance checking, multi-viewport testing, and provides detailed violation reports with remediation guidance.51MIT
- AlicenseAqualityDmaintenanceEnables AI coding agents to perform real-browser accessibility scanning of localhost pages using Playwright and axe-core, returning WCAG 2.1 violations with structured fix plans.323 npm1MIT