MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

MCP server by vovaplanka

Created 3/25/2026
Updated about 7 hours ago
Repository documentation and setup instructions

mcp-astound-a11y

MCP server for WCAG 2.1 accessibility analysis of ISML and HTML templates in Salesforce Commerce Cloud (SFCC) projects.

Powered by axe-core (64 WCAG rules) + 12 custom ISML-specific rules. Integrates into GitHub Copilot Chat and any MCP-compatible AI client. Also works as a standalone CLI tool.


Quick Start

git clone https://github.com/vovaplanka/mcp-astound-a11y.git
cd mcp-astound-a11y
npm install

Register in Your SFCC Project

Add .vscode/mcp.json to your project repo so every team member gets it automatically:

{
  "servers": {
    "astound-a11y": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/mcp-astound-a11y/isml-a11y-server.js"]
    }
  }
}

Or via VS Code user settings.json:

{
  "mcp": {
    "servers": {
      "astound-a11y": {
        "type": "stdio",
        "command": "node",
        "args": ["/path/to/mcp-astound-a11y/isml-a11y-server.js"]
      }
    }
  }
}

The server resolves file paths relative to the working directory, which MCP clients set to your project root automatically.


Copilot Chat Usage (Prompts & Agent)

Copy the .github/ folder from this repo into your SFCC project to get the @a11y agent and prompt aliases.

@a11y Agent

Select a11y in the Copilot Chat agent picker. It formats MCP results as actionable checklists with code fixes — no raw JSON.

Prompt Aliases

Type / in Copilot Chat to see these:

| Command | What it does | |---|---| | /scan cart.isml | Scan a single file, show issues with fixes | | /scan cartridges/templates/ | Scan a directory, highlight top 5 worst files | | /fix-a11y cart.isml | Auto-fix all a11y issues in a file | | /a11y-rules | List all 76 WCAG rules (axe + custom) |

Example — /scan:

Summary: 12 errors, 5 warnings across 8 files

🔴 cart.isml, line 42 — axe-image-alt (WCAG 1.1.1)

  • Problem: <img src="promo.jpg"> missing alt
  • Fix: <img src="promo.jpg" alt="Spring promotion banner">

Next steps: Fix cart.isml first (7 issues), then shipping.isml (3 issues)

Example — /fix-a11y:

Copilot reads the file, applies all fixes automatically, re-scans to verify zero remaining issues, and shows a before/after summary.


CLI Usage

Run from your SFCC project root:

# Analyze a single file (axe-core engine by default)
node /path/to/mcp-astound-a11y/isml-a11y-server.js analyze cart.isml

# Use a specific engine
node .../isml-a11y-server.js analyze cart.isml --engine custom
node .../isml-a11y-server.js analyze cart.isml --engine both

# Works with plain HTML too
node .../isml-a11y-server.js analyze checkout.html

# Scan a directory (custom engine — faster for batch)
node .../isml-a11y-server.js scan cartridges/app_storefront/cartridge/templates/

# List all available rules
node .../isml-a11y-server.js rules

Supported File Types

| Extension | Include chain | axe-core | Custom rules | |---|---|---|---| | .isml | yes (parent + child templates) | yes | yes | | .html / .htm | no | yes | yes |


Analysis Engines

engine: "axe" — axe-core via jsdom (default for single files)

ISML source is converted to clean HTML via isml-to-html.js:

  1. Injects data-isml-line / data-isml-file attributes into every HTML tag
  2. Replaces ${...} expressions with [dynamic] placeholders
  3. Strips ISML tags (<isif>, <isloop>, <isset>, <isscript>, <iscomment>)
  4. Converts <isprint> to [dynamic], <islabel> to <label>
  5. Feeds to axe-core → maps violations back to original ISML line numbers

64 WCAG Level A + AA rules. Page-level rules not applicable to fragments are auto-disabled.

engine: "custom" — ISML cross-file rules (default for batch)

12 rules that understand the ISML include chain:

| Rule | WCAG | Checks | |---|---|---| | a11y-img-alt | 1.1.1 | <img> missing alt | | a11y-form-labels | 1.3.1 | Input without label | | a11y-button-name | 4.1.2 | Button with no accessible name | | a11y-link-name | 2.4.4 | Link with empty/generic text | | a11y-target-blank | 3.2.2 | target="_blank" without rel="noopener" | | a11y-no-div-button | 4.1.2 | <div onclick> without role="button" | | a11y-tabindex | 2.4.3 | Positive tabindex | | a11y-heading-order | 1.3.1 | Skipped heading levels across templates | | a11y-aria-empty | 4.1.2 | Empty aria-label | | a11y-aria-hidden-focus | 4.1.2 | aria-hidden on focusable element | | a11y-duplicate-id | 4.1.1 | Duplicate id across included templates | | a11y-role-valid | 4.1.2 | Invalid ARIA role |

engine: "both" — full audit

Runs both engines and merges results.


MCP Tools

analyze_isml_file

Analyze a single .isml or .html file.

| Parameter | Type | Default | Description | |---|---|---|---| | filePath | string | required | Path to .isml, .html, or .htm file | | engine | "axe" \| "custom" \| "both" | "axe" | Analysis engine | | parentLevels | number | 2 | Parent template levels to resolve (ISML only) | | includeJs | boolean | true | Analyze js- class interactions | | ruleIds | string[] | all | Custom rule IDs to run | | disableAxeRules | string[] | [] | axe rule IDs to skip | | workspaceRoot | string | cwd | Override project root |

analyze_isml_directory

Batch scan for all .isml and .html files in a directory.

| Parameter | Type | Default | Description | |---|---|---|---| | directory | string | required | Directory to scan | | engine | "axe" \| "custom" \| "both" | "custom" | Analysis engine | | maxFiles | number | 50 | Max files to analyze | | ruleIds | string[] | all | Custom rule IDs | | workspaceRoot | string | cwd | Override project root |

get_a11y_rules

List all rules — custom (12) + axe-core (64). No parameters.

check_js_interactions

Find JS files that use js- CSS class selectors and detect dynamic HTML injection.

| Parameter | Type | Description | |---|---|---| | jsClasses | string[] | required — e.g. ["js-cart-btn"] | | directory | string | Directory to scan | | workspaceRoot | string | Override project root |


Project Structure

mcp-astound-a11y/
├── .github/
│   ├── agents/
│   │   └── a11y.agent.md     @a11y Copilot Chat agent
│   └── prompts/
│       ├── scan.prompt.md     /scan — scan file or directory
│       ├── fix-a11y.prompt.md /fix-a11y — auto-fix issues
│       └── a11y-rules.prompt.md /a11y-rules — list all rules
├── isml-a11y-server.js        MCP protocol server + CLI
├── axe-runner.js              axe-core integration via jsdom
├── isml-to-html.js            ISML → HTML converter (line-number preserving)
├── package.json
└── engine/                    Zero-dependency analysis engine
    ├── isml-parser.js         ISML/HTML tokenizer
    ├── include-resolver.js    Include chain resolution
    ├── js-analyzer.js         JS file scanner for js-* class DOM mutations
    └── rules/
        ├── index.js           Rule registry
        ├── images.js          a11y-img-alt
        ├── forms.js           a11y-form-labels
        ├── interactive.js     a11y-button-name, link-name, target-blank, no-div-button, tabindex
        ├── headings.js        a11y-heading-order
        └── aria.js            a11y-aria-empty, aria-hidden-focus, duplicate-id, role-valid

Workspace Root Resolution

Priority order:

  1. workspaceRoot parameter in tool call
  2. ISML_A11Y_WORKSPACE_ROOT environment variable
  3. process.cwd() (set by MCP client — usually your project root)

Known Limitations

  • color-contrast — disabled (jsdom cannot compute CSS styles)
  • <isif> branches — both branches treated as present (possible false positives)
  • Heading order — may false-positive when parentLevels > 0
  • <iscomponent> / <isslot> — rendered output not analyzed

License

MIT

Quick Setup
Installation guide for this server

Install Package (if required)

npx @modelcontextprotocol/server-mcp-astound-a11y

Cursor configuration (mcp.json)

{ "mcpServers": { "vovaplanka-mcp-astound-a11y": { "command": "npx", "args": [ "vovaplanka-mcp-astound-a11y" ] } } }