Skip to main content
Glama

fenestra-mcp

A Model Context Protocol server that lets an AI assistant render and verify native UIs described as fenestra fenestra/1 JSON.

Install

cargo install fenestra-mcp

The server speaks MCP over stdio — point your MCP client at the fenestra-mcp binary.

Related MCP server: winauto-mcp

Tools

  • describe_vocabulary — the description grammar: every node type with a minimal example, and the theme color roles a color may name. Call this first.

  • describe_schema — the formal JSON Schema for a fenestra/1 description, the machine-checkable complement to describe_vocabulary.

  • render_ui — render to a typed access tree, a downscaled preview image, and automatic accessibility warnings.

  • query_ui — find nodes by a semantic selector (role, name, value, or id); a miss returns the nearest candidates to guide a retry.

  • interact — drive scripted interactions (click, type, key, tab, hover, wheel, drag) by semantic selector, never coordinates.

  • check_a11y — theme contrast, labeling of every interactive control, and per-text-node APCA + WCAG 2 legibility.

  • focus_order — the keyboard focus order: the refs a Tab cycle visits, in order, honoring a modal focus trap.

  • check_layout — layout geometry from the real frame: interactive targets below the minimum hit size, and signal-bearing nodes clipped off-screen.

  • match_aria_snapshot — assert an expected accessibility snapshot (partial / strict / regex).

  • match_screenshot — compare against a baseline PNG, pixel by pixel, with an optional tolerance, differing-pixel budget, and mask rectangles to ignore.

  • validate — validate a description without rendering; problems come back path-pointed.

  • run_scenario — drive a description + optional steps through a whole bundle of expectations (emitted intents, a11y, aria, screenshot, queries) in one pass, asserted against the post-interaction frame.

  • film_ui — drive optional steps (applied first, so a click can trigger the transition to watch), then capture frames with real motion on and compose them into one captioned filmstrip. The one tool that turns reduced motion off — every other tool stays reduced-motion for deterministic pixels.

Each tool leads with a typed structured result — query_ui, check_a11y, focus_order, check_layout, match_aria_snapshot, and describe_vocabulary carry a formal outputSchema so a client knows the result shape up front. The visual tools also attach a downscaled preview image and a resource_link to the full-resolution PNG (a file:// temp path), so a large image never bloats the response yet stays one fetch away.

Where baselines are read from

Two tools take a path to a PNG on disk: match_screenshot, and run_scenario through its expect.screenshot.baseline. That path arrives inside a tool call, which means it comes from an agent — and an agent is only as trustworthy as whatever it last read. So the server reads baselines from one directory and no further.

By default that directory is the working directory the MCP client launched the server in, which is the project being worked on. Set FENESTRA_MCP_BASELINE_ROOT to point somewhere else. Paths in a tool call may be relative to the root or absolute inside it; anything that resolves outside — including a symlink inside the root pointing out of it — is refused, and the refusal names the root so a legitimate call can be retried. A root that is not a readable directory stops the server from starting rather than silently widening to the default.

The diff image a failed comparison returns draws the rendered pixels, never the baseline's, for the same reason.

Registry

  • MCP Registry name: mcp-name: io.github.richer-richard/fenestra-mcp

License

Licensed under either of MIT or Apache-2.0 at your option.

Available Tools

13 tools
check_a11yA

Check accessibility of a UI from the real render: theme contrast, labeling of every interactive control, and per-text-node APCA + WCAG 2 legibility. text_contrast_failures lists nodes failing the strict body-text floor even when the theme verdict is legible (catching authored low-contrast text). Returns a structured report; this is a normal result whether or not it passes.

Inputs: description (required), size, theme. Returns: The accessibility report: theme contrast, labeling, and per-node legibility.

check_layoutB

Check layout geometry from the real frame: interactive targets below the 24px minimum hit size, and signal-bearing nodes that fall outside the window (clipped / off-screen). Returns a structured report — a normal result whether or not it finds problems.

Inputs: description (required), size, theme. Returns: Layout problems read from frame geometry — verifiable without pixels: tap targe…

describe_schemaA

Return the formal JSON Schema for a fenestra/1 description — a machine-checkable input grammar to validate or autocomplete against before rendering, the structured complement to describe_vocabulary's prose grammar. Structural only (shape, required/optional fields, unions); still call validate for semantic checks like colour roles, numeric ranges, and enum-like fields.

Inputs: no named parameters.

describe_vocabularyA

Return the description grammar: every node type with a minimal example, and the theme color roles a color may name. Call this first to learn how to author a fenestra/1 description.

Inputs: no named parameters. Returns: The full grammar an agent can request to learn the format up front.

film_uiA

Render a filmstrip: drive optional interaction steps (applied first, so a click can trigger the transition to watch), then capture frames with real motion turned on — every other tool stays reduced-motion for deterministic pixels; this is the one place the point is watching motion play — and compose them into one captioned strip image. Returns the actual frame count/interval/scale used (each is clamped to a documented ceiling, so a hostile request degrades instead of hanging) plus the strip's pixel dimensions, a downscaled inline preview, and a resource_link to the full-resolution strip.

Inputs: description (required), size, scale, steps, +3 more.

focus_orderA

Return the keyboard focus order: the refs a Tab cycle visits, in order, honoring a modal focus trap (disabled controls excluded). Verifies reachability and tab sequence as typed data, without driving the UI.

Inputs: description (required), size, theme. Returns: The keyboard focus order: the refs a Tab cycle visits, in order. An object (not…

interactA

Drive a UI through scripted interactions (click, type, key, tab, hover, wheel, drag — by semantic selector, never coordinates). Returns the emitted intent messages and the access tree afterwards; set screenshot=true for a preview image.

Inputs: steps (required), description (required), size, theme, +1 more.

match_aria_snapshotB

Match an expected accessibility snapshot (Playwright - role "name" [attr] grammar) against a UI. mode: partial (subset, default) | strict (exact) | regex (each expected line is a pattern). Returns a pass/fail diff — a normal result.

Inputs: expected (required), description (required), mode, size, +1 more. Returns: The result of an aria-snapshot match: pass/fail plus a readable line diff.

match_screenshotA

Compare a UI's render against a baseline PNG (path on disk), pixel by pixel, with an optional per-channel tolerance, differing-pixel budget, and mask rectangles to ignore (volatile regions). Returns the diff stats and a diff-image preview on mismatch — a normal result.

Inputs: description (required), baseline_path (required), size, masks, +3 more.

query_uiA

Find nodes in a UI by a semantic selector (role, name, value, or id). Returns matches with stable refs; on a miss, returns the nearest candidates to guide a retry.

Inputs: selector (required), description (required), size, theme. Returns: The result of a `query`: exact matches, plus the nearest candidates on a miss.

render_uiA

Render a fenestra/1 UI description to a typed accessibility tree, a downscaled preview image, and automatic accessibility warnings (contrast, labeling, per-text-node legibility). Read the access tree first; the full-resolution PNG comes back as a resource_link.

Inputs: description (required), size, theme.

run_scenarioA

Run a verification scenario in one pass: a fenestra/1 description, optional interaction steps, and a bundle of expectations (emitted intents, a11y, an aria snapshot, a screenshot baseline, query match-counts). Drives the steps, then asserts every expectation against the resulting frame — the screenshot check compares the POST-interaction pixels. Returns a unified report (one ok plus a per-check breakdown) and a preview: the diff image on a screenshot mismatch, else the final render. A failed check is a normal result, not an error.

Inputs: scenario (required).

validateA

Validate a fenestra/1 description without rendering. Structural problems (unknown fields, bad node tags) and semantic ones (an unknown color role) come back path-pointed. Returns isError when the description is invalid.

Inputs: description (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 13 tools

    Disambiguation4/5

    Most tools have distinct purposes, but `render_ui` and `run_scenario` both involve rendering and could cause confusion when a user wants only rendering. `check_a11y` and `render_ui` both provide accessibility warnings, though with different granularity. Overall, descriptions help distinguish, but minor overlap exists.

    Naming Consistency5/5

    All tool names follow a consistent `verb_noun` pattern in snake_case (e.g., `check_a11y`, `describe_schema`, `run_scenario`). No mixed conventions, making the set predictable and easy to navigate.

    Tool Count5/5

    With 13 tools, the server is well-scoped for its domain of UI accessibility testing. Each tool covers a clear aspect (rendering, interaction, validation, comparison) without excessive overlap or missing essentials.

    Completeness5/5

    The tool set covers the full lifecycle: schema/vocabulary description, validation, rendering, interaction, accessibility checks, layout verification, focus order, aria/screenshot comparison, and scenario orchestration. No obvious gaps for typical UI testing workflows.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      B
      maintenance
      MCP server that lets an LLM see and drive any running Windows app: attach a window, screenshot it, read its UI Automation tree, and send clicks, typed text, and key presses with pixel coordinates.
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server that enables AI agents to control Windows by clicking, typing, and navigating with a visible cursor overlay, using a layered approach (native UIA, browser CDP, pixel fallback) for reliable interaction.
      1
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      MCP server providing AI-friendly computer-use primitives (capture, detect, click) to let LLM agents drive desktop GUI applications on Windows, macOS, and Linux.
      2
      MIT