Want continuous accessibility monitoring? Check out MyA11yReport MyA11yReport is an automated accessibility scanner that uses AI to filter out false positives and explain genuine WCAG issues in plain English, featuring a centralized dashboard to track active issue counts, severities, and site progress over time.
An open-source Model Context Protocol server that gives AI agents real accessibility-auditing abilities. It runs axe-core audits and drives a real browser through Playwright (navigate, click, type, check/uncheck, scroll, screenshots, aria snapshots, page JavaScript), plus page reviews for alt text, structure and tab order, and a session-free WCAG 2.2 color-contrast checker.
Built for agents: sessions are explicit, every action is logged, and audit history is keyed by URL. It speaks MCP over stdio and needs no account, no API key and no network service of its own.
run_a11y_audit runs axe-core on the current page and
accumulates results per URL.navigate, click, type, press_key, check,
uncheck, select_option, scroll_by, screenshot, get_page_snapshot,
evaluate, get_viewport_size, get_scroll_position.list_images (alt text), get_structure (landmarks,
headings, lists, frames), get_tab_order (focus order).check_color_contrast computes the WCAG 2.2 ratio for
any two colors, with no session or browser.get_audit_guide returns the full step-by-step audit
workflow as markdown, including which checks must be done by a human.node --version)headless: false sessions, a machine with a real display.npm i -g mya11yreport-mcp
mya11yreport-mcp install chromium
The second step downloads the Chromium build that matches the server's Playwright version. It is a separate step rather than a post-install script because some machines block npm lifecycle scripts. If you skip it, the server still starts and simply tells you to run the command the first time a browser tool is used.
Prefer not to install globally? Use npx:
npx -y mya11yreport-mcp install chromium
To confirm the server starts on your machine:
echo '{}' | mya11yreport-mcp
It should exit cleanly; EOF on stdin closes the server.
Clone the repository and build it locally:
git clone <repository-url> mya11yreport-mcp
cd mya11yreport-mcp
npm install
npm run build
node dist/index.js install chromium
Then run the server from the checkout:
node /path/to/mya11yreport-mcp/dist/index.js
Optionally put the mya11yreport-mcp command on your PATH with npm link, so
you can use it anywhere:
npm link
mya11yreport-mcp install chromium
Point your MCP client at the server over stdio. In
opencode, add it to your project opencode.json or your
global ~/.config/opencode/opencode.json.
After a global install or npm link:
{
"mcp": {
"mya11y-audit": {
"type": "local",
"command": [
"mya11yreport-mcp"
],
"enabled": true
}
}
}
Without a global install, use npx:
"command": [
"npx",
"-y",
"mya11yreport-mcp"
]
When running from a local checkout, point at the built entry file directly:
"command": [
"node",
"/path/to/mya11yreport-mcp/dist/index.js"
]
Other MCP clients use the same idea — run the server executable with no arguments over stdio. Restart the client after changing its configuration.
You do not call tools yourself: once the server is connected, your agent does. The typical flow is:
get_audit_guide — needs no session: returns the full step-by-step audit
workflow as markdown (sitemap enumeration, the automated pass, the
structure/tab-order/images/contrast reviews, report format, and the
human-only checks). Call it before a full audit. The same guide is published
at https://mya11y.report/mcp/auditor-skill.start_session — returns a sessionId (pass an optional free-form alias,
max 225 chars, sanitized to [A-Za-z0-9_-]; omit for a hex id). Also picks
headless: true|false.sessionId to every call: navigate, click, type, press_key,
check, uncheck, scroll_by, screenshot, get_page_snapshot, evaluate,
get_viewport_size, get_scroll_position, run_a11y_audit, list_images,
get_structure, get_tab_order.{"selector": "#id"} or
{"fn": {"name": "getByRole", "args": ["button", {"name": "Sign in"}]}}
(getByRole | getByText | getByLabel | getByPlaceholder | getByAltText |
getByTitle).run_a11y_audit audits the current session page (or navigates to url
first) and returns the session's audit history:
{pages: string[], audits: [{pageId, audit}]} — one hex pageId per URL,
audits accumulate per page.evaluate runs a JavaScript expression or function in the page via
page.evaluate and returns the serialized value (non-serializable or
undefined results come back as null with serializable: false). Use it
to read computed styles, geometry or custom element state.check_color_contrast needs no session and no browser: pass two colors (hex or rgb()/rgba()) and optionally
fontSizePx/fontWeight, and it
returns the WCAG 2.2 ratio, the AA/AAA grades, and whether the pair counts as
large text.list_images returns every <img> / inline <svg> with its accessible name
and source, src/currentSrc, sanitized SVG markup, a decorative flag and
derived missingAlt/longAlt flags plus counts. Filter with
filter: all | decorative | missing-alt | has-alt.get_structure returns landmark regions, headings, nested lists and iframes,
plus a heading outline grouped by region with skipped-level / repeated-H1
flags. Regions and headings also carry their raw ariaLabel / ariaLabelledby
attributes. Narrow with include: [...].get_tab_order returns the Tab order (positive tabindex first, then
document order) with each stop's tag, accessible name (text), effective
tabindex, shadow-piercing selector, raw ariaLabel / ariaLabelledby,
nameSource, hasLabel and outOfOrder flags.close_session when done.The three review tools (list_images, get_structure, get_tab_order) inspect
the top frame and open shadow roots only. get_tab_order uses the same
tabbable engine, vendored into the build.
.mya11yreport-mcp/logs/<sessionId>/<sessionId>.json. Screenshots land in the
same directory as <actionId>.png.| Variable | Default | Purpose |
|---|---|---|
MYA11Y_MCP_IDLE_CLOSE_MS | 300000 (5 min) | Idle auto-close delay (min 1000) |
MYA11Y_MCP_LOG_DIR | <cwd>/.mya11yreport-mcp/logs | Session log directory |
PLAYWRIGHT_HEADLESS | true | Default headless mode (param overrides) |
headless: false needs a real display on the host machine.
mya11yreport-mcp install chromium" — you have not installed the
browser yet. Run that command once.get_page_snapshot to discover targets, or retry with a
larger timeoutMs.TypeScript
98.8%
JavaScript
1.2%
Want continuous accessibility monitoring? Check out MyA11yReport MyA11yReport is an automated accessibility scanner that uses AI to filter out false positives and explain genuine WCAG issues in plain English, featuring a centralized dashboard to track active issue counts, severities, and site progress over time.
An open-source Model Context Protocol server that gives AI agents real accessibility-auditing abilities. It runs axe-core audits and drives a real browser through Playwright (navigate, click, type, check/uncheck, scroll, screenshots, aria snapshots, page JavaScript), plus page reviews for alt text, structure and tab order, and a session-free WCAG 2.2 color-contrast checker.
Built for agents: sessions are explicit, every action is logged, and audit history is keyed by URL. It speaks MCP over stdio and needs no account, no API key and no network service of its own.
run_a11y_audit runs axe-core on the current page and
accumulates results per URL.navigate, click, type, press_key, check,
uncheck, select_option, scroll_by, screenshot, get_page_snapshot,
evaluate, get_viewport_size, get_scroll_position.list_images (alt text), get_structure (landmarks,
headings, lists, frames), get_tab_order (focus order).check_color_contrast computes the WCAG 2.2 ratio for
any two colors, with no session or browser.get_audit_guide returns the full step-by-step audit
workflow as markdown, including which checks must be done by a human.node --version)headless: false sessions, a machine with a real display.npm i -g mya11yreport-mcp
mya11yreport-mcp install chromium
The second step downloads the Chromium build that matches the server's Playwright version. It is a separate step rather than a post-install script because some machines block npm lifecycle scripts. If you skip it, the server still starts and simply tells you to run the command the first time a browser tool is used.
Prefer not to install globally? Use npx:
npx -y mya11yreport-mcp install chromium
To confirm the server starts on your machine:
echo '{}' | mya11yreport-mcp
It should exit cleanly; EOF on stdin closes the server.
Clone the repository and build it locally:
git clone <repository-url> mya11yreport-mcp
cd mya11yreport-mcp
npm install
npm run build
node dist/index.js install chromium
Then run the server from the checkout:
node /path/to/mya11yreport-mcp/dist/index.js
Optionally put the mya11yreport-mcp command on your PATH with npm link, so
you can use it anywhere:
npm link
mya11yreport-mcp install chromium
Point your MCP client at the server over stdio. In
opencode, add it to your project opencode.json or your
global ~/.config/opencode/opencode.json.
After a global install or npm link:
{
"mcp": {
"mya11y-audit": {
"type": "local",
"command": [
"mya11yreport-mcp"
],
"enabled": true
}
}
}
Without a global install, use npx:
"command": [
"npx",
"-y",
"mya11yreport-mcp"
]
When running from a local checkout, point at the built entry file directly:
"command": [
"node",
"/path/to/mya11yreport-mcp/dist/index.js"
]
Other MCP clients use the same idea — run the server executable with no arguments over stdio. Restart the client after changing its configuration.
You do not call tools yourself: once the server is connected, your agent does. The typical flow is:
get_audit_guide — needs no session: returns the full step-by-step audit
workflow as markdown (sitemap enumeration, the automated pass, the
structure/tab-order/images/contrast reviews, report format, and the
human-only checks). Call it before a full audit. The same guide is published
at https://mya11y.report/mcp/auditor-skill.start_session — returns a sessionId (pass an optional free-form alias,
max 225 chars, sanitized to [A-Za-z0-9_-]; omit for a hex id). Also picks
headless: true|false.sessionId to every call: navigate, click, type, press_key,
check, uncheck, scroll_by, screenshot, get_page_snapshot, evaluate,
get_viewport_size, get_scroll_position, run_a11y_audit, list_images,
get_structure, get_tab_order.{"selector": "#id"} or
{"fn": {"name": "getByRole", "args": ["button", {"name": "Sign in"}]}}
(getByRole | getByText | getByLabel | getByPlaceholder | getByAltText |
getByTitle).run_a11y_audit audits the current session page (or navigates to url
first) and returns the session's audit history:
{pages: string[], audits: [{pageId, audit}]} — one hex pageId per URL,
audits accumulate per page.evaluate runs a JavaScript expression or function in the page via
page.evaluate and returns the serialized value (non-serializable or
undefined results come back as null with serializable: false). Use it
to read computed styles, geometry or custom element state.check_color_contrast needs no session and no browser: pass two colors (hex or rgb()/rgba()) and optionally
fontSizePx/fontWeight, and it
returns the WCAG 2.2 ratio, the AA/AAA grades, and whether the pair counts as
large text.list_images returns every <img> / inline <svg> with its accessible name
and source, src/currentSrc, sanitized SVG markup, a decorative flag and
derived missingAlt/longAlt flags plus counts. Filter with
filter: all | decorative | missing-alt | has-alt.get_structure returns landmark regions, headings, nested lists and iframes,
plus a heading outline grouped by region with skipped-level / repeated-H1
flags. Regions and headings also carry their raw ariaLabel / ariaLabelledby
attributes. Narrow with include: [...].get_tab_order returns the Tab order (positive tabindex first, then
document order) with each stop's tag, accessible name (text), effective
tabindex, shadow-piercing selector, raw ariaLabel / ariaLabelledby,
nameSource, hasLabel and outOfOrder flags.close_session when done.The three review tools (list_images, get_structure, get_tab_order) inspect
the top frame and open shadow roots only. get_tab_order uses the same
tabbable engine, vendored into the build.
.mya11yreport-mcp/logs/<sessionId>/<sessionId>.json. Screenshots land in the
same directory as <actionId>.png.| Variable | Default | Purpose |
|---|---|---|
MYA11Y_MCP_IDLE_CLOSE_MS | 300000 (5 min) | Idle auto-close delay (min 1000) |
MYA11Y_MCP_LOG_DIR | <cwd>/.mya11yreport-mcp/logs | Session log directory |
PLAYWRIGHT_HEADLESS | true | Default headless mode (param overrides) |
headless: false needs a real display on the host machine.
mya11yreport-mcp install chromium" — you have not installed the
browser yet. Run that command once.get_page_snapshot to discover targets, or retry with a
larger timeoutMs.TypeScript
98.8%
JavaScript
1.2%