uxskill
Star on GitHub
Language
English 简体中文 繁體中文 日本語 한국어 हिन्दी Bahasa Indonesia Tiếng Việt ไทย العربية Español Français Deutsch Português Русский Türkçe Italiano
MCP server · stdio · 18 tools · 2026

# Design intelligence over Model Context Protocol.

ux-skill ships a Model Context Protocol server. Any MCP-capable host, Claude Desktop, Cursor, Windsurf, generic agents, can call the recommender, the linter, and all eleven data manifests over stdio. No plugin install, no IDE lock-in, just a long-running daemon and 18 tools.

One MCP daemon, 18 tools, any compatible host, here, answering from inside Cursor.
Why this exists

Reaching design intelligence used to mean installing a plugin into the specific tool the plugin was written for. Claude Code plugins stay in Claude Code. Cursor rules stay in Cursor. The same recommender, the same linter, the same brand specs had to be re-wired for every host. The MCP server collapses that. One process. One protocol. Every host that speaks MCP gets the engine, identically. The recommender is deterministic, the linter is regex-grounded, and both come straight out of the same Python package as the slash commands, so an agent in a fresh repo can ask for the same Stripe-grade landing or fintech-dashboard system that a Claude Code session can.

The asymmetric position

## None of the top eight ship one. We do.

The competition is locked inside Claude Code's plugin runtime. The MCP server makes ux-skill reachable from any agent, even agents that have never heard of a Claude Code plugin.

Plugin | MCP server | Effective reach
--- | --- | ---
ux-skill | yes `ux-mcp` over stdio | Claude Desktop, Cursor, Windsurf, any MCP host, generic agents
ui-ux-pro-max-skill | no | Claude Code only
open-design | no | Claude Code only
taste-skill | no | Claude Code only
huashu-design | no | Claude Code only
stitch-skills | no | Claude Code only
nothing-design-skill | no | Claude Code only
hallmark | no | Claude Code only
material-3-skill | no | Claude Code only

One server. Every host. That's the move.

The catalogue

## Fourteen tools, one engine.

Each tool is a pure `dict -> dict` Python handler. Same code path the slash commands use; same data manifests; same deterministic recommender. The MCP layer is a thin stdio wrapper.

Tool | What it does
--- | ---
`ux_recommend` | Run the 5-parallel-search recommender over a brief. Returns style, palette, type pair, motion presets, components, brand exemplars, anti-pattern guardrails, and a rationale line per lane.
`ux_lint` | Run the 152-rule anti-AI-slop regex linter over file paths. Returns findings with rule id, severity, file, line, excerpt, and fix.
`ux_styles` | Return all 84+ entries from `data/styles.json`, design philosophies with tokens.
`ux_palettes` | Return 176+ entries from `data/palettes.json`. Optional `mode` filter (`light` / `dark`).
`ux_type_pairs` | Return 70+ entries from `data/type-pairs.json`, display + body + mono pairings.
`ux_components` | Return 148+ entries from `data/components.json`. Optional `category` filter.
`ux_industries` | Return 184+ entries from `data/industries.json` with style/palette/type biases per domain.
`ux_motion_presets` | Return 57+ entries from `data/motion-presets.json` with easing, duration, stagger tokens.
`ux_anti_patterns` | Return 35+ entries from `data/anti-patterns.json` (the regex rules that drive the linter). Optional `severity` filter.
`ux_brands` | Return 160 brand specs from `data/brands/*.json` (Apple, Stripe, Linear, Tesla, Notion, etc.). Optional `category` filter.
`ux_landing_patterns` | Return 24+ entries from `data/landing-patterns.json`, proven landing-page section patterns.
`ux_persist_save` | Write a recommendation as `.ux/design-system/MASTER.md` in the given project root. Idempotent, same input writes byte-identical bytes.
`ux_persist_load` | Load `.ux/design-system/MASTER.md` back into a structured dict, or report not-found.
`ux_stats` | Return the engine version and per-manifest entry counts. Useful as a health probe.
`ux_image_extract` | Read a design image (PNG/JPG/WebP) and return a synthetic brief plus diagnostics, dominant colors, canvas polarity, matched palette and style. Pure CV, no multimodal LLM.
`ux_synthesize` | Synthesize a fresh design language from a brief, axes, palette, type pair, spacing, radius, motion. Mode auto-dispatched (pure synthesis / brand anchor / strict brand). Offline and deterministic.
`ux_decisions_query` | Filter the local decisions ledger by industry, ui_type, command, min score, or accepted-only. The recommender re-ranks on this once a brief’s bucket has enough prior decisions.
`ux_decisions_stats` | Aggregate stats over the local decisions ledger, totals by command, industry, ui_type, mode, top brands, median lint score, acceptance rate. No telemetry; your install’s local view.

Example calls

## What it actually does.

### ux_recommend, get a complete system from a brief

    // Input
    {
      "brief": {
        "project_type": "landing",
        "industry": "fintech-neobank",
        "tone": ["warm", "editorial", "precise"],
        "must_have": ["dark-mode", "a11y-AA"],
        "forbidden": ["brutalism", "purple-gradients"],
        "stack": "nextjs-15-app-router",
        "region": "mena"
      }
    }

    // Output (abridged)
    {
      "style": { "id": "monochrome-precise", "name": "Monochrome Precise", ... },
      "palette": { "id": "dark-editorial-cinema", "mode": "dark", ... },
      "type_pair": { "id": "bricolage-inter-jetbrains", ... },
      "motion": [ ... /* top 5 presets compatible with style */ ],
      "components": [ ... /* top 12 compatible components */ ],
      "brand_exemplars": [ ... /* top 5 brands to study */ ],
      "guardrails": [ ... /* all 152 anti-pattern rules, always-on */ ],
      "rationale": [
        "Industry: Fintech Neobank",
        "Style: Monochrome Precise",
        "Palette: Dark Editorial Cinema",
        ...
      ]
    }

### ux_lint, anti-slop regex sweep across paths

    // Input
    { "paths": ["./app", "./components"], "threshold": "high" }

    // Output (abridged)
    {
      "files_scanned": 142,
      "rules_loaded": 35,
      "exit_code": 1,
      "findings": [
        {
          "rule_id": "generic-placeholder-copy",
          "severity": "high",
          "file": "./app/page.tsx",
          "line": 42,
          "excerpt": "<p>Your headline goes here.</p>",
          "fix": "Write real copy that names the user value."
        },
        ...
      ],
      "summary": { "critical": 0, "high": 4, "medium": 7, "low": 12, "total": 23 }
    }

### ux_stats, engine health probe

    // Input: {} ; Output:
    {
      "version": "2.0.0-alpha.1",
      "counts": {
        "styles": 84, "palettes": 176, "type-pairs": 70,
        "components": 148, "industries": 184, "chart-types": 35,
        "tech-stacks": 25, "ux-guidelines": 112,
        "motion-presets": 57, "anti-patterns": 35, "brands": 72
      }
    }

Client configuration

## Connect any MCP host in three lines.

The server is one binary: `ux-mcp`. Once installed, every MCP host points to it the same way.

#### Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json

    {
      "mcpServers": {
        "ux-skill": {
          "command": "ux-mcp",
          "args": [],
          "env": {}
        }
      }
    }

#### Cursor (project + global)

.cursor/mcp.json or ~/.cursor/mcp.json

    {
      "mcpServers": {
        "ux-skill": {
          "command": "ux-mcp"
        }
      }
    }

Then in `.cursorrules`: "When designing UI, call ux-skill MCP tools first: ux_recommend for the system, ux_lint to catch slop."

#### Windsurf

~/.codeium/windsurf/mcp_config.json

    {
      "mcpServers": {
        "ux-skill": {
          "command": "ux-mcp"
        }
      }
    }

#### Generic stdio client

any JSON-RPC over stdio host

    # Spawn ux-mcp as a subprocess.
    # Write JSON-RPC frames to stdin.
    # Read responses from stdout.
    # Logs are on stderr only.

    $ ux-mcp
    # or, equivalently:
    $ python3 -m engine.mcp.server

How it's built

## Transport separated from handlers.

The 18 tools are pure `dict -> dict` Python functions in `engine.mcp.server`. The MCP stdio transport is an optional dependency that lazy-imports inside `run_server()`. Three consequences fall out:

- The `engine.mcp` module imports cleanly whether or not the `mcp` Python package is installed.
- Tests exercise the handlers directly, no async event loop, no subprocess plumbing in the test suite.
- `ux-mcp` fails fast with a clear `pip install` hint if the transport library is missing.

One source of truth, one entry point, every host.

Install. Connect. Run.

## Three lines to design intelligence in any agent.

MIT licensed. No telemetry. No account. The MCP transport is opt-in so the base install stays slim.

$ pip install 'uxskill[mcp]'
$ ux-mcp # starts the stdio server
, then point your MCP host at `ux-mcp` ,