Skip to main content
Glama

GridProof

npm version license

GridProof your UI — automated spacing & grid QA in the agent loop.

GridProof is an MCP server that renders your running frontend with Playwright, measures the computed geometry of every element, checks it against a spacing/token rule set, and hands back a structured fix report — so a coding agent can close the loop itself: generate, audit, fix, re-audit.

The problem

AI coding agents are good at generating UI and bad at keeping it on a grid: py-[13px] instead of py-3, sibling cards with three different gaps, icons at 17px next to 24px. None of it breaks anything, so it ships — because nothing in the agent loop checks for it. GridProof is that check.

Related MCP server: UI Analyzer MCP Server

The loop

agent generates UI → gp_audit(url) → JSON violations with fix hints
→ agent edits source → gp_audit(url) → clean report = done

The server never touches your source files. It measures a rendered page and points; the agent (which has your codebase open) makes the edit.

Quickstart

# One-time: install the Chromium build Playwright uses (~150MB)
npx playwright install chromium

Register in Claude Code

claude mcp add gridproof -- npx -y gridproof

From a local checkout:

npm install && npm run build
claude mcp add gridproof -- node /absolute/path/to/gridproof/dist/index.js

Three ways to use it

1. gp_audit — inside the agent loop. The agent calls this MCP tool directly against your running dev server and gets back structured JSON (violations + fix hints) to act on.

2. gp_report — MCP tool that also writes an HTML report. Same inputs as gp_audit, plus it writes a self-contained, shareable HTML file to disk.

3. npx gridproof --report <url> — one-shot CLI. No MCP client needed; useful for a quick manual check or scripting.

npx gridproof --report http://localhost:5173
# writes ./gridproof-report.html, prints its path

npx gridproof --report http://localhost:5173 --out ./qa/report.html --viewport 375x812

The rules

Four rules. All report warn by default — nothing blocks, nothing has exit-code semantics. Suggest, don't forbid; the one exception is tap targets, which error because it's an accessibility floor, not a style opinion.

Rule

Detects

Severity

Example fix

spacing-scale

Computed margin/padding/gap that isn't a multiple of the base unit (default 4px) and isn't an allowed value

warn

Snaps to the nearest valid value

arbitrary-value

Off-scale arbitrary Tailwind classes

warn

py-[13px]py-3

gap-consistency

Siblings in a flex/grid container spaced inconsistently when gap isn't set

warn

Set gap-4 on the container instead of per-child margins

canonical-size

Icon/interactive-element sizes off the canonical scale, and interactive elements below the tap-target minimum

warn (icons) / error (tap targets)

Snap to canonical size; WCAG 2.5.8

Tailwind, and non-Tailwind pages

GridProof is built for Tailwind projects — that's where all four rules apply, since spacing-scale, arbitrary-value, and gap-consistency reason about Tailwind's spacing scale and utility classes.

On a page it doesn't detect as Tailwind, it auto-falls-back to accessibility-only checks: canonical-size still runs (tap targets, icon sizes), the three Tailwind-specific rules are skipped, and the report says so explicitly rather than silently under-reporting. You can force this with assumeTailwind: false in config.

Configuration

Optional gridproof.config.json at your project root (all fields optional; defaults shown):

{
  "baseUnit": 4,
  "allowedValues": [1, 2],
  "canonicalSizes": [12, 14, 16, 20, 24, 32, 40, 48],
  "minTapTarget": 44,
  "tapTargetBreakpoint": 768,
  "iconTolerance": 2,
  "assumeTailwind": "auto",
  "rules": {
    "spacing-scale": "warn",
    "arbitrary-value": "warn",
    "gap-consistency": "warn",
    "canonical-size": "error"
  },
  "suppress": [
    { "selector": ".hero-art *", "rules": ["spacing-scale"] },
    { "value": "13px", "reason": "optical correction, logo lockup" }
  ]
}

Inline suppression: data-gp-ignore (all rules) or data-gp-ignore="spacing-scale gap-consistency" on any element skips its subtree for those rules. Suppressed findings are counted, never listed.

What it deliberately does NOT do

  • No computer vision / screenshot analysis. It reads computed geometry, not pixels. A screenshot is attached to the HTML report, not analyzed.

  • No CI runner. It's an in-loop tool for an agent, not a merge gate — no exit codes, nothing fails a build.

  • No source editing. The server measures and suggests; the agent (which has your codebase) makes the edits.

  • No auth, no SaaS, no billing. It's a local MCP server and a CLI.

  • Not yet (v2 candidates, not implemented): column-grid clustering, cross-breakpoint alignment drift, Figma token import.

How it works

Playwright renders the target page headless, a single in-page script walks the DOM and collects computed geometry (margins, padding, gap, rects), and the rule engine checks each value against your config and emits violations with selectors, actual/expected values, and fix hints. It's tuned against roughly 60 real-world sites to keep false positives low — a subpixel rounding tolerance, an allowed-values list, and severity defaults all come out of that calibration, not guesswork.

Development

npm install
npm run build   # tsc → dist/
npm test        # vitest (unit + Playwright integration)
npm run dev     # run the server from TypeScript (tsx)

License

MIT — v0.1.0

Available Tools

4 tools
gp_auditGridproof: audit a URLA
Read-only

Render a running frontend and audit its spacing/grid geometry against the spacing-scale and arbitrary-value rules. Returns a structured AuditReport (violations with fix hints) plus a text summary.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL of the running frontend, e.g. http://localhost:5173
rulesNoSubset of rules to run. Default: all enabled in config.
selectorNoLimit audit to a DOM subtree, e.g. '#main'. Default: body.
viewportNoViewport for this audit pass. Run once per breakpoint.
maxViolationsNoCap report size to protect agent context window.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds useful behavioral context: it 'Render[s] a running frontend' and 'Returns a structured AuditReport (violations with fix hints) plus a text summary.' This goes beyond the annotations by describing the output format and the rendering behavior, with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. It front-loads the action ('Render' and 'audit') and succinctly conveys the output, making every word earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite lacking an output schema, the description provides sufficient context: it explains what the tool does and the nature of the return value (violations with fix hints). The schema fills in parameter details, and the annotations cover safety. Minor gap: it doesn't mention that rules can include gap-consistency and canonical-size, but the schema covers that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% parameter coverage with descriptions for all five parameters, so the description's generic mention of rules adds little beyond the schema. The description mentions only two of the four rule types, which is slightly under-informative but not misleading.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('audit a URL') and scope ('spacing/grid geometry against the spacing-scale and arbitrary-value rules'), with a specific verb and resource. It distinguishes itself from siblings like gp_check_element (element-specific) and gp_get_config (config retrieval) by focusing on full-page audit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for auditing a running frontend, but does not explicitly state when to use this tool versus alternatives like gp_check_element or gp_report. It provides context but no exclusions or alternative guidance, so it falls short of clear usage guidelines.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gp_check_elementGridproof: re-check one elementA
Read-only

Re-check a single element's subtree after a fix, without re-running the full audit. Returns the violations found under that selector.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL of the running frontend, e.g. http://localhost:5173
selectorYesCSS selector of the single element (subtree) to re-check.
viewportNoViewport for this check. Defaults to 1440×900.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds behavioral context by stating the check is scoped to a selector's subtree and returns violations, which goes beyond the annotations. It does not contradict any annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is just two sentences, with the core action front-loaded ('Re-check a single element's subtree after a fix'). Every word earns its place, with no unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with 3 parameters, all documented in the schema. The description covers the return value ('Returns the violations found under that selector'), which is necessary since no output schema exists. It also provides usage context and sibling differentiation, making it complete for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description orients the tool around 'selector' but does not add parameter-specific meaning beyond what the schema already provides for url, selector, and viewport. No compensation needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 're-check' and identifies the resource as 'a single element's subtree,' clearly distinguishing it from a full audit. It also states the outcome ('Returns the violations found under that selector'), making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly specifies when to use the tool ('after a fix') and contrasts it with 'the full audit,' which points to the sibling tool gp_audit as the alternative. This gives the agent clear guidance on selecting this tool over others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gp_get_configGridproof: get resolved configA
Read-only

Return the effective Gridproof configuration (defaults merged with gridproof.config.json if present): baseUnit, allowedValues, canonicalSizes, minTapTarget, rule severities, suppressions.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNoDirectory to search upward from for gridproof.config.json. Defaults to the server's working directory.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, establishing this as a safe read. The description adds valuable behavior context by explaining that defaults are merged with gridproof.config.json if present. This goes beyond the annotations to clarify what 'effective' means.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the main purpose and then specifies the returned contents. Every part is informative with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only configuration getter with one optional parameter and no output schema, the description adequately covers the tool's function and return contents. It does not detail the exact return format, but the listed keys and the word 'configuration' provide sufficient context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully covers the single parameter (cwd) with a clear description, so schema coverage is 100%. The tool description does not add parameter-specific details, but this is acceptable because the schema already provides the necessary semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Return') and the resource ('effective Gridproof configuration'), and specifies exactly which elements are included (baseUnit, allowedValues, etc.). This distinguishes it from sibling tools like gp_audit, gp_check_element, and gp_report, which focus on different concerns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage — you call this to obtain the effective configuration — but it does not explicitly state when to use it over alternatives or any exclusions. Sibling tools are clearly different in purpose, so usage is inferable but not explicitly guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gp_reportGridproof: audit + write HTML reportA

Render a URL, audit its spacing/grid geometry, and WRITE a self-contained HTML report to disk (default ./gridproof-report.html). Returns the file path plus the same AuditReport JSON as gp_audit.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL of the running frontend, e.g. http://localhost:5173
rulesNoSubset of rules to run. Default: all enabled in config.
selectorNoLimit audit to a DOM subtree, e.g. '#main'. Default: body.
viewportNoViewport for this audit pass. Run once per breakpoint.
outputPathNoWhere to write the HTML report. Default: ./gridproof-report.html
maxViolationsNoCap report size to protect agent context window.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses the key side effect of writing a self-contained HTML report to disk with a default path, and clarifies the return value includes the file path. This goes beyond the annotations, which only indicate non-read-only, non-destructive behavior, and adds concrete context about file output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long, front-loaded with the core action and side effect, and includes just enough detail (default path, return value) without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's purpose, side effect, and return value, which is sufficient given the rich schema and annotations. However, it does not mention potential error conditions or that it performs a network request to render the URL, leaving some minor contextual gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters are already documented in the input schema. The tool description does not add additional parameter-level meaning; it only mentions the default output path, which is already in the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action: render a URL, audit spacing/grid geometry, and WRITE an HTML report. It distinguishes itself from sibling gp_audit by explicitly stating it returns the file path plus the same AuditReport JSON, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for generating an HTML report and mentions it returns the same JSON as gp_audit, which contextualizes its relationship to the sibling. However, it does not explicitly state when to prefer this over gp_audit or when not to use it, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 4 tool updatesv0.1.2
    • First observedgp_audit
    • First observedgp_check_element
    • First observedgp_get_config
    • First observedgp_report

TDQS

A4.4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct role: gp_audit runs a full audit, gp_check_element re-checks a specific subtree, gp_get_config retrieves configuration, and gp_report writes an HTML report. No two tools overlap in purpose, so an agent can confidently choose the right one.

Naming Consistency5/5

All tools follow a consistent gp_ verb_noun pattern (gp_audit, gp_check_element, gp_get_config, gp_report), with the verb indicating the action and the noun indicating the target. This uniformity makes the toolset predictable and easy to navigate.

Tool Count5/5

Four tools is an ideal size for a focused auditing server. Each tool addresses a distinct need without redundancy or bloat, and the count is well within the recommended 3–15 range.

Completeness5/5

The toolset covers the full workflow: run an audit, re-check a single element after fixes, retrieve effective configuration, and generate a standalone HTML report. There are no obvious dead ends, and configuration management is appropriately delegated to the config file.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers