Free WCAG 2.2/ADA/508 accessibility MCP: scan, AI fixes, verify, vision audit, localhost tunnel
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add a website to the signed-in WebAbility account. The site gets the full widget for its first 30 days and a first scan. Returns the site id and plan tier. Next: put the get_install_snippet tag on the site, and use create_upgrade_link to get a payment link for the WebAbility Pro plan. Needs a free WebAbility account (an AI agent can sign itself up with "Sign in with AgentID").
The site to add, for example https://shop.example.com. One domain per site.
Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Add a website to the signed-in WebAbility account. The site gets the full widget for its first 30 days and a first scan. Returns the site id and plan tier. Next: put the get_install_snippet tag on the site, and use create_upgrade_link to get a payment link for the WebAbility Pro plan. Needs a free WebAbility account (an AI agent can sign itself up with "Sign in with AgentID").
| Argument | Type | Description |
|---|---|---|
| url* | string | The site to add, for example https://shop.example.com. One domain per site. |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "The site to add, for example https://shop.example.com. One domain per site."
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
}
}
}Validate ARIA attribute + accessible name/role/value usage — in an HTML snippet (`html`) or on a live page (`url`), optionally limited to one element and its descendants (`selector`). Runs axe-core `cat.aria` and `cat.name-role-value` rules (aria-* attribute correctness, role validity, required parents/children, aria-hidden-focus, accessible names). Returns `violations`. A selector that matches nothing, or a page that answers an HTTP error, is an error — never "no violations". Nodes cap at 5 per rule by default — every rule reports nodesTotal + truncated; raise nodeLimit (max 50). NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url | string | Live page to check (pass this or `html`) |
| html | string | HTML to test for ARIA correctness (pass this or `url`) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
Check text contrast against the WCAG AA threshold (4.5:1, or 3:1 for large text); the AAA verdict is shown only when you pass level: "AAA". Either pass a `foreground` / `background` color pair, or pass `url` + `selector` to read the element's own text color, background (composited from the nearest painted ancestors), font size and weight from the live page; explicit colors win over the page. A gradient or image background is reported as an error, never a guessed ratio. When it fails, suggests BRAND-aligned replacements — extracts the actual brand palette from the `url` page using our scanner (CSS vars + most-used colors), or use a provided `brandColors` array. No `url` and no `brandColors` = ratio + pass/fail only. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url | string | Live page: with `selector`, the colors are read from that element; on a failing pair, the brand palette is extracted from it (uses our scanner — CSS vars + dominant colors). |
| level | string | Conformance level to judge. Default "AA". "AAA" adds the enhanced-contrast (1.4.6) verdict and AAA palette suggestions. |
| isBold | boolean | Whether text is bold (default false, or the element's computed weight with url + selector) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
Get a Stripe Checkout link that puts one site on the WebAbility Pro plan (the widget subscription). Give the link to the human who pays (your owner). When they pay, the plan activates on that site automatically; check with list_sites. You never handle card details. The site must be on the account (add_site first). Needs a free WebAbility account.
| Argument | Type | Description |
|---|---|---|
| domain* | string | The site to upgrade, as added with add_site (for example shop.example.com) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| billing_interval | string | Billing period. Default monthly. |
{
"type": "object",
"required": [
"domain"
],
"properties": {
"domain": {
"type": "string",
"description": "The site to upgrade, as added with add_site (for example shop.example.com)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"billing_interval": {
"enum": [
"monthly",
"yearly"
],
"type": "string",
"description": "Billing period. Default monthly."
}
}
}Detect a page's stack as two separate fields: `framework` — the application framework, CMS or site builder (e.g. nextjs, nuxt, sveltekit, vitepress, astro, gatsby, wordpress, shopify, mediawiki, vue, react; "unknown" when no signal) — and `cssToolkit` (tailwind, bootstrap, mui, plain-css). Lists the evidence it used and the value to pass as generate_ai_fix `framework`. scan_page reports the same two fields from the same detection. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url* | string | URL to inspect |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
Compare two scans of the same page and report what changed: `fixed[]` (in the baseline, gone now), `new[]` (regressions — not in the baseline, present now), `remaining[]` (still there). Page-level complement to verify_fix (one element). Baseline is a scan_history id (`baselineId`, local installs) or a live scan of `baselineUrl`; current is `url` (scanned live now) or another history id (`currentId`). Findings are matched by issue id (rule + element), so a changed class/id on a fixed element reads as fixed AND new — check `new[]` before calling it a regression. Typical loop: scan_page → edit → diff_scan(baselineId=<that scan id>, url=<same url>) → confirm new[] is empty. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url | string | URL to scan now as the CURRENT side (deployed, staging, or http://localhost:3000). Omit when passing currentId. |
| wcag | array | Only these WCAG criteria. A prefix selects the whole guideline ("1.4") or principle ("2"). |
| level | string | Highest WCAG conformance level to report. Default "AA" — Level AAA criteria are not reported. Pass "AAA" to include them (naming one AAA criterion in `wcag`, e.g. "3.2.5", also includes it). |
| rules | array | Only these rule ids (WebAbility type such as "missing_alt" or axe rule id such as "image-alt"). See get_rules. |
Scan a multi-page user journey. Walks startUrl plus the `autoNavigate` URLs sequentially (deterministic — one page fully rendered and scanned before the next), then returns ONE consolidated report with issues deduplicated across pages, each carrying the same fix payload as scan_page. Every requested URL gets an explicit outcome in `pages[]` (scanned / nav_failed / scan_failed / redirected_duplicate / duplicate_request / skipped_cap / blocked — bot-challenge, not a clean page) — a page is never silently dropped. Better than per-page scans for journeys (login → checkout etc). Without `autoNavigate` it scans only startUrl, exactly like scan_page. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| wcag | array | Only these WCAG criteria. A prefix selects the whole guideline ("1.4") or principle ("2"). |
| level | string | Highest WCAG conformance level to report. Default "AA" — Level AAA criteria are not reported. Pass "AAA" to include them (naming one AAA criterion in `wcag`, e.g. "3.2.5", also includes it). |
| rules | array | Only these rule ids (WebAbility type such as "missing_alt" or axe rule id such as "image-alt"). See get_rules. |
| format | string | "compact" prints one line per element with rule metadata once. "json" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count. |
Generate framework-aware fix alternatives for a specific accessibility issue. For color contrast issues, returns 3 alternatives (minimal, brand-aligned, high contrast); brand palette is auto-extracted from the live URL using our scanner if `brandColors` is omitted. For label/ARIA issues, returns 1-2 alternatives. Each alternative includes ready-to-paste code for the detected framework. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url | string | Page URL — also used to auto-extract brand palette for contrast issues if `brandColors` is not provided. |
| html* | string | The element's outerHTML — send at most ~600 chars |
| issue* | object | string | Issue object from scan_page (with selector, wcag, impact, message, fix.currentValue), or a plain-text issue description |
| context | string | Parent element outerHTML for context (~400 chars) |
| framework* | string | CSS framework — use detect_framework first |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
Check an audit started with start_audit: returns overall status, per-step progress (scan → viewports → screenshots → agent → excel → publish), and — once complete — a severity summary plus short-lived download URLs for the report (JSON) and the Excel workbook. Poll every ~15s while status is pending/running. Only the account that started an audit can read it. Free with a WebAbility account.
| Argument | Type | Description |
|---|---|---|
| id* | number | The audit id returned by start_audit |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "number",
"description": "The audit id returned by start_audit"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
}
}
}Get the one-line script tag that installs the WebAbility accessibility widget. Put it in the <head> or before </body> of every page of a site added with add_site. The widget finds the site by its domain, so the same tag works on every site. No account needed.
| Argument | Type | Description |
|---|---|---|
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
{
"type": "object",
"required": [],
"properties": {
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
}
}
}List accessibility rules from both engines — axe-core (104) and the WebAbility detectors (90+) — with optional filters. Every rule carries `fixability` (mechanical | contextual | visual) and a `fix` op template, so you can pick the rules worth auto-fixing before scanning. Returns ruleId, engine, description, help, helpUrl, tags/wcag, fixability, fix.
| Argument | Type | Description |
|---|---|---|
| rule | string | Only rules whose id contains these whole words (e.g. "link" → link-name, skip-link, not blink; "color-contrast"; case and -/_ insensitive). Also accepted: ruleId, id, query. |
| tags | array | axe tag filter (e.g. ["wcag2aa"], ["best-practice"], ["cat.aria"]; a category also works without "cat."). WebAbility rules match on their WCAG criterion tag (e.g. "wcag143"). An unknown tag or category is an error that lists the valid ones. |
| engine | string | Which engine's rules to list (default all) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model |
List the sites on the signed-in WebAbility account with each site id, plan tier and the date the current plan ends. Use it to check that a payment activated WebAbility Pro on a site. Needs a free WebAbility account.
| Argument | Type | Description |
|---|---|---|
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
{
"type": "object",
"required": [],
"properties": {
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
}
}
}Scan a raw HTML snippet or component markup without serving it — IN-PROCESS by default (jsdom + WebAbility detectors + axe-core): milliseconds, no browser, no network, so it fits inside a tight edit loop. Fragments are auto-wrapped into a document. Returns scan_page's shape (issues / summary) with `fix.op` + `fixability` on every finding. jsdom has no layout, so visual-tier rules (contrast, target size, focus ring) are NOT evaluated — the dropped count is reported as `skippedVisual`; pass `engine: "browser"` to run the axe-core headless-browser path for those (slower, axe rules only, returns axe `violations`).
| Argument | Type | Description |
|---|---|---|
| html* | string | HTML content to test — a full document or a fragment |
| tags | array | WCAG tags to check (default ["wcag2a","wcag2aa","wcag21aa","wcag22aa"]) |
| wcag | array | Only these WCAG criteria. A prefix selects the whole guideline ("1.4") or principle ("2"). |
| level | string | Highest WCAG conformance level to report. Default "AA" — Level AAA criteria are not reported. Pass "AAA" to include them (naming one AAA criterion in `wcag`, e.g. "3.2.5", also includes it). |
| rules | array | Only these rule ids (WebAbility type such as "missing_alt" or axe rule id such as "image-alt"). See get_rules. |
| width | number | Viewport width (browser engine only, default 1280) |
Scan a web page for WCAG accessibility issues. Works on any URL — deployed sites, localhost, staging. Returns `issues` (violations the scanner stands behind; findings the engines cannot decide are settled by the AI judge — a violation with a fix, or a pass recorded in `judged[]` with its reason — and anything unsettled is dropped, never listed for review) and a `summary`. On React ≤18 / Vue dev builds each issue carries `source` ({file, line, column, component}) read from the live component tree. Every issue carries a structured `fix.op` (add-attribute | set-attribute | remove-attribute | add-element | remove-element | add-text-content | suggest) with `fix.attribute` / `fix.value` when known, and a `fixability` tier (mechanical = apply as given; contextual = op known, value needs judgment; visual = needs rendered output, propose only). NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url* | string | URL to scan (e.g. https://webability.io or http://localhost:3000) |
| wcag | array | Only these WCAG criteria. A prefix selects the whole guideline ("1.4") or principle ("2"). |
| level | string | Highest WCAG conformance level to report. Default "AA" — Level AAA criteria are not reported. Pass "AAA" to include them (naming one AAA criterion in `wcag`, e.g. "3.2.5", also includes it). |
| rules |
Kick off a FULL accessibility audit deliverable for a URL — a persistent, timestamped artifact, not an inline scan. Runs the server-side pipeline (axe + advanced checks + mobile viewports + annotated screenshots + optional agent spot-check) and produces a downloadable report and a formatted Excel workbook (Cover / Status / Barriers / ADA context sheets) stored durably. Returns immediately with an audit `id`; poll `get_audit` for progress and, when complete, download URLs. Use this when someone needs a durable artifact to attach as evidence of testing effort for a compliance officer or legal response — for iterating on code, use scan_page + verify_fix instead. Needs a free WebAbility account (sign in by connecting https://mcp.webability.io/mcp/auth, or run `webability login`). Set includeAgent:true to add the slower agentic manual-audit pass. To audit a local dev server, open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` with the printed secret as `tunnel_secret`; keep the tunnel open until get_audit reports complete (about 5 minutes) — the pipeline loads the page several times.
| Argument | Type | Description |
|---|---|---|
| url* | string | URL to audit (a public/staging URL the server can reach, or a webability-tunnel URL — not localhost) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string |
Re-scan a specific element after applying an accessibility fix and confirm the violation is gone. After you edit the code and serve it (deployed, staging, or http://localhost:3000), call this with the URL and the selector you fixed to get a machine-checked verified: true|false (DOM engines only — visual_audit findings are out of scope). Pass the WCAG criterion (e.g. "1.1.1") or axe rule id (e.g. "color-contrast") to check just that criterion; omit it to require the element be clean of ALL violations. A blocked page (bot-challenge / HTTP error) is reported as unverified, never a pass — verification fails closed. verified: true is only returned when the selector matched at least one element AND the criterion is one the DOM engines check; if the selector matches no element the result is verified: false with reason "not-found" ("selector matched no elements"), a criterion outside the coverage set returns reason "not-verifiable" ("not checked by any WebAbility tool"); a finding in scope that only the AI judge can settle, when the judge did not run or gave no verdict, also returns "not-verifiable", and shadow-DOM (>>>) / iframe selectors return "unsupported-selector" — pass the element's current selector, or re-run scan_page if your fix removed the element. Pair with scan_page → generate_ai_fix → verify_fix for a full find-fix-verify cycle. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url* | string | URL now serving the fix (deployed, staging, or http://localhost:3000). Also accepted as `page` or `pageUrl`. |
| wcag | string | Optional: WCAG criterion (e.g. "1.1.1", "1.4.3") or axe rule id (e.g. "color-contrast") to verify specifically. Omit to require the element be free of ALL violations. |
Pixel-level accessibility audit using Claude vision. Catches issues that DOM scanners miss: icon contrast (1.4.11), focus visibility (2.4.7), "looks like a button but isn't" (4.1.2), text rendered as images (1.4.5), visual hierarchy mismatches. Takes a URL, opens it in a headless browser, screenshots, and runs vision-based detection. Complements scan_page — run both for full coverage. Sign in with a free WebAbility account for vision and full audits (sign in by connecting https://mcp.webability.io/mcp/auth, or run `webability login`). Fair-use rate limits apply. NOTE: on this HOSTED server, localhost and private addresses are refused — it runs in our cloud and cannot reach your machine. Two ways to scan a local dev server: run the MCP locally (`npx -y @webability/mcp`, simplest — nothing leaves the machine), or open a tunnel (`webability-tunnel --port 3000`) and pass its URL as `url` together with the printed secret as `tunnel_secret`.
| Argument | Type | Description |
|---|---|---|
| url* | string | URL to audit visually |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| fullPage | boolean | Capture full scrolled page instead of just viewport (default: false) |
| viewport | string |
| selector | string | Only report findings on this element and its descendants (e.g. the `selector` from a scan_page issue). ARIA references outside it still resolve. |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| nodeLimit | number | Max nodes returned per rule (default 5, max 50) |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [],
"properties": {
"url": {
"type": "string",
"description": "Live page to check (pass this or `html`)"
},
"html": {
"type": "string",
"description": "HTML to test for ARIA correctness (pass this or `url`)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"selector": {
"type": "string",
"description": "Only report findings on this element and its descendants (e.g. the `selector` from a scan_page issue). ARIA references outside it still resolve."
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"nodeLimit": {
"type": "number",
"description": "Max nodes returned per rule (default 5, max 50)"
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| fontSize | number | Font size in px (default 16, or the element's computed size with url + selector) |
| selector | string | CSS selector of the text element on `url` (e.g. the `selector` from a scan_page issue) |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| background | string | Background color (hex or rgb). Optional with url + selector. |
| foreground | string | Foreground color (hex or rgb). Optional with url + selector. |
| brandColors | array | Pre-supplied brand palette. Skips URL extraction if provided. |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [],
"properties": {
"url": {
"type": "string",
"description": "Live page: with `selector`, the colors are read from that element; on a failing pair, the brand palette is extracted from it (uses our scanner — CSS vars + dominant colors)."
},
"level": {
"enum": [
"AA",
"AAA"
],
"type": "string",
"description": "Conformance level to judge. Default \"AA\". \"AAA\" adds the enhanced-contrast (1.4.6) verdict and AAA palette suggestions."
},
"isBold": {
"type": "boolean",
"description": "Whether text is bold (default false, or the element's computed weight with url + selector)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"fontSize": {
"type": "number",
"description": "Font size in px (default 16, or the element's computed size with url + selector)"
},
"selector": {
"type": "string",
"description": "CSS selector of the text element on `url` (e.g. the `selector` from a scan_page issue)"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"background": {
"type": "string",
"description": "Background color (hex or rgb). Optional with url + selector."
},
"foreground": {
"type": "string",
"description": "Foreground color (hex or rgb). Optional with url + selector."
},
"brandColors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Pre-supplied brand palette. Skips URL extraction if provided."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL to inspect"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| format | string | "compact" prints one line per element with rule metadata once. "json" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count. |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| viewport | string | Viewport for live scans (default: desktop). Use the same viewport the baseline used. |
| currentId | string | scan_history id to use as the CURRENT side instead of scanning `url` |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| minImpact | string | Only findings at this severity or above (critical > serious > moderate > minor) |
| baselineId | string | scan_history id of the BASELINE scan (local installs only) |
| baselineUrl | string | Scan this URL live as the baseline (e.g. production) — use when there is no stored baseline |
| rootSelector | string | CSS selector to limit live scans to (optional) |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [],
"properties": {
"url": {
"type": "string",
"description": "URL to scan now as the CURRENT side (deployed, staging, or http://localhost:3000). Omit when passing currentId."
},
"wcag": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these WCAG criteria. A prefix selects the whole guideline (\"1.4\") or principle (\"2\")."
},
"level": {
"enum": [
"A",
"AA",
"AAA"
],
"type": "string",
"description": "Highest WCAG conformance level to report. Default \"AA\" — Level AAA criteria are not reported. Pass \"AAA\" to include them (naming one AAA criterion in `wcag`, e.g. \"3.2.5\", also includes it)."
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these rule ids (WebAbility type such as \"missing_alt\" or axe rule id such as \"image-alt\"). See get_rules."
},
"format": {
"enum": [
"json",
"compact"
],
"type": "string",
"description": "\"compact\" prints one line per element with rule metadata once. \"json\" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count."
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"viewport": {
"enum": [
"desktop",
"tablet",
"mobile"
],
"type": "string",
"description": "Viewport for live scans (default: desktop). Use the same viewport the baseline used."
},
"currentId": {
"type": "string",
"description": "scan_history id to use as the CURRENT side instead of scanning `url`"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"minImpact": {
"enum": [
"critical",
"serious",
"moderate",
"minor"
],
"type": "string",
"description": "Only findings at this severity or above (critical > serious > moderate > minor)"
},
"baselineId": {
"type": "string",
"description": "scan_history id of the BASELINE scan (local installs only)"
},
"baselineUrl": {
"type": "string",
"description": "Scan this URL live as the baseline (e.g. production) — use when there is no stored baseline"
},
"rootSelector": {
"type": "string",
"description": "CSS selector to limit live scans to (optional)"
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| maxPages | number | Max pages to scan (default 10) |
| startUrl* | string | Starting URL of the journey |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| minImpact | string | Only findings at this severity or above (critical > serious > moderate > minor) |
| sourceRoot | string | Local project root (local installs only) for `sourceCandidates[]` on issues without a framework `source` pointer. |
| autoNavigate | array | The URLs to walk after startUrl, in order (the MCP server is headless and cannot discover a journey interactively). Omit or pass [] to scan only startUrl as a single page. |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"startUrl"
],
"properties": {
"wcag": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these WCAG criteria. A prefix selects the whole guideline (\"1.4\") or principle (\"2\")."
},
"level": {
"enum": [
"A",
"AA",
"AAA"
],
"type": "string",
"description": "Highest WCAG conformance level to report. Default \"AA\" — Level AAA criteria are not reported. Pass \"AAA\" to include them (naming one AAA criterion in `wcag`, e.g. \"3.2.5\", also includes it)."
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these rule ids (WebAbility type such as \"missing_alt\" or axe rule id such as \"image-alt\"). See get_rules."
},
"format": {
"enum": [
"json",
"compact"
],
"type": "string",
"description": "\"compact\" prints one line per element with rule metadata once. \"json\" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count."
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"maxPages": {
"type": "number",
"description": "Max pages to scan (default 10)"
},
"startUrl": {
"type": "string",
"description": "Starting URL of the journey"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"minImpact": {
"enum": [
"critical",
"serious",
"moderate",
"minor"
],
"type": "string",
"description": "Only findings at this severity or above (critical > serious > moderate > minor)"
},
"sourceRoot": {
"type": "string",
"description": "Local project root (local installs only) for `sourceCandidates[]` on issues without a framework `source` pointer."
},
"autoNavigate": {
"type": "array",
"items": {
"type": "string"
},
"description": "The URLs to walk after startUrl, in order (the MCP server is headless and cannot discover a journey interactively). Omit or pass [] to scan only startUrl as a single page."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| brandColors | array | Brand palette for brand-aligned suggestions. If omitted on a contrast issue with a `url`, auto-extracted via the scanner. |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"issue",
"html",
"framework"
],
"properties": {
"url": {
"type": "string",
"description": "Page URL — also used to auto-extract brand palette for contrast issues if `brandColors` is not provided."
},
"html": {
"type": "string",
"description": "The element's outerHTML — send at most ~600 chars"
},
"issue": {
"type": [
"object",
"string"
],
"description": "Issue object from scan_page (with selector, wcag, impact, message, fix.currentValue), or a plain-text issue description"
},
"context": {
"type": "string",
"description": "Parent element outerHTML for context (~400 chars)"
},
"framework": {
"enum": [
"tailwind",
"bootstrap",
"mui",
"wordpress",
"nextjs",
"plain-css"
],
"type": "string",
"description": "CSS framework — use detect_framework first"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"brandColors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand palette for brand-aligned suggestions. If omitted on a contrast issue with a `url`, auto-extracted via the scanner."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| string |
| The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| fixability | string | Only rules of this fixability tier |
{
"type": "object",
"required": [],
"properties": {
"rule": {
"type": "string",
"description": "Only rules whose id contains these whole words (e.g. \"link\" → link-name, skip-link, not blink; \"color-contrast\"; case and -/_ insensitive). Also accepted: ruleId, id, query."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "axe tag filter (e.g. [\"wcag2aa\"], [\"best-practice\"], [\"cat.aria\"]; a category also works without \"cat.\"). WebAbility rules match on their WCAG criterion tag (e.g. \"wcag143\"). An unknown tag or category is an error that lists the valid ones."
},
"engine": {
"enum": [
"all",
"axe",
"webability"
],
"type": "string",
"description": "Which engine's rules to list (default all)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"fixability": {
"enum": [
"mechanical",
"contextual",
"visual"
],
"type": "string",
"description": "Only rules of this fixability tier"
}
}
}| engine | string | "in-process" (default): jsdom, ms, structural rules. "browser": headless Chromium + axe-core, includes contrast. |
| format | string | "compact" prints one line per element with rule metadata once. "json" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count. |
| height | number | Viewport height (browser engine only, default 800) |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| minImpact | string | Only findings at this severity or above (critical > serious > moderate > minor) |
{
"type": "object",
"required": [
"html"
],
"properties": {
"html": {
"type": "string",
"description": "HTML content to test — a full document or a fragment"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "WCAG tags to check (default [\"wcag2a\",\"wcag2aa\",\"wcag21aa\",\"wcag22aa\"])"
},
"wcag": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these WCAG criteria. A prefix selects the whole guideline (\"1.4\") or principle (\"2\")."
},
"level": {
"enum": [
"A",
"AA",
"AAA"
],
"type": "string",
"description": "Highest WCAG conformance level to report. Default \"AA\" — Level AAA criteria are not reported. Pass \"AAA\" to include them (naming one AAA criterion in `wcag`, e.g. \"3.2.5\", also includes it)."
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these rule ids (WebAbility type such as \"missing_alt\" or axe rule id such as \"image-alt\"). See get_rules."
},
"width": {
"type": "number",
"description": "Viewport width (browser engine only, default 1280)"
},
"engine": {
"enum": [
"in-process",
"browser"
],
"type": "string",
"description": "\"in-process\" (default): jsdom, ms, structural rules. \"browser\": headless Chromium + axe-core, includes contrast."
},
"format": {
"enum": [
"json",
"compact"
],
"type": "string",
"description": "\"compact\" prints one line per element with rule metadata once. \"json\" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count."
},
"height": {
"type": "number",
"description": "Viewport height (browser engine only, default 800)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"minImpact": {
"enum": [
"critical",
"serious",
"moderate",
"minor"
],
"type": "string",
"description": "Only findings at this severity or above (critical > serious > moderate > minor)"
}
}
}| array |
| Only these rule ids (WebAbility type such as "missing_alt" or axe rule id such as "image-alt"). See get_rules. |
| format | string | "compact" prints one line per element with rule metadata once. "json" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count. |
| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| viewport | string | Viewport size (default: desktop) |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| minImpact | string | Only findings at this severity or above (critical > serious > moderate > minor) |
| sourceRoot | string | Local project root (local installs only). Issues without a framework `source` pointer get `sourceCandidates[]` — files whose contents match the selector's id/class/attribute tokens. |
| rootSelector | string | CSS selector to limit scan scope (optional) |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL to scan (e.g. https://webability.io or http://localhost:3000)"
},
"wcag": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these WCAG criteria. A prefix selects the whole guideline (\"1.4\") or principle (\"2\")."
},
"level": {
"enum": [
"A",
"AA",
"AAA"
],
"type": "string",
"description": "Highest WCAG conformance level to report. Default \"AA\" — Level AAA criteria are not reported. Pass \"AAA\" to include them (naming one AAA criterion in `wcag`, e.g. \"3.2.5\", also includes it)."
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these rule ids (WebAbility type such as \"missing_alt\" or axe rule id such as \"image-alt\"). See get_rules."
},
"format": {
"enum": [
"json",
"compact"
],
"type": "string",
"description": "\"compact\" prints one line per element with rule metadata once. \"json\" returns every field (html, fix values, source). Default: JSON when it fits inline (under ~24k chars), otherwise compact plus a JSON summary of every count."
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"viewport": {
"enum": [
"desktop",
"tablet",
"mobile"
],
"type": "string",
"description": "Viewport size (default: desktop)"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"minImpact": {
"enum": [
"critical",
"serious",
"moderate",
"minor"
],
"type": "string",
"description": "Only findings at this severity or above (critical > serious > moderate > minor)"
},
"sourceRoot": {
"type": "string",
"description": "Local project root (local installs only). Issues without a framework `source` pointer get `sourceCandidates[]` — files whose contents match the selector's id/class/attribute tokens."
},
"rootSelector": {
"type": "string",
"description": "CSS selector to limit scan scope (optional)"
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| includeAgent | boolean | Also run the agentic manual-audit pass (keyboard/focus/modal exploration). Slower. Default false. |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL to audit (a public/staging URL the server can reach, or a webability-tunnel URL — not localhost)"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"includeAgent": {
"type": "boolean",
"description": "Also run the agentic manual-audit pass (keyboard/focus/modal exploration). Slower. Default false."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| context | string | Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution." |
| selector* | string | CSS selector of the element you fixed — use the `selector` from the original scan_page issue |
| viewport | string | Viewport size (default: desktop). Use the same viewport the issue was found at. |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"url",
"selector"
],
"properties": {
"url": {
"type": "string",
"description": "URL now serving the fix (deployed, staging, or http://localhost:3000). Also accepted as `page` or `pageUrl`."
},
"wcag": {
"type": "string",
"description": "Optional: WCAG criterion (e.g. \"1.1.1\", \"1.4.3\") or axe rule id (e.g. \"color-contrast\") to verify specifically. Omit to require the element be free of ALL violations."
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"selector": {
"type": "string",
"description": "CSS selector of the element you fixed — use the `selector` from the original scan_page issue"
},
"viewport": {
"enum": [
"desktop",
"tablet",
"mobile"
],
"type": "string",
"description": "Viewport size (default: desktop). Use the same viewport the issue was found at."
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}| Viewport size (default: desktop) |
| llm_model | string | The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess. |
| brandColors | array | Brand hex colors for context-aware filtering |
| tunnel_secret | string | Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL to audit visually"
},
"context": {
"type": "string",
"description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
},
"fullPage": {
"type": "boolean",
"description": "Capture full scrolled page instead of just viewport (default: false)"
},
"viewport": {
"enum": [
"desktop",
"tablet",
"mobile"
],
"type": "string",
"description": "Viewport size (default: desktop)"
},
"llm_model": {
"type": "string",
"description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess."
},
"brandColors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand hex colors for context-aware filtering"
},
"tunnel_secret": {
"type": "string",
"description": "Secret printed by `webability-tunnel`. Required when `url` is a tunnel URL; the URL alone will be refused by the relay. Ignored otherwise."
}
}
}