npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molano/mcp-server

v1.0.0

Published

Molano Design System — MCP Server for AI agents. Provides tools for component lookup, token queries, code validation, accessibility checks, and design governance.

Readme

@molano/mcp-server

MCP (Model Context Protocol) server for the Molano Design System. Exposes design system knowledge — components, tokens, recipes, validation rules, code generation, and governance — to AI agents like GitHub Copilot, Claude, Cursor, and Windsurf.

35 tools · 172+ smoke tests · structured logging · telemetry · rate limiting · auth support

Quick Start

# 1. Install monorepo deps
npm install

# 2. Build
npm run build --workspace=packages/mcp-server

# 3. Run (via MCP client — VS Code, Claude Desktop, Cursor, etc.)
node packages/mcp-server/dist/index.js

Tools (35)

Core (10 tools) — Query the design system

| Tool | Description | |------|-------------| | list_components | List all 91 DS components. Filter by category (forms, layout, overlays…) or status (stable, beta, experimental, deprecated) | | get_component | Get full component detail: props, sub-components, variants, usage do/don't, code examples, a11y notes | | list_tokens | List all design tokens (121 primitive + 28 semantic). Filter by category (color, typography, spacing…) | | get_token | Get a token by name (exact or fuzzy). Returns CSS var, value, and light/dark for semantic tokens | | list_recipes | List 25 pre-composed recipes (FormCard, EmptyState, StatCard…) with composedFrom info | | get_recipe | Get recipe detail with usage guidance and code examples | | list_layouts | List 4 layout components (AppShell, PageLayout, AuthLayout, DashboardLayout) with sub-components and hooks | | search_ds | Full-text search across components + tokens. Returns top matches ranked by relevance | | get_version | Current DS version, total components, and lifecycle breakdown by status | | get_changelog | Get changelog entries. Optionally filter by version. Returns changes, breaking changes, and migration notes |

Validation (7 tools) — Validate agent-generated code

| Tool | Description | |------|-------------| | validate_code | Validate code against 7 DS rules: hardcoded colors, native elements, external libs, asChild, forwardRef, window dialogs, physical CSS | | validate_tokens_usage | Check for hex colors in className, inline styles, hardcoded color values | | check_a11y | Accessibility checks: img alt, icon button labels, div onClick, dialog/sheet titles | | check_contrast | WCAG contrast ratio between two hex colors — returns ratio, AA, AAA, and large text compliance | | validate_composition | Verify recipes compose DS primitives (Card uses CardHeader, not manual styles) | | validate_responsive | Check for hardcoded media queries, fixed pixel widths, missing responsive breakpoints | | validate_i18n | RTL readiness: detects physical CSS properties (ml, mr, pl, pr → ms, me, ps, pe) |

Generation (7 tools) — Generate code that follows DS conventions

| Tool | Description | |------|-------------| | generate_story | Generate Storybook story with all variants, auto-imports, and sub-component rendering | | generate_test | Generate vitest + testing-library tests: render, variants, data-slot, a11y | | generate_page | Generate full page: layout + search + table + empty state + form, with proper DS imports | | scaffold_component | Scaffold new component: cva variants, data-slot, displayName, sub-components | | generate_migration | Generate migration guide between versions with breaking changes and steps | | generate_docs | Generate knowledge doc (.md) with YAML frontmatter: whenToUse, do/don't, a11y, code examples | | generate_rfc | Generate RFC document for proposing new components: API design, a11y, checklist |

Governance (9 tools) — Monitor DS health and adoption

| Tool | Description | |------|-------------| | component_health | List components with health issues: missing docs, deprecated, experimental | | get_anti_patterns | List 12 DS anti-patterns with bad/good code examples and fix reasons | | audit_coverage | Cross-reference metadata vs knowledge docs — reports missing/orphaned docs | | token_coverage | Analyze token usage: which --ds-* vars are used in globals.css vs defined | | bundle_report | Report bundle sizes (files, total KB, budget compliance). Pass budgetKB to configure | | breaking_changes | List all breaking changes since a given version. Helps plan migrations | | ds_audit | Full DS health scorecard: components, tokens, bundle, theme bridge. Returns score with pass/fail | | adoption_report | Analyze code for DS adoption: counts imports, detects violations (native elements, hardcoded colors, external libs) | | deprecation_candidates | List components that are experimental or missing documentation |

Infrastructure (2 tools) — Monitor the MCP server itself

| Tool | Description | |------|-------------| | ds_health | Health check: server status, uptime, version, data counts, and per-tool usage telemetry | | ds_server_info | Server metadata: protocol version, supported DS versions, tool categories, capabilities |

Usage Examples

In VS Code (GitHub Copilot)

The server is pre-configured in .vscode/mcp.json. Just build and restart VS Code.

Natural language queries:

"List all form components"
→ Calls list_components with category="forms" → 16 components

"How do I use Dialog?"
→ Calls get_component("Dialog") → usage do/don't, code example, a11y notes

"Validate this code for DS compliance"
→ Calls validate_code(code) → errors: asChild detected, use render prop instead

"Generate a Storybook story for Badge"
→ Calls generate_story("Badge") → complete story with all variants

"What's the health of the DS?"
→ Calls ds_audit() → scorecard: 14/15 (93%), 4 sections with pass/fail

"How many tokens am I actually using?"
→ Calls token_coverage() → 25/121 vars used in globals.css, orphan analysis

"Is this code using the DS correctly?"
→ Calls adoption_report(code) → 2 imports found, 3 violations detected

Programmatic (JSON-RPC over stdio)

# Start server
node packages/mcp-server/dist/index.js

# Send MCP initialize request via stdin
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node packages/mcp-server/dist/index.js
// Call a tool
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "validate_code",
    "arguments": {
      "code": "<button onClick={handleClick}>Submit</button>"
    }
  }
}

// Response
{
  "valid": false,
  "errors": [
    {
      "rule": "no-native-elements",
      "message": "Use <Button> instead of <button>",
      "suggestion": "<Button onClick={handleClick}>Submit</Button>"
    }
  ]
}

Setup

VS Code (GitHub Copilot)

Pre-configured in .vscode/mcp.json:

{
  "servers": {
    "molano-ds": {
      "type": "stdio",
      "command": "node",
      "args": ["packages/mcp-server/dist/index.js"],
      "cwd": "${workspaceFolder}"
    }
  }
}

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "molano-ds": {
      "command": "node",
      "args": ["/absolute/path/to/Molano-DS/packages/mcp-server/dist/index.js"],
      "cwd": "/absolute/path/to/Molano-DS"
    }
  }
}

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "molano-ds": {
      "command": "node",
      "args": ["packages/mcp-server/dist/index.js"],
      "cwd": "."
    }
  }
}

Docker

# Build image
docker build -t molano-mcp -f packages/mcp-server/Dockerfile .

# Run (stdio mode)
docker run -i molano-mcp

# With auth enabled
docker run -i -e MCP_AUTH_REQUIRED=true -e MCP_API_KEY=your-secret-key molano-mcp

Configuration

All configuration via environment variables:

| Variable | Default | Description | |----------|---------|-------------| | MCP_LOG_LEVEL | info | Log level: debug, info, warn, error | | MCP_AUTH_REQUIRED | false | Set to true to require API key authentication | | MCP_API_KEY | — | API key (required when MCP_AUTH_REQUIRED=true) | | MCP_RATE_LIMIT | 200 | Max tool calls per minute |

Structured Logging

All logs are JSON-formatted and written to stderr (stdout is reserved for MCP JSON-RPC):

{
  "timestamp": "2026-04-22T10:15:30.123Z",
  "level": "info",
  "correlationId": "a1b2c3d4",
  "message": "tool_call_end",
  "data": { "tool": "validate_code", "durationMs": 12 }
}

Telemetry

Call ds_health to see real-time telemetry:

{
  "status": "healthy",
  "uptime": "2h 15m 30s",
  "telemetry": {
    "totalCalls": 142,
    "totalErrors": 3,
    "errorRate": "2.1%",
    "toolStats": {
      "validate_code": { "calls": 45, "errors": 1, "avgDurationMs": 8 },
      "get_component": { "calls": 32, "errors": 0, "avgDurationMs": 3 }
    }
  }
}

Error Handling

Every tool call is wrapped with:

  • Correlation ID — unique per request for log tracing
  • Graceful degradation — errors return structured JSON, never crash the server
  • Rate limiting — 429-style response when limit exceeded
  • Retry hints — error responses include retryAfterMs when rate-limited

Development

# Watch mode
npm run dev --workspace=packages/mcp-server

# Type check
npm run typecheck --workspace=packages/mcp-server

# Smoke tests (172 assertions)
npm test --workspace=packages/mcp-server

# Cross-system integration tests
node packages/mcp-server/scripts/cross-check.mjs

Architecture

packages/mcp-server/
├── src/
│   ├── index.ts        # Server entry: 35 tool registrations + middleware (auth, rate limit, telemetry)
│   ├── data.ts         # Data loading: tokens, components, version, changelog, directory helpers
│   ├── knowledge.ts    # Auto-loads component knowledge from packages/ui/docs/*.md (YAML frontmatter)
│   ├── validators.ts   # Code validation: DS rules, a11y, contrast, i18n, composition, responsive
│   ├── generators.ts   # Code generation: stories, tests, pages, scaffolds, docs, migrations, RFCs
│   ├── governance.ts   # Governance: token coverage, bundle report, audit, adoption, deprecation
│   ├── logger.ts       # Structured JSON logger (stderr, correlation IDs, configurable level)
│   └── telemetry.ts    # In-memory telemetry: tool call tracking, latency, error rates
├── scripts/
│   ├── smoke-test.mjs          # 172-assertion end-to-end MCP server test via JSON-RPC
│   ├── cross-check.mjs         # 22 cross-system integration tests
│   ├── generate-metadata.mjs   # Auto-generates COMPONENT-METADATA.json from source
│   └── validate-metadata.mjs   # Validates metadata sync with disk
├── Dockerfile          # Multi-stage Docker build for shared deployment
├── dist/               # Built output (ESM bundle, ~87 KB)
├── package.json
├── tsconfig.json
└── tsup.config.ts

How it works

  1. Startup: Reads monorepo data — token JSONs, component metadata, knowledge docs, changelog
  2. Middleware: Every tool call gets correlation ID, structured logging, error handling, rate limiting, and telemetry
  3. 35 tools: Registered via MCP SDK, exposed over stdio for any MCP-compatible client
  4. Validation: Regex-based static analysis on code snippets — no AST parser needed
  5. Generation: Template-based code generation following DS conventions
  6. Governance: File system analysis for bundle sizes, token coverage, and adoption metrics
  7. Knowledge is auto-loaded from markdown files — no hardcoded data in the server.

Adding a new tool

// In src/index.ts
server.tool(
  "tool_name",
  "Description for AI agents",
  {
    param: z.string().describe("Parameter description"),
  },
  async ({ param }) => {
    // Tool logic
    return {
      content: [
        { type: "text" as const, text: JSON.stringify(result, null, 2) },
      ],
    };
  },
);

Adding component knowledge

Create a markdown file in packages/ui/docs/ named after the component (e.g., Button.md):

---
whenToUse: For primary actions, form submissions, CTAs.
whenNotToUse: For navigation use Link. For toggles use Switch.
do:
  - Use semantic variants (destructive, outline, ghost)
  - Add aria-label for icon-only buttons
dont:
  - Use native <button> — always use DS Button
  - Wrap in unnecessary divs
a11y: Icon-only buttons need aria-label for screen readers.
---

```tsx
<Button variant="destructive">Delete</Button>

The server auto-loads all `docs/*.md` files at startup — no code changes needed.

## Validation Rules

The server enforces these DS rules:

| Rule | Severity | Description |
|------|----------|-------------|
| `no-hardcoded-colors` | error | No Tailwind color classes (text-red-500) — use semantic tokens |
| `no-physical-properties` | warning | No physical CSS (ml-4) — use logical (ms-4) for RTL |
| `no-native-elements` | error | No native `<button>`, `<input>` — use DS components |
| `no-external-ui-libs` | error | No imports from Radix, Chakra, MUI, etc. |
| `no-window-dialogs` | error | No window.alert/confirm/prompt |
| `no-asChild` | error | No asChild prop — use render prop (base-ui, not Radix) |
| `no-forwardRef` | warning | Unnecessary in React 19 |
| `no-manual-card-styles` | error | No manual Card styles (`rounded-lg border bg-card...`) — compose CardHeader, CardContent, etc. |
| `no-manual-skeleton` | error | No manual skeleton divs (`animate-pulse rounded bg-muted`) — use `<Skeleton />` |
| `no-native-headings` | warning | No native `<h1>`..`<h6>`, `<p>` for page structure — use PageTitle, CardTitle, etc. |
| `no-hardcoded-spacing` | warning | No hardcoded pixel spacing in className — use DS spacing tokens |
| `no-hardcoded-hex` | error | No hex colors in className |
| `prefer-tokens-over-inline` | warning | Prefer Tailwind classes over inline styles |
| `img-alt` | error | Images must have alt text |
| `button-label` | error | Icon buttons need aria-label |
| `no-div-onclick` | error | No `<div onClick>` — use Button or ActionCard |
| `dialog-title` | warning | Dialogs need a title for screen readers |

## Testing

### Smoke test

Runs the server end-to-end: initializes, lists tools, calls key tools, validates responses.

```bash
# From packages/mcp-server/
npm test          # builds + runs all tests
npm run test      # same as above

The smoke test verifies:

  • Server starts and completes MCP handshake
  • All 18 tools are registered
  • Components and tokens load correctly
  • Code validation catches known bad patterns
  • Good code passes validation
  • Contrast checker returns valid ratios
  • Accessibility checks detect issues
  • Search returns relevant results

Metadata generation

Auto-generates COMPONENT-METADATA.json by scanning component source files:

npm run generate-metadata

Scans packages/ui/src/components/ui/*.tsx, extracts displayNames, categorizes components, and writes packages/ui/COMPONENT-METADATA.json.

Metadata sync validation

Checks that COMPONENT-METADATA.json matches the actual component files on disk.

npm run validate-metadata

Detects:

  • Files referenced in metadata that don't exist
  • Component files on disk not tracked in metadata
  • Duplicate component names
  • Missing required fields
  • Incorrect totalComponents count

MCP Inspector (interactive)

The official MCP debugging tool — sends requests interactively and inspects responses.

npx @modelcontextprotocol/inspector node dist/index.js

VS Code quick test

  1. Restart the MCP server: Ctrl+Shift+P → "MCP: List Servers" → restart
  2. Open Copilot chat in Agent mode
  3. Ask: "Using the molano-ds MCP, list all available components"
  4. Verify it returns the component catalog

Keeping in sync

The MCP server reads data at runtime from the monorepo, not at build time:

  • Tokens: loaded from packages/tokens/*.json on every startup
  • Components: loaded from packages/ui/COMPONENT-METADATA.json on startup
  • Knowledge: loaded from packages/ui/docs/*.md on startup (YAML frontmatter + code examples)
  • Version: loaded from packages/ui/package.json on startup

This means tokens, knowledge, and version are always current — just restart the server after changes.

COMPONENT-METADATA.json is auto-generated via npm run generate-metadata. Run npm run validate-metadata to detect drift.

Recommended workflow

  1. Add a new component to packages/ui/src/components/ui/
  2. Regenerate metadata: npm run generate-metadata (from packages/mcp-server/)
  3. Add knowledge doc: create packages/ui/docs/ComponentName.md with YAML frontmatter
  4. Validate sync: npm run validate-metadata
  5. Audit coverage: use the audit_coverage MCP tool or run smoke test
  6. Restart the MCP server to pick up changes