design-system-mcp
by lodado
README.md
# design-system-mcp
[](./LICENSE)
[](https://nodejs.org/)
[](https://www.typescriptlang.org/)
[](https://modelcontextprotocol.io/)
[](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.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing