npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@real-a11y-dev/mcp

v0.1.0-beta.0

Published

Model Context Protocol server that exposes the Real A11y semantic tree and accessibility audits to AI agents

Readme

@real-a11y-dev/mcp

A Model Context Protocol (MCP) server that exposes the Real A11y semantic accessibility tree — and its audits — to AI agents.

Unlike a general browser-automation MCP (which hands an agent the browser's raw accessibility snapshot so it can click things), this server is audit-first: its flagship tool tells an agent what a real screen reader would announce as broken. The tree-inspection tools are perception primitives layered on top.

Tools

| Tool | Purpose | | --- | --- | | open_page | Navigate to a URL and prepare it for queries (call first). waitUntil / settleMs settle dynamic pages; device (e.g. "iPhone 13") audits the mobile/tablet layout. | | audit_page | Flagship. Return every accessibility violation — unlabeled controls, images missing alt, heading gaps, unlabeled dialogs, broken landmarks — as structured findings (grouped, each with a CSS locator + severity). | | inspect_page | Findings plus semantic tree, heading outline, and tab order — all from one extraction, so they can't disagree. Prefer on dynamic pages. | | get_semantic_tree | Deterministic role + accessible-name outline of the page. | | get_heading_outline | Heading structure (h1..h6) in document order. | | get_tab_order | Focusable elements in keyboard Tab order. | | list_elements | Every element of one category (link/button/form/landmark/image/heading) as role + name + locator. | | get_native_tree | Chromium's own accessibility tree (Blink, via CDP) — the authoritative browser tree. | | compare_trees | Diff custom vs. native and report role/name divergences — a fidelity oracle. | | close_browser | Tear down the session. |

Consistency & determinism

  • inspect_page derives all four views from a single extraction, so a report can't be internally inconsistent (e.g. an audit finding referencing a node the tree doesn't show) on a page that changes between separate calls.
  • open_page's waitUntil / settleMs let dynamic pages (SPAs, consent dialogs) reach a stable state before extraction, so results don't vary run to run. Use waitUntil: "networkidle" and/or a settleMs buffer for heavy SPAs.
  • open_page's device / viewport emulate a phone or tablet, so you audit the tree users on that device actually get — a responsive site can differ substantially from desktop (hamburger nav, hidden content, touch-only controls). Open the same URL at desktop and device: "iPhone 13" to diff them.

How it works

It reuses the exact pieces the testing package already ships:

  1. Playwright drives a real browser (a real browser is required — the engine depends on layout/getComputedStyle to decide AT exposure).
  2. The pre-built IIFE page-bundle from @real-a11y-dev/testing is evaluated in the page via page.evaluate(), setting globalThis.__realA11y__. (It is run this way rather than addScriptTag so it works on pages served under a Trusted Types CSP — require-trusted-types-for 'script' — which blocks the <script> injection addScriptTag uses.)
  3. Each tool then routes through page.evaluate() and calls the shared collectFindings / serialize helpers.

Install & run

Playwright is a peer dependency and a Chromium binary is required:

npx playwright install chromium

Wire it into an MCP client — no install step needed, npx -y fetches the package on first run (use the package name, not the bare real-a11y-mcp bin, since the client launches it from an arbitrary working directory):

{
  "mcpServers": {
    "real-a11y": { "command": "npx", "args": ["-y", "@real-a11y-dev/mcp"] }
  }
}

To pin the version instead, add it to your project (pnpm add -D @real-a11y-dev/mcp playwright) and point command/args at the local install.

Scoping. Every audit/inspection tool takes an optional rootSelector (default body) to confine extraction to one region — e.g. audit just a <main> or a specific component — which also keeps output within the agent's context budget. The two native-tree tools (get_native_tree, compare_trees) always read the whole document.

Environment

| Var | Effect | | --- | --- | | REAL_A11Y_MCP_CDP | Attach to a running Chrome over CDP (e.g. http://localhost:9222) instead of launching one — audit pages behind a login you're already signed into. | | REAL_A11Y_MCP_HEADFUL | 1 launches a visible browser instead of headless. | | REAL_A11Y_MCP_ALLOW_FILE | 1 permits auditing file:// URLs. Off by default: an LLM-driven server that can open file:///…/.env and read the DOM back is a local-file exfiltration primitive. | | REAL_A11Y_MCP_STORAGE_STATE | Path to a Playwright storage-state file — audit pages behind a login as that saved session. Create it out-of-band (e.g. real-a11y login); it's never a tool parameter, so session tokens never enter the agent's context. The server refuses to start if the file is missing or malformed. | | REAL_A11Y_MCP_ALLOWED_ORIGINS | Comma-separated origins that auditing is restricted to when a storage state is loaded (origin pinning). Strongly recommended alongside STORAGE_STATE: without it, a redirect could audit an unintended site with your session. |

Auth material is always operator-configured, never a tool parameter — the agent just benefits from a session you set up. Use a dedicated low-privilege test account, and keep the storage-state file out of version control.

Status

Beta, published on npm. Part of the @real-a11y-dev family (core, testing, validate, …); API and tool surface may still change before 1.0.