Architecture
The platform combines two MCP servers with dual-mode scanning:
| Server | What it does | How it works |
|---|---|---|
| Playwright MCP | Visual pattern detection — finds elements that look like headings or cards but may lack semantic markup | LLM-driven browser automation using Gherkin test scenarios |
| CWAC MCP | WCAG compliance scanning — runs axe-core, language, reflow, and other accessibility audits | Subprocess wrapper around GOVTNZ/cwac |
Dual-Mode Scanner
The CWAC MCP server supports two scanning modes, selected automatically at startup:
| Mode | Engine | Available when | Audit types |
|---|---|---|---|
Full (cwac) |
CWAC subprocess | CWAC + chromedriver + selenium available | All CWAC plugins (axe-core, language, readability, etc.) |
Fallback (axe-only) |
Playwright + axe-core | Playwright + axe-core available, CWAC unavailable | axe-core only |
The fallback scanner produces CSV output in the same column format as CWAC, so all downstream tools (result_reader, report_generator, templates) work identically regardless of mode.
For detailed technical documentation:
- CWAC MCP Server — architecture, tools, plugins, scan lifecycle, fallback mode
- Visual Pattern Scanner — analysis pipeline, detection methods, output format
Project Structure
di-test/
├── .claude-plugin/
│ └── plugin.json # Claude Code plugin manifest
├── .mcp.json # MCP server configuration (Playwright + CWAC)
├── marketplace.json # Plugin marketplace listing
├── cwac_mcp/ # CWAC MCP server
│ ├── __init__.py # Package init, CWAC_PATH + PROJECT_ROOT discovery
│ ├── server.py # FastMCP server with 6 tools, dual-mode routing
│ ├── environment_check.py # Detect scan mode (cwac vs axe-only)
│ ├── cwac_runner.py # Subprocess execution of CWAC
│ ├── axe_scanner.py # Standalone Playwright + axe-core scanner
│ ├── scanner_runner.py # Subprocess launcher for axe_scanner
│ ├── config_builder.py # Builds CWAC + axe-core configs from tool params
│ ├── result_reader.py # Reads/parses result CSVs (both modes)
│ ├── scan_registry.py # Tracks active/completed scans in memory
│ ├── report_generator.py # Markdown + DOCX report generation
│ └── requirements.txt # Python dependencies (incl. playwright)
├── skills/ # Plugin skill definitions
│ ├── scan/SKILL.md # /di-test:scan
│ ├── scan-status/SKILL.md # /di-test:scan-status
│ ├── results/SKILL.md # /di-test:results
│ ├── summary/SKILL.md # /di-test:summary
│ ├── report/SKILL.md # /di-test:report
│ ├── list-scans/SKILL.md # /di-test:list-scans
│ └── visual-scan/SKILL.md # /di-test:visual-scan
├── hooks/
│ └── hooks.json # SessionStart hook configuration
├── scripts/
│ └── install-deps.sh # Dependency installation (idempotent)
├── templates/ # Jinja2 report templates
│ ├── cwac_scan_report.md.j2 # Detailed CWAC scan report
│ ├── cwac_summary_report.md.j2 # Summary report
│ └── visual_scan_report.md.j2 # Visual pattern scan report
├── tests/ # Test suites
│ ├── *.feature # Gherkin scenarios (visual scanner)
│ ├── fixtures/ # HTML test fixtures
│ │ ├── violations.html # Page with known a11y violations
│ │ └── no_violations.html # Clean accessible page
│ ├── conftest.py # Shared pytest fixtures
│ ├── test_environment_check.py # Environment detection tests
│ ├── test_axe_scanner.py # axe-core scanner pure function tests
│ ├── test_config_builder.py # Config builder tests (both modes)
│ ├── test_result_reader.py # Result reader tests
│ ├── test_scan_registry.py # Scan registry tests (dual results root)
│ ├── test_plugin_manifest.py # Plugin manifest validation
│ ├── test_report_generator.py # Report generator tests
│ └── test_report_templates.py # Template rendering tests
├── docs/
│ ├── ARCHITECTURE.md # Architecture overview and project structure
│ ├── MANUAL-SETUP.md # Manual setup without plugin system
│ ├── CWAC-MCP.md # CWAC MCP server technical reference
│ ├── VISUAL-SCANNER.md # Visual scanner technical reference
│ ├── EXAMPLES.md # Example scan results
│ ├── adr/ # Architecture Decision Records
│ │ ├── ADR-000 through ADR-007
│ └── specs/ # Technical Specifications
│ ├── SPEC-000-A through SPEC-007-A
└── output/ # Generated scan output
├── accessibility-scan-report.md
├── accessibility-scan-report.docx
├── findings.json
└── screenshots/
Architecture Decision Records (ADRs)
All architectural decisions are documented using the WH(Y) ADR format:
| ADR | Decision | Key Trade-off |
|---|---|---|
| ADR-000 | LLM-driven visual pattern detection via Playwright MCP | Catches non-semantic patterns automated tools miss; AI-dependent, flags not violations |
| ADR-001 | MCP server wrapper for CWAC integration | MCP provides structured tools + Claude Code integration; requires additional server process |
| ADR-002 | Subprocess execution instead of direct Python import | Zero CWAC modifications + update compatibility; subprocess overhead + temp file management |
| ADR-003 | Async scan model with in-memory registry | Non-blocking scans + concurrent support; state lost on server restart |
| ADR-004 | Same-repo Claude Code plugin with marketplace | Zero-friction install + skill discoverability; requires repo access |
| ADR-005 | Jinja2 + python-docx dual-format reports | Markdown + DOCX from structured data, no pandoc; python-docx adds dependency |
| ADR-006 | SessionStart hook with CWAC_PATH discovery chain | Auto-install + portable paths; startup latency on first session |
| ADR-007 | Playwright + axe-core fallback mode | Architecture independence + graceful degradation; fewer audit types in fallback |
Technical Specifications
| Spec | Covers | Parent ADR |
|---|---|---|
| SPEC-000-A | Visual pattern detection: heading-like and card-like content analysis pipeline | ADR-000 |
| SPEC-001-A | All 6 MCP tool definitions with parameters, return values, and behaviour | ADR-001 |
| SPEC-002-A | Subprocess invocation, config generation, process monitoring, cleanup | ADR-002 |
| SPEC-003-A | Scan registry data structure, state transitions, thread safety | ADR-003 |
| SPEC-004-A | Plugin manifest schema, skill definitions, marketplace config | ADR-004 |
| SPEC-005-A | Report templates, Jinja2 rendering, DOCX generation, auto-report | ADR-005 |
| SPEC-006-A | SessionStart hook, install script, CWAC_PATH discovery, verification | ADR-006 |
| SPEC-007-A | axe-core scanner design, CSV mapping, environment check | ADR-007 |