Docs > API reference
The WebAbility API is the hosted MCP server at https://mcp.webability.io. It speaks JSON-RPC 2.0 over Streamable HTTP. Integrations such as Zapier and MCP clients use the endpoints on this page.
Product overview: WebAbility MCP server.
Signed-in endpoints use OAuth 2.0 authorization code flow with PKCE (method S256) and the scope mcp. The user signs in to their WebAbility account and approves access. Field lists below follow RFC 6749, RFC 7591 and RFC 7636.
Alternative: create an API key in the WebAbility dashboard and send it as Authorization: Bearer <key>.
Discovery document for the protected resource. No authentication.
curl -s https://mcp.webability.io/.well-known/oauth-protected-resource
{
"resource": "https://mcp.webability.io/mcp",
"authorization_servers": ["https://mcp.webability.io"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["mcp"],
"resource_documentation": "https://www.webability.io/docs/mcp"
}Authorization server metadata (RFC 8414). No authentication.
curl -s https://mcp.webability.io/.well-known/oauth-authorization-server
{
"issuer": "https://mcp.webability.io",
"authorization_endpoint": "https://mcp.webability.io/authorize",
"token_endpoint": "https://mcp.webability.io/token",
"registration_endpoint": "https://mcp.webability.io/register",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["none"],
"scopes_supported": ["mcp"],
"service_documentation": "https://www.webability.io/docs/mcp"
}Send the user’s browser here. After sign-in and approval, the server redirects to redirect_uri with code and state.
| Parameter | Value |
|---|---|
response_type | code |
client_id | The client id from registration. |
redirect_uri | A redirect URI registered for the client. |
code_challenge | Base64url SHA-256 hash of the code verifier. |
code_challenge_method | S256 |
scope | mcp |
state | An opaque value you generate. Returned unchanged. |
https://mcp.webability.io/authorize?response_type=code
&client_id=<client_id>
&redirect_uri=<redirect_uri>
&code_challenge=<S256 challenge>
&code_challenge_method=S256
&scope=mcp
&state=<state>Content type: application/x-www-form-urlencoded. Clients are public, so no client secret is sent (token_endpoint_auth_methods_supported is none).
Exchange an authorization code. Fields: grant_type=authorization_code, code, redirect_uri, client_id, code_verifier.
curl -s -X POST https://mcp.webability.io/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code' \
-d 'code=<code>' \
-d 'redirect_uri=<redirect_uri>' \
-d 'client_id=<client_id>' \
-d 'code_verifier=<code_verifier>'Response (the expires_in value is in seconds and is shown as an example):
{
"access_token": "<access_token>",
"refresh_token": "<refresh_token>",
"token_type": "Bearer",
"expires_in": 3600
}Refresh an access token. Fields: grant_type=refresh_token, refresh_token, client_id. The response has the same shape and carries new tokens.
curl -s -X POST https://mcp.webability.io/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=<refresh_token>' \
-d 'client_id=<client_id>'OAuth dynamic client registration (RFC 7591) for MCP clients. Send a JSON body with the client metadata, for example client_name and redirect_uris. The response contains the client_id to use in the flow above.
| Method and path | Auth | Purpose |
|---|---|---|
POST /mcp/auth | Bearer token | Signed-in JSON-RPC endpoint. All tools, including the account tools. |
POST /mcp | None | Anonymous JSON-RPC endpoint. Scan and check tools only, under fair-use limits per IP. |
GET /health | None | Health check. |
Required headers:
Content-Type: application/jsonAccept: application/json, text/event-streamAuthorization: Bearer <access_token>The body is a JSON-RPC 2.0 request. Supported methods: initialize, tools/list, tools/call. The server returns HTTP 401 when the token is missing or expired. Clients refresh the token and retry.
A tools/call request has params.name (the tool name) and params.arguments (an object). A tools/list request returns every tool with its JSON Schema in inputSchema.
Same request format, no token. Use it for the scan and check tools. Account tools return sign-in steps as a normal tool result.
curl -s https://mcp.webability.io/health
{"ok":true,"service":"webability-mcp","transport":"streamable-http"}result.content is an array of text items. The first item is a human-readable summary. A tool that returns structured data adds an item with a fenced json code block. Parse that block to read the fields documented below.
The Zapier app calls three tools through tools/call: scan_page, start_audit and get_audit.
Scan a live URL for WCAG issues. Works on the anonymous endpoint (POST /mcp) and on POST /mcp/auth. Read-only. It does not change the scanned site.
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL to scan. It must be reachable from the public internet. Localhost and private addresses are refused by the hosted server. |
rootSelector | string | No | CSS selector that limits the scan scope. |
viewport | string | No | One of desktop, tablet, mobile. Default: desktop. |
level | string | No | Highest WCAG conformance level to report: A, AA or AAA. Default: AA. |
minImpact | string | No | Report only findings at this severity or above: critical, serious, moderate, minor. |
rules | string[] | No | Report only these rule ids (a WebAbility type such as missing_alt, or an axe rule id such as image-alt). |
wcag | string[] | No | Report only these WCAG criteria. A prefix selects a whole guideline (1.4) or principle (2). |
format | string | No | json returns every field. compact returns one line per element. Default: json when the result fits inline, otherwise compact. |
tunnel_secret | string | No | Advanced. Secret printed by webability-tunnel. Needed only when url is a tunnel URL. |
sourceRoot | string | No | Advanced. Local project root. Local installs only. |
context, llm_model | string | No | Advanced. Analytics hints sent by MCP clients. Safe to omit. |
Request:
curl -s -X POST https://mcp.webability.io/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "scan_page",
"arguments": { "url": "https://www.webability.io", "format": "json" }
}
}'Response (shortened). The second item holds the structured data:
{
"result": {
"content": [
{
"type": "text",
"text": "Found 1 high-confidence issue on https://www.webability.io: 0 critical, 1 serious, 0 moderate, 0 minor. Total to report: 1 issue (one per affected element and problem)."
},
{
"type": "text",
"text": "```json\n{ \"url\": \"https://www.webability.io\", \"summary\": {...}, \"issues\": [...] }\n```"
}
]
},
"jsonrpc": "2.0",
"id": 1
}Structured data from the JSON block (real output for one scan, trimmed to its main fields):
{
"url": "https://www.webability.io",
"summary": { "total": 1, "critical": 0, "serious": 1, "moderate": 0, "minor": 0 },
"issues": [
{
"id": "wa-resize_text_clipped-2gihud",
"impact": "serious",
"wcag": "1.4.4",
"type": "resize_text_clipped",
"message": "resize text clipped: missing style",
"selector": "span.font-bold.truncate",
"count": null
}
]
}Each item in issues also carries fix guidance, the affected HTML and a fixability tier. Impact values are critical, serious, moderate and minor.
Start a full audit report for a URL. The audit runs on the server and takes several minutes. The call returns immediately with an audit id. Requires a signed-in account, so use POST /mcp/auth with a bearer token.
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL to audit. It must be a public or staging URL the server can reach, or a webability-tunnel URL. Not localhost. |
includeAgent | boolean | No | Also run the agentic manual-audit pass (keyboard, focus and modal exploration). Slower. Default: false. |
tunnel_secret | string | No | Advanced. Secret printed by webability-tunnel. Needed only when url is a tunnel URL. |
context, llm_model | string | No | Advanced. Analytics hints sent by MCP clients. Safe to omit. |
Request:
curl -s -X POST https://mcp.webability.io/mcp/auth \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'Authorization: Bearer <access_token>' \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "start_audit",
"arguments": { "url": "https://www.example.com" }
}
}'Response (documented shape, shown with example values):
{
"result": {
"content": [
{ "type": "text", "text": "Audit started for https://www.example.com. Poll get_audit with this id." },
{ "type": "text", "text": "```json\n{ \"id\": 1234, \"status\": \"pending\" }\n```" }
]
},
"jsonrpc": "2.0",
"id": 2
}Read the status and report links of an audit. The Zapier action “Find Audit” uses this tool. Requires a signed-in account. Only the account that started an audit can read it. Poll about every 15 seconds while the status is pending or running.
| Field | Type | Required | Description |
|---|---|---|---|
id | number | Yes | The audit id returned by start_audit. |
context, llm_model | string | No | Advanced. Analytics hints sent by MCP clients. Safe to omit. |
Request (POST /mcp/auth, same headers as above):
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": { "name": "get_audit", "arguments": { "id": 1234 } }
}Structured data from the JSON block (documented shape; the exact keys for progress and download links can vary):
{
"id": 1234,
"status": "complete",
"report": "<short-lived download URL for the JSON report>",
"excel": "<short-lived download URL for the Excel workbook>"
}The text summary also lists per-step progress (scan, viewports, screenshots, agent, excel, publish) and, when the audit is complete, a severity summary. Download URLs are short-lived. Call get_audit again for a fresh link.
Call tools/list for the full list and the JSON Schema of each tool. These tools use the same tools/call request format.
| Tool | What it does |
|---|---|
scan_html | Scan an HTML snippet or component markup without a URL. |
flow_scan | Scan a multi-page user journey in one report. |
diff_scan | Compare two scans of the same page: fixed, new and remaining issues. |
verify_fix | Re-scan one element after a fix and confirm the violation is gone. |
generate_ai_fix | Generate framework-aware fix alternatives for one issue. |
visual_audit | Vision-based audit for issues DOM scanners miss. Needs a signed-in account. |
detect_framework | Detect the framework, CMS or site builder of a page. |
check_color_contrast | Check text contrast against the WCAG thresholds. |
check_aria | Validate ARIA attributes, roles and accessible names in a snippet or on a live page. |
get_rules | List the accessibility rules with WCAG tags and fixability tier. |
add_site | Add a website to the signed-in account. Needs a signed-in account. |
list_sites | List the sites on the signed-in account. Needs a signed-in account. |
get_install_snippet | Get the script tag that installs the WebAbility widget. Needs a signed-in account. |
create_upgrade_link | Get a Stripe Checkout link to upgrade one site. Needs a signed-in account. |
error object with code and message.isError: true and a text message in content./mcp/auth. The WWW-Authenticate header points to the resource metadata. Refresh the token and retry.Accept: application/json, text/event-stream is rejected with a JSON-RPC error (“Not Acceptable”).Retry-After header gives the wait in seconds. The token is still valid. Retry after that wait.Content-Type is not application/json.JSON-RPC error:
{
"jsonrpc": "2.0",
"id": 4,
"error": { "code": -32601, "message": "Method not found" }
}Tool error:
{
"result": {
"content": [{ "type": "text", "text": "Error: url is required" }],
"isError": true
},
"jsonrpc": "2.0",
"id": 5
}