Skip to main content
Glama

polish

polish is a self-hosted review CLI and MCP server for UI code. It scores usability, design craft, accessibility, and interface writing from 0-100, with file-level findings and concrete fixes. Run it locally, wire in your own API keys, and keep the review loop inside your workflow.

Built for designers and engineers reviewing real UI code.

See it live: https://tomiabe.github.io/polish/

Why

Hosted design review tools are useful, but they run on quotas and monthly limits. polish keeps the review loop local, using your own API key and a small Node CLI. Point it at your UI files, it sends them to an LLM with a rubric, and returns a score plus findings with severity, category, file:line, and a concrete fix.

Related MCP server: @gridwork/siteaudit

Features

  • Reviews against a layered rubric: usability heuristics, design craft, interface writing, and accessibility. It checks headings, descriptions, labels, and helper text alongside visual and interaction code. The rubric is plain data, so it can be swapped for any design philosophy.

  • Polish weighted scoring. Critical findings deduct 22, serious findings deduct 9, and moderate findings deduct 3. There is no severity ceiling.

  • Provider support for Groq, OpenAI, Anthropic, Gemini, and OpenRouter, plus any OpenAI-compatible endpoint through baseUrl.

  • Optional provider fallback chains, so you can try multiple APIs in order.

  • One engine drives both a CLI and an MCP server, so terminal users and AI agents get identical results.

  • polish init-agent writes a safe, repo-local AGENTS.md that teaches coding agents when to review UI changes, how to recognize a receipt, and how to verify fixes.

  • Verify mode re-checks previous findings against updated files at a fraction of the cost of a full review and returns a new remaining-issues score.

  • Exits with code 1 when critical findings exist, so it works as a pre-commit or CI gate.

Install

git clone https://github.com/tomiabe/polish.git
cd polish
npm link          # makes `polish` available in every project

Set one API key in your shell profile:

export GROQ_API_KEY=...        # or:
export OPENAI_API_KEY=...      # or:
export ANTHROPIC_API_KEY=...   # or:
export GEMINI_API_KEY=...      # or:
export OPENROUTER_API_KEY=...

Usage

polish                                   # audit files matched by config globs
polish src/components src/pages/*.tsx    # audit specific files or directories
polish --verify findings.json           # re-check that previous findings are fixed
polish --dry-run                        # preview what would be sent, no API call
polish --json                           # machine-readable receipt + findings, for CI or agents
polish init-agent                       # add the Polish workflow to AGENTS.md

Config

Create .polish.json in a project root. Everything is optional:

{
  "provider": "anthropic",
  "model": "claude-sonnet-4-20250514",
  "providers": ["gemini", "groq"],
  "include": ["src/**/*.{ts,tsx,css}"],
  "exclude": ["src/generated/**"],
  "rubric": ["usability", "craft", "accessibility"],
  "maxFiles": 20,
  "maxFileBytes": 100000
}
  • provider - openai, anthropic, openrouter, groq, or gemini. Auto-detected from the env key that is present.

  • providers - ordered fallback list. If set, polish tries each provider in order until one succeeds.

  • model - defaults are gpt-4o-mini, claude-sonnet-4-20250514, openai/gpt-4o-mini (OpenRouter), llama-3.3-70b-versatile (Groq), and gemini-2.5-flash.

  • baseUrl - override the API endpoint, for a proxy or self-hosted gateway.

  • include / exclude - glob patterns using **, *, ?, and {a,b}. node_modules and .git are always skipped.

  • rubric - which rubric layers to use. usability (core heuristics), craft (typography, color, spacing, motion, components, writing), accessibility (contrast, keyboard, semantics, forms, touch targets, reduced motion). All three are on by default; pick a subset to cut token cost on large reviews.

  • maxFiles / maxFileBytes - safety caps so a large file does not blow the token budget. Every run prints its estimated token count.

The rubric and tailoring it

The default rubric is three layers:

  • usability - 10 core heuristics: visibility of system status, match with the real world, user control and freedom, consistency and standards, error prevention, recognition rather than recall, flexibility and efficiency, aesthetic and minimalist design, error diagnosis and recovery, help and documentation.

  • craft - design-system discipline: visual craft (concentric radius, optical alignment, no magic numbers, no generic AI-default styling), color and tokens, typography, spacing and layout, motion, component composition, and writing.

  • accessibility - checkable requirements: contrast, keyboard support, semantic elements, forms, touch targets, and reduced motion.

The rubric is a data structure. To replace it with your own philosophy, put a principles array in .polish.json:

{
  "principles": [
    {
      "id": "D1",
      "name": "Your design principles",
      "rules": [
        "A concrete rule the model can verify in code",
        "Another concrete rule"
      ]
    }
  ]
}

Rules work best when they are worded as things a model can check ("buttons show a loading state"), not as aesthetic vibes.

Scoring

  • Start at 100. Each finding deducts according to Polish weights: critical -22, serious -9, moderate -3.

  • The score never drops below 0.

Every review run also emits a receipt with polishApplied: true, a run id, the score, and the files reviewed. In human mode, polish prints that receipt before the score. In --json mode, agents can read the same receipt without parsing the plain-text output.

Verify mode

polish > findings.json
# fix the issues
polish --verify findings.json

Verify mode re-runs only the flagged findings against the current file contents and reports FIXED or STILL PRESENT for each one. It also emits a fresh score based on the findings that remain, plus the same receipt shape as a full review. Add --json to get the verify score, receipt, and statuses as machine-readable JSON.

MCP server

polish also runs as an MCP server over stdio, so AI agents can call it as tools. It exposes:

  • polish_review_files - review UI files by content, returns a score, receipt, and findings

  • polish_verify_fixes - re-check findings against updated content, returning a new score, receipt, and statuses

  • polish_usage - usage status, always unlimited and self-hosted

Register it in any MCP-capable client. For opencode, in ~/.config/opencode/opencode.json:

{
  "mcp": {
    "polish": {
      "type": "local",
      "command": ["node", "/absolute/path/to/polish/mcp-server.js"],
      "enabled": true,
      "environment": {
        "GROQ_API_KEY": "your-key"
      }
    }
  }
}

Claude Desktop reads ~/Library/Application Support/Claude/claude_desktop_config.json, and Codex reads ~/.codex/config.toml. In all three, use the absolute path to node (for example /usr/local/bin/node) because GUI apps do not inherit your shell PATH, and pass the API key in the server's environment because GUI apps do not load your shell profile.

Agent instructions

After registering the MCP server, run polish init-agent from the project root. It creates AGENTS.md with a review loop for UI changes. The command refuses to replace an existing file unless you pass --force.

Development

npm test          # node --test: unit tests plus a mock-server end-to-end test
node scripts/demo.mjs            # before/after demo, no API key needed
node scripts/mcp-handshake.mjs   # manual MCP handshake test

Demo

node scripts/demo.mjs runs the full pipeline (config, prompts, LLM call, scoring, verify) against a mock OpenAI-compatible server, so no API key is needed. It reviews demo/ProfileCard.before.jsx, a component with accessibility blockers and design-system leaks, then its fixed twin demo/ProfileCard.after.jsx (plus its stylesheet demo/profile.css), and finally verifies that the before-findings are resolved in the after code. The mock is deterministic: expect 39/100 to 97/100 and 8/8 findings fixed.

With an API key set, the same commands run against a live model, and the verdicts are real. Recorded live runs on Groq (llama-3.3-70b-versatile) scored the card demo 62/100 before and 78/100 after, and the form demo 43/100 before and 66/100 after. Verdicts vary by model and run, so use a live run to judge your own code:

polish demo/ProfileCard.before.jsx
polish demo/ProfileCard.after.jsx demo/profile.css
polish demo/SettingsForm.before.jsx
polish demo/SettingsForm.after.jsx demo/settings-form.css

Files

bin/polish.js        CLI entry, output rendering, exit codes
mcp-server.js        MCP server (stdio) wrapping the review engine
lib/rubric.js        default rubric layers (usability, craft, accessibility), swap for your own
lib/config.js        config loading, glob expansion, defaults
lib/llm.js           LLM provider callers and JSON extraction
lib/prompt.js        review and verify prompt builders
lib/review.js        shared review and verify engine, used by CLI and MCP
lib/agent.js         repo-local instructions for coding agents
lib/scoring.js       weighted scoring and summaries
demo/                before/after demo components (ProfileCard, SettingsForm)
test/                unit and integration tests
scripts/             manual test scripts

Notes on token cost

polish sends full, line-numbered file contents to the model. The estimated token count is printed before each run. Keep maxFiles and maxFileBytes tight, and audit the screens you touch in a change rather than whole repositories.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    This MCP server renders UI design artifacts headlessly, runs deterministic linters, and manages stateful design review loops with an independent vision critic.
  • F
    license
    A
    quality
    D
    maintenance
    An MCP server that audits websites for accessibility (WCAG 2.1 AA/EAA), performance, SEO, design quality, and mobile responsiveness, providing actionable scores, grades, and prioritized fixes.
    6
  • A
    license
    A
    quality
    A
    maintenance
    MCP server that enables AI coding assistants to audit repositories against engineering rules, generating self-contained HTML reports with citations and optional GitHub issue filing.
    10
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server for in-loop design review of web previews. It enables agents to submit a preview URL, receive structured findings with suggested fixes, and recheck after applying changes, while never editing code itself.
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tomiabe/polish'

If you have feedback or need assistance with the MCP directory API, please join our Discord server