@ncds/ui-admin-mcp 1.0.0-alpha.10
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 +113 -0
- package/bin/components.bundle.js +1 -0
- package/bin/definitions/compliance-rules.json +64 -0
- package/bin/definitions/instructions.md +164 -0
- package/bin/definitions/js-api.json +165 -0
- package/bin/definitions/rules.json +59 -0
- package/bin/definitions/token-descriptions.json +27 -0
- package/bin/definitions/tool-definitions.json +58 -0
- package/bin/server.d.ts +1 -0
- package/bin/server.js +217 -0
- package/bin/server.mjs +8 -0
- package/bin/tools/getComponentProps.d.ts +4 -0
- package/bin/tools/getComponentProps.js +20 -0
- package/bin/tools/getDesignTokens.d.ts +13 -0
- package/bin/tools/getDesignTokens.js +20 -0
- package/bin/tools/listComponents.d.ts +16 -0
- package/bin/tools/listComponents.js +24 -0
- package/bin/tools/listIcons.d.ts +22 -0
- package/bin/tools/listIcons.js +23 -0
- package/bin/tools/ping.d.ts +17 -0
- package/bin/tools/ping.js +20 -0
- package/bin/tools/renderToHtml.d.ts +23 -0
- package/bin/tools/renderToHtml.js +267 -0
- package/bin/tools/searchComponent.d.ts +4 -0
- package/bin/tools/searchComponent.js +33 -0
- package/bin/tools/searchIcon.d.ts +7 -0
- package/bin/tools/searchIcon.js +19 -0
- package/bin/tools/validateHtml.d.ts +18 -0
- package/bin/tools/validateHtml.js +85 -0
- package/bin/types.d.ts +123 -0
- package/bin/types.js +5 -0
- package/bin/utils/bemValidator.d.ts +36 -0
- package/bin/utils/bemValidator.js +198 -0
- package/bin/utils/compliance.d.ts +52 -0
- package/bin/utils/compliance.js +199 -0
- package/bin/utils/dataLoader.d.ts +35 -0
- package/bin/utils/dataLoader.js +192 -0
- package/bin/utils/domEnvironment.d.ts +9 -0
- package/bin/utils/domEnvironment.js +75 -0
- package/bin/utils/fuzzyMatch.d.ts +21 -0
- package/bin/utils/fuzzyMatch.js +110 -0
- package/bin/utils/logger.d.ts +18 -0
- package/bin/utils/logger.js +27 -0
- package/bin/utils/response.d.ts +28 -0
- package/bin/utils/response.js +39 -0
- package/bin/utils/tokenValidator.d.ts +24 -0
- package/bin/utils/tokenValidator.js +162 -0
- package/bin/version.d.ts +4 -0
- package/bin/version.js +7 -0
- package/data/_icons.json +12401 -0
- package/data/_meta.json +12 -0
- package/data/_tokens.json +661 -0
- package/data/badge-group.json +295 -0
- package/data/badge.json +246 -0
- package/data/bread-crumb.json +87 -0
- package/data/button-group.json +94 -0
- package/data/button.json +259 -0
- package/data/carousel-arrow.json +87 -0
- package/data/carousel-number-group.json +87 -0
- package/data/checkbox.json +99 -0
- package/data/combo-box.json +173 -0
- package/data/date-picker.json +123 -0
- package/data/divider.json +91 -0
- package/data/dot.json +103 -0
- package/data/dropdown.json +258 -0
- package/data/empty-state.json +227 -0
- package/data/featured-icon.json +139 -0
- package/data/file-input.json +315 -0
- package/data/horizontal-tab.json +329 -0
- package/data/image-file-input.json +339 -0
- package/data/input-base.json +299 -0
- package/data/modal.json +143 -0
- package/data/notification.json +194 -0
- package/data/number-input.json +295 -0
- package/data/pagination.json +101 -0
- package/data/password-input.json +263 -0
- package/data/progress-bar.json +109 -0
- package/data/progress-circle.json +96 -0
- package/data/radio.json +86 -0
- package/data/range-date-picker-with-buttons.json +273 -0
- package/data/range-date-picker.json +259 -0
- package/data/select-box.json +193 -0
- package/data/select.json +132 -0
- package/data/slider.json +100 -0
- package/data/spinner.json +93 -0
- package/data/switch.json +156 -0
- package/data/tag.json +159 -0
- package/data/textarea.json +96 -0
- package/data/toggle.json +102 -0
- package/data/tooltip.json +185 -0
- package/data/vertical-tab.json +314 -0
- package/package.json +61 -0
- package/templates/.mcp.json.example +8 -0
- package/templates/README.md +30 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"patterns": [
|
|
3
|
+
{
|
|
4
|
+
"match": { "tag": "button" },
|
|
5
|
+
"ncuaComponent": "button",
|
|
6
|
+
"confidence": "high"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"match": { "tag": "input", "hints": [{ "attr": "type", "values": ["text", "search", "email", "url", "tel"] }] },
|
|
10
|
+
"ncuaComponent": "input-base",
|
|
11
|
+
"confidence": "high"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"match": { "tag": "input", "hints": [{ "attr": "type", "values": ["checkbox"] }] },
|
|
15
|
+
"ncuaComponent": "checkbox",
|
|
16
|
+
"confidence": "high"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"match": { "tag": "input", "hints": [{ "attr": "type", "values": ["radio"] }] },
|
|
20
|
+
"ncuaComponent": "radio",
|
|
21
|
+
"confidence": "high"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"match": { "tag": "input", "hints": [{ "attr": "type", "values": ["range"] }] },
|
|
25
|
+
"ncuaComponent": "slider",
|
|
26
|
+
"confidence": "high"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"match": { "tag": "textarea" },
|
|
30
|
+
"ncuaComponent": "textarea",
|
|
31
|
+
"confidence": "high"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"match": { "tag": "select" },
|
|
35
|
+
"ncuaComponent": "select",
|
|
36
|
+
"confidence": "high"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"match": { "tag": "dialog" },
|
|
40
|
+
"ncuaComponent": "modal",
|
|
41
|
+
"confidence": "high"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"match": { "tag": "progress" },
|
|
45
|
+
"ncuaComponent": "progress-bar",
|
|
46
|
+
"confidence": "high"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"match": { "tag": "nav", "hints": [{ "attr": "aria-label", "values": ["breadcrumb"] }] },
|
|
50
|
+
"ncuaComponent": "bread-crumb",
|
|
51
|
+
"confidence": "high"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"match": { "tag": "nav", "hints": [{ "attr": "aria-label", "values": ["pagination"] }] },
|
|
55
|
+
"ncuaComponent": "pagination",
|
|
56
|
+
"confidence": "medium"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"match": { "tag": "table" },
|
|
60
|
+
"ncuaComponent": "table",
|
|
61
|
+
"confidence": "medium"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# NCUA MCP Server — Required Workflow
|
|
2
|
+
|
|
3
|
+
You are an agent that builds UI using NCUA (NCDS UI Admin) design system components from NHN Commerce.
|
|
4
|
+
|
|
5
|
+
## Absolute Rules (VIOLATION = CRITICAL FAILURE)
|
|
6
|
+
|
|
7
|
+
1. Call ping ONCE at the start of every session before using any other tool. This loads version info and usage rules.
|
|
8
|
+
2. NEVER define or guess NCUA CSS variables (--ncua-\*). NCUA component styles are controlled by CDN CSS only.
|
|
9
|
+
3. NEVER write SVG icons or icon markup manually. ALL icons MUST come from search_icon or list_icons. If you write a single svg tag by hand, you have FAILED.
|
|
10
|
+
4. NEVER use emoji in generated HTML, CSS, or any output. No exceptions.
|
|
11
|
+
5. You MUST generate NCUA component HTML using render_to_html or render_to_html_batch only. Never write component HTML/CSS manually.
|
|
12
|
+
6. If an NCUA component exists for the use case, you MUST use it. Do NOT recreate it manually.
|
|
13
|
+
7. For custom areas, call get_design_tokens FIRST and prefer NCUA tokens for colors, spacing, typography, and shadows to maintain visual consistency. If no suitable token exists, you may use standard CSS values (hex, rgb, px).
|
|
14
|
+
|
|
15
|
+
## Required Workflow (follow this order strictly)
|
|
16
|
+
|
|
17
|
+
### Step 0: Version Check (do this once per session)
|
|
18
|
+
|
|
19
|
+
1. Call `ping` to get the MCP server info. Note `cdn.version` (ui-admin) and `icon.version` (ui-admin-icon).
|
|
20
|
+
2. Check the project's `package.json` for `@ncds/ui-admin`:
|
|
21
|
+
- **Not found** → The project uses HTML+CDN mode. Skip version comparison and proceed to Step 1.
|
|
22
|
+
- **Found** → Compare the project's `@ncds/ui-admin` major.minor version with `cdn.version` (ignore patch).
|
|
23
|
+
3. If versions **match** → Proceed to Step 1.
|
|
24
|
+
4. If versions **differ**:
|
|
25
|
+
- Warn the user: "MCP data is based on @ncds/ui-admin X.Y, but your project uses Z.W. Generated code may not match your installed version."
|
|
26
|
+
- Wait for the user's confirmation before proceeding. Do NOT upgrade or downgrade package versions on your own.
|
|
27
|
+
5. For **React projects**, also compare `@ncds/ui-admin-icon` major.minor in `package.json` with `icon.version` from ping. Apply the same mismatch rules.
|
|
28
|
+
6. `ping.version` is the MCP server's own release version — do NOT compare it with any project package. Only `cdn.version` and `icon.version` matter.
|
|
29
|
+
7. The `dataVersion` field in `render_to_html` responses shows the same versions as ping. One ping call per session is sufficient — no need to re-check on every `render_to_html` call.
|
|
30
|
+
|
|
31
|
+
### Step 1: Component Discovery
|
|
32
|
+
|
|
33
|
+
- Call **list_components** first to see all available components and their categories. This prevents reinventing components that already exist.
|
|
34
|
+
- Use **search_component** with Korean/English keywords to find the right component
|
|
35
|
+
- Example: "비밀번호" → password-input, "모달" → modal
|
|
36
|
+
- **IMPORTANT**: input is for plain text only. For passwords, always use password-input.
|
|
37
|
+
|
|
38
|
+
### Step 2: Props Check
|
|
39
|
+
|
|
40
|
+
- Use **get_component_props** to see available properties BEFORE calling render_to_html.
|
|
41
|
+
- Pass all required props. Choose enum values only from the allowed list.
|
|
42
|
+
- Check `type: "object"` props carefully — they often expect arrays or structured objects. Read the `rawType` field for the actual TypeScript type.
|
|
43
|
+
- For icon props (`leadingIcon`, `trailingIcon`, `icon`), pass `{ type: "icon", icon: "IconName" }` where IconName is a PascalCase name from search_icon.
|
|
44
|
+
|
|
45
|
+
### Step 3: HTML Generation
|
|
46
|
+
|
|
47
|
+
- When building a page with multiple components, use **render_to_html_batch** to render them all in one call (max 30). This is much more efficient than calling render_to_html repeatedly.
|
|
48
|
+
- For a single component, use **render_to_html**.
|
|
49
|
+
- Use the returned html as-is. Do NOT modify class names, structure, or attributes.
|
|
50
|
+
- Check the `warnings` field in the response — it reports invalid enum values and missing required props.
|
|
51
|
+
- **If render returns empty or minimal HTML**, the component likely needs data props (e.g. `menus` for HorizontalTab, `items` for BreadCrumb). Check get_component_props and retry with proper data.
|
|
52
|
+
- **Empty result recovery** (max 3 attempts):
|
|
53
|
+
1. Call get_component_props to identify required/data props
|
|
54
|
+
2. Retry render_to_html with meaningful prop values
|
|
55
|
+
3. If still empty after 3 attempts, report the issue to the user
|
|
56
|
+
|
|
57
|
+
### Step 4: CDN Inclusion
|
|
58
|
+
|
|
59
|
+
- Get CSS/JS URLs from the **cdn** field in the render_to_html response
|
|
60
|
+
- Include them in <head>/<body> of the final HTML
|
|
61
|
+
- When **js.required is true**, include the CDN JS <script> tag. This is mandatory.
|
|
62
|
+
|
|
63
|
+
### Step 5: Composition
|
|
64
|
+
|
|
65
|
+
- Combine render_to_html results to build the final page
|
|
66
|
+
- Do NOT modify NCUA component styles
|
|
67
|
+
- Apply spacing between components using NCUA design tokens: call **get_design_tokens** with category "spacing" to get available spacing values (e.g. var(--spacing-4), var(--spacing-8))
|
|
68
|
+
- When deciding component size or hierarchy, document your reasoning in an HTML comment (e.g. `<!-- size:sm chosen for compact sidebar layout -->`)
|
|
69
|
+
- If a commerce-rag MCP server is available, query it for page layout patterns and spacing guidelines specific to the project
|
|
70
|
+
|
|
71
|
+
## Building Custom Areas (not covered by NCUA)
|
|
72
|
+
|
|
73
|
+
When NCUA does not have a component for your needs, you may write custom HTML/CSS with these rules:
|
|
74
|
+
|
|
75
|
+
1. **No ncua- prefix** — Use a unique BEM prefix to avoid confusion with NCUA components (e.g. pw-form, order-summary)
|
|
76
|
+
2. **BEM naming** — Write custom classes using BEM convention (e.g. pw-form**title, pw-form**field--error)
|
|
77
|
+
3. **Reuse NCUA design tokens ONLY** — Use ONLY CSS variables that actually exist in the CDN CSS. Do NOT invent tokens.
|
|
78
|
+
- Colors: var(--color-text-primary), var(--color-border-secondary), var(--color-background-primary), etc.
|
|
79
|
+
- Fonts: var(--font-size-_), var(--font-weight-_), etc.
|
|
80
|
+
- Spacing: var(--spacing-\*), etc.
|
|
81
|
+
- Do NOT hardcode hex values like #5B5BD6 or rgb values. Always use existing token variables.
|
|
82
|
+
- If no exact token exists for your need, choose the closest available token. Do NOT create new tokens or hex values.
|
|
83
|
+
4. **Clear separation** — NCUA component areas (from render_to_html) and custom areas must be clearly distinguishable
|
|
84
|
+
|
|
85
|
+
## Step 6: Design System Compliance Check (after Step 5)
|
|
86
|
+
|
|
87
|
+
After composing the final HTML, validate design system compliance:
|
|
88
|
+
|
|
89
|
+
1. Call **validate_html** with the generated HTML
|
|
90
|
+
2. Check `compliance.score` in the response:
|
|
91
|
+
- **score = 1.0** → All design system rules followed. Proceed.
|
|
92
|
+
- **score < 1.0** → Fix the reported errors and re-validate.
|
|
93
|
+
3. **Self-correction loop** (max 3 attempts):
|
|
94
|
+
- Read `compliance.errors` — each error has a `type`, `target`, and `suggestion`
|
|
95
|
+
- Fix based on error type:
|
|
96
|
+
- `ncua_not_used` → Replace native HTML element with the suggested NCUA component (call search_component)
|
|
97
|
+
- `token_not_used` → Replace hardcoded color with the suggested CSS variable
|
|
98
|
+
- `invalid_token` → Call get_design_tokens to find the correct token name
|
|
99
|
+
- `custom_not_separated` → Move custom styles to a wrapper outside the NCUA component
|
|
100
|
+
- Re-call validate_html with the fixed HTML
|
|
101
|
+
- Repeat until score = 1.0 or 3 attempts reached
|
|
102
|
+
|
|
103
|
+
**Note:** `compliance.score` is independent from `valid`. `valid=true` with `score<1.0` means BEM classes are correct but design system usage can be improved.
|
|
104
|
+
|
|
105
|
+
## Props Usage Guide
|
|
106
|
+
|
|
107
|
+
When calling `get_component_props`, the response includes:
|
|
108
|
+
|
|
109
|
+
- `props`: Full props specification with types, defaults, and allowed values
|
|
110
|
+
- `usageExamples` (if available): Ready-to-use props objects for `render_to_html`
|
|
111
|
+
|
|
112
|
+
For components with complex object/array props (e.g., dropdown, range-date-picker), always check `usageExamples` first. Copy the example and modify values as needed — this avoids required prop omission errors.
|
|
113
|
+
|
|
114
|
+
If you call `render_to_html` with missing required props:
|
|
115
|
+
|
|
116
|
+
- The server auto-fills safe defaults (empty string, empty array, etc.) to prevent crashes
|
|
117
|
+
- `warnings` field lists what was missing and what was auto-filled
|
|
118
|
+
- The rendered HTML may be incomplete — check warnings and retry with proper values
|
|
119
|
+
|
|
120
|
+
## Component Selection Guide
|
|
121
|
+
|
|
122
|
+
- Password → **password-input** (never use input)
|
|
123
|
+
- Numbers → **number-input**
|
|
124
|
+
- File upload → **file-input**
|
|
125
|
+
- Image upload → **image-file-input**
|
|
126
|
+
- Plain text → **input**
|
|
127
|
+
- Each component's description includes usage guidance and alternatives.
|
|
128
|
+
|
|
129
|
+
## Rules Schema
|
|
130
|
+
|
|
131
|
+
The `rules` array in ping response is a flat list of strings grouped by category. Categories:
|
|
132
|
+
|
|
133
|
+
| Category | Purpose |
|
|
134
|
+
| ------------------ | -------------------------------------------------- |
|
|
135
|
+
| workflow | Required tool call order and HTML generation rules |
|
|
136
|
+
| componentSelection | Which component to use for each use case |
|
|
137
|
+
| version | MCP↔project version comparison rules |
|
|
138
|
+
| cdn | CDN CSS/JS inclusion rules |
|
|
139
|
+
| react | React-specific package and import rules |
|
|
140
|
+
| forbidden | Actions that must never be performed |
|
|
141
|
+
| customArea | Rules for building areas not covered by NCUA |
|
|
142
|
+
| compliance | validate_html self-correction loop rules |
|
|
143
|
+
| category | Component category naming standard |
|
|
144
|
+
|
|
145
|
+
## Error Response Format
|
|
146
|
+
|
|
147
|
+
All tool errors follow a consistent JSON structure:
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{ "code": "ERROR_CODE", "message": "Human-readable description", "suggestion": "What to do next" }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Error codes:
|
|
154
|
+
|
|
155
|
+
| Code | When |
|
|
156
|
+
| ----------------------- | -------------------------------------------------------------------- |
|
|
157
|
+
| COMPONENT_NOT_FOUND | Component name does not exist |
|
|
158
|
+
| EXPORT_NAME_MISSING | Component data is corrupted — re-extract needed |
|
|
159
|
+
| COMPONENT_NOT_IN_BUNDLE | Component exists in data but not in runtime bundle — re-build needed |
|
|
160
|
+
| RENDER_FAILED | React rendering threw an error — check props |
|
|
161
|
+
| INVALID_TOKEN_CATEGORY | get_design_tokens called with unknown category |
|
|
162
|
+
| ICON_NOT_FOUND | Icon name does not exist in the icon library |
|
|
163
|
+
| INVALID_PARAMS | Tool called with invalid or missing parameters |
|
|
164
|
+
| INTERNAL_ERROR | Unexpected server error |
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Modal": {
|
|
3
|
+
"className": "Modal",
|
|
4
|
+
"constructor": "new window.ncua.Modal(options?)",
|
|
5
|
+
"constructorParams": {
|
|
6
|
+
"size": "'sm' | 'md' | 'lg' (default: 'md')",
|
|
7
|
+
"closeOnBackdropClick": "boolean (default: false)",
|
|
8
|
+
"closeOnEsc": "boolean (default: true)",
|
|
9
|
+
"onClose": "() => void"
|
|
10
|
+
},
|
|
11
|
+
"methods": ["open()", "close()", "destroy()", "setContent(html: string | HTMLElement)", "isModalOpen()"],
|
|
12
|
+
"example": "const modal = new window.ncua.Modal({ size: 'sm', onClose: () => {} });\nmodal.setContent('<p>Content</p>');\nmodal.open();"
|
|
13
|
+
},
|
|
14
|
+
"SelectBox": {
|
|
15
|
+
"className": "SelectBox",
|
|
16
|
+
"constructor": "new window.ncua.SelectBox(element, config?)",
|
|
17
|
+
"constructorParams": {
|
|
18
|
+
"element": "HTMLElement — target container",
|
|
19
|
+
"config.options": "Array<{ id: string, text: string, disabled?: boolean }>",
|
|
20
|
+
"config.placeholder": "string (default: '선택하세요')",
|
|
21
|
+
"config.value": "string | number",
|
|
22
|
+
"config.onChange": "(value) => void",
|
|
23
|
+
"config.size": "'xs' | 'sm' | 'md'",
|
|
24
|
+
"config.multiple": "boolean",
|
|
25
|
+
"config.disabled": "boolean"
|
|
26
|
+
},
|
|
27
|
+
"methods": ["getValues()", "setValues(options[])", "getSelectedCount()"],
|
|
28
|
+
"example": "const select = new window.ncua.SelectBox(document.getElementById('my-select'), {\n options: [{ id: '1', text: 'Option 1' }],\n onChange: (value) => console.log(value)\n});"
|
|
29
|
+
},
|
|
30
|
+
"ComboBox": {
|
|
31
|
+
"className": "ComboBox",
|
|
32
|
+
"constructor": "new window.ncua.ComboBox(element, config?)",
|
|
33
|
+
"constructorParams": {
|
|
34
|
+
"element": "HTMLElement — target container",
|
|
35
|
+
"config.options": "Array<{ id: string, label: string, disabled?: boolean }>",
|
|
36
|
+
"config.placeholder": "string (default: '검색하고 선택하세요')",
|
|
37
|
+
"config.value": "string | number",
|
|
38
|
+
"config.onChange": "(value) => void",
|
|
39
|
+
"config.onSearch": "(searchValue: string) => void",
|
|
40
|
+
"config.size": "'xs' | 'sm'",
|
|
41
|
+
"config.multiple": "boolean"
|
|
42
|
+
},
|
|
43
|
+
"methods": ["getValues()", "setValues(options[])", "clearInput()", "getSelectedCount()"],
|
|
44
|
+
"example": "const combo = new window.ncua.ComboBox(document.getElementById('my-combo'), {\n options: [{ id: '1', label: 'React' }],\n onSearch: (q) => console.log(q)\n});"
|
|
45
|
+
},
|
|
46
|
+
"DatePicker": {
|
|
47
|
+
"className": "DatePicker",
|
|
48
|
+
"constructor": "new window.ncua.DatePicker(wrapper, options)",
|
|
49
|
+
"constructorParams": {
|
|
50
|
+
"wrapper": "HTMLElement — container element",
|
|
51
|
+
"options.size": "'xs' | 'sm'",
|
|
52
|
+
"options.datePickerOptions": "Array<{ element: string, placeholder?: string, options: FlatpickrOptions }>",
|
|
53
|
+
"options.buttons": "Array<{ text: string, period: number, unit: 'days'|'months', isCurrent: boolean }>",
|
|
54
|
+
"options.onValidationError": "(error) => void"
|
|
55
|
+
},
|
|
56
|
+
"methods": ["getDates()", "setDate(dates: string[])", "setMultipleDates(dates: string[])"],
|
|
57
|
+
"example": "const dp = new window.ncua.DatePicker(document.getElementById('my-dp'), {\n size: 'xs',\n datePickerOptions: [{ element: 'date-input', placeholder: 'Select date', options: { dateFormat: 'Y-m-d' } }]\n});"
|
|
58
|
+
},
|
|
59
|
+
"Slider": {
|
|
60
|
+
"className": "Slider",
|
|
61
|
+
"constructor": "new window.ncua.Slider(element, options)",
|
|
62
|
+
"constructorParams": {
|
|
63
|
+
"element": "HTMLElement — container",
|
|
64
|
+
"options.min": "number (default: 0)",
|
|
65
|
+
"options.max": "number (default: 100)",
|
|
66
|
+
"options.step": "number (default: 1)",
|
|
67
|
+
"options.value": "number | [number, number]",
|
|
68
|
+
"options.onChange": "(value) => void",
|
|
69
|
+
"options.disabled": "boolean"
|
|
70
|
+
},
|
|
71
|
+
"methods": ["getValue()", "setValue(value)", "enable()", "disable()", "destroy()"],
|
|
72
|
+
"example": "const slider = new window.ncua.Slider(document.getElementById('my-slider'), {\n min: 0, max: 100, value: 50,\n onChange: (v) => console.log(v)\n});"
|
|
73
|
+
},
|
|
74
|
+
"Tab": {
|
|
75
|
+
"className": "Tab",
|
|
76
|
+
"constructor": "new window.ncua.Tab(element)",
|
|
77
|
+
"constructorParams": {
|
|
78
|
+
"element": "HTMLElement — container with swiper structure"
|
|
79
|
+
},
|
|
80
|
+
"methods": ["destroy()"],
|
|
81
|
+
"example": "const tab = new window.ncua.Tab(document.getElementById('my-tab'));"
|
|
82
|
+
},
|
|
83
|
+
"Tooltip": {
|
|
84
|
+
"className": "Tooltip",
|
|
85
|
+
"constructor": "window.ncua.Tooltip.createShort(title, content?, options?)",
|
|
86
|
+
"constructorParams": {
|
|
87
|
+
"title": "string",
|
|
88
|
+
"content": "string (HTML supported)",
|
|
89
|
+
"options.position": "'top' | 'bottom' | 'left' | 'right' (default: 'top')"
|
|
90
|
+
},
|
|
91
|
+
"methods": ["getElement()", "showTooltip()", "hideTooltip()", "destroy()"],
|
|
92
|
+
"example": "const tip = window.ncua.Tooltip.createShort('Help', 'Tooltip content');\ndocument.getElementById('container').appendChild(tip.getElement());"
|
|
93
|
+
},
|
|
94
|
+
"Notification": {
|
|
95
|
+
"className": "Notification",
|
|
96
|
+
"constructor": "window.ncua.Notification.success(title, supportingText?, options?)",
|
|
97
|
+
"constructorParams": {
|
|
98
|
+
"title": "string",
|
|
99
|
+
"supportingText": "string",
|
|
100
|
+
"options.autoClose": "number (ms, 0 = no auto-close)"
|
|
101
|
+
},
|
|
102
|
+
"methods": ["show(parent?)", "remove()", "destroy()"],
|
|
103
|
+
"staticMethods": ["success()", "error()", "warning()", "info()", "neutral()"],
|
|
104
|
+
"example": "window.ncua.Notification.success('Saved', 'Changes saved successfully');"
|
|
105
|
+
},
|
|
106
|
+
"ProgressBar": {
|
|
107
|
+
"className": "ProgressBar",
|
|
108
|
+
"constructor": "new window.ncua.ProgressBar(options?)",
|
|
109
|
+
"constructorParams": {
|
|
110
|
+
"options.value": "number (0-100)",
|
|
111
|
+
"options.label": "'right' | 'bottom' | 'top-float' | 'bottom-float'"
|
|
112
|
+
},
|
|
113
|
+
"methods": ["getElement()", "updateOptions(newOptions)", "toHTML()"],
|
|
114
|
+
"example": "const bar = new window.ncua.ProgressBar({ value: 65, label: 'right' });\ndocument.getElementById('container').appendChild(bar.getElement());"
|
|
115
|
+
},
|
|
116
|
+
"Tag": {
|
|
117
|
+
"className": "Tag",
|
|
118
|
+
"constructor": "new window.ncua.Tag(options)",
|
|
119
|
+
"constructorParams": {
|
|
120
|
+
"options.text": "string",
|
|
121
|
+
"options.size": "'sm' | 'md' (default: 'sm')",
|
|
122
|
+
"options.close": "boolean — show close button",
|
|
123
|
+
"options.onButtonClick": "() => void — close handler"
|
|
124
|
+
},
|
|
125
|
+
"methods": ["getElement()", "setText(text)", "setCount(count)", "destroy()"],
|
|
126
|
+
"example": "const tag = new window.ncua.Tag({ text: 'Label', close: true, onButtonClick: () => tag.destroy() });\ndocument.getElementById('container').appendChild(tag.getElement());"
|
|
127
|
+
},
|
|
128
|
+
"FileInput": {
|
|
129
|
+
"className": "FileInput",
|
|
130
|
+
"constructor": "new window.ncua.FileInput(options)",
|
|
131
|
+
"constructorParams": {
|
|
132
|
+
"options.container": "HTMLElement | string — auto-append target",
|
|
133
|
+
"options.onChange": "(files: File[]) => void",
|
|
134
|
+
"options.onFail": "(invalidFiles: File[]) => void",
|
|
135
|
+
"options.disabled": "boolean"
|
|
136
|
+
},
|
|
137
|
+
"methods": ["getElement()", "setDisabled(boolean)", "destroy()"],
|
|
138
|
+
"example": "const fi = new window.ncua.FileInput({\n container: 'file-container',\n onChange: (files) => console.log(files)\n});"
|
|
139
|
+
},
|
|
140
|
+
"ImageFileInput": {
|
|
141
|
+
"className": "ImageFileInput",
|
|
142
|
+
"constructor": "new window.ncua.ImageFileInput(options)",
|
|
143
|
+
"constructorParams": {
|
|
144
|
+
"options.container": "HTMLElement | string — auto-append target",
|
|
145
|
+
"options.onChange": "(files: File[]) => void",
|
|
146
|
+
"options.maxFileCount": "number",
|
|
147
|
+
"options.acceptedFileTypes": "string[]",
|
|
148
|
+
"options.maxFileSize": "number"
|
|
149
|
+
},
|
|
150
|
+
"methods": ["getElement()", "getFiles()", "clearFiles()", "setDisabled(boolean)", "destroy()"],
|
|
151
|
+
"example": "const img = new window.ncua.ImageFileInput({\n container: 'image-container',\n maxFileCount: 5,\n onChange: (files) => console.log(files)\n});"
|
|
152
|
+
},
|
|
153
|
+
"FeaturedIcon": {
|
|
154
|
+
"className": "FeaturedIcon",
|
|
155
|
+
"constructor": "new window.ncua.FeaturedIcon(options)",
|
|
156
|
+
"constructorParams": {
|
|
157
|
+
"options.svgString": "string — SVG content",
|
|
158
|
+
"options.theme": "'light-circle' | 'dark-circle' | 'outline-circle' | 'square-outline'",
|
|
159
|
+
"options.color": "'neutral' | 'error' | 'warning' | 'success'",
|
|
160
|
+
"options.size": "'sm' | 'md' | 'lg' | 'xl'"
|
|
161
|
+
},
|
|
162
|
+
"methods": ["getElement()", "updateColor(color)", "updateSize(size)", "destroy()"],
|
|
163
|
+
"example": "const icon = new window.ncua.FeaturedIcon({ svgString: '<svg>...</svg>', color: 'success', size: 'md' });\ndocument.getElementById('container').appendChild(icon.getElement());"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workflow": [
|
|
3
|
+
"You MUST generate component HTML using the render_to_html tool. Never write HTML/CSS manually.",
|
|
4
|
+
"Use the HTML returned by render_to_html as-is. Do NOT modify class names, structure, or attributes.",
|
|
5
|
+
"Use search_component to find the right component by Korean/English keywords before building any UI.",
|
|
6
|
+
"Use list_components to browse available components by category and choose the appropriate one.",
|
|
7
|
+
"When building a page with multiple components, use render_to_html_batch to render them all in one call instead of calling render_to_html repeatedly."
|
|
8
|
+
],
|
|
9
|
+
"componentSelection": [
|
|
10
|
+
"For password fields, you MUST use password-input. The input component is for plain text only.",
|
|
11
|
+
"For numbers use number-input, for file uploads use file-input, for image uploads use image-file-input.",
|
|
12
|
+
"Each component's description lists its intended use case and alternative components. Always read it."
|
|
13
|
+
],
|
|
14
|
+
"version": [
|
|
15
|
+
"The MCP server's own version (ping.version) is independent from the design system packages. Do NOT compare it with project packages.",
|
|
16
|
+
"ping.cdn.version shows which @ncds/ui-admin version this MCP data was built from. ping.icon.version shows the @ncds/ui-admin-icon version.",
|
|
17
|
+
"The dataVersion field in render_to_html response contains the same values as ping.cdn.version and ping.icon.version. One ping per session is sufficient.",
|
|
18
|
+
"HTML (CDN) mode: if the project does not have @ncds/ui-admin in package.json, it uses CDN-only mode. Skip version comparison.",
|
|
19
|
+
"If the project has @ncds/ui-admin in package.json, compare its major.minor version with ping.cdn.version (ignore patch). For React projects, also compare @ncds/ui-admin-icon with ping.icon.version.",
|
|
20
|
+
"If versions match, proceed normally. If versions differ, warn the user and wait for their confirmation BEFORE proceeding.",
|
|
21
|
+
"Do NOT upgrade or downgrade @ncds/ui-admin or @ncds/ui-admin-icon versions on your own. Version changes require explicit team approval."
|
|
22
|
+
],
|
|
23
|
+
"cdn": [
|
|
24
|
+
"You MUST include CDN CSS and JS URLs in the final HTML. The cdn field in render_to_html response has the exact URLs.",
|
|
25
|
+
"When js.required is true in render_to_html response, include the CDN JS <script> tag. This is mandatory.",
|
|
26
|
+
"In HTML mode, icons are rendered as SVG via CDN JS. No separate package installation is needed.",
|
|
27
|
+
"When js.required is true, the component needs its own JS for interactivity — ensure the CDN JS script is loaded."
|
|
28
|
+
],
|
|
29
|
+
"react": [
|
|
30
|
+
"React projects require @ncds/ui-admin and @ncds/ui-admin-icon packages. Install ONLY packages listed in react.dependencies.",
|
|
31
|
+
"For non-developer users, the agent should check package.json and auto-install required packages.",
|
|
32
|
+
"Use react.jsx code as-is from render_to_html response. Do NOT write JSX manually — this prevents hallucination.",
|
|
33
|
+
"Icons in React are imported as components from @ncds/ui-admin-icon (e.g. import { ChevronDown } from '@ncds/ui-admin-icon')."
|
|
34
|
+
],
|
|
35
|
+
"forbidden": [
|
|
36
|
+
"Do NOT override ncua-* classes with custom CSS. Control appearance through component props only.",
|
|
37
|
+
"Do NOT define CSS variables (--ncua-*) yourself. They are already included in the CDN CSS.",
|
|
38
|
+
"Do NOT write SVG icons manually. Use search_icon to find icons from the icon library."
|
|
39
|
+
],
|
|
40
|
+
"customArea": [
|
|
41
|
+
"When building areas not covered by NCUA components, do NOT use the ncua- prefix. Use a unique BEM prefix (e.g. pw-form, order-summary).",
|
|
42
|
+
"Custom areas MUST use ONLY existing NCUA design tokens (CSS variables from CDN) for colors, fonts, spacing, and shadows. Do NOT hardcode hex values like #5B5BD6 or rgb values.",
|
|
43
|
+
"Do NOT invent token names. If no exact token exists, choose the closest available token. Never fall back to raw color/size values.",
|
|
44
|
+
"Before writing custom CSS, call get_design_tokens to see available tokens. Filter by category (color, typography, spacing, shadow) to reduce response size.",
|
|
45
|
+
"For spacing, use spacing tokens (--spacing-xs through --spacing-xxl) instead of hardcoded px values. Follow the principle: inner-block spacing < between-block spacing."
|
|
46
|
+
],
|
|
47
|
+
"compliance": [
|
|
48
|
+
"After generating HTML, call validate_html to check the compliance score. If compliance.score < 1.0, fix the reported errors and re-validate.",
|
|
49
|
+
"Self-correction loop: generate HTML → validate_html → fix errors → re-validate. Repeat until score = 1.0 (max 3 attempts).",
|
|
50
|
+
"If validate_html reports ncua_not_used, replace native HTML elements with the suggested NCUA component using search_component.",
|
|
51
|
+
"If validate_html reports token_not_used, replace hardcoded color values with the suggested CSS variable (var(--token-name)).",
|
|
52
|
+
"If validate_html reports invalid_token, call get_design_tokens to find the correct token name.",
|
|
53
|
+
"If validate_html reports custom_not_separated, move custom styles to a wrapper element outside the NCUA component."
|
|
54
|
+
],
|
|
55
|
+
"category": [
|
|
56
|
+
"Component categories follow the design team standard (DES INDEX): action, input, icon, overlay, navigation, feedback, data-display."
|
|
57
|
+
],
|
|
58
|
+
"pingReminder": "IMPORTANT: You have NOT called ping yet. Call ping ONCE before proceeding. Rules: (1) NEVER hardcode hex/rgb colors - use get_design_tokens. (2) NEVER write SVG icons - use search_icon. (3) Use render_to_html or render_to_html_batch for all NCUA components. (4) For custom CSS, prefer NCUA tokens. Call get_design_tokens first."
|
|
59
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"categoryDescriptions": {
|
|
3
|
+
"color": "Design system color tokens. Use these CSS variables instead of hex/rgb values in custom areas.",
|
|
4
|
+
"typography": "Typography tokens: font-size, line-height, font-weight, font-family.",
|
|
5
|
+
"shadow": "Shadow and focus-ring tokens for elevation and focus states."
|
|
6
|
+
},
|
|
7
|
+
"groupDescriptions": {
|
|
8
|
+
"primary-red": "Brand primary. 450 is the default CTA color.",
|
|
9
|
+
"secondary-gray-blue": "Secondary accent color.",
|
|
10
|
+
"base": "Pure white (#fff) and black (#000).",
|
|
11
|
+
"gray": "Neutral color. Text (700-500), border (200-300), background (50-100).",
|
|
12
|
+
"green": "Success / positive state.",
|
|
13
|
+
"cyan": "Informational accent.",
|
|
14
|
+
"blue": "Information / link state.",
|
|
15
|
+
"violet": "Accent / decorative.",
|
|
16
|
+
"pink": "Accent / decorative.",
|
|
17
|
+
"orange": "Warning state.",
|
|
18
|
+
"yellow": "Caution / highlight.",
|
|
19
|
+
"font-families": "Base font family (Commerce Sans).",
|
|
20
|
+
"font-size": "Font size scale: 0 (12px) to 10 (72px).",
|
|
21
|
+
"line-heights": "Line height scale: 0 (90) to 10 (18). Pair with font-size.",
|
|
22
|
+
"font-weights": "Font weight: 0 (Regular), 1 (Medium), 2 (Bold).",
|
|
23
|
+
"focus-ring": "Focus ring shadows for interactive elements.",
|
|
24
|
+
"shadow": "Elevation shadow scale: xs to 3xl.",
|
|
25
|
+
"shadow-portfolio-mockup": "Portfolio mockup layout shadows."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tools": {
|
|
3
|
+
"ping": {
|
|
4
|
+
"description": "Check NCUA MCP server health, version, capabilities, and usage rules."
|
|
5
|
+
},
|
|
6
|
+
"list_icons": {
|
|
7
|
+
"description": "List all available icons from the @ncds/ui-admin-icon package."
|
|
8
|
+
},
|
|
9
|
+
"search_icon": {
|
|
10
|
+
"description": "Search icons by keyword. Supports name and kebab-case lookups."
|
|
11
|
+
},
|
|
12
|
+
"list_components": {
|
|
13
|
+
"description": "List all available UI components grouped by category. Check this before building any UI to understand what components exist."
|
|
14
|
+
},
|
|
15
|
+
"search_component": {
|
|
16
|
+
"description": "Search components by Korean/English keyword. Returns name, category, description, aliases."
|
|
17
|
+
},
|
|
18
|
+
"get_component_props": {
|
|
19
|
+
"description": "Get the available props (properties) for a component. Use this before render_to_html to understand what props you can pass."
|
|
20
|
+
},
|
|
21
|
+
"validate_html": {
|
|
22
|
+
"description": "Validate HTML markup for NCUA BEM class correctness AND design system compliance (component usage, token usage, custom separation). Returns errors, auto-fix suggestions, and a compliance score (0-1)."
|
|
23
|
+
},
|
|
24
|
+
"render_to_html": {
|
|
25
|
+
"description": "Generate exact HTML for an NCUA component with given props. Returns html, appliedProps, defaultsUsed, js, cdn."
|
|
26
|
+
},
|
|
27
|
+
"render_to_html_batch": {
|
|
28
|
+
"description": "Render multiple NCUA components in a single call (max 30). Pass an array of {name, props} objects. Returns an array of render results. Use this instead of calling render_to_html repeatedly when building a page."
|
|
29
|
+
},
|
|
30
|
+
"get_design_tokens": {
|
|
31
|
+
"description": "Get available design tokens (CSS variables) for colors, typography, spacing, and shadows. Use when building custom areas to pick real tokens instead of guessing."
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"capabilities": [
|
|
35
|
+
{ "tool": "ping", "description": "Server health check + version + capabilities/rules", "available": true },
|
|
36
|
+
{ "tool": "list_components", "description": "Browse all components by category", "available": true },
|
|
37
|
+
{ "tool": "search_component", "description": "Find components by keyword", "available": true },
|
|
38
|
+
{ "tool": "list_icons", "description": "Browse all available icons", "available": true },
|
|
39
|
+
{ "tool": "search_icon", "description": "Find icons by keyword", "available": true },
|
|
40
|
+
{ "tool": "get_component_props", "description": "Get component props spec", "available": true },
|
|
41
|
+
{
|
|
42
|
+
"tool": "validate_html",
|
|
43
|
+
"description": "Validate HTML BEM classes + design system compliance score + auto-fix",
|
|
44
|
+
"available": true
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"tool": "render_to_html",
|
|
48
|
+
"description": "Props-based dynamic HTML rendering + icon SVG resolve",
|
|
49
|
+
"available": true
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"tool": "render_to_html_batch",
|
|
53
|
+
"description": "Batch render multiple components in one call (max 30)",
|
|
54
|
+
"available": true
|
|
55
|
+
},
|
|
56
|
+
{ "tool": "get_design_tokens", "description": "Design token (CSS variable) lookup by category", "available": true }
|
|
57
|
+
]
|
|
58
|
+
}
|
package/bin/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|