Skip to main content
Glama
lodado

design-system-mcp

by lodado
README.md
# design-system-mcp

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
[![Node.js >=20](https://img.shields.io/badge/node-%3E%3D20-339933.svg)](https://nodejs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.8-3178c6.svg)](https://www.typescriptlang.org/)
[![MCP](https://img.shields.io/badge/MCP-ready-6f42c1.svg)](https://modelcontextprotocol.io/)
[![GitHub](https://img.shields.io/badge/GitHub-lodado%2Fdesign--system--mcp-181717.svg)](https://github.com/lodado/design-system-mcp)

A shadcn-style local MCP installer for design-system repositories.

`design-system-mcp` helps AI coding agents use your real design system by lookup instead of guesswork. Run one install command in a design-system repo and it creates a local managed MCP runtime, scans components/icons/tokens, and wires Cursor/Codex to the generated index.

```text
design-system repo
  -> .design-system-mcp/ local runtime and index
  -> .cursor/.codex MCP client entries
  -> Cursor / Codex / other MCP clients
```

## Status

MVP is working:

- `ds-mcp install`
- `ds-mcp doctor`
- `ds-mcp generate`
- `ds-mcp serve`
- TypeScript/TSX component export scanning
- prop metadata with type summaries, optional flags, defaults, and literal unions
- icon export scanning
- JSON/TS/CSS token extraction
- local MD/MDX docs reference linking

## Quick Start

Run this from the root of a design-system repository:

```bash
npx github:lodado/design-system-mcp install
```

The package is not published to npm yet. After it is published, the command will become:

```bash
npx design-system-mcp install
```

The installer creates a local managed runtime and project MCP client entries:

```text
.design-system-mcp/
  bin/server.js       # bundled stdio MCP server
  bin/generate.js     # bundled index generator
  cache/index.json    # generated component/icon/token index
  config.json         # scanner/input paths
  manifest.json       # install metadata

.cursor/mcp.json      # Cursor project MCP entry
.codex/config.toml    # Codex project MCP entry
.gitignore            # gets `.design-system-mcp/` if missing
```

`.design-system-mcp/` is a generated local managed area. Do not edit it by hand and do not commit it. Re-run install to refresh it.

Existing Cursor/Codex `design-system` MCP entries are skipped, not overwritten. The installer does not force an ignore policy for `.cursor/` or `.codex/`; each repo can decide whether those client settings are local-only or shared.

## Verify Install

```bash
npx github:lodado/design-system-mcp doctor
```

`doctor` fails only when the local MCP runtime cannot run. Missing optional client entries are warnings.

Use JSON output for agents or CI:

```bash
npx github:lodado/design-system-mcp doctor --json
```

## Local Runtime Commands

The MCP client entries run the vendored server directly:

```bash
node .design-system-mcp/bin/server.js
```

Regenerate the local index manually:

```bash
node .design-system-mcp/bin/generate.js
```

## Onboarding Snippet

The installer prints this snippet instead of editing your README automatically:

````md
## Design-system MCP

Run this once after cloning to create local MCP runtime files:

```bash
npx github:lodado/design-system-mcp install
```
````

## Copy-paste prompt: use the MCP while implementing UI

Use this prompt in a consumer application repository after the design-system MCP server is connected.

```text
Before implementing UI, use the connected design-system MCP.

Workflow:
1. Call inspect_system to verify the MCP server and generated index are available.
2. Call discover_components with a narrow query and limit to find existing design-system components before creating custom UI.
3. Pick one componentId from discover_components, then call explain_component with that id and detailLevel="summary".
4. Request explain_component detailLevel="props" or "full" only for the selected component when summary is not enough.
5. Before choosing colors, typography, spacing, radius, shadow, or theme values, call discover_tokens with kind/query/limit.
6. Before using icons, call discover_icons with query/category/limit.
7. Prefer existing design-system components, props, and tokens over custom components or custom styles.
8. If a needed component, prop, token, or icon is missing, state that explicitly instead of inventing an API.

Token-budget rules:
- Do not call discover_components with many broad keyword variants. Start with 1-3 intent queries.
- Do not call explain_component for every candidate. Explain only the selected componentId.
- Keep explain_component at detailLevel="summary" unless implementation requires prop details.
- Treat totalMatches > returned as a signal to refine the query instead of dumping more results.

When reporting your implementation plan, include:
- MCP tools called
- selected componentIds and why
- selected tokens/icons and why
- any missing design-system APIs
```

Korean version:

```text
UI 구현 전에는 연결된 design-system MCP를 반드시 사용한다.

작업 순서:
1. inspect_system으로 MCP 서버와 generated index 상태를 확인한다.
2. 커스텀 UI를 만들기 전에 좁은 query와 limit으로 discover_components를 호출해 기존 디자인시스템 컴포넌트를 찾는다.
3. discover_components가 반환한 componentId 하나를 선택한 뒤 explain_component에 id와 detailLevel="summary"를 넘긴다.
4. summary만으로 부족할 때만 선택한 컴포넌트에 대해 detailLevel="props" 또는 "full"을 요청한다.
5. 색상, 타이포그래피, spacing, radius, shadow, theme 값을 고르기 전에는 kind/query/limit과 함께 discover_tokens를 호출한다.
6. 아이콘을 쓰기 전에는 query/category/limit과 함께 discover_icons를 호출한다.
7. 커스텀 컴포넌트/커스텀 스타일보다 기존 디자인시스템 컴포넌트, props, token을 우선한다.
8. 필요한 컴포넌트, prop, token, icon이 없으면 추측하지 말고 누락 사실을 명시한다.

토큰 예산 규칙:
- discover_components를 많은 broad keyword 조합으로 반복 호출하지 말고, 먼저 1~3개의 intent query로 좁힌다.
- 모든 후보에 explain_component를 호출하지 말고, 선택한 componentId 하나에만 호출한다.
- 구현에 prop 상세가 필요하기 전까지 explain_component는 detailLevel="summary"로 유지한다.
- totalMatches가 returned보다 크면 더 많은 결과를 덤프하지 말고 query를 좁힌다.

구현 계획을 보고할 때는 다음을 포함한다:
- 호출한 MCP tool
- 선택한 componentId와 이유
- 선택한 token/icon과 이유
- 누락된 디자인시스템 API
```

## MCP tools

| Tool                  | When to use it                                                                                                                                                             |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inspect_system`      | Start UI work and verify MCP/index availability.                                                                                                                           |
| `discover_components` | Find existing design-system components before creating custom UI. Accepts `query` and `limit`; returns compact entries with `componentId`, `totalMatches`, and `returned`. |
| `explain_component`   | Read selected component details by stable `id`. Defaults to `detailLevel="summary"`; use `"props"` or `"full"` only when needed. `name` is a fallback for compatibility.   |
| `discover_icons`      | Verify available icon names and keywords before using icons. Accepts `query`, `category`, and `limit`; returns `totalMatches` and `returned`.                              |
| `discover_tokens`     | Find color, spacing, typography, radius, shadow, or other tokens. Accepts `kind`, `query`, `theme`, and `limit`; returns `totalMatches` and `returned`.                    |
| `explain_token_usage` | Read semantic-token usage rules.                                                                                                                                           |
| `read_design_rules`   | Read agent-facing design-system implementation rules.                                                                                                                      |
| `read_setup_guide`    | Read setup steps from inside an MCP client.                                                                                                                                |

### Token-budget tool flow

```text
inspect_system
  -> discover_components({ query, limit })
  -> explain_component({ id: componentId, detailLevel: "summary" })
  -> explain_component({ id: componentId, detailLevel: "props" }) only if needed
  -> discover_tokens({ kind, query, limit })
  -> discover_icons({ query, category, limit })
```

## Manual MCP Config

`ds-mcp install` creates project-local Cursor and Codex config by default. If you need to wire a client manually, point it at the vendored runtime.

Cursor-style example:

```json
{
  "mcpServers": {
    "design-system": {
      "command": "node",
      "args": [".design-system-mcp/bin/server.js"],
      "cwd": "."
    }
  }
}
```

The server reads this file from `cwd`:

```text
.design-system-mcp/cache/index.json
```

## Generate behavior

The vendored generator reads `.design-system-mcp/config.json` and writes `.design-system-mcp/cache/index.json`.

```bash
node .design-system-mcp/bin/generate.js
```

Default config:

```json
{
  "indexPath": ".design-system-mcp/cache/index.json",
  "components": ["src/**/*.{ts,tsx}"],
  "icons": ["src/**/*Icon.{ts,tsx}"],
  "tokens": ["src/**/*tokens*.{ts,tsx,json,css}"],
  "docs": ["docs/**/*.{md,mdx}"]
}
```

Extraction policy:

- exported PascalCase functions/consts become component candidates
- local public props are expanded with `name`, `required`, `typeSummary`, `typeKind`, JSDoc description, defaults, and literal unions
- external/React/DOM inherited props are summarized, not expanded
- exported `*Icon` symbols become icons with generated keywords
- JSON/TS/CSS token sources are flattened into token paths
- CSS custom properties are kept as their real usable names, e.g. `--color-blue-100`
- `light`/`dark` token objects become `resolvedValueByTheme`
- local MD/MDX files are linked as `docsRef` when their filename matches a component name

## Index shape

The runtime index is intentionally small. Discovery tools should not return full docs, SVG bodies, Storybook DOM, or source files.

```ts
type DesignSystemIndex = {
  version: string;
  generatedAt: string;
  components: ComponentMetadata[];
  icons: IconMetadata[];
  tokens: TokenMetadata[];
};
```

Conceptual fields:

```text
ComponentMetadata
- name
- group
- description
- props[]
- inheritedProps
- subcomponents
- docsRef
- sourceRef
- packageName

PropMetadata
- name
- required
- typeSummary
- typeKind
- description
- defaultValue
- literals

IconMetadata
- name
- description
- keywords
- category

TokenMetadata
- name
- kind
- value
- description
- resolvedValueByTheme
```

## Development

```bash
npm install
npm run build
npm run test
npm run check
```

`npm run check` runs:

1. TypeScript build
2. Vitest tests
3. tool-name stability check

## Roadmap

- richer TypeScript edge cases for polymorphic/as-child components
- configurable inherited prop expansion
- remote/versioned docs fetch
- optional HTTP transport/auth/telemetry

## Clean-room boundary

This project is a clean-room implementation pattern. Do not copy private source code, generated JSON payloads from proprietary systems, complete component/icon lists from private docs, docs HTML/MDX bodies, internal endpoints, secrets, client ids, or tokens into this repository.

Maintenance

ActivityMaintained
ResponsivenessSyncing