Skip to main content
AccessibilityHub is a Model Context Protocol (MCP) server that exposes web accessibility testing capabilities to AI assistants and other MCP-compatible clients.

What is MCP?

The Model Context Protocol (MCP) is an open protocol that enables AI assistants to connect to external data sources and tools. It provides a standardized way for AI models to:
  • Access external tools - Execute functions and retrieve results
  • Read resources - Access reference data and documentation
  • Use prompts - Leverage pre-defined prompt templates
  • Maintain context - Share information across interactions
Think of MCP as a universal adapter that lets AI assistants interact with specialized systems in a consistent way.

How AccessibilityHub Implements MCP

AccessibilityHub implements three core MCP primitives:

Tools

5 accessibility analysis tools for testing web pages

Resources

WCAG criteria reference data and contrast thresholds

Prompts

8 pre-built prompt templates for common workflows

MCP Architecture

┌────────────────────┐
│   MCP Client         │
│  (Claude Desktop,   │
│   Cursor, etc.)     │
└─────────┬──────────┘

         │ MCP Protocol
         │ (JSON-RPC over stdio)

┌────────┴────────────────────┐
│   AccessibilityHub MCP Server   │
│                                  │
│  ┌──────────────────────┐  │
│  │ Tools                 │  │
│  │ - analyze-with-axe    │  │
│  │ - analyze-with-pa11y  │  │
│  │ - analyze-contrast    │  │
│  │ - analyze-mixed       │  │
│  │ - analyze-lighthouse  │  │
│  └──────────────────────┘  │
│                                  │
│  ┌──────────────────────┐  │
│  │ Resources             │  │
│  │ - wcag://criteria     │  │
│  │ - contrast://thresholds│ │
│  │ - lighthouse://audits │  │
│  └──────────────────────┘  │
│                                  │
│  ┌──────────────────────┐  │
│  │ Prompts               │  │
│  │ - full-audit          │  │
│  │ - quick-check         │  │
│  │ - pre-deploy-check    │  │
│  └──────────────────────┘  │
└──────────────────────────────────┘

┌────────┴────────────────────┐
│   Testing Tools               │
│   - axe-core                  │
│   - Pa11y                     │
│   - Lighthouse                │
│   - Puppeteer                 │
└──────────────────────────────┘

MCP Tools

Tools are the primary way to execute accessibility analyses. AccessibilityHub provides 5 tools:

Tool Registration

Tools are registered when the server starts (from src/server.ts:47-62):
function registerTools(): void {
  analyzeWithAxeTool.register(server);
  analyzeWithPa11yTool.register(server);
  analyzeMixedTool.register(server);
  analyzeContrastTool.register(server);
  analyzeWithLighthouseTool.register(server);
}

Available Tools

Purpose: Full accessibility analysis using axe-coreBest for: Comprehensive WCAG 2.0/2.1 compliance checkingInput Schema:
  • url or html (required)
  • options.wcagLevel (“A”, “AA”, “AAA”)
  • options.includeIncomplete (boolean)
  • options.browser (viewport, waitForSelector, etc.)
Returns: Issues with WCAG mappings, severity, affected users, remediation guidance
Purpose: Alternative WCAG testing engineBest for: Cross-validation with axe-coreInput Schema: Similar to analyze-with-axeReturns: Issues in standardized format, can be combined with axe-core results
Purpose: Google Lighthouse accessibility scoringBest for: Accessibility score (0-100) and score improvement trackingInput Schema:
  • url (required, no HTML support)
  • options.wcagLevel
  • options.browser
Returns: Score, audits, passed/failed checks, WCAG mappings
Purpose: Dedicated color contrast analysisBest for: WCAG 2.1 and APCA contrast validation with color fix suggestionsInput Schema:
  • url or html
  • options.wcagLevel (“AA”, “AAA”)
  • options.contrastAlgorithm (“WCAG21”, “APCA”)
  • options.selector (scope to specific section)
  • options.suggestFixes (boolean)
Returns: Contrast issues with current/required ratios, suggested colors, CSS fixes
Purpose: Run multiple tools in parallelBest for: Maximum coverage with intelligent deduplicationInput Schema:
  • url or html
  • tools array (default: [“axe-core”, “pa11y”])
  • options.deduplicateResults (boolean)
  • options.wcagLevel
  • options.browser
Returns: Combined issues, individual tool results, deduplication stats

Tool Input Validation

All tools use Zod schemas for input validation. Example from src/tools/Axe/types/input.type.ts:
import { z } from 'zod';

export const AxeToolInputSchema = z.object({
  url: z.string().url().optional(),
  html: z.string().optional(),
  options: z.object({
    wcagLevel: z.enum(['A', 'AA', 'AAA']).optional(),
    includeIncomplete: z.boolean().optional(),
    browser: z.object({
      waitForSelector: z.string().optional(),
      waitForTimeout: z.number().optional(),
      viewport: z.object({
        width: z.number().optional(),
        height: z.number().optional()
      }).optional()
    }).optional()
  }).optional()
}).refine(
  data => !!data.url || !!data.html,
  { message: 'Either url or html must be provided' }
);

MCP Resources

Resources provide read-only reference data that complements the analysis tools.

Resource Registration

From src/server.ts:82-91:
function registerResources(): void {
  registerWcagResources(server);      // WCAG 2.1 criteria
  registerContrastResources(server);  // Contrast thresholds
  registerLighthouseResources(server); // Lighthouse audits
}

Available Resources

URI Patterns:
  • wcag://criteria - All WCAG 2.1 criteria
  • wcag://criteria/{id} - Specific criterion (e.g., 1.4.3)
  • wcag://criteria/level/{level} - Filter by A, AA, or AAA
  • wcag://criteria/principle/{principle} - Filter by POUR principle
Data Source: src/shared/data/wcag-criteria.jsonResponse Format:
{
  "criterion": "1.4.3",
  "level": "AA",
  "principle": "perceivable",
  "title": "Contrast (Minimum)",
  "description": "Text must have contrast ratio of 4.5:1...",
  "userImpact": {
    "affectedUsers": ["low-vision", "color-blind"],
    "impactDescription": "...",
    "realWorldExample": "..."
  },
  "remediation": {
    "effort": "low",
    "priority": "high",
    "commonSolutions": ["..."]
  }
}

MCP Prompts

Prompts are pre-defined templates for common workflows. They combine tool calls with structured guidance.

Prompt Registration

From src/server.ts:64-80:
function registerPrompts(): void {
  const prompts = [
    fullAccessibilityAuditPrompt,
    lighthouseAuditPrompt,
    quickAccessibilityCheckPrompt,
    contrastCheckPrompt,
    preDeployCheckPrompt,
    quickWinsReportPrompt,
    lighthouseScoreImprovementPrompt,
    explainWcagCriterionPrompt
  ];

  for (const prompt of prompts) {
    prompt.register(server);
  }
}

Available Prompts

PromptPurposeArguments
full-accessibility-auditComprehensive audit with all toolsurl, wcagLevel
lighthouse-auditScore-focused analysisurl, wcagLevel
quick-accessibility-checkFast critical issue checkurl
contrast-checkDetailed contrast reviewurl, algorithm, wcagLevel
pre-deploy-checkDeployment gate analysisurl, threshold
quick-wins-reportHigh-impact, low-effort fixesurl
lighthouse-score-improvementScore improvement planurl, targetScore
explain-wcag-criterionEducational WCAG deep divecriterion

Prompt Usage

Users can invoke prompts naturally:
Use the full-accessibility-audit prompt with:
- url: https://example.com
- wcagLevel: AA
The AI assistant:
  1. Recognizes the prompt invocation
  2. Extracts arguments
  3. Calls appropriate tools (e.g., analyze-mixed, analyze-with-lighthouse)
  4. Formats results according to prompt template
  5. Returns structured output (executive summary, issues by principle, remediation plan)

Communication Protocol

MCP uses JSON-RPC 2.0 over stdio for communication between client and server.

Lifecycle

1

Server Initialization

When the MCP client starts, it spawns the AccessibilityHub server process using the configured command (npx -y accessibility-hub).
2

Capability Exchange

Client and server exchange capability information:
  • Available tools
  • Available resources
  • Available prompts
  • Protocol version
3

Request/Response

Client sends JSON-RPC requests over stdin:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "analyze-with-axe",
    "arguments": {
      "url": "https://example.com"
    }
  }
}
Server responds over stdout:
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": { /* tool output */ }
}
4

Shutdown

When the client exits, it sends SIGTERM/SIGINT to the server process. AccessibilityHub cleans up resources (closes browser instances) before exiting.

Error Handling

From src/tools/Base/index.ts, all tools use standardized error responses:
export function createErrorResponse(error: Error): ToolResponse {
  return {
    content: [
      {
        type: 'text',
        text: JSON.stringify({
          success: false,
          error: error.message,
          timestamp: new Date().toISOString()
        }, null, 2)
      }
    ],
    isError: true
  };
}

Server Implementation Details

Entry Point

The server is initialized in src/server.ts:93-129:
const server = new McpServer({
  name: 'AccesibilityHub',
  version: APP_VERSION,
  icons: [
    {
      src: `${REPO_RAW_URL}/assets/logo_light.svg`,
      mimeType: 'image/svg+xml',
      theme: 'light',
    },
    {
      src: `${REPO_RAW_URL}/assets/logo_dark.svg`,
      mimeType: 'image/svg+xml',
      theme: 'dark',
    },
  ],
});

async function main(): Promise<void> {
  registerTools();
  registerPrompts();
  registerResources();

  const transport = new StdioServerTransport();
  await server.connect(transport);
}

Resource Management

AccessibilityHub uses singleton adapters for browser instances to improve performance:
// From src/tools/Axe/main.ts:14-30
let sharedAdapter: AxeAdapter | null = null;

function getAdapter(ignoreHTTPSErrors = false): AxeAdapter {
  if (!sharedAdapter || currentIgnoreHTTPS !== ignoreHTTPSErrors) {
    if (sharedAdapter) {
      sharedAdapter.dispose().catch(() => {});
    }
    sharedAdapter = new AxeAdapter({
      headless: true,
      timeout: 30000,
      ignoreHTTPSErrors,
    });
  }
  return sharedAdapter;
}
This ensures:
  • Browser instances are reused across multiple analyses
  • Resources are properly cleaned up on shutdown
  • Performance is optimized for sequential analyses

Benefits of MCP Architecture

Standardization

One protocol works with all MCP-compatible clients (Claude Desktop, Cursor, Windsurf, etc.)

Discoverability

Clients can discover available tools, resources, and prompts automatically

Type Safety

Input validation via Zod schemas ensures correct tool usage

Composability

Tools can be combined (like analyze-mixed) for powerful workflows

Extensibility

New tools and resources can be added without changing the protocol

Context Sharing

Resources provide shared context across multiple tool invocations

Next Steps

Accessibility Testing Concepts

Learn about the testing tools and methodologies

Enriched Context

Understand the enriched human context feature

Creating Tools

Guide for creating new MCP tools

Project Structure

Detailed project structure explanation

Build docs developers (and LLMs) love