@wizeworks/silicaui-mcp 0.3.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.
@@ -0,0 +1,63 @@
1
+ [
2
+ {
3
+ "name": "@wizeworks/silicaui",
4
+ "purpose": "Tailwind v4 plugin — design tokens + component CSS classes (the vocabulary every other package builds on).",
5
+ "install": "pnpm add -D @wizeworks/silicaui tailwindcss",
6
+ "version": "0.3.0"
7
+ },
8
+ {
9
+ "name": "@wizeworks/silicaui-react",
10
+ "purpose": "Typed React components over the @wizeworks/silicaui classes, built on Base UI.",
11
+ "install": "pnpm add @wizeworks/silicaui-react",
12
+ "version": "0.3.0"
13
+ },
14
+ {
15
+ "name": "@wizeworks/silicaui-html",
16
+ "purpose": "Framework-neutral node-tree schema + HTML projection + composed blocks (for non-React output).",
17
+ "install": "pnpm add @wizeworks/silicaui-html",
18
+ "version": "0.3.0"
19
+ },
20
+ {
21
+ "name": "@wizeworks/silicaui-behaviors",
22
+ "purpose": "Zero-dependency runtime that hydrates data-sui-* markers with interactivity (the vanilla-JS counterpart to @wizeworks/silicaui-react's Base UI behavior).",
23
+ "install": "pnpm add @wizeworks/silicaui-behaviors",
24
+ "version": "0.3.0"
25
+ },
26
+ {
27
+ "name": "@wizeworks/silicaui-builder",
28
+ "purpose": "The visual document editor/engine used to build the SilicaUI sitebuilder itself — not typically installed by app developers.",
29
+ "install": null,
30
+ "private": true,
31
+ "version": "0.3.0"
32
+ },
33
+ {
34
+ "name": "@wizeworks/silicaui-charts",
35
+ "purpose": "Apache ECharts wrapped and auto-themed to Silica's design tokens.",
36
+ "install": "pnpm add @wizeworks/silicaui-charts @wizeworks/silicaui-react",
37
+ "version": "0.3.0"
38
+ },
39
+ {
40
+ "name": "@wizeworks/silicaui-table",
41
+ "purpose": "TanStack Table wrapped in Silica's table CSS.",
42
+ "install": "pnpm add @wizeworks/silicaui-table @wizeworks/silicaui-react",
43
+ "version": "0.3.0"
44
+ },
45
+ {
46
+ "name": "@wizeworks/silicaui-editor",
47
+ "purpose": "TipTap rich-text editor with a Silica-styled toolbar.",
48
+ "install": "pnpm add @wizeworks/silicaui-editor @wizeworks/silicaui-react",
49
+ "version": "0.3.0"
50
+ },
51
+ {
52
+ "name": "@wizeworks/silicaui-dnd",
53
+ "purpose": "dnd-kit wrapped — SortableList + drag primitives.",
54
+ "install": "pnpm add @wizeworks/silicaui-dnd @wizeworks/silicaui-react",
55
+ "version": "0.3.0"
56
+ },
57
+ {
58
+ "name": "@wizeworks/silicaui-panels",
59
+ "purpose": "react-resizable-panels wrapped in Silica styling.",
60
+ "install": "pnpm add @wizeworks/silicaui-panels @wizeworks/silicaui-react",
61
+ "version": "0.3.0"
62
+ }
63
+ ]
@@ -0,0 +1,65 @@
1
+ {
2
+ "semanticColors": [
3
+ "primary",
4
+ "secondary",
5
+ "accent",
6
+ "neutral",
7
+ "info",
8
+ "success",
9
+ "warning",
10
+ "error"
11
+ ],
12
+ "light": {
13
+ "base-100": "oklch(98% 0.003 250)",
14
+ "base-200": "oklch(95% 0.004 250)",
15
+ "base-300": "oklch(90% 0.006 250)",
16
+ "base-content": "oklch(21% 0.012 255)",
17
+ "primary": "oklch(42% 0.055 252)",
18
+ "primary-content": "oklch(98% 0.004 250)",
19
+ "secondary": "oklch(55% 0.035 255)",
20
+ "secondary-content": "oklch(98% 0.004 250)",
21
+ "accent": "oklch(64% 0.13 211)",
22
+ "accent-content": "oklch(15% 0.02 255)",
23
+ "neutral": "oklch(26% 0.014 255)",
24
+ "neutral-content": "oklch(95% 0.004 250)",
25
+ "info": "oklch(68% 0.1 232)",
26
+ "info-content": "oklch(16% 0.03 232)",
27
+ "success": "oklch(70% 0.12 150)",
28
+ "success-content": "oklch(18% 0.03 150)",
29
+ "warning": "oklch(80% 0.11 85)",
30
+ "warning-content": "oklch(24% 0.04 85)",
31
+ "error": "oklch(58% 0.17 25)",
32
+ "error-content": "oklch(97% 0.01 25)"
33
+ },
34
+ "dark": {
35
+ "base-100": "oklch(16% 0.01 255)",
36
+ "base-200": "oklch(13.5% 0.01 255)",
37
+ "base-300": "oklch(11% 0.01 255)",
38
+ "base-content": "oklch(93% 0.006 250)",
39
+ "primary": "oklch(72% 0.06 252)",
40
+ "primary-content": "oklch(14% 0.015 255)",
41
+ "secondary": "oklch(78% 0.035 255)",
42
+ "secondary-content": "oklch(15% 0.015 255)",
43
+ "accent": "oklch(72% 0.13 211)",
44
+ "accent-content": "oklch(14% 0.02 255)",
45
+ "neutral": "oklch(32% 0.016 255)",
46
+ "neutral-content": "oklch(93% 0.006 250)",
47
+ "info": "oklch(74% 0.09 232)",
48
+ "info-content": "oklch(14% 0.03 232)",
49
+ "success": "oklch(75% 0.11 150)",
50
+ "success-content": "oklch(14% 0.03 150)",
51
+ "warning": "oklch(83% 0.1 85)",
52
+ "warning-content": "oklch(16% 0.04 85)",
53
+ "error": "oklch(66% 0.18 25)",
54
+ "error-content": "oklch(14% 0.03 25)"
55
+ },
56
+ "typography": {
57
+ "baseFontSize": "100% (≈16px) — an explicit anchor, not the UA default by accident; the whole rem-based type scale (text-md = 1rem) scales with it.",
58
+ "fontFamilyTokens": [
59
+ "--font-sans",
60
+ "--font-serif",
61
+ "--font-mono"
62
+ ],
63
+ "note": "Every non-namespace token (--size-field, --border, --depth, --duration, --ease, --focus-width, --focus-offset, --disabled-opacity, --noise, …) carries its default inline via var(--token, default) in each component, so an app's own :root/@theme override always wins."
64
+ }
65
+ }
@@ -0,0 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+
3
+ declare function createServer(): McpServer;
4
+ declare function main(): Promise<void>;
5
+
6
+ export { createServer, main };
package/dist/server.js ADDED
@@ -0,0 +1,240 @@
1
+ import { readFileSync } from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { z } from 'zod';
7
+
8
+ // src/server.ts
9
+ var here = path.dirname(fileURLToPath(import.meta.url));
10
+ var dataDir = path.join(here, "data");
11
+ function loadJson(name) {
12
+ return JSON.parse(readFileSync(path.join(dataDir, `${name}.json`), "utf8"));
13
+ }
14
+ var packages = loadJson("packages");
15
+ var tokens = loadJson("tokens");
16
+ var classesByComponent = loadJson("classes");
17
+ var blocks = loadJson("blocks");
18
+ var behaviors = loadJson("behaviors");
19
+ var components = loadJson("components");
20
+ function toKebab(name) {
21
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
22
+ }
23
+ function blockSummary(b) {
24
+ const { root: _root, ...summary } = b;
25
+ return summary;
26
+ }
27
+ function createServer() {
28
+ const server = new McpServer({
29
+ name: "@wizeworks/silicaui-mcp",
30
+ version: "0.1.0"
31
+ });
32
+ server.registerTool(
33
+ "list_packages",
34
+ {
35
+ title: "List Silica UI packages",
36
+ description: "List every package in the Silica UI family (@wizeworks/silicaui, @wizeworks/silicaui-react, @wizeworks/silicaui-html, @wizeworks/silicaui-behaviors, and the wrapper packages), with purpose, install command, and version.",
37
+ inputSchema: {}
38
+ },
39
+ async () => ({
40
+ content: [{ type: "text", text: JSON.stringify(packages, null, 2) }]
41
+ })
42
+ );
43
+ server.registerTool(
44
+ "list_components",
45
+ {
46
+ title: "List Silica UI components",
47
+ description: "List component names, categories, and source packages. Optionally filter to one package (e.g. '@wizeworks/silicaui-react', '@wizeworks/silicaui-charts').",
48
+ inputSchema: {
49
+ package: z.string().optional().describe("Filter to one package name, e.g. '@wizeworks/silicaui-react'.")
50
+ }
51
+ },
52
+ async ({ package: pkg }) => {
53
+ const filtered = pkg ? components.filter((c) => c.package === pkg) : components;
54
+ const summary = filtered.map(({ name, package: p, category, sourceFile }) => ({
55
+ name,
56
+ package: p,
57
+ category,
58
+ sourceFile
59
+ }));
60
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
61
+ }
62
+ );
63
+ server.registerTool(
64
+ "get_component",
65
+ {
66
+ title: "Get a Silica UI component's real props and usage example",
67
+ description: "Get a component's props (name, type, optional, doc \u2014 extracted from its actual TypeScript source) and a real, working usage example pulled from the playground demos. Use this instead of guessing prop names or shapes.",
68
+ inputSchema: {
69
+ name: z.string().describe("Component name, e.g. 'Button', 'DataTable', 'Select'.")
70
+ }
71
+ },
72
+ async ({ name }) => {
73
+ const component = components.find((c) => c.name.toLowerCase() === name.toLowerCase());
74
+ if (!component) {
75
+ return {
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: `No component named "${name}". Call list_components to see valid names.`
80
+ }
81
+ ],
82
+ isError: true
83
+ };
84
+ }
85
+ return { content: [{ type: "text", text: JSON.stringify(component, null, 2) }] };
86
+ }
87
+ );
88
+ server.registerTool(
89
+ "list_classes",
90
+ {
91
+ title: "List real Silica UI CSS class names",
92
+ description: "List the exact, literal CSS class names Silica UI generates for a core component (e.g. 'button', 'card', 'badge') \u2014 or all components if none given. These are extracted directly from the class generators, so they are never hallucinated. Also covers 'color-utilities' (text-*/bg-*/border-* for every declared color).",
93
+ inputSchema: {
94
+ component: z.string().optional().describe("A core @wizeworks/silicaui component name, e.g. 'button'. Omit to list every component's classes.")
95
+ }
96
+ },
97
+ async ({ component }) => {
98
+ if (!component) {
99
+ return { content: [{ type: "text", text: JSON.stringify(classesByComponent, null, 2) }] };
100
+ }
101
+ const key = toKebab(component);
102
+ const classes = classesByComponent[key];
103
+ if (!classes) {
104
+ return {
105
+ content: [
106
+ {
107
+ type: "text",
108
+ text: `No class data for "${component}". Known components: ${Object.keys(classesByComponent).join(", ")}`
109
+ }
110
+ ],
111
+ isError: true
112
+ };
113
+ }
114
+ return { content: [{ type: "text", text: JSON.stringify({ component: key, classes }, null, 2) }] };
115
+ }
116
+ );
117
+ server.registerTool(
118
+ "get_tokens",
119
+ {
120
+ title: "Get Silica UI design tokens",
121
+ description: "Get the semantic color list and their light/dark OKLCH values, plus the typography token model.",
122
+ inputSchema: {}
123
+ },
124
+ async () => ({ content: [{ type: "text", text: JSON.stringify(tokens, null, 2) }] })
125
+ );
126
+ server.registerTool(
127
+ "list_blocks",
128
+ {
129
+ title: "List Silica UI composed blocks",
130
+ description: "List composed page blocks from @wizeworks/silicaui-html (hero sections, FAQs, feature grids, \u2026) without their full node tree. Optionally filter by category or tag.",
131
+ inputSchema: {
132
+ category: z.string().optional(),
133
+ tag: z.string().optional()
134
+ }
135
+ },
136
+ async ({ category, tag }) => {
137
+ const filtered = blocks.filter(
138
+ (b) => (!category || b.category === category) && (!tag || (b.tags ?? []).includes(tag))
139
+ );
140
+ return { content: [{ type: "text", text: JSON.stringify(filtered.map(blockSummary), null, 2) }] };
141
+ }
142
+ );
143
+ server.registerTool(
144
+ "get_block",
145
+ {
146
+ title: "Get a Silica UI block's full node tree",
147
+ description: "Get one composed block's full definition, including its node tree \u2014 the real, validated structure to reuse or adapt, not a guess.",
148
+ inputSchema: {
149
+ key: z.string().describe("The block's stable key, e.g. 'hero_split_cta'.")
150
+ }
151
+ },
152
+ async ({ key }) => {
153
+ const block = blocks.find((b) => b.key === key);
154
+ if (!block) {
155
+ return {
156
+ content: [
157
+ {
158
+ type: "text",
159
+ text: `No block "${key}". Known keys: ${blocks.map((b) => b.key).join(", ")}`
160
+ }
161
+ ],
162
+ isError: true
163
+ };
164
+ }
165
+ return { content: [{ type: "text", text: JSON.stringify(block, null, 2) }] };
166
+ }
167
+ );
168
+ server.registerTool(
169
+ "list_behaviors",
170
+ {
171
+ title: "List Silica UI behavior types",
172
+ description: "List the closed set of interactive behaviors (carousel, disclosure, tabs, menu, marquee, scrollspy, counter, dismiss, toc) that @wizeworks/silicaui-behaviors hydrates from data-sui-* markers.",
173
+ inputSchema: {}
174
+ },
175
+ async () => ({ content: [{ type: "text", text: JSON.stringify(behaviors, null, 2) }] })
176
+ );
177
+ server.registerTool(
178
+ "get_behavior",
179
+ {
180
+ title: "Get one Silica UI behavior's contract",
181
+ description: "Get the marker contract and semantics for one behavior type.",
182
+ inputSchema: {
183
+ type: z.string().describe("Behavior type, e.g. 'disclosure'.")
184
+ }
185
+ },
186
+ async ({ type }) => {
187
+ const behavior = behaviors.find((b) => b.type === type);
188
+ if (!behavior) {
189
+ return {
190
+ content: [
191
+ {
192
+ type: "text",
193
+ text: `No behavior "${type}". Known types: ${behaviors.map((b) => b.type).join(", ")}`
194
+ }
195
+ ],
196
+ isError: true
197
+ };
198
+ }
199
+ return { content: [{ type: "text", text: JSON.stringify(behavior, null, 2) }] };
200
+ }
201
+ );
202
+ server.registerTool(
203
+ "search_docs",
204
+ {
205
+ title: "Search Silica UI catalog data",
206
+ description: "Full-text search across everything this server knows: component names/descriptions, block names/descriptions, behavior descriptions, literal CSS class names, and design tokens. Use this when you don't know the exact name to look up.",
207
+ inputSchema: {
208
+ query: z.string().describe("Search term, case-insensitive.")
209
+ }
210
+ },
211
+ async ({ query }) => {
212
+ const q = query.toLowerCase();
213
+ const matchedComponents = components.filter((c) => c.name.toLowerCase().includes(q) || c.description.toLowerCase().includes(q)).map((c) => ({ kind: "component", name: c.name, package: c.package }));
214
+ const matchedBlocks = blocks.filter((b) => b.name.toLowerCase().includes(q) || b.description.toLowerCase().includes(q)).map((b) => ({ kind: "block", key: b.key, name: b.name }));
215
+ const matchedBehaviors = behaviors.filter((b) => b.type.toLowerCase().includes(q) || b.description.toLowerCase().includes(q)).map((b) => ({ kind: "behavior", type: b.type }));
216
+ const matchedClasses = Object.entries(classesByComponent).flatMap(
217
+ ([component, classes]) => classes.filter((cls) => cls.toLowerCase().includes(q)).map((cls) => ({ kind: "class", component, class: cls }))
218
+ );
219
+ const matchedTokens = tokens.semanticColors.filter((name) => name.toLowerCase().includes(q)).map((name) => ({ kind: "token", name }));
220
+ const results = [
221
+ ...matchedComponents,
222
+ ...matchedBlocks,
223
+ ...matchedBehaviors,
224
+ ...matchedClasses,
225
+ ...matchedTokens
226
+ ];
227
+ return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
228
+ }
229
+ );
230
+ return server;
231
+ }
232
+ async function main() {
233
+ const server = createServer();
234
+ const transport = new StdioServerTransport();
235
+ await server.connect(transport);
236
+ }
237
+
238
+ export { createServer, main };
239
+ //# sourceMappingURL=server.js.map
240
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\n\nconst here = path.dirname(fileURLToPath(import.meta.url));\nconst dataDir = path.join(here, \"data\");\n\nfunction loadJson<T>(name: string): T {\n return JSON.parse(readFileSync(path.join(dataDir, `${name}.json`), \"utf8\")) as T;\n}\n\ninterface PackageMeta {\n name: string;\n purpose: string;\n install: string | null;\n private?: boolean;\n version: string;\n}\n\ninterface TokensData {\n semanticColors: string[];\n light: Record<string, string>;\n dark: Record<string, string>;\n typography: { baseFontSize: string; fontFamilyTokens: string[]; note: string };\n}\n\ninterface PropMember {\n name: string;\n optional: boolean;\n type: string;\n doc: string;\n}\n\ninterface PropsInterface {\n name: string;\n extends?: string;\n members: PropMember[];\n}\n\ninterface ComponentData {\n name: string;\n package: string;\n category: string;\n sourceFile: string;\n description: string;\n props: PropsInterface[];\n usageExample: string | null;\n}\n\ninterface BlockSlot {\n name: string;\n [key: string]: unknown;\n}\n\ninterface BlockData {\n key: string;\n name: string;\n category: string;\n version: string;\n description: string;\n tags?: string[];\n colors: string[];\n behaviors: string[];\n emailEligible: boolean;\n slots: BlockSlot[];\n root: unknown;\n preview?: unknown;\n}\n\ninterface BehaviorData {\n type: string;\n description: string;\n}\n\nconst packages = loadJson<PackageMeta[]>(\"packages\");\nconst tokens = loadJson<TokensData>(\"tokens\");\nconst classesByComponent = loadJson<Record<string, string[]>>(\"classes\");\nconst blocks = loadJson<BlockData[]>(\"blocks\");\nconst behaviors = loadJson<BehaviorData[]>(\"behaviors\");\nconst components = loadJson<ComponentData[]>(\"components\");\n\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\nfunction blockSummary(b: BlockData) {\n const { root: _root, ...summary } = b;\n return summary;\n}\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: \"@wizeworks/silicaui-mcp\",\n version: \"0.1.0\",\n });\n\n server.registerTool(\n \"list_packages\",\n {\n title: \"List Silica UI packages\",\n description:\n \"List every package in the Silica UI family (@wizeworks/silicaui, @wizeworks/silicaui-react, @wizeworks/silicaui-html, @wizeworks/silicaui-behaviors, and the wrapper packages), with purpose, install command, and version.\",\n inputSchema: {},\n },\n async () => ({\n content: [{ type: \"text\", text: JSON.stringify(packages, null, 2) }],\n }),\n );\n\n server.registerTool(\n \"list_components\",\n {\n title: \"List Silica UI components\",\n description:\n \"List component names, categories, and source packages. Optionally filter to one package (e.g. '@wizeworks/silicaui-react', '@wizeworks/silicaui-charts').\",\n inputSchema: {\n package: z.string().optional().describe(\"Filter to one package name, e.g. '@wizeworks/silicaui-react'.\"),\n },\n },\n async ({ package: pkg }) => {\n const filtered = pkg ? components.filter((c) => c.package === pkg) : components;\n const summary = filtered.map(({ name, package: p, category, sourceFile }) => ({\n name,\n package: p,\n category,\n sourceFile,\n }));\n return { content: [{ type: \"text\", text: JSON.stringify(summary, null, 2) }] };\n },\n );\n\n server.registerTool(\n \"get_component\",\n {\n title: \"Get a Silica UI component's real props and usage example\",\n description:\n \"Get a component's props (name, type, optional, doc — extracted from its actual TypeScript source) and a real, working usage example pulled from the playground demos. Use this instead of guessing prop names or shapes.\",\n inputSchema: {\n name: z.string().describe(\"Component name, e.g. 'Button', 'DataTable', 'Select'.\"),\n },\n },\n async ({ name }) => {\n const component = components.find((c) => c.name.toLowerCase() === name.toLowerCase());\n if (!component) {\n return {\n content: [\n {\n type: \"text\",\n text: `No component named \"${name}\". Call list_components to see valid names.`,\n },\n ],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify(component, null, 2) }] };\n },\n );\n\n server.registerTool(\n \"list_classes\",\n {\n title: \"List real Silica UI CSS class names\",\n description:\n \"List the exact, literal CSS class names Silica UI generates for a core component (e.g. 'button', 'card', 'badge') — or all components if none given. These are extracted directly from the class generators, so they are never hallucinated. Also covers 'color-utilities' (text-*/bg-*/border-* for every declared color).\",\n inputSchema: {\n component: z\n .string()\n .optional()\n .describe(\"A core @wizeworks/silicaui component name, e.g. 'button'. Omit to list every component's classes.\"),\n },\n },\n async ({ component }) => {\n if (!component) {\n return { content: [{ type: \"text\", text: JSON.stringify(classesByComponent, null, 2) }] };\n }\n const key = toKebab(component);\n const classes = classesByComponent[key];\n if (!classes) {\n return {\n content: [\n {\n type: \"text\",\n text: `No class data for \"${component}\". Known components: ${Object.keys(classesByComponent).join(\", \")}`,\n },\n ],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify({ component: key, classes }, null, 2) }] };\n },\n );\n\n server.registerTool(\n \"get_tokens\",\n {\n title: \"Get Silica UI design tokens\",\n description:\n \"Get the semantic color list and their light/dark OKLCH values, plus the typography token model.\",\n inputSchema: {},\n },\n async () => ({ content: [{ type: \"text\", text: JSON.stringify(tokens, null, 2) }] }),\n );\n\n server.registerTool(\n \"list_blocks\",\n {\n title: \"List Silica UI composed blocks\",\n description:\n \"List composed page blocks from @wizeworks/silicaui-html (hero sections, FAQs, feature grids, …) without their full node tree. Optionally filter by category or tag.\",\n inputSchema: {\n category: z.string().optional(),\n tag: z.string().optional(),\n },\n },\n async ({ category, tag }) => {\n const filtered = blocks.filter(\n (b) => (!category || b.category === category) && (!tag || (b.tags ?? []).includes(tag)),\n );\n return { content: [{ type: \"text\", text: JSON.stringify(filtered.map(blockSummary), null, 2) }] };\n },\n );\n\n server.registerTool(\n \"get_block\",\n {\n title: \"Get a Silica UI block's full node tree\",\n description:\n \"Get one composed block's full definition, including its node tree — the real, validated structure to reuse or adapt, not a guess.\",\n inputSchema: {\n key: z.string().describe(\"The block's stable key, e.g. 'hero_split_cta'.\"),\n },\n },\n async ({ key }) => {\n const block = blocks.find((b) => b.key === key);\n if (!block) {\n return {\n content: [\n {\n type: \"text\",\n text: `No block \"${key}\". Known keys: ${blocks.map((b) => b.key).join(\", \")}`,\n },\n ],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify(block, null, 2) }] };\n },\n );\n\n server.registerTool(\n \"list_behaviors\",\n {\n title: \"List Silica UI behavior types\",\n description:\n \"List the closed set of interactive behaviors (carousel, disclosure, tabs, menu, marquee, scrollspy, counter, dismiss, toc) that @wizeworks/silicaui-behaviors hydrates from data-sui-* markers.\",\n inputSchema: {},\n },\n async () => ({ content: [{ type: \"text\", text: JSON.stringify(behaviors, null, 2) }] }),\n );\n\n server.registerTool(\n \"get_behavior\",\n {\n title: \"Get one Silica UI behavior's contract\",\n description: \"Get the marker contract and semantics for one behavior type.\",\n inputSchema: {\n type: z.string().describe(\"Behavior type, e.g. 'disclosure'.\"),\n },\n },\n async ({ type }) => {\n const behavior = behaviors.find((b) => b.type === type);\n if (!behavior) {\n return {\n content: [\n {\n type: \"text\",\n text: `No behavior \"${type}\". Known types: ${behaviors.map((b) => b.type).join(\", \")}`,\n },\n ],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify(behavior, null, 2) }] };\n },\n );\n\n server.registerTool(\n \"search_docs\",\n {\n title: \"Search Silica UI catalog data\",\n description:\n \"Full-text search across everything this server knows: component names/descriptions, block names/descriptions, behavior descriptions, literal CSS class names, and design tokens. Use this when you don't know the exact name to look up.\",\n inputSchema: {\n query: z.string().describe(\"Search term, case-insensitive.\"),\n },\n },\n async ({ query }) => {\n const q = query.toLowerCase();\n const matchedComponents = components\n .filter((c) => c.name.toLowerCase().includes(q) || c.description.toLowerCase().includes(q))\n .map((c) => ({ kind: \"component\", name: c.name, package: c.package }));\n const matchedBlocks = blocks\n .filter((b) => b.name.toLowerCase().includes(q) || b.description.toLowerCase().includes(q))\n .map((b) => ({ kind: \"block\", key: b.key, name: b.name }));\n const matchedBehaviors = behaviors\n .filter((b) => b.type.toLowerCase().includes(q) || b.description.toLowerCase().includes(q))\n .map((b) => ({ kind: \"behavior\", type: b.type }));\n const matchedClasses = Object.entries(classesByComponent).flatMap(([component, classes]) =>\n classes\n .filter((cls) => cls.toLowerCase().includes(q))\n .map((cls) => ({ kind: \"class\" as const, component, class: cls })),\n );\n const matchedTokens = tokens.semanticColors\n .filter((name) => name.toLowerCase().includes(q))\n .map((name) => ({ kind: \"token\" as const, name }));\n const results = [\n ...matchedComponents,\n ...matchedBlocks,\n ...matchedBehaviors,\n ...matchedClasses,\n ...matchedTokens,\n ];\n return { content: [{ type: \"text\", text: JSON.stringify(results, null, 2) }] };\n },\n );\n\n return server;\n}\n\nexport async function main(): Promise<void> {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@wizeworks/silicaui-mcp",
3
+ "version": "0.3.0",
4
+ "description": "A local MCP server that lets AI coding assistants query the Silica UI design system — real class names, component props, blocks, and behaviors — instead of guessing.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "WizeWorks",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/silicaui/silicaui.git",
11
+ "directory": "packages/silicaui-mcp"
12
+ },
13
+ "homepage": "https://silicaui.com",
14
+ "bugs": "https://github.com/silicaui/silicaui/issues",
15
+ "sideEffects": false,
16
+ "bin": {
17
+ "silicaui-mcp": "bin/silicaui-mcp.mjs"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/server.d.ts",
22
+ "import": "./dist/server.js"
23
+ }
24
+ },
25
+ "main": "./dist/server.js",
26
+ "types": "./dist/server.d.ts",
27
+ "files": [
28
+ "dist",
29
+ "bin"
30
+ ],
31
+ "dependencies": {
32
+ "@modelcontextprotocol/sdk": "^1.29.0",
33
+ "zod": "^3.25.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.0.0",
37
+ "tsup": "^8.3.0",
38
+ "typescript": "^5.6.0"
39
+ },
40
+ "keywords": [
41
+ "mcp",
42
+ "model-context-protocol",
43
+ "design-system",
44
+ "silica",
45
+ "ai",
46
+ "claude"
47
+ ],
48
+ "scripts": {
49
+ "gen": "node scripts/gen-catalog.mjs",
50
+ "build": "tsup",
51
+ "dev": "tsup --watch",
52
+ "typecheck": "tsc --noEmit",
53
+ "verify": "node verify.mjs"
54
+ }
55
+ }