-
Notifications
You must be signed in to change notification settings - Fork 6
MCP Server
ux-skill ships a Model Context Protocol server (ux-mcp) that exposes the engine as 14 tools any MCP-capable host can call. None of the top 8 Claude UX skills ship one. This is the asymmetric move.
Without MCP: the engine is a CLI you call from a terminal, plus markdown rules the LLM reads as context. The LLM has to remember to invoke commands.
With MCP: the engine is a tool the model can call directly mid-conversation, just like any other function. Claude Desktop, Cursor, Windsurf, generic MCP agents — all of them see ux_recommend, ux_lint, ux_brands, etc. as native tools. No prompt engineering, no rules file to load — the model calls them when needed.
pip install 'uxskill[mcp]' # Python 3.10+ required
ux-mcp # serves over stdioThe ux-mcp binary runs as a long-lived stdio server. MCP hosts spawn it as a subprocess and communicate over stdin/stdout in the standard MCP protocol.
# (excerpt from engine/mcp/server.py — see TOOLS dict)
TOOLS = {
# —— REASONING ——
"ux_recommend": "Run the 5-parallel-search recommender against a brief. Returns picked style + palette + type pair + top 5 motion presets + top 12 components + top 5 brand exemplars + all 100 anti-pattern guardrails active.",
"ux_lint": "Run the 100-rule anti-AI-slop regex linter over file paths. Returns findings with rule id, severity, file, line, excerpt, why, fix.",
"ux_stats": "Engine telemetry — version + per-manifest counts.",
# —— MANIFEST READERS (11) ——
"ux_styles": "Return all 84 styles from data/styles.json.",
"ux_palettes": "Return all 176 palettes from data/palettes.json.",
"ux_type_pairs": "Return all 70 type pairs from data/type-pairs.json.",
"ux_components": "Return all 148 components from data/components.json.",
"ux_industries": "Return all 184 industry profiles from data/industries.json.",
"ux_motion_presets": "Return all 57 motion presets from data/motion-presets.json.",
"ux_anti_patterns": "Return all 100 anti-pattern rules from data/anti-patterns.json.",
"ux_brands": "Return all 110 brand DESIGN.md specs from data/brands/*.json. Optional category filter.",
"ux_landing_patterns": "Return all 40 landing-page patterns from data/landing-patterns.json.",
# —— PERSISTENCE ——
"ux_persist_save": "Write MASTER.md from a recommendation to a project root.",
"ux_persist_load": "Load MASTER.md from a project root, return parsed content.",
}Each tool is a pure dict -> dict Python function. The stdio wrapper is a thin async layer around them. Tests exercise handlers directly — no event loop, no subprocess plumbing required to validate the engine logic.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%/Claude/claude_desktop_config.json (Windows):
{
"mcpServers": {
"ux-skill": {
"command": "ux-mcp"
}
}
}If ux-mcp isn't on Claude Desktop's PATH, use the full path:
{
"mcpServers": {
"ux-skill": {
"command": "/Users/you/.pyenv/shims/ux-mcp"
}
}
}Restart Claude Desktop. The 14 tools now appear in the model's available functions and Claude can call them mid-conversation.
Cursor supports MCP via the Model Context Protocol Servers settings panel (Settings → Features → MCP). Add a new server:
- Name: ux-skill
-
Command:
ux-mcp - Args: (none)
- Transport: stdio (default)
Save. The 14 tools become available to Cursor's chat agent.
Windsurf's Cascade MCP support is enabled by default. Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"ux-skill": {
"command": "ux-mcp",
"args": []
}
}
}Restart Windsurf. The tools appear in Cascade's tool palette.
Any MCP-1.0-compatible host can register ux-mcp over stdio:
ux-mcp # stdio serverThe server speaks the standard MCP protocol — initialize, tools/list, tools/call, resources/list (no resources yet), prompts/list (no prompts yet).
User: "I'm building a fintech landing page for a Saudi neobank. Tone is precise, audience is institutional procurement. Pick a style and palette."
Claude (decides to call ux_recommend):
{
"tool": "ux_recommend",
"arguments": {
"brief": {
"project_type": "landing",
"industry": "fintech-neobank",
"audience": ["procurement", "institutional"],
"tone": ["precise", "serious"],
"must_have": ["a11y-AA", "rtl"],
"forbidden": ["purple-to-blue-gradient", "cormorant-garamond"],
"region": "mena"
}
}
}Server returns (excerpt):
{
"style": {
"id": "fintech-precise",
"name": "Fintech Precise",
"philosophy": "Hairline-rule discipline, generous whitespace, tabular figures."
},
"palette": {
"id": "saudi-institutional-cool",
"primary": "#0a2540",
"accent": "#16a085",
"canvas": "#fafbfc",
"ink": "#1b1f23"
},
"type_pair": {
"id": "ibm-plex-sans-pair",
"display": "IBM Plex Sans",
"body": "IBM Plex Sans",
"mono": "IBM Plex Mono"
},
"motion": [
{"id": "fade-up-12px"},
{"id": "tab-slide"},
{"id": "route-crossfade"}
],
"components": [
{"id": "fintech-rate-card"},
{"id": "table-with-stripe-hover"},
"...10 more"
],
"brand_exemplars": [
{"id": "stripe"},
{"id": "ramp"},
{"id": "monzo"},
{"id": "mercury"},
{"id": "n26"}
],
"guardrails": ["...all 100 anti-pattern rules active..."],
"rationale": [
"Industry: Fintech — Neobank",
"Style: Fintech Precise (matches 'precise' + 'serious' tone)",
"Palette: Saudi institutional cool (RTL-compatible)",
"Type pair: IBM Plex Sans (geometric, neutral, multilingual)",
"Motion: Fade-up + tab-slide (no overshoot, no spring)"
]
}Claude now writes the landing page directly grounded in this recommendation.
None of these ship MCP:
| Plugin | MCP Server | # MCP Tools |
|---|---|---|
| ux-skill | Yes | 14 |
| ui-ux-pro-max-skill (84k) | no | 0 |
| taste-skill (25k) | no | 0 |
| huashu-design (15k) | no | 0 |
| nothing-design-skill | no | 0 |
| hallmark | no | 0 |
| material-3-skill | no | 0 |
| open-design | no | 0 |
| stitch-skill | no | 0 |
This is the asymmetric move. We're 14 stars right now and they're 84k. But on architecture, we're the only one with an MCP surface — and MCP is where the agent ecosystem is going.
-
Transport split from handlers: each tool is a pure
dict -> dictPython function inengine/mcp/handlers.py. The stdio wrapper inengine/mcp/server.pyis a thin async layer that calls them. -
Optional dependency:
pip install 'uxskill[mcp]'pulls inmcp>=1.0. Base install stays slim. Module imports cleanly without the transport library;ux-mcpfails fast with a clear install hint if it's missing. -
No event loop in tests:
tests/test_mcp.pyexercises the 14 handlers directly. No subprocess plumbing, no async, no flaky integration tests. -
Graceful import: if
mcpisn't installed,engine.mcpstill imports —MCP_AVAILABLE = Falselets callers branch.
- Server:
engine/mcp/server.py - Handlers:
engine/mcp/handlers.py - Tests:
tests/test_mcp.py(5 tests, all passing) - Entry point:
pyproject.toml → [project.scripts]→ux-mcp = "engine.mcp.server:run_server"
Read the source: github.com/Laith0003/ux-skill/tree/main/engine/mcp