@spaced-out/ui-design-system 0.5.34 ā 0.5.35
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/.github/workflows/publish-mcp.yml +11 -10
- package/CHANGELOG.md +13 -0
- package/lib/components/Button/Button.d.ts +1 -0
- package/lib/components/Button/Button.d.ts.map +1 -1
- package/lib/components/Button/Button.js +7 -3
- package/lib/components/Button/Button.module.css +28 -1
- package/lib/components/ButtonDropdown/SimpleButtonDropdown.d.ts +6 -1
- package/lib/components/ButtonDropdown/SimpleButtonDropdown.d.ts.map +1 -1
- package/lib/components/ButtonDropdown/SimpleButtonDropdown.js +3 -1
- package/mcp/README.md +28 -494
- package/mcp/build-mcp-data.js +78 -72
- package/mcp/index.js +1 -1
- package/mcp/package.json +2 -2
- package/mcp/test-server.js +1 -1
- package/package.json +1 -1
|
@@ -3,23 +3,20 @@
|
|
|
3
3
|
|
|
4
4
|
name: Publish MCP Server to NPM
|
|
5
5
|
|
|
6
|
-
# WORKFLOW DISABLED - Triggers commented out to prevent automatic runs
|
|
7
|
-
# Uncomment below to re-enable the workflow triggers
|
|
8
6
|
on:
|
|
9
7
|
# Run after the main NPM publish workflow completes successfully
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
workflow_dispatch:
|
|
8
|
+
workflow_run:
|
|
9
|
+
workflows: ['Release Genesis to NPM']
|
|
10
|
+
types:
|
|
11
|
+
- completed
|
|
12
|
+
branches: [master]
|
|
13
|
+
workflow_dispatch:
|
|
16
14
|
|
|
17
15
|
jobs:
|
|
18
16
|
publish-mcp:
|
|
19
17
|
runs-on: ubuntu-latest
|
|
20
|
-
# WORKFLOW DISABLED - Set to false to prevent execution
|
|
21
18
|
# Only run if triggered manually or if the workflow_run succeeded
|
|
22
|
-
if:
|
|
19
|
+
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
|
|
23
20
|
steps:
|
|
24
21
|
- name: Check Permissions
|
|
25
22
|
id: check-permissions
|
|
@@ -54,6 +51,10 @@ jobs:
|
|
|
54
51
|
working-directory: ./mcp
|
|
55
52
|
run: yarn install
|
|
56
53
|
|
|
54
|
+
- name: Build type definitions
|
|
55
|
+
run: yarn build:types
|
|
56
|
+
# Only generates .d.ts files in lib/ - much faster than full build
|
|
57
|
+
|
|
57
58
|
- name: Auto-bump patch version
|
|
58
59
|
if: github.event_name == 'workflow_run'
|
|
59
60
|
working-directory: ./mcp
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.5.35](https://github.com/spaced-out/ui-design-system/compare/v0.5.34...v0.5.35) (2025-12-15)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* introducing tertiary gradient type button ([#449](https://github.com/spaced-out/ui-design-system/issues/449)) ([9c8d740](https://github.com/spaced-out/ui-design-system/commit/9c8d740c2c932f74935699013ea45d0d2a2fed29))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **mcp:** expose .d.ts type definitions instead of source code ([#450](https://github.com/spaced-out/ui-design-system/issues/450)) ([4583947](https://github.com/spaced-out/ui-design-system/commit/45839475dec006acf9e99ca07b6c32cd7260f069))
|
|
16
|
+
* static label support for simple button dropdown ([#401](https://github.com/spaced-out/ui-design-system/issues/401)) ([f37c03f](https://github.com/spaced-out/ui-design-system/commit/f37c03f80af9f1a4b4cf04b7ff998b9c3a433639))
|
|
17
|
+
|
|
5
18
|
### [0.5.34](https://github.com/spaced-out/ui-design-system/compare/v0.5.34-beta.2...v0.5.34) (2025-12-12)
|
|
6
19
|
|
|
7
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAOlD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAOlD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;;;;;;EAQvB,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;EAI7B,CAAC;AAEH,eAAO,MAAM,WAAW;;;EAGtB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAC1E,MAAM,MAAM,gBAAgB,GAC1B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAC/D,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,WAAW,CAAC;AAElD,MAAM,WAAW,eACf,SAAQ,IAAI,CACV,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC3C,UAAU,GACV,UAAU,GACV,YAAY,GACZ,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,MAAM,CACT;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CACV,eAAe,EACb,YAAY,GACZ,cAAc,GACd,cAAc,GACd,eAAe,GACf,eAAe,GACf,MAAM,GACN,SAAS,GACT,MAAM,CACT;IACD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAsBD,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,CACjD,mBAAmB,EACnB,iBAAiB,CAoClB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,iBAAiB,CAsKvE,CAAC"}
|
|
@@ -29,7 +29,8 @@ const BUTTON_TYPES = exports.BUTTON_TYPES = Object.freeze({
|
|
|
29
29
|
tertiary: 'tertiary',
|
|
30
30
|
ghost: 'ghost',
|
|
31
31
|
danger: 'danger',
|
|
32
|
-
gradient: 'gradient'
|
|
32
|
+
gradient: 'gradient',
|
|
33
|
+
'tertiary-gradient': 'tertiaryGradient'
|
|
33
34
|
});
|
|
34
35
|
const BUTTON_ACTION_TYPE = exports.BUTTON_ACTION_TYPE = Object.freeze({
|
|
35
36
|
button: 'button',
|
|
@@ -46,7 +47,8 @@ const ButtonTypeToIconColorMap = {
|
|
|
46
47
|
tertiary: 'primary',
|
|
47
48
|
ghost: 'primary',
|
|
48
49
|
danger: 'inversePrimary',
|
|
49
|
-
gradient: 'inversePrimary'
|
|
50
|
+
gradient: 'inversePrimary',
|
|
51
|
+
tertiaryGradient: 'clickable'
|
|
50
52
|
};
|
|
51
53
|
const ButtonTypeToLoaderColorMap = {
|
|
52
54
|
primary: 'colorTextInversePrimary',
|
|
@@ -54,7 +56,8 @@ const ButtonTypeToLoaderColorMap = {
|
|
|
54
56
|
tertiary: 'colorTextPrimary',
|
|
55
57
|
ghost: 'colorTextPrimary',
|
|
56
58
|
danger: 'colorTextInversePrimary',
|
|
57
|
-
gradient: 'colorTextInversePrimary'
|
|
59
|
+
gradient: 'colorTextInversePrimary',
|
|
60
|
+
tertiaryGradient: 'colorTextClickable'
|
|
58
61
|
};
|
|
59
62
|
const UnstyledButton = exports.UnstyledButton = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
60
63
|
let {
|
|
@@ -123,6 +126,7 @@ const Button = exports.Button = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
123
126
|
[_ButtonModule.default.ghost]: type === 'ghost',
|
|
124
127
|
[_ButtonModule.default.danger]: type === 'danger',
|
|
125
128
|
[_ButtonModule.default.gradient]: type === 'gradient',
|
|
129
|
+
[_ButtonModule.default.tertiaryGradient]: type === 'tertiaryGradient',
|
|
126
130
|
[_ButtonModule.default.disabled]: disabled,
|
|
127
131
|
[_ButtonModule.default.small]: size === 'small',
|
|
128
132
|
[_ButtonModule.default.medium]: size === 'medium',
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
colorFocusPrimary,
|
|
23
23
|
colorFocusDanger,
|
|
24
|
+
colorFocusSecondary,
|
|
25
|
+
colorFocusInformation,
|
|
24
26
|
|
|
25
27
|
colorFillDisabled,
|
|
26
28
|
|
|
@@ -32,6 +34,8 @@
|
|
|
32
34
|
colorBorderSecondary,
|
|
33
35
|
|
|
34
36
|
colorFillPrimary,
|
|
37
|
+
colorFillSecondary,
|
|
38
|
+
colorInformationLightest,
|
|
35
39
|
colorInformation
|
|
36
40
|
|
|
37
41
|
) from '../../styles/variables/_color.css';
|
|
@@ -154,7 +158,7 @@ button {
|
|
|
154
158
|
background-color: colorButtonFillPrimaryPressed;
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
/* Currently
|
|
161
|
+
/* Currently Buttons with type `gradient` don't support hover / active states */
|
|
158
162
|
.gradient {
|
|
159
163
|
color: colorTextInversePrimary;
|
|
160
164
|
background-image: linear-gradient(
|
|
@@ -164,6 +168,29 @@ button {
|
|
|
164
168
|
);
|
|
165
169
|
}
|
|
166
170
|
|
|
171
|
+
.tertiaryGradient {
|
|
172
|
+
color: colorTextClickable;
|
|
173
|
+
border: borderWidthPrimary solid transparent;
|
|
174
|
+
background: linear-gradient(
|
|
175
|
+
to right,
|
|
176
|
+
colorFillSecondary,
|
|
177
|
+
colorInformationLightest
|
|
178
|
+
)
|
|
179
|
+
padding-box,
|
|
180
|
+
linear-gradient(to right, colorFocusSecondary, colorInformation) border-box;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.tertiaryGradient:hover,
|
|
184
|
+
.tertiaryGradient:active {
|
|
185
|
+
background: linear-gradient(
|
|
186
|
+
to right,
|
|
187
|
+
colorButtonFillSecondaryHovered,
|
|
188
|
+
colorFocusInformation
|
|
189
|
+
)
|
|
190
|
+
padding-box,
|
|
191
|
+
linear-gradient(to right, colorFocusSecondary, colorInformation) border-box;
|
|
192
|
+
}
|
|
193
|
+
|
|
167
194
|
.secondary {
|
|
168
195
|
color: colorTextClickable;
|
|
169
196
|
background-color: colorButtonFillSecondaryEnabled;
|
|
@@ -14,7 +14,7 @@ type ClassNames = Readonly<{
|
|
|
14
14
|
export interface SimpleButtonDropdownRef {
|
|
15
15
|
selectedKeys?: Array<string>;
|
|
16
16
|
}
|
|
17
|
-
export interface SimpleButtonDropdownProps extends Omit<ButtonProps, 'elevation' | 'classNames' | 'anchorPosition' | 'tooltip' | 'options' | 'optionsVariant' | 'allowSearch' | 'selectedKeys' | 'menuVirtualization' | 'header' | 'footer' | 'menuClassNames' | 'showLabelTooltip' | 'allowWrap' | 'onOptionSelect' | 'onMenuOpen' | 'onMenuClose' | 'resolveLabel' | 'resolveSecondaryLabel' | 'clickAwayRef'> {
|
|
17
|
+
export interface SimpleButtonDropdownProps extends Omit<ButtonProps, 'elevation' | 'classNames' | 'anchorPosition' | 'tooltip' | 'options' | 'optionsVariant' | 'allowSearch' | 'selectedKeys' | 'menuVirtualization' | 'header' | 'footer' | 'menuClassNames' | 'showLabelTooltip' | 'allowWrap' | 'onOptionSelect' | 'onMenuOpen' | 'onMenuClose' | 'staticLabels' | 'resolveLabel' | 'resolveSecondaryLabel' | 'clickAwayRef'> {
|
|
18
18
|
elevation?: ElevationType;
|
|
19
19
|
classNames?: ClassNames;
|
|
20
20
|
anchorPosition?: AnchorType;
|
|
@@ -32,6 +32,11 @@ export interface SimpleButtonDropdownProps extends Omit<ButtonProps, 'elevation'
|
|
|
32
32
|
onOptionSelect?: (option: MenuOption, arg2?: React.SyntheticEvent<HTMLElement> | null | undefined) => unknown;
|
|
33
33
|
onMenuOpen?: () => unknown;
|
|
34
34
|
onMenuClose?: () => unknown;
|
|
35
|
+
staticLabels?: {
|
|
36
|
+
RESULT?: string;
|
|
37
|
+
RESULTS?: string;
|
|
38
|
+
SEARCH_PLACEHOLDER?: string;
|
|
39
|
+
};
|
|
35
40
|
resolveLabel?: (option: MenuOption) => string | React.ReactNode;
|
|
36
41
|
resolveSecondaryLabel?: (option: MenuOption) => string | React.ReactNode;
|
|
37
42
|
clickAwayRef?: React.RefObject<ClickAwayRefType | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleButtonDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonDropdown/SimpleButtonDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAM3D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8CAA8C,CAAC;AAE7E,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,gBAAgB,EAAE,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAG5E,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,yBACf,SAAQ,IAAI,CACV,WAAW,EACT,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,SAAS,GACT,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,QAAQ,GACR,QAAQ,GACR,gBAAgB,GAChB,kBAAkB,GAClB,WAAW,GACX,gBAAgB,GAChB,YAAY,GACZ,aAAa,GACb,cAAc,GACd,uBAAuB,GACvB,cAAc,CACjB;IACD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5B,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,kBAAkB,CAAC,EAAE,cAAc,CAAC;IACpC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KACxD,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAC5B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAChE,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACzE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"SimpleButtonDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonDropdown/SimpleButtonDropdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,7 @@ const SimpleButtonDropdownBase = (props, ref) => {
|
|
|
33
33
|
allowWrap = false,
|
|
34
34
|
clickAwayRef,
|
|
35
35
|
elevation = 'modal',
|
|
36
|
+
staticLabels,
|
|
36
37
|
testId,
|
|
37
38
|
...buttonProps
|
|
38
39
|
} = props;
|
|
@@ -87,7 +88,8 @@ const SimpleButtonDropdownBase = (props, ref) => {
|
|
|
87
88
|
footer,
|
|
88
89
|
classNames: menuClassNames,
|
|
89
90
|
showLabelTooltip,
|
|
90
|
-
allowWrap
|
|
91
|
+
allowWrap,
|
|
92
|
+
staticLabels
|
|
91
93
|
},
|
|
92
94
|
children: optionsVariant === 'checkbox' ? btnText : children
|
|
93
95
|
});
|
package/mcp/README.md
CHANGED
|
@@ -1,526 +1,60 @@
|
|
|
1
|
-
# Genesis
|
|
1
|
+
# Genesis MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MCP server for AI assistants to access the Genesis UI Design System.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick Setup
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- šØ **Design Tokens**: Access colors, spacing, typography, shadows, and more
|
|
9
|
-
- š **Documentation**: Browse component stories and TypeScript definitions
|
|
10
|
-
- š **Dependency Analysis**: Understand component dependencies
|
|
11
|
-
- š **Onboarding Templates**: Get starter templates for new components
|
|
12
|
-
- šŖ **Hooks Information**: Query available React hooks
|
|
7
|
+
### Cursor / Claude Desktop
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Unlike traditional MCP servers that require a local copy of the design system, this server **bundles all data at build time**. Users only need to run `npx` - no cloning, no environment variables!
|
|
17
|
-
|
|
18
|
-
## š¦ Installation for Users
|
|
19
|
-
|
|
20
|
-
### With Cursor
|
|
21
|
-
|
|
22
|
-
ā ļø **macOS Users**: Cursor may not find `npx` in its PATH. Use the full path instead.
|
|
23
|
-
|
|
24
|
-
1. Find your `npx` path in terminal:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
which npx
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
2. Add to your Cursor MCP settings with the **full path**:
|
|
31
|
-
|
|
32
|
-
```json
|
|
33
|
-
{
|
|
34
|
-
"mcpServers": {
|
|
35
|
-
"genesis-design-system": {
|
|
36
|
-
"command": "/opt/homebrew/bin/npx",
|
|
37
|
-
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**Common npx locations:**
|
|
44
|
-
|
|
45
|
-
- Apple Silicon Mac (Homebrew): `/opt/homebrew/bin/npx`
|
|
46
|
-
- Intel Mac (Homebrew): `/usr/local/bin/npx`
|
|
47
|
-
- nvm users: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
48
|
-
|
|
49
|
-
**Windows/Linux users** can typically use `"command": "npx"` directly.
|
|
50
|
-
|
|
51
|
-
### With Claude Desktop
|
|
52
|
-
|
|
53
|
-
ā ļø **macOS Users**: Claude Desktop may not find `npx` in its PATH. Use the full path instead.
|
|
54
|
-
|
|
55
|
-
Add to your Claude config file:
|
|
56
|
-
|
|
57
|
-
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
58
|
-
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
59
|
-
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
60
|
-
|
|
61
|
-
1. Find your `npx` path in terminal:
|
|
9
|
+
1. Find your `npx` path:
|
|
62
10
|
|
|
63
11
|
```bash
|
|
64
12
|
which npx
|
|
65
13
|
```
|
|
66
14
|
|
|
67
|
-
2.
|
|
15
|
+
2. Add to MCP settings:
|
|
68
16
|
|
|
69
17
|
```json
|
|
70
18
|
{
|
|
71
19
|
"mcpServers": {
|
|
72
20
|
"genesis-design-system": {
|
|
73
21
|
"command": "/opt/homebrew/bin/npx",
|
|
74
|
-
"args": ["-y", "@spaced-out/genesis-mcp
|
|
22
|
+
"args": ["-y", "@spaced-out/genesis-mcp@latest"]
|
|
75
23
|
}
|
|
76
24
|
}
|
|
77
25
|
}
|
|
78
26
|
```
|
|
79
27
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- Apple Silicon Mac (Homebrew): `/opt/homebrew/bin/npx`
|
|
83
|
-
- Intel Mac (Homebrew): `/usr/local/bin/npx`
|
|
84
|
-
- nvm users: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
85
|
-
|
|
86
|
-
**Windows/Linux users** can typically use `"command": "npx"` directly.
|
|
28
|
+
> Replace `/opt/homebrew/bin/npx` with your actual path from step 1.
|
|
87
29
|
|
|
88
|
-
|
|
30
|
+
3. Restart the app.
|
|
89
31
|
|
|
90
|
-
##
|
|
32
|
+
## Available Tools
|
|
91
33
|
|
|
92
|
-
|
|
34
|
+
| Tool | Description |
|
|
35
|
+
| -------------------------------- | ----------------------------- |
|
|
36
|
+
| `list_components` | List all components |
|
|
37
|
+
| `get_component` | Get component details & types |
|
|
38
|
+
| `search_components` | Search by name |
|
|
39
|
+
| `list_hooks` | List all hooks |
|
|
40
|
+
| `get_hook` | Get hook details |
|
|
41
|
+
| `get_design_tokens` | Get design tokens |
|
|
42
|
+
| `get_component_template` | New component template |
|
|
43
|
+
| `get_css_module_guidelines` | CSS Module patterns |
|
|
44
|
+
| `analyze_component_dependencies` | Dependency analysis |
|
|
93
45
|
|
|
94
|
-
|
|
46
|
+
## Development
|
|
95
47
|
|
|
96
48
|
```bash
|
|
97
|
-
# Install dependencies
|
|
98
49
|
yarn install
|
|
99
|
-
|
|
100
|
-
#
|
|
101
|
-
yarn build
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
This creates `data/design-system.json` with all component, hook, and token information.
|
|
105
|
-
|
|
106
|
-
### Testing Locally
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
# After building, test the server
|
|
110
|
-
node index.js
|
|
50
|
+
yarn build # Generate design-system.json
|
|
51
|
+
node index.js # Test locally
|
|
111
52
|
```
|
|
112
53
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
npx @modelcontextprotocol/inspector node index.js
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Publishing
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
# The prepublishOnly script runs yarn build automatically
|
|
123
|
-
yarn publish
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## š How It Works
|
|
127
|
-
|
|
128
|
-
### Build Time (CI/CD)
|
|
129
|
-
|
|
130
|
-
1. `build-mcp-data.js` scans the design system:
|
|
131
|
-
|
|
132
|
-
- Reads all components from `src/components/`
|
|
133
|
-
- Reads all hooks from `src/hooks/`
|
|
134
|
-
- Reads all design tokens from `design-tokens/`
|
|
135
|
-
|
|
136
|
-
2. Extracts file contents and metadata
|
|
137
|
-
|
|
138
|
-
3. Bundles everything into `data/design-system.json`
|
|
139
|
-
|
|
140
|
-
4. Package is published to npm with bundled data
|
|
141
|
-
|
|
142
|
-
### Runtime (User's Machine)
|
|
143
|
-
|
|
144
|
-
1. User runs `npx @spaced-out/genesis-mcp-server`
|
|
145
|
-
|
|
146
|
-
2. Server loads pre-bundled `data/design-system.json`
|
|
147
|
-
|
|
148
|
-
3. Serves data via MCP protocol (stdio)
|
|
149
|
-
|
|
150
|
-
4. AI assistant queries the server for design system info
|
|
151
|
-
|
|
152
|
-
**Result:** No local design system needed! āØ
|
|
153
|
-
|
|
154
|
-
## šļø Architecture
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
ui-design-system/
|
|
158
|
-
āāā src/
|
|
159
|
-
ā āāā components/ # Source components
|
|
160
|
-
ā āāā hooks/ # Source hooks
|
|
161
|
-
āāā design-tokens/ # Source tokens
|
|
162
|
-
āāā mcp/ # š MCP Server
|
|
163
|
-
āāā index.js # MCP server (reads from data/)
|
|
164
|
-
āāā build-mcp-data.js # Build script (extracts from ../)
|
|
165
|
-
āāā data/
|
|
166
|
-
ā āāā design-system.json # Bundled data (git-ignored)
|
|
167
|
-
āāā package.json
|
|
168
|
-
āāā README.md
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## š Available Tools
|
|
172
|
-
|
|
173
|
-
The MCP server provides these tools to AI assistants:
|
|
174
|
-
|
|
175
|
-
- `list_components` - List all available components
|
|
176
|
-
- `get_component` - Get detailed component information **including exported types** (e.g., IconType, IconSize from Icon component)
|
|
177
|
-
- `search_components` - Search components by name
|
|
178
|
-
- `list_hooks` - List all available hooks
|
|
179
|
-
- `get_hook` - Get detailed hook information
|
|
180
|
-
- `get_design_tokens` - Get all or filtered design tokens
|
|
181
|
-
- `get_component_template` - Get template for new components
|
|
182
|
-
- `get_design_token_import_guidelines` - Get guidelines for importing design tokens in CSS Module files with correct paths and examples
|
|
183
|
-
- `get_css_module_guidelines` - **NEW!** Get comprehensive CSS Module styling guidelines including class naming conventions (BEM patterns), token usage, icon color patterns, and common mistakes to avoid
|
|
184
|
-
- `analyze_component_dependencies` - Analyze component dependencies
|
|
185
|
-
|
|
186
|
-
## š CI/CD Integration
|
|
187
|
-
|
|
188
|
-
### Automatic Publishing
|
|
189
|
-
|
|
190
|
-
The MCP server is automatically published to npm via GitHub Actions (`.github/workflows/publish-mcp.yml`).
|
|
191
|
-
|
|
192
|
-
**Triggers:**
|
|
193
|
-
|
|
194
|
-
- Push to `master` branch when files change in:
|
|
195
|
-
- `src/**` (component/hook changes)
|
|
196
|
-
- `design-tokens/**` (token changes)
|
|
197
|
-
- `mcp/**` (MCP server changes)
|
|
198
|
-
- Manual workflow dispatch
|
|
199
|
-
|
|
200
|
-
**Process:**
|
|
201
|
-
|
|
202
|
-
1. **Auto-version bump**: If `src/` or `design-tokens/` changed, automatically bumps patch version
|
|
203
|
-
2. **Build**: Generates fresh MCP data bundle with latest design system changes
|
|
204
|
-
3. **Commit**: Pushes version bump back to master (with `[skip ci]` to avoid loops)
|
|
205
|
-
4. **Publish**: Publishes new version to npm
|
|
206
|
-
|
|
207
|
-
**What this means for you:**
|
|
208
|
-
|
|
209
|
-
ā
Update a component ā Merge to master ā New MCP version automatically published!
|
|
210
|
-
|
|
211
|
-
No need to manually bump versions when changing design system files. The workflow handles it for you.
|
|
212
|
-
|
|
213
|
-
### Version Management
|
|
214
|
-
|
|
215
|
-
**Automatic (recommended):**
|
|
216
|
-
|
|
217
|
-
- Changes to `src/` or `design-tokens/` ā patch version bumped automatically
|
|
218
|
-
- E.g., `1.0.5` ā `1.0.6`
|
|
219
|
-
|
|
220
|
-
**Manual (for major/minor releases):**
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
cd mcp
|
|
224
|
-
yarn version --minor # or --major
|
|
225
|
-
git push --follow-tags
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Manual MCP-only changes:**
|
|
229
|
-
|
|
230
|
-
- If you only change files in `mcp/`, manually bump the version to publish
|
|
231
|
-
|
|
232
|
-
## š Data Size
|
|
233
|
-
|
|
234
|
-
The bundled JSON includes:
|
|
235
|
-
|
|
236
|
-
- Full TypeScript component implementations
|
|
237
|
-
- Storybook stories
|
|
238
|
-
- CSS modules
|
|
239
|
-
- Design tokens
|
|
240
|
-
- Hook implementations
|
|
241
|
-
|
|
242
|
-
Typical size: 5-15 MB (cached by npm, so only downloaded once)
|
|
243
|
-
|
|
244
|
-
## š Private Packages
|
|
245
|
-
|
|
246
|
-
If publishing to a private npm registry:
|
|
247
|
-
|
|
248
|
-
```json
|
|
249
|
-
{
|
|
250
|
-
"publishConfig": {
|
|
251
|
-
"registry": "https://your-private-registry.com"
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
Users configure their registry:
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
npm config set @spaced-out:registry https://your-private-registry.com
|
|
260
|
-
# or with yarn
|
|
261
|
-
yarn config set registry https://your-private-registry.com
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## š Troubleshooting
|
|
265
|
-
|
|
266
|
-
### "spawn npx ENOENT" Error (macOS/Windows)
|
|
267
|
-
|
|
268
|
-
**Symptoms:**
|
|
269
|
-
|
|
270
|
-
- Cursor or Claude Desktop logs show `spawn npx ENOENT` error
|
|
271
|
-
- MCP server fails to start with connection errors
|
|
272
|
-
- Error message: `Server transport closed unexpectedly`
|
|
273
|
-
|
|
274
|
-
**Cause:**
|
|
275
|
-
GUI applications on macOS and Windows don't inherit your terminal's PATH environment variables, so they cannot find the `npx` command.
|
|
276
|
-
|
|
277
|
-
**Solution:**
|
|
278
|
-
|
|
279
|
-
1. Find your `npx` path in terminal:
|
|
280
|
-
|
|
281
|
-
**macOS/Linux:**
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
which npx
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
**Windows (PowerShell):**
|
|
288
|
-
|
|
289
|
-
```powershell
|
|
290
|
-
where.exe npx
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
2. Use the **full path** in your MCP configuration instead of just `"command": "npx"`:
|
|
294
|
-
|
|
295
|
-
**Example (macOS):**
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{
|
|
299
|
-
"mcpServers": {
|
|
300
|
-
"genesis-design-system": {
|
|
301
|
-
"command": "/opt/homebrew/bin/npx",
|
|
302
|
-
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Example (Windows):**
|
|
309
|
-
|
|
310
|
-
```json
|
|
311
|
-
{
|
|
312
|
-
"mcpServers": {
|
|
313
|
-
"genesis-design-system": {
|
|
314
|
-
"command": "C:\\Program Files\\nodejs\\npx.cmd",
|
|
315
|
-
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**Common npx locations:**
|
|
322
|
-
|
|
323
|
-
**macOS:**
|
|
324
|
-
|
|
325
|
-
- Homebrew (Apple Silicon): `/opt/homebrew/bin/npx`
|
|
326
|
-
- Homebrew (Intel): `/usr/local/bin/npx`
|
|
327
|
-
- nvm: `/Users/YOUR_USERNAME/.nvm/versions/node/vX.X.X/bin/npx`
|
|
328
|
-
|
|
329
|
-
**Windows:**
|
|
330
|
-
|
|
331
|
-
- Default Node.js: `C:\Program Files\nodejs\npx.cmd`
|
|
332
|
-
- nvm-windows: `C:\Users\YOUR_USERNAME\AppData\Roaming\nvm\vX.X.X\npx.cmd`
|
|
333
|
-
|
|
334
|
-
**Linux:**
|
|
335
|
-
|
|
336
|
-
- Most distributions: `/usr/bin/npx` or `/usr/local/bin/npx`
|
|
337
|
-
|
|
338
|
-
3. Restart your AI assistant (Cursor or Claude Desktop)
|
|
339
|
-
|
|
340
|
-
**Verify the fix:**
|
|
341
|
-
After restarting, check the application logs. You should see successful initialization:
|
|
342
|
-
|
|
343
|
-
```
|
|
344
|
-
ā
Loaded Genesis design system data
|
|
345
|
-
Version: X.X.X
|
|
346
|
-
Components: XX
|
|
347
|
-
Hooks: XX
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
Instead of `ENOENT` errors.
|
|
351
|
-
|
|
352
|
-
### MCP Inspector (Advanced Debugging)
|
|
353
|
-
|
|
354
|
-
If you're still having issues, use the MCP Inspector to debug:
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
npx @modelcontextprotocol/inspector
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
Navigate to `http://127.0.0.1:6274` and configure:
|
|
361
|
-
|
|
362
|
-
- **Transport type:** Stdio
|
|
363
|
-
- **Command:** Your full npx path (e.g., `/opt/homebrew/bin/npx`)
|
|
364
|
-
- **Arguments:** `-y @spaced-out/genesis-mcp-server@latest`
|
|
365
|
-
|
|
366
|
-
Click **Connect** to test the connection. If it fails, check the terminal logs for detailed error messages.
|
|
367
|
-
|
|
368
|
-
### Test the Server Directly
|
|
369
|
-
|
|
370
|
-
Test if the server runs correctly in your terminal:
|
|
371
|
-
|
|
372
|
-
```bash
|
|
373
|
-
npx -y @spaced-out/genesis-mcp-server@latest
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
You should see:
|
|
377
|
-
|
|
378
|
-
```
|
|
379
|
-
ā
Loaded Genesis design system data
|
|
380
|
-
Version: X.X.X
|
|
381
|
-
Components: XX
|
|
382
|
-
Hooks: XX
|
|
383
|
-
Built: YYYY-MM-DD
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
If this fails, there may be an issue with the published package.
|
|
387
|
-
|
|
388
|
-
### Package Not Found
|
|
389
|
-
|
|
390
|
-
**Error:** `npm ERR! 404 '@spaced-out/genesis-mcp-server@latest' is not in this registry`
|
|
391
|
-
|
|
392
|
-
**Solution:**
|
|
393
|
-
|
|
394
|
-
- Verify the package is published: `npm view @spaced-out/genesis-mcp-server`
|
|
395
|
-
- If using a private registry, ensure you're authenticated
|
|
396
|
-
- Check your npm registry configuration: `npm config get registry`
|
|
397
|
-
|
|
398
|
-
### Node.js Version
|
|
399
|
-
|
|
400
|
-
**Error:** `The engine "node" is incompatible with this module`
|
|
401
|
-
|
|
402
|
-
**Solution:**
|
|
403
|
-
This server requires Node.js >= 18.0.0. Update your Node.js installation:
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
node --version # Check current version
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
Use [nvm](https://github.com/nvm-sh/nvm) or download from [nodejs.org](https://nodejs.org/).
|
|
410
|
-
|
|
411
|
-
## š¤ Contributing
|
|
412
|
-
|
|
413
|
-
When updating the design system:
|
|
414
|
-
|
|
415
|
-
1. Changes to components/hooks/tokens are automatically detected
|
|
416
|
-
2. CI/CD runs `npm run build` to regenerate data
|
|
417
|
-
3. New version is published to npm
|
|
418
|
-
4. Users get updates on next `npx` run (or immediately with `@latest`)
|
|
419
|
-
|
|
420
|
-
## šØ Integration with Figma MCP
|
|
421
|
-
|
|
422
|
-
The Genesis MCP server works seamlessly alongside the Figma MCP server, enabling a powerful design-to-code workflow. By using both servers together, you can bridge design and implementation.
|
|
423
|
-
|
|
424
|
-
### Why Use Both?
|
|
425
|
-
|
|
426
|
-
**Figma MCP** provides:
|
|
427
|
-
|
|
428
|
-
- Design screenshots and visual context
|
|
429
|
-
- Component properties and variants from Figma
|
|
430
|
-
- Design tokens and variables from Figma files
|
|
431
|
-
- Layout measurements and spacing
|
|
432
|
-
|
|
433
|
-
**Genesis MCP** provides:
|
|
434
|
-
|
|
435
|
-
- Actual React component implementations
|
|
436
|
-
- Design system tokens and guidelines
|
|
437
|
-
- TypeScript types and APIs
|
|
438
|
-
- CSS Module styling patterns
|
|
439
|
-
|
|
440
|
-
Together, they create a complete workflow: **Design in Figma ā Implement with Genesis**
|
|
441
|
-
|
|
442
|
-
### Configuration Examples
|
|
443
|
-
|
|
444
|
-
You can run multiple MCP servers simultaneously:
|
|
445
|
-
|
|
446
|
-
**VS Code/Cursor:**
|
|
447
|
-
|
|
448
|
-
```json
|
|
449
|
-
{
|
|
450
|
-
"mcpServers": {
|
|
451
|
-
"genesis-design-system": {
|
|
452
|
-
"command": "/opt/homebrew/bin/npx",
|
|
453
|
-
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
454
|
-
},
|
|
455
|
-
"figma-desktop": {
|
|
456
|
-
"command": "/opt/homebrew/bin/npx",
|
|
457
|
-
"args": ["-y", "@modelcontextprotocol/server-figma"]
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
**Claude Desktop:**
|
|
464
|
-
|
|
465
|
-
```json
|
|
466
|
-
{
|
|
467
|
-
"mcpServers": {
|
|
468
|
-
"genesis-design-system": {
|
|
469
|
-
"command": "/opt/homebrew/bin/npx",
|
|
470
|
-
"args": ["-y", "@spaced-out/genesis-mcp-server@latest"]
|
|
471
|
-
},
|
|
472
|
-
"figma-desktop": {
|
|
473
|
-
"command": "/opt/homebrew/bin/npx",
|
|
474
|
-
"args": ["-y", "@modelcontextprotocol/server-figma"]
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
### Workflow Examples
|
|
481
|
-
|
|
482
|
-
**Design-to-Code:**
|
|
483
|
-
|
|
484
|
-
```
|
|
485
|
-
"Show me the current Figma selection"
|
|
486
|
-
"Find the matching Genesis component for this design"
|
|
487
|
-
"Implement this Figma button using Genesis Button component"
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
**Token Mapping:**
|
|
491
|
-
|
|
492
|
-
```
|
|
493
|
-
"Compare Figma colors with Genesis color tokens"
|
|
494
|
-
"What Genesis spacing token matches this 16px gap?"
|
|
495
|
-
"Map this Figma shadow to Genesis elevation tokens"
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
**Validation:**
|
|
499
|
-
|
|
500
|
-
```
|
|
501
|
-
"Does Genesis have a component matching this Figma design?"
|
|
502
|
-
"Are these Figma colors available in Genesis palette?"
|
|
503
|
-
"What Genesis components would I need for this Figma screen?"
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
### Requirements
|
|
507
|
-
|
|
508
|
-
- **Figma MCP**: Figma Desktop app running with design files open
|
|
509
|
-
- **Genesis MCP**: Node.js >= 18.0.0
|
|
510
|
-
|
|
511
|
-
See [Figma MCP documentation](https://modelcontextprotocol.io/docs/tools/figma) for Figma setup details.
|
|
512
|
-
|
|
513
|
-
## š Additional Resources
|
|
514
|
-
|
|
515
|
-
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
516
|
-
- [Figma MCP Documentation](https://modelcontextprotocol.io/docs/tools/figma)
|
|
517
|
-
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
|
|
518
|
-
- [Genesis Storybook MCP Guide](https://your-storybook-url.com/?path=/docs/model-context-protocol--docs)
|
|
519
|
-
|
|
520
|
-
## š License
|
|
54
|
+
## Troubleshooting
|
|
521
55
|
|
|
522
|
-
|
|
56
|
+
**"spawn npx ENOENT"**: Use full path to `npx` (see setup above).
|
|
523
57
|
|
|
524
|
-
|
|
58
|
+
**Package not found**: Run `npm view @spaced-out/genesis-mcp` to verify.
|
|
525
59
|
|
|
526
|
-
**
|
|
60
|
+
**Node version**: Requires Node.js >= 18.0.0
|
package/mcp/build-mcp-data.js
CHANGED
|
@@ -70,72 +70,69 @@ function getAllFilesRecursively(dirPath, filesList = [], baseDir = dirPath) {
|
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Extract all components with their files (including sub-components)
|
|
73
|
+
* For main component files and sub-components, we use .d.ts files from lib/
|
|
74
|
+
* to avoid exposing source code in the public npm package
|
|
73
75
|
*/
|
|
74
76
|
function buildComponentsData() {
|
|
75
77
|
console.log('š¦ Extracting components...');
|
|
76
|
-
const
|
|
78
|
+
const srcComponentsPath = join(DESIGN_SYSTEM_PATH, 'src/components');
|
|
79
|
+
const libComponentsPath = join(DESIGN_SYSTEM_PATH, 'lib/components');
|
|
77
80
|
const components = {};
|
|
78
81
|
|
|
79
|
-
if (!existsSync(
|
|
82
|
+
if (!existsSync(srcComponentsPath)) {
|
|
80
83
|
console.warn('ā ļø Components path not found');
|
|
81
84
|
return components;
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
const componentDirs = getDirectories(
|
|
87
|
+
const componentDirs = getDirectories(srcComponentsPath).filter(name => name !== 'index.ts');
|
|
85
88
|
|
|
86
89
|
for (const componentName of componentDirs) {
|
|
87
|
-
const
|
|
90
|
+
const srcComponentDir = join(srcComponentsPath, componentName);
|
|
91
|
+
const libComponentDir = join(libComponentsPath, componentName);
|
|
88
92
|
|
|
89
|
-
// Get all files in the component directory
|
|
90
|
-
const allFiles = getAllFilesRecursively(
|
|
93
|
+
// Get all files in the component directory (from src for reference)
|
|
94
|
+
const allFiles = getAllFilesRecursively(srcComponentDir);
|
|
91
95
|
|
|
92
|
-
// Extract main component
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const mainContent = safeReadFile(mainTsx) || safeReadFile(mainTs);
|
|
96
|
+
// Extract main component .d.ts file from lib/ (type definitions only)
|
|
97
|
+
const mainDts = join(libComponentDir, `${componentName}.d.ts`);
|
|
98
|
+
const mainContent = safeReadFile(mainDts);
|
|
96
99
|
|
|
97
|
-
// Extract story files
|
|
98
|
-
const storyTsx = join(
|
|
99
|
-
const storyTs = join(
|
|
100
|
+
// Extract story files (keep from src - useful for usage examples)
|
|
101
|
+
const storyTsx = join(srcComponentDir, `${componentName}.stories.tsx`);
|
|
102
|
+
const storyTs = join(srcComponentDir, `${componentName}.stories.ts`);
|
|
100
103
|
const storyContent = safeReadFile(storyTsx) || safeReadFile(storyTs);
|
|
101
104
|
|
|
102
|
-
// Extract CSS file
|
|
103
|
-
const cssFile = join(
|
|
105
|
+
// Extract CSS file (keep from src - needed for styling reference)
|
|
106
|
+
const cssFile = join(srcComponentDir, `${componentName}.module.css`);
|
|
104
107
|
const cssContent = safeReadFile(cssFile);
|
|
105
108
|
|
|
106
|
-
// Extract index file
|
|
107
|
-
const
|
|
108
|
-
const indexContent = safeReadFile(
|
|
109
|
+
// Extract index .d.ts file from lib/
|
|
110
|
+
const indexDts = join(libComponentDir, 'index.d.ts');
|
|
111
|
+
const indexContent = safeReadFile(indexDts);
|
|
109
112
|
|
|
110
|
-
// Extract all additional
|
|
113
|
+
// Extract all additional sub-component .d.ts files from lib/
|
|
111
114
|
const additionalFiles = {};
|
|
112
|
-
|
|
115
|
+
const libAllFiles = existsSync(libComponentDir) ? getAllFilesRecursively(libComponentDir) : [];
|
|
116
|
+
|
|
117
|
+
for (const file of libAllFiles) {
|
|
113
118
|
// Skip main files we already extracted
|
|
114
119
|
if (
|
|
115
|
-
file === `${componentName}.
|
|
116
|
-
file ===
|
|
117
|
-
file
|
|
118
|
-
file
|
|
119
|
-
file === `${componentName}.module.css` ||
|
|
120
|
-
file === 'index.ts' ||
|
|
121
|
-
file.endsWith('.module.css') ||
|
|
122
|
-
file.endsWith('.stories.tsx') ||
|
|
123
|
-
file.endsWith('.stories.ts') ||
|
|
124
|
-
file.endsWith('.stories.module.css')
|
|
120
|
+
file === `${componentName}.d.ts` ||
|
|
121
|
+
file === 'index.d.ts' ||
|
|
122
|
+
!file.endsWith('.d.ts') ||
|
|
123
|
+
file.endsWith('.d.ts.map')
|
|
125
124
|
) {
|
|
126
125
|
continue;
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
};
|
|
138
|
-
}
|
|
128
|
+
// Include .d.ts files for sub-components
|
|
129
|
+
const fullPath = join(libComponentDir, file);
|
|
130
|
+
const content = safeReadFile(fullPath);
|
|
131
|
+
if (content) {
|
|
132
|
+
additionalFiles[file] = {
|
|
133
|
+
path: file,
|
|
134
|
+
content: content
|
|
135
|
+
};
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
|
|
@@ -143,10 +140,10 @@ function buildComponentsData() {
|
|
|
143
140
|
name: componentName,
|
|
144
141
|
path: `src/components/${componentName}`,
|
|
145
142
|
files: {
|
|
146
|
-
main: mainContent ? { path: `${componentName}.
|
|
143
|
+
main: mainContent ? { path: `${componentName}.d.ts`, content: mainContent } : null,
|
|
147
144
|
story: storyContent ? { path: `${componentName}.stories.tsx`, content: storyContent } : null,
|
|
148
145
|
css: cssContent ? { path: `${componentName}.module.css`, content: cssContent } : null,
|
|
149
|
-
index: indexContent ? { path: 'index.ts', content: indexContent } : null,
|
|
146
|
+
index: indexContent ? { path: 'index.d.ts', content: indexContent } : null,
|
|
150
147
|
additional: additionalFiles,
|
|
151
148
|
},
|
|
152
149
|
allFiles,
|
|
@@ -159,48 +156,50 @@ function buildComponentsData() {
|
|
|
159
156
|
|
|
160
157
|
/**
|
|
161
158
|
* Extract all hooks
|
|
159
|
+
* For main hook files, we use .d.ts files from lib/
|
|
160
|
+
* to avoid exposing source code in the public npm package
|
|
162
161
|
*/
|
|
163
162
|
function buildHooksData() {
|
|
164
163
|
console.log('šŖ Extracting hooks...');
|
|
165
|
-
const
|
|
164
|
+
const srcHooksPath = join(DESIGN_SYSTEM_PATH, 'src/hooks');
|
|
165
|
+
const libHooksPath = join(DESIGN_SYSTEM_PATH, 'lib/hooks');
|
|
166
166
|
const hooks = {};
|
|
167
167
|
|
|
168
|
-
if (!existsSync(
|
|
168
|
+
if (!existsSync(srcHooksPath)) {
|
|
169
169
|
console.warn('ā ļø Hooks path not found');
|
|
170
170
|
return hooks;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
const hookDirs = getDirectories(
|
|
173
|
+
const hookDirs = getDirectories(srcHooksPath).filter(name => name !== 'index.ts');
|
|
174
174
|
|
|
175
175
|
for (const hookName of hookDirs) {
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
// Read main hook file
|
|
179
|
-
const mainTs = join(hookDir, `${hookName}.ts`);
|
|
180
|
-
const mainTsx = join(hookDir, `${hookName}.tsx`);
|
|
176
|
+
const srcHookDir = join(srcHooksPath, hookName);
|
|
177
|
+
const libHookDir = join(libHooksPath, hookName);
|
|
181
178
|
|
|
182
|
-
// Read
|
|
183
|
-
const
|
|
184
|
-
const
|
|
179
|
+
// Read main hook .d.ts file from lib/ (type definitions only)
|
|
180
|
+
const mainDts = join(libHookDir, `${hookName}.d.ts`);
|
|
181
|
+
const mainContent = safeReadFile(mainDts);
|
|
185
182
|
|
|
186
|
-
// Read
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
const mainContent = safeReadFile(mainTs) || safeReadFile(mainTsx);
|
|
183
|
+
// Read story file (keep from src - useful for usage examples)
|
|
184
|
+
const storyTsx = join(srcHookDir, `${hookName}.stories.tsx`);
|
|
185
|
+
const storyTs = join(srcHookDir, `${hookName}.stories.ts`);
|
|
190
186
|
const storyContent = safeReadFile(storyTsx) || safeReadFile(storyTs);
|
|
191
|
-
const indexContent = safeReadFile(indexFile);
|
|
192
187
|
|
|
193
|
-
|
|
194
|
-
|
|
188
|
+
// Read index .d.ts file from lib/
|
|
189
|
+
const indexDts = join(libHookDir, 'index.d.ts');
|
|
190
|
+
const indexContent = safeReadFile(indexDts);
|
|
191
|
+
|
|
192
|
+
const allFiles = existsSync(srcHookDir)
|
|
193
|
+
? readdirSync(srcHookDir).filter(f => !f.startsWith('.'))
|
|
195
194
|
: [];
|
|
196
195
|
|
|
197
196
|
hooks[hookName] = {
|
|
198
197
|
name: hookName,
|
|
199
198
|
path: `src/hooks/${hookName}`,
|
|
200
199
|
files: {
|
|
201
|
-
main: mainContent ? { path: `${hookName}.ts`, content: mainContent } : null,
|
|
200
|
+
main: mainContent ? { path: `${hookName}.d.ts`, content: mainContent } : null,
|
|
202
201
|
story: storyContent ? { path: `${hookName}.stories.tsx`, content: storyContent } : null,
|
|
203
|
-
index: indexContent ? { path: 'index.ts', content: indexContent } : null,
|
|
202
|
+
index: indexContent ? { path: 'index.d.ts', content: indexContent } : null,
|
|
204
203
|
},
|
|
205
204
|
allFiles,
|
|
206
205
|
};
|
|
@@ -254,30 +253,37 @@ function buildTokensData() {
|
|
|
254
253
|
|
|
255
254
|
/**
|
|
256
255
|
* Extract all utils
|
|
256
|
+
* For util files, we use .d.ts files from lib/
|
|
257
|
+
* to avoid exposing source code in the public npm package
|
|
257
258
|
*/
|
|
258
259
|
function buildUtilsData() {
|
|
259
260
|
console.log('š§ Extracting utils...');
|
|
260
|
-
const
|
|
261
|
+
const srcUtilsPath = join(DESIGN_SYSTEM_PATH, 'src/utils');
|
|
262
|
+
const libUtilsPath = join(DESIGN_SYSTEM_PATH, 'lib/utils');
|
|
261
263
|
const utils = {};
|
|
262
264
|
|
|
263
|
-
if (!existsSync(
|
|
265
|
+
if (!existsSync(srcUtilsPath)) {
|
|
264
266
|
console.warn('ā ļø Utils path not found');
|
|
265
267
|
return utils;
|
|
266
268
|
}
|
|
267
269
|
|
|
268
|
-
const utilDirs = getDirectories(
|
|
270
|
+
const utilDirs = getDirectories(srcUtilsPath);
|
|
269
271
|
|
|
270
272
|
for (const utilName of utilDirs) {
|
|
271
|
-
const
|
|
273
|
+
const srcUtilDir = join(srcUtilsPath, utilName);
|
|
274
|
+
const libUtilDir = join(libUtilsPath, utilName);
|
|
272
275
|
|
|
273
|
-
// Get all files in the util directory
|
|
274
|
-
const allFiles = getAllFilesRecursively(
|
|
276
|
+
// Get all files in the util directory (from src for reference)
|
|
277
|
+
const allFiles = getAllFilesRecursively(srcUtilDir);
|
|
275
278
|
|
|
276
|
-
// Read all
|
|
279
|
+
// Read all .d.ts files from lib/
|
|
277
280
|
const files = {};
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
+
const libAllFiles = existsSync(libUtilDir) ? getAllFilesRecursively(libUtilDir) : [];
|
|
282
|
+
|
|
283
|
+
for (const file of libAllFiles) {
|
|
284
|
+
// Only include .d.ts files (skip .js and .d.ts.map)
|
|
285
|
+
if (file.endsWith('.d.ts') && !file.endsWith('.d.ts.map')) {
|
|
286
|
+
const fullPath = join(libUtilDir, file);
|
|
281
287
|
const content = safeReadFile(fullPath);
|
|
282
288
|
if (content) {
|
|
283
289
|
files[file] = {
|
package/mcp/index.js
CHANGED
package/mcp/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@spaced-out/genesis-mcp
|
|
3
|
-
"version": "1.0.
|
|
2
|
+
"name": "@spaced-out/genesis-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "MCP server for Genesis UI Design System - provides AI assistants with access to components, hooks, and design tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
package/mcp/test-server.js
CHANGED
|
@@ -55,7 +55,7 @@ try {
|
|
|
55
55
|
console.log('\nš Next steps:');
|
|
56
56
|
console.log(' 1. Update package.json version if needed');
|
|
57
57
|
console.log(' 2. Publish: npm publish');
|
|
58
|
-
console.log(' 3. Users can run: npx @spaced-out/genesis-mcp
|
|
58
|
+
console.log(' 3. Users can run: npx @spaced-out/genesis-mcp@latest');
|
|
59
59
|
console.log('\nš MCP server is ready to use!\n');
|
|
60
60
|
|
|
61
61
|
} catch (error) {
|