@sdaia-ds/mcp 0.0.0-stage → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +291 -0
- package/dist/index.js.map +1 -0
- package/knowledge/actions/breadcrumb.md +50 -0
- package/knowledge/actions/button-menu.md +82 -0
- package/knowledge/actions/button-split.md +69 -0
- package/knowledge/actions/button.md +101 -0
- package/knowledge/actions/content-switcher.md +66 -0
- package/knowledge/actions/date-picker.md +115 -0
- package/knowledge/actions/floating-button.md +100 -0
- package/knowledge/actions/horizontal-tabs.md +52 -0
- package/knowledge/actions/link.md +76 -0
- package/knowledge/actions/modal.md +103 -0
- package/knowledge/actions/pagination.md +69 -0
- package/knowledge/actions/radio-button.md +88 -0
- package/knowledge/actions/switch.md +87 -0
- package/knowledge/actions/tag.md +69 -0
- package/knowledge/ai/agent-activity.md +65 -0
- package/knowledge/ai/agent-card.md +65 -0
- package/knowledge/ai/agent-handoff.md +65 -0
- package/knowledge/ai/ai-citation.md +78 -0
- package/knowledge/ai/ai-code-block.md +86 -0
- package/knowledge/ai/ai-disclaimer.md +84 -0
- package/knowledge/ai/ai-message-bubble.md +81 -0
- package/knowledge/ai/ai-message.md +118 -0
- package/knowledge/ai/ai-prompt-input.md +93 -0
- package/knowledge/ai/ai-states.md +107 -0
- package/knowledge/ai/ai-status-indicator.md +81 -0
- package/knowledge/ai/ai-suggested-prompts.md +62 -0
- package/knowledge/ai/ai-thinking-indicator.md +94 -0
- package/knowledge/ai/artifact-viewer.md +105 -0
- package/knowledge/ai/citation.md +61 -0
- package/knowledge/ai/context-manager.md +111 -0
- package/knowledge/ai/prompt-context.md +72 -0
- package/knowledge/ai/prompt-suggestion.md +68 -0
- package/knowledge/ai/prompt-template.md +71 -0
- package/knowledge/ai/prompt-variable.md +61 -0
- package/knowledge/ai/reasoning-trace.md +106 -0
- package/knowledge/ai/source-explorer.md +117 -0
- package/knowledge/ai/source-group.md +59 -0
- package/knowledge/ai/source-reference.md +70 -0
- package/knowledge/ai/thinking-panel.md +77 -0
- package/knowledge/ai/tool-activity-feed.md +67 -0
- package/knowledge/ai/tool-call-card.md +66 -0
- package/knowledge/ai/tool-status-row.md +72 -0
- package/knowledge/ai/tool-timeline-item.md +71 -0
- package/knowledge/ai/voice-session.md +93 -0
- package/knowledge/feedback/alert.md +106 -0
- package/knowledge/feedback/badge.md +86 -0
- package/knowledge/feedback/card.md +54 -0
- package/knowledge/feedback/feedback-overview.md +37 -0
- package/knowledge/feedback/feedback.md +46 -0
- package/knowledge/feedback/help-icon.md +57 -0
- package/knowledge/feedback/loading-indicator.md +76 -0
- package/knowledge/feedback/notification-banner.md +73 -0
- package/knowledge/feedback/notification-popup.md +87 -0
- package/knowledge/feedback/notifications.md +158 -0
- package/knowledge/feedback/progress-bar.md +69 -0
- package/knowledge/feedback/rating-overview.md +58 -0
- package/knowledge/feedback/rating.md +64 -0
- package/knowledge/feedback/skeleton-avatar.md +48 -0
- package/knowledge/feedback/skeleton.md +53 -0
- package/knowledge/feedback/toast.md +74 -0
- package/knowledge/feedback/tooltip.md +72 -0
- package/knowledge/form/autocomplete.md +100 -0
- package/knowledge/form/checkbox.md +95 -0
- package/knowledge/form/date-time-field.md +63 -0
- package/knowledge/form/error-summary.md +56 -0
- package/knowledge/form/field-group.md +57 -0
- package/knowledge/form/file-uploader.md +60 -0
- package/knowledge/form/form-section.md +58 -0
- package/knowledge/form/number-input.md +92 -0
- package/knowledge/form/otp-input.md +83 -0
- package/knowledge/form/password-input.md +49 -0
- package/knowledge/form/range-slider.md +71 -0
- package/knowledge/form/rich-text-editor.md +106 -0
- package/knowledge/form/select.md +113 -0
- package/knowledge/form/signature.md +83 -0
- package/knowledge/form/slider.md +66 -0
- package/knowledge/form/text-area.md +90 -0
- package/knowledge/form/text-input.md +132 -0
- package/knowledge/form/time-input.md +44 -0
- package/knowledge/form/time-picker.md +73 -0
- package/knowledge/foundations/accessibility.md +97 -0
- package/knowledge/foundations/colors.md +1113 -0
- package/knowledge/foundations/figma.md +30 -0
- package/knowledge/foundations/icon-usage.md +114 -0
- package/knowledge/foundations/icons.md +16 -0
- package/knowledge/foundations/motion.md +39 -0
- package/knowledge/foundations/radius.md +17 -0
- package/knowledge/foundations/responsive.md +64 -0
- package/knowledge/foundations/rtl.md +106 -0
- package/knowledge/foundations/spacing.md +27 -0
- package/knowledge/foundations/theme.md +115 -0
- package/knowledge/foundations/tokens.json +12080 -0
- package/knowledge/foundations/typography.md +45 -0
- package/knowledge/general/accordion.md +79 -0
- package/knowledge/general/activity.md +44 -0
- package/knowledge/general/app-shell.md +64 -0
- package/knowledge/general/area-chart.md +89 -0
- package/knowledge/general/audio-player.md +85 -0
- package/knowledge/general/avatar-group.md +50 -0
- package/knowledge/general/avatar.md +61 -0
- package/knowledge/general/carousel-image.md +103 -0
- package/knowledge/general/chart.md +25 -0
- package/knowledge/general/chip.md +90 -0
- package/knowledge/general/code-snippet.md +80 -0
- package/knowledge/general/column-chart.md +84 -0
- package/knowledge/general/context-menu.md +55 -0
- package/knowledge/general/digital-stamp.md +77 -0
- package/knowledge/general/divider.md +65 -0
- package/knowledge/general/donut-chart.md +75 -0
- package/knowledge/general/draggable-list.md +43 -0
- package/knowledge/general/dropdown.md +90 -0
- package/knowledge/general/empty-state.md +60 -0
- package/knowledge/general/filtration.md +85 -0
- package/knowledge/general/footer.md +59 -0
- package/knowledge/general/line-chart.md +95 -0
- package/knowledge/general/list.md +91 -0
- package/knowledge/general/media-gallery.md +85 -0
- package/knowledge/general/media-viewer.md +78 -0
- package/knowledge/general/menu.md +66 -0
- package/knowledge/general/metric.md +92 -0
- package/knowledge/general/nav-bar.md +62 -0
- package/knowledge/general/nav-header.md +125 -0
- package/knowledge/general/number.md +72 -0
- package/knowledge/general/page-template.md +80 -0
- package/knowledge/general/pdf-viewer.md +91 -0
- package/knowledge/general/pie-chart-panel.md +86 -0
- package/knowledge/general/popover.md +115 -0
- package/knowledge/general/progress-circle.md +63 -0
- package/knowledge/general/quote.md +64 -0
- package/knowledge/general/radial-stepper.md +72 -0
- package/knowledge/general/scatter-chart.md +62 -0
- package/knowledge/general/second-nav-header.md +55 -0
- package/knowledge/general/slideout-menu.md +92 -0
- package/knowledge/general/stepper.md +42 -0
- package/knowledge/general/structured-list.md +52 -0
- package/knowledge/general/table-bulk-actions-bar.md +66 -0
- package/knowledge/general/table-of-content.md +49 -0
- package/knowledge/general/table.md +113 -0
- package/knowledge/general/tree-view.md +55 -0
- package/knowledge/general/vertical-tabs.md +48 -0
- package/knowledge/general/video-player.md +88 -0
- package/knowledge/manifest.json +919 -0
- package/knowledge/patterns/buttons-with-sdaia-touch.md +34 -0
- package/knowledge/patterns/sdaia-logo-animation.md +35 -0
- package/knowledge/patterns/switch-with-sdaia-touch.md +29 -0
- package/knowledge/setup.md +125 -0
- package/package.json +45 -4
package/README.md
CHANGED
|
@@ -1,3 +1,213 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sdaia-ds/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Published from the `sdaia-dga` npm account, like `sdaia-ui` and `@sdaia-ds/tokens`.
|
|
4
|
+
|
|
5
|
+
MCP server for the [SDAIA Design System](https://ds.nacew.com) — gives AI coding agents (Claude Code, Claude Desktop, GitHub Copilot, Cursor, …) **accurate, source-derived** knowledge of the `sdaia-ui` components and `@sdaia-ds/tokens`.
|
|
6
|
+
|
|
7
|
+
Instead of hallucinating component APIs, the agent looks them up — and what it gets is parsed straight from the design system's own TypeScript source and token package, not guessed from a rendered web page.
|
|
8
|
+
|
|
9
|
+
**Transport:** stdio (works with any MCP-compatible client)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
The knowledge base is **generated from the authoritative sources the `sdaia-ui` CLI itself uses**:
|
|
16
|
+
|
|
17
|
+
- The **live registry** (`GET https://ds.nacew.com/api/registry`) → the exact set of installable components and their valid `npx sdaia-ui@latest add <slug>` ids.
|
|
18
|
+
- Each component's raw **`.types.ts` / `.variants.ts`** (served by the registry) → real props, allowed option values (variant/size/color/…), and the `--ds-*` tokens it uses, parsed with the TypeScript compiler.
|
|
19
|
+
- Each component's **`<Name>.tsx`** → the runtime default of every prop (the destructuring defaults), so docs show e.g. Modal `showTertiary` = `false`.
|
|
20
|
+
- The pinned **`@sdaia-ds/tokens`** npm package (2.0.1, the version `sdaia-ui` pins) → every design token with its CSS variable and light/dark value.
|
|
21
|
+
- The design system's accessibility test suite → the per-component "Accessibility" section lists only behaviour a keyboard spec or the axe scan verifies (`scripts/lib/a11yNotes.ts`).
|
|
22
|
+
|
|
23
|
+
No HTML scraping, no heuristics. Every fact a tool returns is traceable to source, so `npx sdaia-ui@latest add <slug>` commands always work and prop/variant APIs are always correct.
|
|
24
|
+
|
|
25
|
+
> **Hard rule the tools enforce for generated projects:** `sdaia-ui` is a source-copying CLI, **not** a runtime package. Agents are told to **never** run `npm install sdaia-ui` and **never** `import … from 'sdaia-ui'` — only `npx sdaia-ui@latest init` (once) + `npx sdaia-ui@latest add <slug>`, then import from `@/components/ui/<Name>` — the same flow as the docs site's Installation guide (Next.js App Router or Pages Router, Vite + React).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Tools
|
|
30
|
+
|
|
31
|
+
| Tool | Description |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `setup_project` | Step-by-step setup for using `sdaia-ui` in a React project (CLI init, Tailwind v4 + tokens, `.theme-dark` bridge, icons). Call first when scaffolding. |
|
|
34
|
+
| `list_components` | All installable components grouped by category (`general`, `actions`, `form`, `feedback`, `patterns`, `ai`), each with its exact install command. |
|
|
35
|
+
| `search_components` | Find a component slug by keyword (name or slug). |
|
|
36
|
+
| `get_component_docs` | Accurate docs for one component: real props, allowed option values, accessibility, the tokens it uses, and AI usage guidance. |
|
|
37
|
+
| `get_foundations` | Foundation guidance by topic: `colors`, `spacing`, `radius`, `icons`, `icon-usage`, `motion`, `typography`, `theme` (dark mode + the six brands), `responsive`, `rtl`, `figma`, `accessibility`. |
|
|
38
|
+
| `get_tokens` | Structured design tokens with CSS variable + light/dark values. Filter by `category` (`colors`, `palette`, `spacing`, `radius`, `typography`, `icons`, `motion`, `all`) and optional `query`. |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
- Node.js >= 18
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Add it to your AI client
|
|
49
|
+
|
|
50
|
+
### Claude Code (CLI)
|
|
51
|
+
|
|
52
|
+
After publishing (uses `npx`):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# available in the current project (writes .mcp.json)
|
|
56
|
+
claude mcp add sdaia-ds -s project -- npx -y @sdaia-ds/mcp
|
|
57
|
+
|
|
58
|
+
# or available in every project
|
|
59
|
+
claude mcp add sdaia-ds -s user -- npx -y @sdaia-ds/mcp
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Running from a local clone (not published yet):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
claude mcp add sdaia-ds -s project -- node <path-to-your-clone>/dist/index.js
|
|
66
|
+
# (run `npm install && npm run build` in the clone first)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Verify with `claude mcp list`, then in a session: `/mcp`.
|
|
70
|
+
|
|
71
|
+
### Claude Desktop
|
|
72
|
+
|
|
73
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"sdaia-ds": {
|
|
79
|
+
"command": "npx",
|
|
80
|
+
"args": ["-y", "@sdaia-ds/mcp"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Local clone instead of npx:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"sdaia-ds": {
|
|
92
|
+
"command": "node",
|
|
93
|
+
"args": ["<path-to-your-clone>/dist/index.js"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### VS Code (GitHub Copilot agent mode)
|
|
100
|
+
|
|
101
|
+
`.vscode/mcp.json` in your workspace:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"servers": {
|
|
106
|
+
"sdaia-ds": {
|
|
107
|
+
"type": "stdio",
|
|
108
|
+
"command": "npx",
|
|
109
|
+
"args": ["-y", "@sdaia-ds/mcp"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Cursor
|
|
116
|
+
|
|
117
|
+
`.cursor/mcp.json`:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"mcpServers": {
|
|
122
|
+
"sdaia-ds": { "command": "npx", "args": ["-y", "@sdaia-ds/mcp"] }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Restart the client after editing config.
|
|
128
|
+
|
|
129
|
+
### Example prompts
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Use the sdaia-ds tools to scaffold a React page with a NavBar and a DataTable.
|
|
133
|
+
What are the allowed variants and sizes for the Button component?
|
|
134
|
+
Give me the SDAIA color tokens and their dark-mode values.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
git clone https://github.com/Ewwwolution-L-L-C/sdaia_mcp.git
|
|
143
|
+
cd sdaia_mcp
|
|
144
|
+
npm install
|
|
145
|
+
npm test # starts the server over stdio and calls every tool; lints knowledge/
|
|
146
|
+
npm start # runs the server via tsx (no build) → "… running on stdio"
|
|
147
|
+
npm run build # compiles index.ts → dist/
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The committed [`.vscode/mcp.json`](.vscode/mcp.json) (VS Code) and [`.mcp.json`](.mcp.json) (Claude Code) run the local `index.ts` with `tsx` from the repo root — no machine-specific paths — so opening this repo wires up the server automatically.
|
|
151
|
+
|
|
152
|
+
### Regenerate the knowledge base
|
|
153
|
+
|
|
154
|
+
`knowledge/` is generated. To rebuild it from the live registry + tokens package:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npm run generate
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This fetches the registry, parses each top-level component's source, parses `@sdaia-ds/tokens`, and writes `knowledge/<category>/<slug>.md`, `knowledge/manifest.json`, and `knowledge/foundations/*`. It **fails loudly** if any configured slug is no longer a valid registry slug, so broken install commands can never ship.
|
|
161
|
+
|
|
162
|
+
To generate from a design-system-platform checkout instead of the live site (same content once master is deployed, and no requests to production):
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# in design-system-platform
|
|
166
|
+
REGISTRY_OUT_DIR=/tmp/sdaia-registry node scripts/build-registry.mjs
|
|
167
|
+
node --input-type=module -e "import { startRegistryServer } from './scripts/ci/serve-registry.mjs'; await startRegistryServer({ port: 4874, dir: '/tmp/sdaia-registry' })"
|
|
168
|
+
# in sdaia_mcp
|
|
169
|
+
SDAIA_REGISTRY_URL=http://127.0.0.1:4874/api/registry npm run generate
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Environment overrides:
|
|
173
|
+
|
|
174
|
+
| Var | Default | Purpose |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| `SDAIA_REGISTRY_URL` | `https://ds.nacew.com/api/registry` | Registry manifest + raw source |
|
|
177
|
+
| `SDAIA_DOCS_URL` | `https://ds.nacew.com` | Docs base for source links |
|
|
178
|
+
|
|
179
|
+
The set of components covered is curated in [`components.config.ts`](components.config.ts): one entry per component page in the docs sidebar (registry slug, docs page name when it differs, category). To add one, add it there and re-run `npm run generate`. Docs of components that leave the list are deleted by the generator.
|
|
180
|
+
|
|
181
|
+
Hand-written guides (`knowledge/setup.md`, `knowledge/foundations/{typography,theme,responsive,rtl,figma,accessibility,icon-usage}.md` and the two AI pattern docs) follow the docs site pages of the same name; update them when those pages change.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## How it's wired
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
components.config.ts ──┐
|
|
189
|
+
├─► scripts/generate.ts ─► knowledge/** (committed, shipped)
|
|
190
|
+
live /api/registry ───┤ │
|
|
191
|
+
@sdaia-ds/tokens (npm) ─┘ └─ parsers: scripts/lib/{parseTypes,tokens,renderDoc}.ts
|
|
192
|
+
|
|
193
|
+
index.ts (MCP server) ─► reads knowledge/** at runtime ─► 6 stdio tools
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Publishing
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
npm run generate # refresh knowledge from source
|
|
202
|
+
npm test # must pass
|
|
203
|
+
npm run build # prepublishOnly also runs this
|
|
204
|
+
npm publish --access public
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The published package ships `dist/` + `knowledge/` (see `files` in package.json).
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
ISC
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
9
|
+
const CATEGORY_ORDER = ["general", "actions", "form", "feedback", "patterns", "ai"];
|
|
10
|
+
// Display labels for categories where naive capitalization is wrong (e.g. "Ai" → "AI").
|
|
11
|
+
const CATEGORY_LABELS = {
|
|
12
|
+
general: "General",
|
|
13
|
+
actions: "Actions",
|
|
14
|
+
form: "Form",
|
|
15
|
+
feedback: "Feedback",
|
|
16
|
+
patterns: "Patterns",
|
|
17
|
+
ai: "AI",
|
|
18
|
+
};
|
|
19
|
+
const FOUNDATION_TOPICS = [
|
|
20
|
+
"typography", "colors", "spacing", "radius", "icons", "icon-usage", "motion", "theme", "responsive", "rtl", "figma", "accessibility",
|
|
21
|
+
];
|
|
22
|
+
const TOKEN_CATEGORIES = ["colors", "palette", "spacing", "radius", "typography", "icons", "motion", "all"];
|
|
23
|
+
// Resolve the knowledge dir for both dev (`tsx index.ts` → __dirname = repo
|
|
24
|
+
// root) and prod (`node dist/index.js` → __dirname = dist/). The package ships
|
|
25
|
+
// `knowledge/` at the root (see package.json "files"), so prod falls back to
|
|
26
|
+
// `../knowledge`.
|
|
27
|
+
function resolveKnowledgeDir() {
|
|
28
|
+
const candidates = [join(__dirname, "knowledge"), join(__dirname, "..", "knowledge")];
|
|
29
|
+
for (const dir of candidates) {
|
|
30
|
+
if (existsSync(join(dir, "manifest.json")))
|
|
31
|
+
return dir;
|
|
32
|
+
}
|
|
33
|
+
return candidates[0];
|
|
34
|
+
}
|
|
35
|
+
const KNOWLEDGE_DIR = resolveKnowledgeDir();
|
|
36
|
+
const manifest = JSON.parse(readFileSync(join(KNOWLEDGE_DIR, "manifest.json"), "utf-8"));
|
|
37
|
+
function loadKnowledge(relativePath) {
|
|
38
|
+
const fullPath = join(KNOWLEDGE_DIR, relativePath);
|
|
39
|
+
if (!existsSync(fullPath))
|
|
40
|
+
return null;
|
|
41
|
+
try {
|
|
42
|
+
return readFileSync(fullPath, "utf-8");
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function loadTokens() {
|
|
49
|
+
const raw = loadKnowledge("foundations/tokens.json");
|
|
50
|
+
return raw ? JSON.parse(raw) : [];
|
|
51
|
+
}
|
|
52
|
+
const server = new Server({ name: "sdaia-design-system-mcp", version: "3.1.0" }, { capabilities: { tools: {} } });
|
|
53
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
54
|
+
tools: [
|
|
55
|
+
{
|
|
56
|
+
name: "setup_project",
|
|
57
|
+
description: "Returns the step-by-step setup for using the SDAIA Design System (`sdaia-ui`) in a Next.js (App Router or Pages Router) or Vite + React project, matching the docs site's Installation guide: " +
|
|
58
|
+
"what `npx sdaia-ui@latest init` sets up (Tailwind v4, tokens, IBM Plex Sans Arabic, dark-mode variant, `@/` alias), adding and importing components (`@/components/ui/<Name>`), Arabic / dark mode / brands on `<html>`, icons (DgaIcon + `@platformscode/icons`), and keeping components up to date with `diff` / `update`. " +
|
|
59
|
+
"HARD RULE: `sdaia-ui` is a source-copying CLI — NEVER `npm install sdaia-ui` and NEVER import from it; run `npx sdaia-ui@latest init` then `npx sdaia-ui@latest add <slug>`. " +
|
|
60
|
+
"ALWAYS call this before get_component_docs when scaffolding a new project or installing components for the first time.",
|
|
61
|
+
inputSchema: { type: "object", properties: {}, required: [] },
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "list_components",
|
|
65
|
+
description: "Lists all installable SDAIA components by category (general, actions, form, feedback, patterns, ai), each with its exact " +
|
|
66
|
+
"`npx sdaia-ui@latest add <slug>` command. Every slug is validated against the live CLI registry, so install commands are guaranteed valid. " +
|
|
67
|
+
"Call this first to discover component slugs before get_component_docs.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties: {
|
|
71
|
+
category: {
|
|
72
|
+
type: "string",
|
|
73
|
+
enum: ["all", ...CATEGORY_ORDER],
|
|
74
|
+
description: "Filter by docs category. Omit or pass 'all' for the complete list.",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
required: [],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "search_components",
|
|
82
|
+
description: "Find component slugs by keyword (matches name or slug). Use when you know what a component does but not its exact slug.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: { query: { type: "string", description: "Keyword, e.g. 'date', 'upload', 'nav'." } },
|
|
86
|
+
required: ["query"],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "get_component_docs",
|
|
91
|
+
description: "Returns accurate, source-derived docs for one SDAIA component: real props (parsed from the component's TypeScript), allowed option " +
|
|
92
|
+
"values (variant/size/color/etc.), accessibility notes, the design tokens it uses, and AI usage guidance. " +
|
|
93
|
+
"Install via `npx sdaia-ui@latest add <slug>` — NEVER `npm install sdaia-ui` or import from it (it is a source-copying CLI). Use list_components / search_components to find the slug. " +
|
|
94
|
+
"Icons are NOT a component — do not pass 'icon'/'icons'; call setup_project for icon usage.",
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {
|
|
98
|
+
componentId: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "Component slug, e.g. 'button', 'text-input', 'card', 'nav-bar', or an AI component like 'ai-message', 'tool-call-card', 'reasoning-trace'.",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
required: ["componentId"],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "get_foundations",
|
|
108
|
+
description: "Returns SDAIA foundation guidance by topic. Token topics (colors, spacing, radius, icons, motion) are generated from " +
|
|
109
|
+
"`@sdaia-ds/tokens` with light + dark values; typography/theme (dark mode + the six brands)/responsive (breakpoints 768 / 1280)/icon-usage/rtl/figma/accessibility are authored guides that follow the docs site. " +
|
|
110
|
+
"Call `icon-usage` before any UI with icons (DgaIcon + @platformscode/icons — never emoji or invented icons). For exact token lookups use get_tokens.",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {
|
|
114
|
+
topic: { type: "string", enum: [...FOUNDATION_TOPICS], description: "Foundation topic to fetch." },
|
|
115
|
+
},
|
|
116
|
+
required: ["topic"],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "get_tokens",
|
|
121
|
+
description: "Returns structured SDAIA design tokens with their CSS variable and light + dark values, so you never hardcode or invent colors. " +
|
|
122
|
+
"Filter by category and optionally a keyword. Use these `--ds-*` tokens (via Tailwind utilities or var()) for any custom layout around DS components.",
|
|
123
|
+
inputSchema: {
|
|
124
|
+
type: "object",
|
|
125
|
+
properties: {
|
|
126
|
+
category: {
|
|
127
|
+
type: "string",
|
|
128
|
+
enum: [...TOKEN_CATEGORIES],
|
|
129
|
+
description: "colors = semantic color tokens; palette = raw color primitives; or spacing | radius | typography | icons | motion | all.",
|
|
130
|
+
},
|
|
131
|
+
query: { type: "string", description: "Optional substring filter on token key, CSS var, or description." },
|
|
132
|
+
},
|
|
133
|
+
required: ["category"],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
}));
|
|
138
|
+
function listComponents(category) {
|
|
139
|
+
const tiers = category === "all" ? CATEGORY_ORDER : [category];
|
|
140
|
+
let out = "# SDAIA Design System — Component Library\n\n";
|
|
141
|
+
for (const tier of tiers) {
|
|
142
|
+
const components = Object.values(manifest)
|
|
143
|
+
.filter((e) => e.category === tier)
|
|
144
|
+
.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
145
|
+
if (!components.length)
|
|
146
|
+
continue;
|
|
147
|
+
const label = CATEGORY_LABELS[tier] ?? tier.charAt(0).toUpperCase() + tier.slice(1);
|
|
148
|
+
out += `## ${label} (${components.length})\n\n`;
|
|
149
|
+
out += "| Component | Slug | Install command |\n|---|---|---|\n";
|
|
150
|
+
for (const e of components)
|
|
151
|
+
out += `| ${e.name} | \`${e.slug}\` | \`${e.install}\` |\n`;
|
|
152
|
+
out += "\n";
|
|
153
|
+
}
|
|
154
|
+
out += "> Install with `npx sdaia-ui@latest add <slug>` (after `npx sdaia-ui@latest init`). NEVER `npm install sdaia-ui` or import from it — it is a source-copying CLI.\n";
|
|
155
|
+
out += "> Use `get_component_docs` with a slug for full props + options.\n";
|
|
156
|
+
out += "> Use `get_foundations` / `get_tokens` for theming, tokens, RTL, and accessibility.";
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
function searchComponents(query) {
|
|
160
|
+
const q = query.toLowerCase();
|
|
161
|
+
const hits = Object.values(manifest)
|
|
162
|
+
.filter((e) => e.slug.includes(q) || e.name.toLowerCase().includes(q))
|
|
163
|
+
.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
164
|
+
if (!hits.length)
|
|
165
|
+
return `No components match "${query}". Try list_components to browse all.`;
|
|
166
|
+
let out = `# Components matching "${query}"\n\n| Component | Slug | Install command |\n|---|---|---|\n`;
|
|
167
|
+
for (const e of hits)
|
|
168
|
+
out += `| ${e.name} | \`${e.slug}\` | \`${e.install}\` |\n`;
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
const TOKEN_CATEGORY_MAP = {
|
|
172
|
+
colors: ["Colors"],
|
|
173
|
+
palette: ["Primitives"],
|
|
174
|
+
spacing: ["Spacing"],
|
|
175
|
+
radius: ["Radius"],
|
|
176
|
+
typography: ["Typography"],
|
|
177
|
+
icons: ["Icons"],
|
|
178
|
+
motion: ["Motion"],
|
|
179
|
+
};
|
|
180
|
+
const MAX_TOKEN_ROWS = 250;
|
|
181
|
+
function getTokens(category, query) {
|
|
182
|
+
const all = loadTokens();
|
|
183
|
+
if (!all.length)
|
|
184
|
+
return "Token data not found. Run `npm run generate` to build it.";
|
|
185
|
+
const cats = category === "all" ? null : TOKEN_CATEGORY_MAP[category];
|
|
186
|
+
const q = query?.toLowerCase();
|
|
187
|
+
let rows = all.filter((t) => (!cats || cats.includes(t.category)));
|
|
188
|
+
if (q)
|
|
189
|
+
rows = rows.filter((t) => t.key.toLowerCase().includes(q) || t.cssVar.toLowerCase().includes(q) || t.description.toLowerCase().includes(q));
|
|
190
|
+
if (!rows.length)
|
|
191
|
+
return `No tokens match category="${category}"${query ? ` query="${query}"` : ""}.`;
|
|
192
|
+
const truncated = rows.length > MAX_TOKEN_ROWS;
|
|
193
|
+
const shown = rows.slice(0, MAX_TOKEN_ROWS);
|
|
194
|
+
const byGroup = new Map();
|
|
195
|
+
for (const t of shown) {
|
|
196
|
+
if (!byGroup.has(t.group))
|
|
197
|
+
byGroup.set(t.group, []);
|
|
198
|
+
byGroup.get(t.group).push(t);
|
|
199
|
+
}
|
|
200
|
+
let out = `# SDAIA Tokens — ${category}${query ? ` (filter: "${query}")` : ""}\n\n`;
|
|
201
|
+
out += "> Apply via Tailwind utilities (e.g. `bg-[var(--ds-color-bg-default)]`, `p-spacing-md`) or `var(--ds-…)`. Dark values switch automatically under `.theme-dark`.\n";
|
|
202
|
+
out += "> **Brand:** `sdaia-dga` is the default (no class). Other brands are a class on `<html>`: `brand-spectrum`, `brand-canvas`, `brand-dessert`, `brand-dune`, `brand-carbon` (see `get_foundations` topic `theme`). Prefer semantic `brand-*` / `color-*` tokens — they resolve per brand + theme. Never hardcode a palette hex.\n";
|
|
203
|
+
out += "> **Values** are the `@sdaia-ds/tokens` defaults (sdaia-dga). The core CSS that `sdaia-ui init` installs corrects a few of them for contrast, and brands override others — so write `var(--ds-…)`, never the literal value.\n\n";
|
|
204
|
+
for (const [group, list] of byGroup) {
|
|
205
|
+
out += `## ${group}\n\n| Token | CSS variable | Light | Dark |\n|---|---|---|---|\n`;
|
|
206
|
+
for (const t of list) {
|
|
207
|
+
out += `| \`${t.key}\` | \`var(${t.cssVar})\` | \`${t.lightValue}\` | ${t.hasDarkVariant ? `\`${t.darkValue}\`` : "—"} |\n`;
|
|
208
|
+
}
|
|
209
|
+
out += "\n";
|
|
210
|
+
}
|
|
211
|
+
if (truncated)
|
|
212
|
+
out += `> Showing ${MAX_TOKEN_ROWS} of ${rows.length}. Narrow with a \`query\`.\n`;
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
216
|
+
const { name, arguments: args = {} } = request.params;
|
|
217
|
+
if (name === "setup_project") {
|
|
218
|
+
const content = loadKnowledge("setup.md");
|
|
219
|
+
return { content: [{ type: "text", text: content ?? "Setup guide not found. Run `npm run generate`." }] };
|
|
220
|
+
}
|
|
221
|
+
if (name === "list_components") {
|
|
222
|
+
const { category = "all" } = args;
|
|
223
|
+
return { content: [{ type: "text", text: listComponents(category) }] };
|
|
224
|
+
}
|
|
225
|
+
if (name === "search_components") {
|
|
226
|
+
const { query } = args;
|
|
227
|
+
return { content: [{ type: "text", text: searchComponents(query ?? "") }] };
|
|
228
|
+
}
|
|
229
|
+
if (name === "get_foundations") {
|
|
230
|
+
const { topic } = args;
|
|
231
|
+
const local = loadKnowledge(`foundations/${topic}.md`);
|
|
232
|
+
if (local)
|
|
233
|
+
return { content: [{ type: "text", text: local }] };
|
|
234
|
+
return {
|
|
235
|
+
content: [{ type: "text", text: `Unknown or missing topic '${topic}'. Valid: ${FOUNDATION_TOPICS.join(", ")}. Run \`npm run generate\` if a token topic is missing.` }],
|
|
236
|
+
isError: true,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (name === "get_tokens") {
|
|
240
|
+
const { category, query } = args;
|
|
241
|
+
return { content: [{ type: "text", text: getTokens(category, query) }] };
|
|
242
|
+
}
|
|
243
|
+
if (name === "get_component_docs") {
|
|
244
|
+
const { componentId } = args;
|
|
245
|
+
// "icon" / "icons" → the icon section of setup.md (Step 6).
|
|
246
|
+
if (componentId === "icon" || componentId === "icons") {
|
|
247
|
+
const setup = loadKnowledge("setup.md");
|
|
248
|
+
const idx = setup?.indexOf("## Step 6") ?? -1;
|
|
249
|
+
const iconDocs = setup && idx !== -1 ? setup.slice(idx) : setup;
|
|
250
|
+
return {
|
|
251
|
+
content: [{
|
|
252
|
+
type: "text",
|
|
253
|
+
text: "# Icons — @platformscode/icons + DgaIcon\n\n" +
|
|
254
|
+
"> `DgaIcon` comes with any component that uses icons, or on its own with `npx sdaia-ui@latest add dga-icon` (it lives at `@/components/ui/DgaIcon`); " +
|
|
255
|
+
"icon data comes from `@platformscode/icons`, installed by `npx sdaia-ui@latest init`. Use two imports:\n" +
|
|
256
|
+
"> ```tsx\n" +
|
|
257
|
+
"> import { DgaIcon } from '@/components/ui/DgaIcon';\n" +
|
|
258
|
+
"> import { search01Stroke } from '@platformscode/icons';\n" +
|
|
259
|
+
"> // <span className=\"size-icon-sm\"><DgaIcon data={search01Stroke} /></span>\n" +
|
|
260
|
+
"> ```\n\n" +
|
|
261
|
+
(iconDocs ?? "Run `npm run generate` to restore setup docs."),
|
|
262
|
+
}],
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const entry = manifest[componentId];
|
|
266
|
+
if (!entry) {
|
|
267
|
+
return {
|
|
268
|
+
content: [{ type: "text", text: `Unknown component '${componentId}'. Use list_components or search_components to find a valid slug.` }],
|
|
269
|
+
isError: true,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const local = loadKnowledge(`${entry.category}/${componentId}.md`);
|
|
273
|
+
if (local)
|
|
274
|
+
return { content: [{ type: "text", text: local }] };
|
|
275
|
+
return {
|
|
276
|
+
content: [{ type: "text", text: `Docs for '${componentId}' are missing. Run \`npm run generate\`.` }],
|
|
277
|
+
isError: true,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
281
|
+
});
|
|
282
|
+
const transport = new StdioServerTransport();
|
|
283
|
+
await server.connect(transport);
|
|
284
|
+
console.error("SDAIA Design System MCP Server v3.1.0 running on stdio");
|
|
285
|
+
// Self-terminate when the parent (generate.py) goes away. The MCP SDK's stdio transport
|
|
286
|
+
// does NOT watch for stdin EOF, so without this an orphaned server keeps its event loop
|
|
287
|
+
// alive forever (the leak we saw when the studio's Stop button kills the parent). When the
|
|
288
|
+
// parent dies, our stdin pipe closes — exit immediately.
|
|
289
|
+
process.stdin.on("end", () => process.exit(0));
|
|
290
|
+
process.stdin.on("close", () => process.exit(0));
|
|
291
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
- Component: Breadcrumb
|
|
5
|
+
- Slug: `breadcrumb`
|
|
6
|
+
- Category: Actions
|
|
7
|
+
- Install: `npx sdaia-ui@latest add breadcrumb`
|
|
8
|
+
- Import: `import { Breadcrumb } from '@/components/ui/Breadcrumb'`
|
|
9
|
+
- Installed files: `Breadcrumb.tsx`, `Breadcrumb.types.ts`, `Breadcrumb.variants.ts`, `BreadcrumbItem.tsx`, `BreadcrumbItem.types.ts`, `BreadcrumbItem.variants.ts`, `index.ts`
|
|
10
|
+
- Docs: https://ds.nacew.com/components/breadcrumb
|
|
11
|
+
|
|
12
|
+
> **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add breadcrumb`. It copies the source into your components folder (`components/ui/Breadcrumb/`, under `src/` when the project has one); import it as `@/components/ui/Breadcrumb`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
|
|
13
|
+
|
|
14
|
+
## Props
|
|
15
|
+
| Prop | Type | Default | Description |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| `items` | `BreadcrumbItem[]` | — | Breadcrumb trail. The first item is the home link (icon + label); remaining items render after the home slot. The last item is the current page (`aria-current="page"`). |
|
|
18
|
+
| `homeLabel?` | `string` | — | Home label — takes precedence over `items[0].label` and `labels.home`. |
|
|
19
|
+
| `divider?` | `'chevron' \| 'slash'` | 'chevron' | Divider style between items |
|
|
20
|
+
| `homeIcon?` | `ReactNode` | — | Custom home icon |
|
|
21
|
+
| `homeDisplay?` | `'icon-and-text' \| 'icon'` | 'icon-and-text' | How the home item shows: the icon with its label (default), or the icon alone (Figma Breadcrumb, LTR: `_Breadcrumb Item` Type=Icon), with the label kept for assistive tech. |
|
|
22
|
+
| `chevronIcon?` | `ReactNode` | — | Custom chevron icon (used when divider="chevron"). Mirrored in RTL. |
|
|
23
|
+
| `labels?` | `Partial<BreadcrumbLabels>` | — | Translatable built-in strings. |
|
|
24
|
+
| `dir?` | `'ltr' \| 'rtl'` | — | Layout direction applied to the root. Inherits when omitted. |
|
|
25
|
+
|
|
26
|
+
Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …).
|
|
27
|
+
|
|
28
|
+
## Options (allowed values)
|
|
29
|
+
- `divider`: `'chevron'` \| `'slash'` — Divider style between items
|
|
30
|
+
- `homeDisplay`: `'icon-and-text'` \| `'icon'` — Home item display: icon + label, or the icon alone (label for assistive tech).
|
|
31
|
+
- `dir`: `'ltr'` \| `'rtl'` — Layout direction applied to the root. Inherits when omitted.
|
|
32
|
+
|
|
33
|
+
## Accessibility
|
|
34
|
+
- Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
|
|
35
|
+
- Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
|
|
36
|
+
- For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
|
|
37
|
+
|
|
38
|
+
## Design tokens used
|
|
39
|
+
Keep these consistent (resolve values with `get_tokens`):
|
|
40
|
+
- `var(--ds-color-icon-default-400)`
|
|
41
|
+
- `var(--ds-spacing-xs)`
|
|
42
|
+
- `var(--ds-text-leading-line-heights-text-sm)`
|
|
43
|
+
|
|
44
|
+
## AI usage guidance
|
|
45
|
+
When generating UI:
|
|
46
|
+
- Install with `npx sdaia-ui@latest add breadcrumb` (after `npx sdaia-ui@latest init`), then import `{ Breadcrumb }` from `@/components/ui/Breadcrumb`.
|
|
47
|
+
- NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
|
|
48
|
+
- Use only the documented option values listed under "Options".
|
|
49
|
+
- Pass icons via `<DgaIcon data={…} className="size-icon-sm" />` from `@platformscode/icons` only — see `get_foundations` (`icon-usage`). Never emoji, Lucide, or random icons (e.g. `pizza01Stroke` for dark mode).
|
|
50
|
+
- Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
|