$npx -y skills add weAAAre/a11y-agents-kit --skill figma-a11y-auditGenerates a formatted Excel accessibility audit report from Figma file comments with visual evidence screenshots. Parses structured audit comments containing WCAG criteria, error descriptions, and proposed solutions. Captures PNG evidence of each affected component and outputs a
| 1 | # Figma A11y Audit |
| 2 | |
| 3 | Generate formatted Excel accessibility audit reports from Figma file comments, with visual evidence screenshots of each issue. |
| 4 | |
| 5 | ## How it works |
| 6 | |
| 7 | Accessibility auditors leave structured comments in Figma files while reviewing designs. This skill reads those comments via the `figma-console` MCP server, parses them into structured data, captures a PNG of the affected component as evidence, and produces a styled Excel spreadsheet ready for handoff. |
| 8 | |
| 9 | ## Prerequisites |
| 10 | |
| 11 | This skill depends on the **figma-console MCP server** to communicate with Figma. If the user hasn't set it up yet, read `references/setup.md` and guide them through the setup process. The requirements are: |
| 12 | |
| 13 | 1. **Figma Desktop** app (not browser) with the **Desktop Bridge plugin** installed and running |
| 14 | 2. **figma-console MCP server** configured in `.vscode/mcp.json` with a Figma Personal Access Token |
| 15 | 3. **Python 3** with `openpyxl` (`pip3 install openpyxl`) for Excel generation |
| 16 | |
| 17 | ## Audit comment format |
| 18 | |
| 19 | Each audit comment in Figma follows this structure: |
| 20 | |
| 21 | ``` |
| 22 | Componente: <name>. Error: <description>. Criterio: <WCAG criterion>. Solucion: <proposed fix> |
| 23 | ``` |
| 24 | |
| 25 | All possible fields: |
| 26 | |
| 27 | | Field | Key in comment | Required | |
| 28 | |---|---|---| |
| 29 | | Componente | `Componente:` | Yes | |
| 30 | | Error | `Error:` | Yes | |
| 31 | | Criterio | `Criterio:` | Yes | |
| 32 | | Solución | `Solucion:` or `Solución:` | Yes | |
| 33 | | Metodología | `Metodologia:` or `Metodología:` | No | |
| 34 | | Instancia | `Instancia:` | No | |
| 35 | |
| 36 | Fields are separated by `. ` (period + space). Key matching is case-insensitive. |
| 37 | |
| 38 | ## Workflow |
| 39 | |
| 40 | Follow these steps in order. Complete each step before moving to the next. |
| 41 | |
| 42 | ### Step 1 — Verify Figma connection |
| 43 | |
| 44 | Use `figma_get_status` to confirm a Figma file is connected. If there's no connection, point the user to `references/setup.md` and stop. |
| 45 | |
| 46 | ### Step 2 — Determine scope and fetch comments |
| 47 | |
| 48 | If the user provided a Figma URL (e.g., `https://www.figma.com/design/FILE_KEY/Name?node-id=45-123`), extract the `node-id` query parameter to scope the audit to that specific frame or page. Normalise the separator to `:` (the URL may use `-` or `%3A` — both become `45:123`). |
| 49 | |
| 50 | Use `figma_execute` to collect every node ID within that linked frame: |
| 51 | |
| 52 | ```javascript |
| 53 | const root = await figma.getNodeByIdAsync("LINKED_NODE_ID"); |
| 54 | const ids = []; |
| 55 | const collect = (n) => { |
| 56 | ids.push(n.id); |
| 57 | if ('children' in n) n.children.forEach(collect); |
| 58 | }; |
| 59 | collect(root); |
| 60 | return { ids, total: ids.length }; |
| 61 | ``` |
| 62 | |
| 63 | Store this set — it is used in Step 3 to restrict comments to those anchored within the linked frame. If the user didn't provide a URL with a `node-id`, skip the collection and keep all audit comments in scope. |
| 64 | |
| 65 | Then use `figma_get_comments` with `include_resolved: true` to fetch every comment (active and resolved). |
| 66 | |
| 67 | ### Step 3 — Parse and scope audit comments |
| 68 | |
| 69 | Filter comments that contain at least `"Error:"` or `"Criterio:"` in the text — these are audit comments. Ignore generic comments. |
| 70 | |
| 71 | **Scope filtering:** if a node-id scope was established in Step 2, further filter to only those comments whose `client_meta.node_id` is present in the collected set. Discard every comment that falls outside the linked frame — only issues belonging to the specific link the user provided should appear in the report. This is important: without this filter, comments from unrelated pages or frames would pollute the output. |
| 72 | |
| 73 | Parsing rules: |
| 74 | |
| 75 | - Extract each `Key: value` pair from the comment text |
| 76 | - If **Metodología** isn't specified, infer it from the WCAG criterion: |
| 77 | - 1.4.3, 1.4.6, 1.4.11, 1.4.1 → `"Color"` |
| 78 | - 1.1.1 → `"Lector"` |
| 79 | - 1.3.4 → `"Giro"` |
| 80 | - 1.4.4 → `"Zoom"` |
| 81 | - Anything else → `"Manual"` |
| 82 | - If **Instancia** isn't specified, default to `"Sucede en toda la app"` |
| 83 | - Pre |