Atlas / MCP servers / snayyar00 / snayyar00-webability

snayyar00-webabilityBLOCK

mcp/snayyar00/webability-mcp

Free accessibility MCP server (WCAG 2.2, ADA, Section 508, EAA). Hosted at https://mcp.webability.io/mcp, no API key for scans. Three engines, structured fixes, verify_fix.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
14 13r · 1w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Accessibility checks your coding agent can act on: scan a page with three engines, get a structured fix for each issue, then re-check that the fix landed.

Free. Hosted at https://mcp.webability.io/mcp. No API key for scans. MIT.

Install

Claude Code (plugin)

/plugin marketplace add snayyar00/webability-mcp
/plugin install webability-accessibility@webability

or claude mcp add --transport http webability https://mcp.webability.io/mcp

Cursor: Add to Cursor

VS Code: Install in VS Code · or run code --add-mcp '{"name":"webability","type":"http","url":"https://mcp.webability.io/mcp"}'

Claude.ai / ChatGPT / any MCP client: add a custom connector with the URL https://mcp.webability.io/mcp.

Local (the browser runs on your machine, so it scans localhost directly): npx -y -p @webability/mcp webability-mcp

What you get back

Real output, scan_page on https://demo.vercel.store (trimmed):

Found 16 high-confidence issue(s): 0 critical, 4 serious, 8 moderate, 4 minor.
20 additional finding(s) need human review — see incomplete[]. Do NOT auto-fix these.

missing_label · serious · WCAG 1.3.1 · input.text-md.w-full.rounded-lg
fix: { op: "add-attribute", attribute: "aria-label" }   fixability: contextual
missing_table_scope · moderate · WCAG 1.3.1 · thead > tr > th:nth-of-type(1)   (vite.dev/guide)
fix: { op: "add-attribute", attribute: "scope", value: "col" }   fixability: mechanical

verify_fix input.text-md.w-full.rounded-lg wcag=4.1.2
NOT RESOLVED: 1 violation still present → "verified": false
  • `fix.op` is one of add-attribute, set-attribute, remove-attribute, add-element, remove-element, add-text-content, `s
Read from source at commit 1fbff19ca2d5OBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add mcp -- npx -y @webability/[email protected]
03

Exposed tools (14)

13 read · 1 write · 0 destructive.

ToolRiskDescription
check_ariareadValidate ARIA attribute + accessible name/role/value usage — in an HTML snippet (
check_color_contrastreadCheck 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:
detect_frameworkreadDetect a page\
diff_scanreadCompare two scans of the same page and report what changed:
find_sourcereadFind source files in the local project that contain a given CSS selector. Maps DOM selectors back to source code so you can edit the right file. Searches React/Vue/Svelte/HTML/PHP/Astro files.
flow_scanreadScan a multi-page user journey. Walks startUrl plus the required
generate_ai_fixreadGenerate 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
generate_report_pdfreadTurn scan findings into a branded WebAbility accessibility-report PDF, saved next to the project (local installs only). Pass the
get_install_snippetwriteGet 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.
get_rulesreadList accessibility rules from both engines — axe-core (104) and the WebAbility detectors (90+) — with optional filters. Every rule carries
list_sitesreadList 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.
scan_htmlreadScan 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\
scan_pagereadScan a web page for WCAG accessibility issues. Works on any URL — deployed sites, localhost, staging. Returns
visual_auditreadPixel-level accessibility audit using Claude vision. Catches issues that DOM scanners miss: icon contrast (1.4.11), focus visibility (2.4.7),
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
declared (9 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (14)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/sourcePointers.ts:93
const readPointersInPage = new Function('selectors', READ_POINTERS_SOURCE) as (selectors: string[]) => Record<string, SourcePointer>
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHNetwork egress · net.metadata_ip · CWE-200, CWE-319
src/server.ts:136
if (o1 === 169 && o2 === 254) return true                     // link-local + cloud metadata (169.254.169.254)
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/tunnel-cli.ts:49
console.log(`    ${tunnel.secretHeader}: ${tunnel.secret}\n`)
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/tunnel-cli.ts:45
console.log(`\n  Tunnel open: http://127.0.0.1:${port} is reachable at\n`)
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/tunnel/localFetch.ts:85
return { error: `could not reach http://127.0.0.1:${port} — is your dev server running? (${(err as Error).name})` }
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/tunnel/requestGuard.ts:96
return `http://127.0.0.1:${port}${path}`
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/openai-challenge.test.ts:12
const TOKEN = 'tok_Abc123-xyz_PUBLIC'
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/anon-account-tools.test.ts:244
for (const url of ['http://localhost:3000', 'http://169.254.169.254/']) {
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/blocked-url-message.test.ts:44
const msg = blockedUrlMessage('"x.test" resolves to blocked internal address 169.254.169.254', '169.254.169.254')
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/blocked-url-message.test.ts:47
assert.equal(msg, 'Blocked URL: "x.test" resolves to blocked internal address 169.254.169.254')
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/blocked-url-message.test.ts:61
for (const a of ['169.254.169.254', '100.64.0.1', '100.127.0.1', '8.8.8.8', '172.32.0.1', '172.15.0.1', '', 'not-an-ip']) {
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/_countsFixture.ts:20
const url = `http://127.0.0.1:${(http.address() as any).port}/`
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/aa-default.test.ts:46
base = `http://127.0.0.1:${(http.address() as any).port}/`
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, axe-core, jsdom, posthog-node, ws, @types/jsdom, @types/node, @types/ws
Why it matters. 11 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 1fbff19ca2d5full audit observations/trust-audit/mcp-server/snayyar00__webability-mcp.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-111fbff19ca2d5BLOCKD69first audit
06

Questions

What is the snayyar00-webability MCP server?

Free accessibility MCP server (WCAG 2.2, ADA, Section 508, EAA). Hosted at https://mcp.webability.io/mcp, no API key for scans. Three engines, structured fixes, verify_fix.

What tools does snayyar00-webability expose?

14 in total: 13 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is snayyar00-webability safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does snayyar00-webability need?

It reads ABILYO_API_KEY, MCP_AUTH_TOKEN, OAUTH_SIGNING_SECRET, OPENAI_APPS_CHALLENGE_TOKEN, POSTHOG_API_KEY, POSTHOG_PROJECT_API_KEY and WEBABILITY_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does snayyar00-webability run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @webability/mcp at 1.8.0.

How current is this page?

The grade is for one exact copy of the source (1fbff19ca2d5), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement