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

genat-mcp

v2.3.5

Published

MCP server GenAT: generate accessibility tests via n8n workflow (url + project folder)

Downloads

2,511

Readme

GenAT MCP

MCP server that exposes a GenAT tool: generate accessibility tests for a URL based on your project folder. It detects framework (TypeScript, JavaScript, or Python, BDD, Page Object), calls an n8n GenAT workflow, and returns (or writes) generated test files.

Full setup (n8n workflow, services, usage) is in the project README. GenAT workflows also instruct the AI to align with OCLC internal Confluence pages (Accessibility Guidelines and Resources, OCLC Accessibility Release Blockers); the MCP sends optional extra context from oclc-accessibility-confluence-context.md or GENAT_OCLC_ACCESSIBILITY_CONTEXT.

For teams: See GENAT_OVERVIEW.md for a concise, presentation-ready overview. Suitable as a source for NotebookLM or other AI tools to create slide decks.

Coverage claims: Teams can copy examples/coverage-manifest.example.yaml into their own repo (e.g. as coverage-manifest.yaml) and adjust it to document which standards, axe tags, workflows, and verification steps apply to their deployment. The manifest does not replace manual accessibility review; it aligns documented claims with the analyzer defaults and GenAT workflow behavior.

CI (Phase D): The parent repo includes scripts/ci/a11y-analyzer-scan.mjs and a GitHub Actions example to save analyzer JSON and gate on violation impact—useful even when GenAT is not invoked.

Install

If the package is published to npm (otherwise you get 404):

# Global (binary on PATH)
npm install -g genat-mcp

# Or local / project
npm install genat-mcp

Until published, or for development, install from the repo:

# From this repo root
cd mcp-genat && npm install
# Then in Cursor MCP use: node with args ["/path/to/n8n_playwright_tests/mcp-genat/index.js"]

# Or from another project (local path)
npm install /path/to/n8n_playwright_tests/mcp-genat
# Then use npx genat-mcp or node node_modules/genat-mcp/index.js

Environment

| Variable | Required | Default | Description | |--------------------|----------|---------|-------------| | N8N_WEBHOOK_URL | No | http://localhost:5678/webhook-test/webhook-genat-login | n8n GenAT webhook URL. Set this if your n8n instance is elsewhere (e.g. https://your-n8n-host/webhook-test/webhook-genat-login). | | N8N_INSECURE_TLS | No | (off) | Set to 1, true, or yes to skip TLS certificate verification for HTTPS webhooks. Use only for dev/internal n8n with self-signed or internal CA certs (e.g. K8s). Not recommended for production. | | SERVICE_BASE_URL | No | (none) | Base URL for DOM Analyzer and Accessibility Analyzer (e.g. http://host.docker.internal or http://your-tunnel.ngrok.io). Required when n8n runs on a remote host (K8s) so the workflow can reach the services. The workflow appends :3456/analyze-dom and :3458/analyze-accessibility. | | N8N_MAX_ASSERTIONS | No | (none) | Override assertion count for complex pages (e.g. 25). Used as default when the tool is invoked without maxAssertions; also used by run-genat.mjs. | | N8N_SCOPE_TO_REGIONS | No | (none) | Comma-separated regions to focus tests on (e.g. header,main,table). Used as default when the tool is invoked without scopeToRegions; also used by run-genat.mjs. | | N8N_ANALYZE_STATES | No | (off) | Set to 1, true, or yes to analyze dropdown/combobox expanded states and include state-specific violations in generated tests. Used as default when the tool is invoked without analyzeStates; also used by run-genat.mjs. Increases analysis time. | | GENAT_PROJECT_ROOT | No | (cwd) | Base path for resolving parentProjectFolder. When set, parentProjectFolder is resolved relative to this path. Use when your project is outside the MCP's working directory. Example: if your pytest project is at /Users/me/projects/ill_tests, set GENAT_PROJECT_ROOT=/Users/me/projects and use parentProjectFolder ill_tests in the prompt. | | GENAT_FETCH_TIMEOUT_MS | No | 600000 (10 min) | Max time in milliseconds to wait for the n8n webhook response. Increase if GenAT times out before the workflow completes (e.g. complex pages with JIRA + AI Agent). Set in MCP env, e.g. GENAT_FETCH_TIMEOUT_MS=900000 for 15 minutes. | | GENAT_OCLC_ACCESSIBILITY_CONTEXT | No | (bundled file) | Optional multiline text sent as oclcAccessibilityContext in the webhook body. Overrides the default oclc-accessibility-confluence-context.md (OCLC UAD guidelines + UXUI release blockers links and notes). Use to paste updated Confluence excerpts without republishing the package. |

Framework detection and auto-discovery

GenAT detects language (TypeScript, JavaScript, Python), BDD framework (Cucumber, pytest-bdd, Behave), and Page Object pattern from the project folder.

Auto-discovery: When you pass a folder that contains both tooling (e.g. package.json at root) and a test subfolder (tests/, e2e/, tests/e2e/, tests/accessibility/), GenAT scores each candidate and uses the folder with the most test-specific content (.feature files, conftest.py, *_test.py, .spec.ts, pages/, steps/, etc.). This ensures correct detection when tests live in subfolders.

Path guidance: Pass the project root (e.g. . or /path/to/project). GenAT will auto-discover the best folder when tests are in tests/ or e2e/. For monorepos, pass the specific test project folder (e.g. packages/e2e-tests) when the root has mixed content.

pytest-bdd (Python): When scriptType is Python and bddFramework is pytest-bdd, detection also scans conftest.py for common Playwright fixtures (browser_page, page, base_url, etc.) and prefers features/ or tests/features/ and step_defs/ or steps/ for layout hints. Those hints are sent as projectLayoutHints in the webhook body (and merged into projectSummary) so the n8n workflow can steer the model. Generated code uses axe-playwright-python (from axe_playwright_python.sync_playwright import Axe); ensure pip install axe-playwright-python pytest-bdd pytest-playwright (or your lockfile equivalent) in the project.

Cursor MCP config

Using npx (local install):

{
  "mcpServers": {
    "GenAT": {
      "command": "npx",
      "args": ["genat-mcp"]
    }
  }
}

Using global install:

{
  "mcpServers": {
    "GenAT": {
      "command": "genat-mcp"
    }
  }
}

With environment variables (e.g. remote n8n, self-signed certs):

{
  "mcpServers": {
    "GenAT": {
      "command": "npx",
      "args": ["genat-mcp"],
      "env": {
        "N8N_WEBHOOK_URL": "https://n8n.example.com/webhook-test/webhook-genat-login",
        "N8N_INSECURE_TLS": "1",
        "SERVICE_BASE_URL": "http://your-tunnel.ngrok.io"
      }
    }
  }
}

With GENAT_PROJECT_ROOT (when project is outside MCP working directory):

{
  "mcpServers": {
    "GenAT": {
      "command": "npx",
      "args": ["genat-mcp"],
      "env": {
        "GENAT_PROJECT_ROOT": "/Users/me/projects"
      }
    }
  }
}

With GENAT_FETCH_TIMEOUT_MS (increase timeout when workflow takes longer):

{
  "mcpServers": {
    "GenAT": {
      "command": "npx",
      "args": ["genat-mcp"],
      "env": {
        "GENAT_FETCH_TIMEOUT_MS": "900000",
        "N8N_WEBHOOK_URL": "https://n8n.example.com/webhook-test/webhook-genat-login"
      }
    }
  }
}

(900000 = 15 minutes. Default is 600000 = 10 minutes.) Then use parentProjectFolder ill_tests in the prompt to target /Users/me/projects/ill_tests.

With optional params for complex pages (N8N_MAX_ASSERTIONS, N8N_SCOPE_TO_REGIONS, N8N_ANALYZE_STATES):

{
  "mcpServers": {
    "GenAT": {
      "command": "npx",
      "args": ["genat-mcp"],
      "env": {
        "N8N_WEBHOOK_URL": "https://n8n.example.com/webhook-test/webhook-genat-login",
        "N8N_MAX_ASSERTIONS": "30",
        "N8N_SCOPE_TO_REGIONS": "header,main,table",
        "N8N_ANALYZE_STATES": "1"
      }
    }
  }
}

These env vars are passed to the webhook: maxAssertions (number), scopeToRegions (array), analyzeStates (boolean). Use N8N_MAX_ASSERTIONS for complex pages that need more assertions; N8N_SCOPE_TO_REGIONS to focus tests on specific regions; N8N_ANALYZE_STATES to run axe in expanded dropdown/combobox states (increases analysis time).

If the global binary is not on PATH, use the full path, e.g. node $(npm root -g)/genat-mcp/index.js.

Requirements

  • Node.js 20+
  • n8n with a GenAT workflow imported and activated. Use genat-accessibility-tests-with-login-jira.json (path webhook-test/webhook-genat-login-jira) for JIRA support, or genat-accessibility-tests-with-login.json (path webhook-test/webhook-genat-login). Set N8N_WEBHOOK_URL to the workflow's webhook URL.
  • Optional v2 pipeline (Python / pytest-bdd quality): Import GenAT Accessibility Tests (with Login + JIRA) v2.json and set N8N_WEBHOOK_URL to …/webhook-test/webhook-genat-login-jira-v2. v2 adds stricter pytest-bdd + Python rules (no nested markdown in code, layout hints, fixture-aware steps) and can run alongside the original workflow. The original v1 workflow is unchanged.
  • Optional v3 pipeline (a11y contract validation): Import GenAT Accessibility Tests (with Login + JIRA) v3.json and set N8N_WEBHOOK_URL to …/webhook-test/webhook-genat-login-jira-v3. Same as v2, plus a terminal A11y contract validator node that sets a11yContractOk (boolean) and a11yContractErrors (string[]) on the webhook JSON. The MCP also exposes _a11yContractOk / _a11yContractErrors. Optional JSON body failOnA11yContract: true fails the execution when the contract check fails (default is warn-only: still returns generated code). To rebuild v3 from an updated v2 in this repo, run node scripts/build-genat-v3-workflow.mjs from the n8n_playwright_tests root (regenerates webhookId; re-import or update the webhook in n8n if needed).
  • DOM Analyzer and Accessibility Analyzer services running (see main README: npm run services from repo root)

Standalone script: run-genat.mjs

When the MCP fails (e.g. TLS/connection issues), use the standalone script:

# From a project that has genat-mcp installed
N8N_WEBHOOK_URL='https://your-n8n/webhook-test/webhook-genat-login' N8N_INSECURE_TLS=1 node node_modules/genat-mcp/run-genat.mjs https://example.com .

# Or from mcp-genat directory
N8N_WEBHOOK_URL='https://your-n8n/webhook-test/webhook-genat-login' N8N_INSECURE_TLS=1 node run-genat.mjs https://example.com /path/to/project

Optional env vars (same as MCP tool parameters):

  • N8N_MAX_ASSERTIONS – Override assertion count (e.g. 25)
  • N8N_SCOPE_TO_REGIONS – Comma-separated regions (e.g. header,main,table)
  • N8N_ANALYZE_STATES – Set to 1 to analyze expanded dropdown/combobox states
N8N_MAX_ASSERTIONS=30 N8N_SCOPE_TO_REGIONS=header,main N8N_ANALYZE_STATES=1 node node_modules/genat-mcp/run-genat.mjs https://example.com .

Important: Use webhook-genat-login or webhook-genat-login-jira (not webhook-genat). For JIRA support, import and activate genat-accessibility-tests-with-login-jira.json and set N8N_WEBHOOK_URL to its webhook URL.

Optional – Cursor rule: Copy the rule so the AI uses the correct webhook when creating workarounds (the MCP error responses also include this hint):

mkdir -p .cursor/rules
# If genat-mcp is installed in the project:
cp node_modules/genat-mcp/rules/genat-mcp.mdc .cursor/rules/
# Or from the n8n_playwright_tests repo (if you have it):
cp /path/to/n8n_playwright_tests/mcp-genat/rules/genat-mcp.mdc .cursor/rules/

If the rule file is missing (e.g. genat-mcp installed from npm before rules were added), create .cursor/rules/genat-mcp.mdc with:

---
description: GenAT MCP and run-genat workaround - use webhook-genat-login
alwaysApply: true
---

# GenAT MCP and run-genat.mjs Workaround

When creating run-genat.mjs: Use webhook-genat-login, NOT webhook-genat. Prefer `node node_modules/genat-mcp/run-genat.mjs <url> .` Never use webhook-genat.

Tool: GenAT

  • url (string): Page URL to analyze for accessibility.
  • parentProjectFolder (string): Path to the project root (TypeScript, JavaScript, or Python Playwright).
  • writeToProject (boolean, optional): If true, write generated files under tests/accessibility/ by default; for pytest-bdd Python projects, files go under features/ / step_defs/ (or tests/features, steps, etc.) when those directories exist. New projects get step_defs/test_accessibility_steps.py when accessibility_steps.py is not already present.
  • maxAssertions (number, optional): Override default assertion count for complex pages (e.g. 25).
  • scopeToRegions (string[], optional): Limit tests to specific regions (e.g. ["header", "main", "table"]).
  • analyzeStates (boolean, optional): If true, run axe in expanded dropdown/combobox states and include state-specific violations. Increases analysis time.
  • loginUsername (string, optional): Login username. Overrides .env when provided. Requires loginPassword.
  • loginPassword (string, optional): Login password. Overrides .env when provided. Requires loginUsername.
  • loginUrl (string, optional): Login page URL if different from target URL.
  • jiraNumber (string, optional): JIRA issue key (e.g. PROJ-123). When provided, the workflow fetches the issue and injects acceptance criteria into the AI prompt.
  • failOnA11yContract (boolean, optional): When N8N_WEBHOOK_URL points at the v3 JIRA workflow (webhook-genat-login-jira-v3), set true to make n8n error if the A11y contract validator fails (default is warn-only: JSON still returns generated files with a11yContractOk / a11yContractErrors).

Login credentials: provide in the prompt (loginUsername, loginPassword) or in project .env (TEST_USER, TEST_PASSWORD, LOGIN_USER, LOGIN_PASSWORD). Tool params override .env. For sensitive environments, prefer .env (gitignored) since credentials in the prompt are visible in chat history.

Framework detection: language (TypeScript vs JavaScript vs Python), BDD (Cucumber, pytest-bdd, Behave), and Page Object pattern (e.g. pages/ directory or *Page.ts, *Page.js, *_page.py files). Returns JSON with testCode, featureFile, stepDefCode, pageObjectCode (and _written paths when writing).

Response fields for calling applications: When stepDefCode is present, the MCP may set _stepDefIncomplete (boolean) and _stepDefIncompleteReason (string) using a lightweight heuristic (unclosed strings/delimiters, line continuation at EOF). Treat true as a signal to warn the user, retry generation, or block merge—do not assume the step file is runnable. Other optional fields from the workflow include usedLogin and loginReason when using login-capable workflows. With the v3 JIRA workflow, responses may include a11yContractOk / a11yContractErrors and mirrored _a11yContractOk / _a11yContractErrors (static checks for withTags / AxeBuilder on TS/JS and axe-playwright-python usage on Python).

Generated tests include keyboard accessibility checks (Tab order, focus) by default. For complex pages, the workflow uses page complexity (regions, tables, widgets) to scale assertion count.

Feature ↔ step parity (consumer CI)

GenAT does not guarantee that every Gherkin line has an implemented step. For pytest-bdd projects, the calling application or CI can:

  1. Parse *.feature step lines (after Given/When/Then/And/But).
  2. Confirm test_accessibility_steps.py or accessibility_steps.py (your step module) defines matching @given/@when/@then patterns (or run pytest --collect-only / a dry run).

Keep this as an optional pre-merge check alongside _stepDefIncomplete.

pytest-bdd discovery and axe-playwright-python

  • Pytest collects test_*.py by default. GenAT now prefers writing step_defs/test_accessibility_steps.py for new projects; if accessibility_steps.py already exists, that path is used. Ensure @scenario test functions are in a collected module (often the same file when named test_*.py) or import step defs from conftest.py / pytest_plugins.
  • axe-playwright-python (sync): from axe_playwright_python.sync_playwright import Axe; axe = Axe(); results = axe.run(page); read results.response (axe-core JSON) and results.violations_count. Do not invent other APIs—see axe-playwright-python docs.

Sample prompts

See prompts.md for a full list of prompts including specific parent folders, login, JIRA, and combined options.

With login credentials in the prompt:

Use GenAT to generate accessibility tests for https://myapp.example.com/dashboard. Use parentProjectFolder . and writeToProject true. Login with username myuser and password mypass.
Use GenAT with url https://myapp.example.com, loginUsername admin, loginPassword secret123, parentProjectFolder . Write the files to the project.

With credentials in .env:

Use GenAT for https://myapp.example.com/dashboard. Credentials are in .env.
Use GenAT to generate accessibility tests for https://myapp.example.com/dashboard using this project folder: . Write the files to the project.

With JIRA acceptance criteria:

Use GenAT for https://myapp.example.com/dashboard with jiraNumber PROJ-123. Write the files to the project.
Generate accessibility tests for https://example.com using JIRA ticket A11Y-456. Use parentProjectFolder . and writeToProject true.

Publishing to npm

Until the package is published, npm install genat-mcp returns 404. To publish:

  1. Replace your-username in package.json (repository, homepage, bugs) and in server.json if you use the MCP Registry.
  2. npm requires 2FA or a granular access token with "bypass 2FA" enabled to publish. Enable 2FA on your npm account (Account → "Require two-factor authentication for writes"), or create an Automation / granular token with "bypass 2FA for publish" and use it: npm login (paste token as password) or set NPM_CONFIG_//registry.npmjs.org/:_authToken=your-token.
  3. From this directory: npm publish (or npm publish --access public for a scoped package).

After publishing, the "Install from npm" instructions above work.

Publishing to the MCP Registry

To list this server on the MCP Registry: use your GitHub identity in package.json and server.json, publish to npm (see above), install mcp-publisher, run mcp-publisher login github and mcp-publisher publish.