MCP Axe has 4 tools with basic schemas and descriptions, but significant gaps reduce quality. All tools have descriptions (10-50 chars, below baseline avg 194), which is concerning. Input schemas are present with type information, but parameter descriptions are minimal. The server exposes accessibility scanning via Selenium/Playwright but lacks error recovery guidance, pagination support for batch results, and output schema documentation. No tool annotations (readOnlyHint) despite all being read-only. Batch results lack per-item error reporting.
Tool descriptions critically short (10-50 chars vs baseline 194). 'Accessibility scan on a URL' and 'Batch scan multiple URLs' lack context on WHEN to use, WHAT is returned, and any prerequisites. LLMs cannot distinguish between scan-url and scan-batch without richer descriptions.
Input parameter descriptions are missing or trivial. 'URL to audit' and 'Raw HTML to audit' do not specify expected format (http vs https), timeout behavior, what happens on 404/timeout, or retry semantics. No guidance on URL validation or HTML size limits.
Output schema for all tools is undocumented. ScanResult(url, violations) is visible in code but LLM does not see the Pydantic model definition. No documentation of violations structure (list of dicts with what fields?), error codes, or what happens on network failure. Downstream agents cannot plan what to extract.
Recommendations
Expand tool descriptions to 100-200 chars, following the pattern: 'Scans a single URL for WCAG accessibility violations using Axe-core. Returns a list of violations with severity (critical/serious/minor/best-practice), description, and remediation hints. Use this for individual URL audits; use scan-batch for multiple URLs. Supports http/https URLs; times out after 30s. Failures include 404, timeout, blocked JS execution.'
Document parameter constraints in descriptions: 'url (string, required): Full URL starting with http:// or https://. Max 2048 chars. Timeouts after 30 seconds. If the page blocks JavaScript or uses CORS-blocked resources, Axe injection may fail, try a different URL or check browser console logs.'
Add output schema documentation as a comment or return annotation: 'Returns ScanResult { url: string, violations: [{id: string, impact: "critical"|"serious"|"minor"|"best-practice", description: string, nodes: [{html: string, target: [string]}]}'. This helps LLMs understand chaining requirements.
Implement per-item error tracking in scan-batch. Instead of returning list[ScanResult], return { results: list[ScanResult], errors: [{url: string, reason: string, retryable: bool}], total_count: int, failed_count: int }. This allows agents to distinguish succeeded, failed, and partially-complete batches.
Add readOnlyHint: true to all tool definitions via FastMCP decorator or schema amendment. This signals to clients that these tools are safe to call repeatedly without side effects.
No error recovery guidance. If a URL times out, returns 403, or contains JavaScript that prevents Axe injection, the LLM sees only a RuntimeError('Axe injection or run failed'). No indication of whether to retry, ask user for a different URL, or check browser logs. Violates recovery-guide pattern.
Tool annotations missing. All 4 tools are read-only (no side effects), but lack readOnlyHint in MCP schema. This prevents clients from optimizing caching, batch handling, or safety policies.
Batch results lack per-item error reporting. scan-batch_tool returns list[ScanResult], but if one URL fails, the entire batch succeeds with no indication of which URLs were skipped or errored. An LLM cannot know whether to retry individual items or consider the batch complete.
No result pagination or limits. scan-batch accepts unlimited URLs; violations lists are unbounded. Large results will blow context windows. No limit parameter, no pagination fields (next_cursor, total_count) documented.
summarise-violations parameter 'result' is a raw dict with no schema. LLM must guess the structure (is it the output of scan-url? A list of violations? Raw Axe JSON?). Undocumented dependencies on prior tool outputs.
summarise-violations
Add a 'limit' parameter to scan-batch with range 1-100 (default 10). Document: 'Maximum number of URLs to scan in one batch. Larger batches consume more tokens and latency. Recommend 10-20 for most use cases.'
For summarise-violations, define the 'result' parameter precisely: 'result (object, required): Raw scan output from scan-url or scan-html, containing { url: string, violations: [{id, impact, description, nodes}] }. This tool extracts high-level summaries and remediation steps from the violations array.'
Implement structured error responses with recovery hints: if axe injection fails, return { error: 'Axe injection failed', reason: 'JavaScript execution blocked or timeout', retryable: true, suggestions: ['Try a publicly-cached CDN URL', 'Check if the page loads in a browser', 'Verify network connectivity'] }.
Document timeout behavior: 'Each URL scan has a 30-second timeout. Slow pages or pages with heavy JavaScript may fail. No automatic retries are performed; the LLM must decide to retry based on the error reason.'
Add a simple discovery tool or document pre-requisites: clarify whether scan-url requires the URL to be publicly accessible (not behind auth/VPN), whether cookies/headers are supported, and what browsers are available (Chromium/Firefox).