@hareru/mcp 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MUSUBI Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @hareru/mcp
2
+
3
+ MCP server for [Hareru UI](https://github.com/hareru-ai/ui) — exposes design tokens, component registry, and usage rules to AI agents via [Model Context Protocol](https://modelcontextprotocol.io/).
4
+
5
+ [![npm](https://img.shields.io/npm/v/@hareru/mcp)](https://www.npmjs.com/package/@hareru/mcp)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENSE)
7
+
8
+ ## Features
9
+
10
+ - **6 resources** — Tokens, token schema, component registry, component schema, task bundles, and consumer rules
11
+ - **5 tools** — Component usage, bundle usage, token validation, CSS mode recommendation, and group filtering
12
+ - **3 prompts** — UI generation, Tailwind coexistence, and consumer rules
13
+ - **stdio transport** — Works with Claude Desktop, Cursor, and any MCP-compatible client
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ # npm
19
+ npm install @hareru/mcp
20
+
21
+ # pnpm
22
+ pnpm add @hareru/mcp
23
+ ```
24
+
25
+ ### Claude Desktop Configuration
26
+
27
+ Add to your `claude_desktop_config.json`:
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "hareru-ui": {
33
+ "command": "npx",
34
+ "args": ["@hareru/mcp"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Resources
41
+
42
+ | URI | Description |
43
+ |-----|-------------|
44
+ | `hareru-ui://tokens` | DTCG design tokens (light/dark themes, 150+ CSS custom properties) |
45
+ | `hareru-ui://tokens/schema` | JSON Schema for design tokens — CSS variable enums and type constraints |
46
+ | `hareru-ui://components` | Component registry — 40+ components with CVA variants and Props interfaces |
47
+ | `hareru-ui://components/schema` | JSON Schema for the component registry |
48
+ | `hareru-ui://bundles` | Task bundles — curated component sets for common UI patterns |
49
+ | `hareru-ui://rules/consumer` | Consumer rules for AI agents — import patterns, styling rules, and token reference |
50
+
51
+ ## Tools
52
+
53
+ | Tool | Description | Parameters |
54
+ |------|-------------|------------|
55
+ | `get-component-usage` | Get usage docs for a component — import, variants, props, and JSX example | `componentName` (string) |
56
+ | `get-bundle-usage` | Get usage docs for a task bundle — components, CSS imports, and token categories | `bundleName` (string) |
57
+ | `validate-token-value` | Validate a CSS value against the token schema | `tokenType` (string), `value` (string) |
58
+ | `recommend-css-mode` | Recommend the best CSS import mode based on project context | `hasTailwind` (boolean), `componentCount` (number), `hasExistingReset?` (boolean) |
59
+ | `list-components-by-group` | List components filtered by group | `group` (enum: core, form, layout, overlay, navigation, feedback, data-display, agent, di-domain) |
60
+
61
+ ## Prompts
62
+
63
+ | Prompt | Description | Parameters |
64
+ |--------|-------------|------------|
65
+ | `create-ui` | Generate a UI component using Hareru UI design system | `description` (string), `framework?` (string) |
66
+ | `create-ui-tailwind` | Generate a component mixing Hareru UI and Tailwind CSS with Cascade Layer guidance | `description` (string) |
67
+ | `consumer-rules` | Get the rules for using Hareru UI in your project | — |
68
+
69
+ ## Programmatic Usage
70
+
71
+ ```ts
72
+ import { createServer } from "@hareru/mcp";
73
+
74
+ const server = createServer();
75
+
76
+ // Connect with stdio transport
77
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
78
+ const transport = new StdioServerTransport();
79
+ await server.connect(transport);
80
+ ```
81
+
82
+ ### Testing with InMemoryTransport
83
+
84
+ ```ts
85
+ import { createServer } from "@hareru/mcp";
86
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
87
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
88
+
89
+ const client = new Client({ name: "test", version: "1.0.0" });
90
+ const server = createServer();
91
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
92
+
93
+ await Promise.all([
94
+ client.connect(clientTransport),
95
+ server.connect(serverTransport),
96
+ ]);
97
+
98
+ const result = await client.callTool({
99
+ name: "get-component-usage",
100
+ arguments: { componentName: "Button" },
101
+ });
102
+ ```
103
+
104
+ ## Links
105
+
106
+ - [Documentation](https://ui.hareru.ai/docs/mcp-server)
107
+ - [GitHub](https://github.com/hareru-ai/ui/tree/main/packages/mcp)
108
+
109
+ ## License
110
+
111
+ [MIT](../../LICENSE) — Copyright (c) 2026 MUSUBI Inc.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { startServer } from '../dist/index.js';
3
+
4
+ startServer().catch((error) => {
5
+ console.error('Failed to start Hareru UI MCP server:', error);
6
+ process.exit(1);
7
+ });
@@ -0,0 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+
3
+ declare function createServer(): McpServer;
4
+ declare function startServer(): Promise<void>;
5
+
6
+ export { createServer, startServer };
package/dist/index.js ADDED
@@ -0,0 +1,664 @@
1
+ // src/index.ts
2
+ import { readFileSync } from "fs";
3
+ import { dirname, join } from "path";
4
+ import { fileURLToPath } from "url";
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+
8
+ // src/prompts.ts
9
+ import { z } from "zod";
10
+
11
+ // src/utils.ts
12
+ import {
13
+ loadTokens,
14
+ loadSchema,
15
+ loadRegistry,
16
+ loadComponentSchema,
17
+ loadConsumerRules,
18
+ CSS_MODES,
19
+ CSS_MODE_DESCRIPTIONS,
20
+ recommendCssMode
21
+ } from "@hareru/registry";
22
+
23
+ // src/prompts.ts
24
+ function registerPrompts(server) {
25
+ server.prompt(
26
+ "create-ui",
27
+ "Generate a UI component using Hareru UI design system",
28
+ {
29
+ description: z.string().describe(
30
+ 'What the component should do (e.g. "A settings form with name and email fields")'
31
+ ),
32
+ framework: z.string().optional().describe("Target framework: react (default)")
33
+ },
34
+ async ({ description, framework }) => {
35
+ const registry = loadRegistry();
36
+ const schema = loadSchema();
37
+ const componentList = registry.components.map((c) => {
38
+ const variants = c.variants ?? [];
39
+ const variantInfo = variants.length > 0 ? ` [${variants.flatMap((v) => Object.entries(v.variants).map(([k, opts]) => `${k}(${opts.join("|")})`)).join(", ")}]` : "";
40
+ const desc = c.description ? ` \u2014 ${c.description}` : "";
41
+ return `- ${c.name}${variantInfo}${desc}`;
42
+ }).join("\n");
43
+ const bundles = registry.taskBundles ?? [];
44
+ const bundleList = bundles.length > 0 ? bundles.map((b) => `- ${b.name}: ${b.description} (${b.components.length} components)`).join("\n") : "";
45
+ const cssVars = schema.properties.cssVariables.items.enum.slice(0, 20).join(", ");
46
+ const fw = framework ?? "react";
47
+ return {
48
+ messages: [
49
+ {
50
+ role: "user",
51
+ content: {
52
+ type: "text",
53
+ text: `You are a UI developer using the Hareru UI design system (${fw}).
54
+
55
+ ## Available Components
56
+
57
+ ${componentList}
58
+
59
+ ## Design Token CSS Variables (sample)
60
+
61
+ ${cssVars}, ...
62
+
63
+ ## Rules
64
+
65
+ 1. Import components from '@hareru/ui'. For CSS setup, refer to the consumer-rules (standalone: '@hareru/ui/styles.css', portable: '@hareru/tokens/css' + '@hareru/ui/styles/components.css')
66
+ 2. Use only semantic variant props (e.g. variant="default"), never hardcode CSS values
67
+ 3. Use CSS variables (--hui-*) for any custom styling
68
+ 4. All components support forwardRef
69
+ 5. Use BEM class naming (hui-*) if adding custom classes
70
+ 6. Colors use OKLCH format
71
+
72
+ ## Task
73
+
74
+ ${description}
75
+ ${bundleList ? `
76
+ ## Available Bundles
77
+
78
+ ${bundleList}
79
+ ` : ""}
80
+ Generate a complete ${fw} component that fulfills this requirement.`
81
+ }
82
+ }
83
+ ]
84
+ };
85
+ }
86
+ );
87
+ server.prompt(
88
+ "create-ui-tailwind",
89
+ "Generate a UI component mixing Hareru UI and Tailwind CSS with Cascade Layer guidance",
90
+ {
91
+ description: z.string().describe(
92
+ 'What the component should do (e.g. "A dashboard card with Tailwind layout and Hareru UI buttons")'
93
+ )
94
+ },
95
+ async ({ description }) => {
96
+ const registry = loadRegistry();
97
+ const componentList = registry.components.map((c) => {
98
+ const desc = c.description ? ` \u2014 ${c.description}` : "";
99
+ return `- ${c.name}${desc}`;
100
+ }).join("\n");
101
+ return {
102
+ messages: [
103
+ {
104
+ role: "user",
105
+ content: {
106
+ type: "text",
107
+ text: `You are a UI developer using Hareru UI + Tailwind CSS v4 together.
108
+
109
+ ## Cascade Layer Order
110
+
111
+ Declare this layer order at the top of your CSS entry point:
112
+
113
+ \`\`\`css
114
+ @layer theme, base, hui, components, utilities;
115
+ @import 'tailwindcss';
116
+ @import '@hareru/tokens/css';
117
+ @import '@hareru/ui/styles/components.layer.css';
118
+ \`\`\`
119
+
120
+ - Hareru components live in \`@layer hui\` \u2014 below Tailwind \`utilities\`
121
+ - Tailwind utility classes (e.g. \`flex\`, \`gap-4\`, \`p-2\`) can safely override Hareru layout
122
+ - Never use Tailwind classes to override Hareru component internals (colors, border-radius, shadows) \u2014 use \`--hui-*\` CSS variables instead
123
+
124
+ ## Mixing Classes Example
125
+
126
+ \`\`\`tsx
127
+ {/* Tailwind for layout, Hareru for components */}
128
+ <div className="flex gap-4 p-6">
129
+ <Card className="flex-1">
130
+ <CardHeader>Title</CardHeader>
131
+ <CardContent>
132
+ <Button variant="default">Action</Button>
133
+ </CardContent>
134
+ </Card>
135
+ </div>
136
+ \`\`\`
137
+
138
+ ## Available Components
139
+
140
+ ${componentList}
141
+
142
+ ## Rules
143
+
144
+ 1. Import components from \`@hareru/ui\`
145
+ 2. Use Tailwind utilities for layout (flex, grid, gap, padding, margin)
146
+ 3. Use Hareru components for interactive UI elements (Button, Input, Card, Dialog)
147
+ 4. Use \`--hui-*\` CSS variables for theming \u2014 do not override with Tailwind color classes
148
+ 5. Use BEM class naming (\`hui-*\`) if adding custom component styles
149
+ 6. Colors are OKLCH format
150
+
151
+ ## Task
152
+
153
+ ${description}
154
+
155
+ Generate a complete React component that combines Tailwind layout utilities with Hareru UI components.`
156
+ }
157
+ }
158
+ ]
159
+ };
160
+ }
161
+ );
162
+ server.prompt(
163
+ "consumer-rules",
164
+ "Get the rules for using Hareru UI in your project",
165
+ {},
166
+ async () => {
167
+ const rules = loadConsumerRules();
168
+ const CODE_BLOCK_SECTIONS = /* @__PURE__ */ new Set(["cssImports"]);
169
+ const rulesSections = Object.entries(rules.rules).map(([key, section]) => {
170
+ const ruleList = section.rules.map((r) => `- ${r}`).join("\n");
171
+ const examples = Object.entries(section.examples).map(
172
+ ([label, code]) => CODE_BLOCK_SECTIONS.has(key) ? `**${label}:**
173
+ \`\`\`css
174
+ ${code}
175
+ \`\`\`` : ` ${label}: ${code}`
176
+ ).join("\n");
177
+ return `### ${key}
178
+ ${section.description}
179
+
180
+ ${ruleList}
181
+
182
+ Examples:
183
+ ${examples}`;
184
+ }).join("\n\n");
185
+ const tokenRef = Object.entries(rules.tokenQuickReference).map(([category, pattern]) => `- ${category}: ${pattern}`).join("\n");
186
+ return {
187
+ messages: [
188
+ {
189
+ role: "user",
190
+ content: {
191
+ type: "text",
192
+ text: `# Hareru UI Consumer Rules (v${rules.version})
193
+
194
+ These rules apply when using Hareru UI in any project.
195
+
196
+ ## Rules
197
+
198
+ ${rulesSections}
199
+
200
+ ## Token Quick Reference
201
+
202
+ ${tokenRef}`
203
+ }
204
+ }
205
+ ]
206
+ };
207
+ }
208
+ );
209
+ }
210
+
211
+ // src/resources.ts
212
+ function registerResources(server) {
213
+ const schema = loadSchema();
214
+ const tokenCount = schema.properties.tokenCount.const;
215
+ const registry = loadRegistry();
216
+ server.resource(
217
+ "tokens",
218
+ "hareru-ui://tokens",
219
+ {
220
+ description: `DTCG design tokens (light/dark themes, ${tokenCount} CSS custom properties)`,
221
+ mimeType: "application/json"
222
+ },
223
+ async (uri) => ({
224
+ contents: [{ uri: uri.href, text: JSON.stringify(loadTokens(), null, 2) }]
225
+ })
226
+ );
227
+ server.resource(
228
+ "tokens-schema",
229
+ "hareru-ui://tokens/schema",
230
+ {
231
+ description: "JSON Schema for design tokens \u2014 CSS variable enums and type constraints",
232
+ mimeType: "application/json"
233
+ },
234
+ async (uri) => ({
235
+ contents: [{ uri: uri.href, text: JSON.stringify(loadSchema(), null, 2) }]
236
+ })
237
+ );
238
+ server.resource(
239
+ "components",
240
+ "hareru-ui://components",
241
+ {
242
+ description: `Component registry \u2014 ${registry.componentCount} components with CVA variants and Props interfaces`,
243
+ mimeType: "application/json"
244
+ },
245
+ async (uri) => ({
246
+ contents: [{ uri: uri.href, text: JSON.stringify(registry, null, 2) }]
247
+ })
248
+ );
249
+ server.resource(
250
+ "bundles",
251
+ "hareru-ui://bundles",
252
+ {
253
+ description: `Task bundles \u2014 ${registry.taskBundles?.length ?? 0} curated component sets for common UI patterns`,
254
+ mimeType: "application/json"
255
+ },
256
+ async (uri) => ({
257
+ contents: [{ uri: uri.href, text: JSON.stringify(registry.taskBundles ?? [], null, 2) }]
258
+ })
259
+ );
260
+ server.resource(
261
+ "components-schema",
262
+ "hareru-ui://components/schema",
263
+ {
264
+ description: "JSON Schema for the component registry",
265
+ mimeType: "application/json"
266
+ },
267
+ async (uri) => ({
268
+ contents: [{ uri: uri.href, text: JSON.stringify(loadComponentSchema(), null, 2) }]
269
+ })
270
+ );
271
+ server.resource(
272
+ "consumer-rules",
273
+ "hareru-ui://rules/consumer",
274
+ {
275
+ description: "Consumer rules for AI agents \u2014 import patterns, styling rules, and token reference",
276
+ mimeType: "application/json"
277
+ },
278
+ async (uri) => ({
279
+ contents: [{ uri: uri.href, text: JSON.stringify(loadConsumerRules(), null, 2) }]
280
+ })
281
+ );
282
+ }
283
+
284
+ // src/tools.ts
285
+ import { z as z2 } from "zod";
286
+ function escPipe(s) {
287
+ return s.replace(/\|/g, "\\|");
288
+ }
289
+ function formatVariantsTable(entry) {
290
+ const variants = entry.variants ?? [];
291
+ if (variants.length === 0) return "No CVA variants defined.";
292
+ const lines = ["| Variant | Options | Default |", "|---------|---------|---------|"];
293
+ for (const v of variants) {
294
+ for (const [key, options] of Object.entries(v.variants)) {
295
+ const defaultVal = v.defaultVariants[key] ?? "-";
296
+ lines.push(
297
+ `| ${escPipe(key)} | ${options.map(escPipe).join(", ")} | ${escPipe(defaultVal)} |`
298
+ );
299
+ }
300
+ }
301
+ return lines.join("\n");
302
+ }
303
+ function formatUsageMarkdown(entry) {
304
+ const parts = [];
305
+ parts.push(`# ${entry.displayName}`);
306
+ parts.push("");
307
+ parts.push(entry.description);
308
+ parts.push("");
309
+ if (entry.aiHint) {
310
+ parts.push("## AI Guidance");
311
+ parts.push("");
312
+ parts.push(entry.aiHint);
313
+ parts.push("");
314
+ }
315
+ parts.push("## Import");
316
+ parts.push("");
317
+ parts.push("```tsx");
318
+ const subs = entry.subcomponents ?? [];
319
+ const allNames = [entry.name, ...subs];
320
+ parts.push(`import { ${allNames.join(", ")} } from '@hareru/ui';`);
321
+ parts.push("```");
322
+ parts.push("");
323
+ parts.push("## CSS");
324
+ parts.push("");
325
+ parts.push("**Standalone:**");
326
+ parts.push("```css");
327
+ parts.push(`@import '@hareru/ui/styles.css';`);
328
+ parts.push("```");
329
+ parts.push("");
330
+ parts.push("**Per-component:**");
331
+ parts.push("```css");
332
+ parts.push(`@import '@hareru/tokens/css';`);
333
+ for (const dep of entry.requiredCssArtifacts ?? []) {
334
+ parts.push(`@import '@hareru/ui/${dep}';`);
335
+ }
336
+ parts.push(`@import '@hareru/ui/${entry.cssArtifact}';`);
337
+ parts.push("```");
338
+ parts.push("");
339
+ const variants = entry.variants ?? [];
340
+ const props = entry.props ?? [];
341
+ if (variants.length > 0) {
342
+ parts.push("## Variants");
343
+ parts.push("");
344
+ parts.push(formatVariantsTable(entry));
345
+ parts.push("");
346
+ }
347
+ if (props.length > 0) {
348
+ parts.push("## Props");
349
+ parts.push("");
350
+ for (const prop of props) {
351
+ if (prop.extends) {
352
+ parts.push(`- **${prop.name}** extends \`${prop.extends}\``);
353
+ } else {
354
+ parts.push(`- **${prop.name}**`);
355
+ }
356
+ }
357
+ parts.push("");
358
+ }
359
+ if (entry.peerComponents) {
360
+ parts.push("## Also Consider");
361
+ parts.push("");
362
+ for (const peer of entry.peerComponents) {
363
+ parts.push(`- ${peer}`);
364
+ }
365
+ parts.push("");
366
+ }
367
+ parts.push("## Example");
368
+ parts.push("");
369
+ parts.push("```tsx");
370
+ if (variants.length > 0) {
371
+ const firstVariant = variants[0];
372
+ const propsStr = Object.entries(firstVariant.defaultVariants).map(([k, v]) => `${k}="${v}"`).join(" ");
373
+ parts.push(`<${entry.name} ${propsStr}>Content</${entry.name}>`);
374
+ } else if (subs.length > 0) {
375
+ parts.push(`<${entry.name}>`);
376
+ for (const sub of subs) {
377
+ parts.push(` <${sub}>Content</${sub}>`);
378
+ }
379
+ parts.push(`</${entry.name}>`);
380
+ } else {
381
+ parts.push(`<${entry.name}>Content</${entry.name}>`);
382
+ }
383
+ parts.push("```");
384
+ return parts.join("\n");
385
+ }
386
+ function registerTools(server) {
387
+ server.tool(
388
+ "get-component-usage",
389
+ "Get usage documentation for a Hareru UI component \u2014 import, variants, props, and JSX example",
390
+ { componentName: z2.string().describe('Component name (e.g. "Button", "Card", "Alert")') },
391
+ async ({ componentName }) => {
392
+ const registry = loadRegistry();
393
+ const entry = registry.components.find(
394
+ (c) => c.name.toLowerCase() === componentName.toLowerCase()
395
+ );
396
+ if (!entry) {
397
+ const available = registry.components.map((c) => c.name).join(", ");
398
+ return {
399
+ content: [
400
+ {
401
+ type: "text",
402
+ text: `Component "${componentName}" not found. Available components: ${available}`
403
+ }
404
+ ],
405
+ isError: true
406
+ };
407
+ }
408
+ return {
409
+ content: [{ type: "text", text: formatUsageMarkdown(entry) }]
410
+ };
411
+ }
412
+ );
413
+ server.tool(
414
+ "get-bundle-usage",
415
+ "Get usage documentation for a Hareru UI task bundle \u2014 components, CSS imports, and token categories",
416
+ { bundleName: z2.string().describe('Bundle name (e.g. "agent-chat-shell", "form-basics")') },
417
+ async ({ bundleName }) => {
418
+ const registry = loadRegistry();
419
+ const bundles = registry.taskBundles ?? [];
420
+ const bundle = bundles.find((b) => b.name.toLowerCase() === bundleName.toLowerCase());
421
+ if (!bundle) {
422
+ const available = bundles.map((b) => b.name).join(", ");
423
+ return {
424
+ content: [
425
+ {
426
+ type: "text",
427
+ text: `Bundle "${bundleName}" not found. Available bundles: ${available}`
428
+ }
429
+ ],
430
+ isError: true
431
+ };
432
+ }
433
+ const componentMap = new Map(registry.components.map((c) => [c.name, c]));
434
+ const parts = [];
435
+ parts.push(`# Bundle: ${bundle.name}`);
436
+ parts.push("");
437
+ parts.push(bundle.description);
438
+ parts.push("");
439
+ const allImports = [];
440
+ for (const compName of bundle.components) {
441
+ const comp = componentMap.get(compName);
442
+ allImports.push(compName);
443
+ if (comp?.subcomponents) {
444
+ allImports.push(...comp.subcomponents);
445
+ }
446
+ }
447
+ parts.push("## Import");
448
+ parts.push("");
449
+ parts.push("```tsx");
450
+ parts.push(`import { ${allImports.join(", ")} } from '@hareru/ui';`);
451
+ parts.push("```");
452
+ parts.push("");
453
+ parts.push("## CSS");
454
+ parts.push("");
455
+ parts.push("**Standalone:**");
456
+ parts.push("```css");
457
+ parts.push(`@import '@hareru/ui/styles.css';`);
458
+ parts.push("```");
459
+ parts.push("");
460
+ parts.push("**Per-component:**");
461
+ parts.push("```css");
462
+ parts.push(`@import '@hareru/tokens/css';`);
463
+ for (const artifact of bundle.cssArtifacts) {
464
+ parts.push(`@import '@hareru/ui/${artifact}';`);
465
+ }
466
+ parts.push("```");
467
+ parts.push("");
468
+ parts.push("## Token Categories");
469
+ parts.push("");
470
+ parts.push(bundle.tokenCategories.join(", "));
471
+ parts.push("");
472
+ parts.push("## Components");
473
+ parts.push("");
474
+ for (const compName of bundle.components) {
475
+ const comp = componentMap.get(compName);
476
+ if (comp) {
477
+ parts.push(`- **${comp.name}** \u2014 ${comp.description}`);
478
+ } else {
479
+ parts.push(`- **${compName}**`);
480
+ }
481
+ }
482
+ parts.push("");
483
+ return {
484
+ content: [{ type: "text", text: parts.join("\n") }]
485
+ };
486
+ }
487
+ );
488
+ server.tool(
489
+ "validate-token-value",
490
+ "Validate a CSS token value against the Hareru UI design token schema",
491
+ {
492
+ tokenType: z2.string().describe(
493
+ "Token type: color, dimension, fontFamily, fontWeight, duration, number, shadow, typography, cubicBezier"
494
+ ),
495
+ value: z2.string().describe('The value to validate (e.g. "oklch(0.5 0.2 250)")')
496
+ },
497
+ async ({ tokenType, value }) => {
498
+ const schema = loadSchema();
499
+ const constraint = schema.properties.typeConstraints.properties[tokenType];
500
+ if (!constraint) {
501
+ const availableTypes = Object.keys(schema.properties.typeConstraints.properties).join(", ");
502
+ return {
503
+ content: [
504
+ {
505
+ type: "text",
506
+ text: `Unknown token type "${tokenType}". Available types: ${availableTypes}`
507
+ }
508
+ ],
509
+ isError: true
510
+ };
511
+ }
512
+ if (!constraint.pattern) {
513
+ return {
514
+ content: [
515
+ {
516
+ type: "text",
517
+ text: `Valid \u2014 token type "${tokenType}" has no pattern constraint (any ${constraint.type ?? "string"} value accepted).`
518
+ }
519
+ ]
520
+ };
521
+ }
522
+ let regex;
523
+ try {
524
+ regex = new RegExp(constraint.pattern);
525
+ } catch {
526
+ return {
527
+ content: [
528
+ {
529
+ type: "text",
530
+ text: `Error \u2014 invalid pattern for token type "${tokenType}": ${constraint.pattern}`
531
+ }
532
+ ],
533
+ isError: true
534
+ };
535
+ }
536
+ const isValid = regex.test(value);
537
+ if (isValid) {
538
+ return {
539
+ content: [
540
+ {
541
+ type: "text",
542
+ text: `Valid \u2014 "${value}" matches the ${tokenType} pattern: ${constraint.pattern}`
543
+ }
544
+ ]
545
+ };
546
+ }
547
+ return {
548
+ content: [
549
+ {
550
+ type: "text",
551
+ text: `Invalid \u2014 "${value}" does not match the ${tokenType} pattern.
552
+ Expected: ${constraint.pattern}
553
+ Description: ${constraint.description ?? tokenType}`
554
+ }
555
+ ]
556
+ };
557
+ }
558
+ );
559
+ server.tool(
560
+ "recommend-css-mode",
561
+ "Recommend the best CSS import mode for a Hareru UI project based on project context",
562
+ {
563
+ hasTailwind: z2.boolean().describe("Whether Tailwind CSS is detected in the project"),
564
+ componentCount: z2.number().int().min(0).describe("Number of Hareru components used in the project"),
565
+ hasExistingReset: z2.boolean().optional().describe(
566
+ "Whether the project already has a CSS reset or framework (e.g. Bootstrap, Pico CSS)"
567
+ )
568
+ },
569
+ async ({ hasTailwind, componentCount, hasExistingReset }) => {
570
+ const result = recommendCssMode({ hasTailwind, componentCount, hasExistingReset });
571
+ const allModes = CSS_MODES.map((m) => {
572
+ const marker = m === result.mode ? " \u2190 recommended" : "";
573
+ return `- **${m}**: ${CSS_MODE_DESCRIPTIONS[m]}${marker}`;
574
+ }).join("\n");
575
+ return {
576
+ content: [
577
+ {
578
+ type: "text",
579
+ text: `## Recommended CSS Mode: \`${result.mode}\`
580
+
581
+ ${result.reason}
582
+
583
+ ## All Modes
584
+
585
+ ${allModes}`
586
+ }
587
+ ]
588
+ };
589
+ }
590
+ );
591
+ server.tool(
592
+ "list-components-by-group",
593
+ "List Hareru UI components filtered by group",
594
+ {
595
+ group: z2.enum([
596
+ "core",
597
+ "form",
598
+ "layout",
599
+ "overlay",
600
+ "navigation",
601
+ "feedback",
602
+ "data-display",
603
+ "agent",
604
+ "di-domain"
605
+ ]).describe("Component group to filter by")
606
+ },
607
+ async ({ group }) => {
608
+ const registry = loadRegistry();
609
+ const filtered = registry.components.filter((c) => c.group === group);
610
+ if (filtered.length === 0) {
611
+ const groups = [...new Set(registry.components.map((c) => c.group))].sort();
612
+ return {
613
+ content: [
614
+ {
615
+ type: "text",
616
+ text: `No components in group "${group}". Available groups: ${groups.join(", ")}`
617
+ }
618
+ ],
619
+ isError: true
620
+ };
621
+ }
622
+ const lines = filtered.map((c) => {
623
+ const variants = c.variants ?? [];
624
+ const variantInfo = variants.length > 0 ? ` [${variants.flatMap((v) => Object.entries(v.variants).map(([k, opts]) => `${k}(${opts.join("|")})`)).join(", ")}]` : "";
625
+ return `- **${c.name}**${variantInfo} \u2014 ${c.description}`;
626
+ }).join("\n");
627
+ return {
628
+ content: [
629
+ {
630
+ type: "text",
631
+ text: `## ${group} (${filtered.length} components)
632
+
633
+ ${lines}`
634
+ }
635
+ ]
636
+ };
637
+ }
638
+ );
639
+ }
640
+
641
+ // src/index.ts
642
+ var __dirname = dirname(fileURLToPath(import.meta.url));
643
+ var pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
644
+ function createServer() {
645
+ const server = new McpServer({
646
+ name: "hareru-ui",
647
+ version: pkg.version
648
+ });
649
+ registerResources(server);
650
+ registerTools(server);
651
+ registerPrompts(server);
652
+ return server;
653
+ }
654
+ async function startServer() {
655
+ const server = createServer();
656
+ const transport = new StdioServerTransport();
657
+ await server.connect(transport);
658
+ console.error("Hareru UI MCP server started (stdio)");
659
+ }
660
+ export {
661
+ createServer,
662
+ startServer
663
+ };
664
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/prompts.ts","../src/utils.ts","../src/resources.ts","../src/tools.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname, join } 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 { registerPrompts } from './prompts.js';\nimport { registerResources } from './resources.js';\nimport { registerTools } from './tools.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')) as {\n version: string;\n};\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: 'hareru-ui',\n version: pkg.version,\n });\n\n registerResources(server);\n registerTools(server);\n registerPrompts(server);\n\n return server;\n}\n\nexport async function startServer(): Promise<void> {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('Hareru UI MCP server started (stdio)');\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { loadConsumerRules, loadRegistry, loadSchema } from './utils.js';\n\nexport function registerPrompts(server: McpServer): void {\n server.prompt(\n 'create-ui',\n 'Generate a UI component using Hareru UI design system',\n {\n description: z\n .string()\n .describe(\n 'What the component should do (e.g. \"A settings form with name and email fields\")',\n ),\n framework: z.string().optional().describe('Target framework: react (default)'),\n },\n async ({ description, framework }) => {\n const registry = loadRegistry();\n const schema = loadSchema();\n\n const componentList = registry.components\n .map((c) => {\n const variants = c.variants ?? [];\n const variantInfo =\n variants.length > 0\n ? ` [${variants.flatMap((v) => Object.entries(v.variants).map(([k, opts]) => `${k}(${opts.join('|')})`)).join(', ')}]`\n : '';\n const desc = c.description ? ` — ${c.description}` : '';\n return `- ${c.name}${variantInfo}${desc}`;\n })\n .join('\\n');\n\n const bundles = registry.taskBundles ?? [];\n const bundleList =\n bundles.length > 0\n ? bundles\n .map((b) => `- ${b.name}: ${b.description} (${b.components.length} components)`)\n .join('\\n')\n : '';\n\n const cssVars = schema.properties.cssVariables.items.enum.slice(0, 20).join(', ');\n const fw = framework ?? 'react';\n\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `You are a UI developer using the Hareru UI design system (${fw}).\n\n## Available Components\n\n${componentList}\n\n## Design Token CSS Variables (sample)\n\n${cssVars}, ...\n\n## Rules\n\n1. Import components from '@hareru/ui'. For CSS setup, refer to the consumer-rules (standalone: '@hareru/ui/styles.css', portable: '@hareru/tokens/css' + '@hareru/ui/styles/components.css')\n2. Use only semantic variant props (e.g. variant=\"default\"), never hardcode CSS values\n3. Use CSS variables (--hui-*) for any custom styling\n4. All components support forwardRef\n5. Use BEM class naming (hui-*) if adding custom classes\n6. Colors use OKLCH format\n\n## Task\n\n${description}\n${bundleList ? `\\n## Available Bundles\\n\\n${bundleList}\\n` : ''}\nGenerate a complete ${fw} component that fulfills this requirement.`,\n },\n },\n ],\n };\n },\n );\n\n server.prompt(\n 'create-ui-tailwind',\n 'Generate a UI component mixing Hareru UI and Tailwind CSS with Cascade Layer guidance',\n {\n description: z\n .string()\n .describe(\n 'What the component should do (e.g. \"A dashboard card with Tailwind layout and Hareru UI buttons\")',\n ),\n },\n async ({ description }) => {\n const registry = loadRegistry();\n\n const componentList = registry.components\n .map((c) => {\n const desc = c.description ? ` — ${c.description}` : '';\n return `- ${c.name}${desc}`;\n })\n .join('\\n');\n\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `You are a UI developer using Hareru UI + Tailwind CSS v4 together.\n\n## Cascade Layer Order\n\nDeclare this layer order at the top of your CSS entry point:\n\n\\`\\`\\`css\n@layer theme, base, hui, components, utilities;\n@import 'tailwindcss';\n@import '@hareru/tokens/css';\n@import '@hareru/ui/styles/components.layer.css';\n\\`\\`\\`\n\n- Hareru components live in \\`@layer hui\\` — below Tailwind \\`utilities\\`\n- Tailwind utility classes (e.g. \\`flex\\`, \\`gap-4\\`, \\`p-2\\`) can safely override Hareru layout\n- Never use Tailwind classes to override Hareru component internals (colors, border-radius, shadows) — use \\`--hui-*\\` CSS variables instead\n\n## Mixing Classes Example\n\n\\`\\`\\`tsx\n{/* Tailwind for layout, Hareru for components */}\n<div className=\"flex gap-4 p-6\">\n <Card className=\"flex-1\">\n <CardHeader>Title</CardHeader>\n <CardContent>\n <Button variant=\"default\">Action</Button>\n </CardContent>\n </Card>\n</div>\n\\`\\`\\`\n\n## Available Components\n\n${componentList}\n\n## Rules\n\n1. Import components from \\`@hareru/ui\\`\n2. Use Tailwind utilities for layout (flex, grid, gap, padding, margin)\n3. Use Hareru components for interactive UI elements (Button, Input, Card, Dialog)\n4. Use \\`--hui-*\\` CSS variables for theming — do not override with Tailwind color classes\n5. Use BEM class naming (\\`hui-*\\`) if adding custom component styles\n6. Colors are OKLCH format\n\n## Task\n\n${description}\n\nGenerate a complete React component that combines Tailwind layout utilities with Hareru UI components.`,\n },\n },\n ],\n };\n },\n );\n\n server.prompt(\n 'consumer-rules',\n 'Get the rules for using Hareru UI in your project',\n {},\n async () => {\n const rules = loadConsumerRules();\n\n const CODE_BLOCK_SECTIONS = new Set(['cssImports']);\n\n const rulesSections = Object.entries(rules.rules)\n .map(([key, section]) => {\n const ruleList = section.rules.map((r) => `- ${r}`).join('\\n');\n const examples = Object.entries(section.examples)\n .map(([label, code]) =>\n CODE_BLOCK_SECTIONS.has(key)\n ? `**${label}:**\\n\\`\\`\\`css\\n${code}\\n\\`\\`\\``\n : ` ${label}: ${code}`,\n )\n .join('\\n');\n return `### ${key}\\n${section.description}\\n\\n${ruleList}\\n\\nExamples:\\n${examples}`;\n })\n .join('\\n\\n');\n\n const tokenRef = Object.entries(rules.tokenQuickReference)\n .map(([category, pattern]) => `- ${category}: ${pattern}`)\n .join('\\n');\n\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `# Hareru UI Consumer Rules (v${rules.version})\n\nThese rules apply when using Hareru UI in any project.\n\n## Rules\n\n${rulesSections}\n\n## Token Quick Reference\n\n${tokenRef}`,\n },\n },\n ],\n };\n },\n );\n}\n","export {\n loadTokens,\n loadSchema,\n loadRegistry,\n loadComponentSchema,\n loadConsumerRules,\n CSS_MODES,\n CSS_MODE_DESCRIPTIONS,\n recommendCssMode,\n} from '@hareru/registry';\n\nexport type {\n TokensJSON,\n SchemaJSON,\n ComponentRegistryJSON,\n ComponentEntry,\n TaskBundle,\n ComponentGroup,\n TokenCategory,\n VariantDef,\n CustomPropDef,\n PropDef,\n ComponentSchemaJSON,\n ConsumerRulesJSON,\n CssMode,\n CssModeContext,\n} from '@hareru/registry';\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n loadComponentSchema,\n loadConsumerRules,\n loadRegistry,\n loadSchema,\n loadTokens,\n} from './utils.js';\n\nexport function registerResources(server: McpServer): void {\n const schema = loadSchema();\n const tokenCount = schema.properties.tokenCount.const;\n const registry = loadRegistry();\n\n server.resource(\n 'tokens',\n 'hareru-ui://tokens',\n {\n description: `DTCG design tokens (light/dark themes, ${tokenCount} CSS custom properties)`,\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(loadTokens(), null, 2) }],\n }),\n );\n\n server.resource(\n 'tokens-schema',\n 'hareru-ui://tokens/schema',\n {\n description: 'JSON Schema for design tokens — CSS variable enums and type constraints',\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(loadSchema(), null, 2) }],\n }),\n );\n\n server.resource(\n 'components',\n 'hareru-ui://components',\n {\n description: `Component registry — ${registry.componentCount} components with CVA variants and Props interfaces`,\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(registry, null, 2) }],\n }),\n );\n\n server.resource(\n 'bundles',\n 'hareru-ui://bundles',\n {\n description: `Task bundles — ${registry.taskBundles?.length ?? 0} curated component sets for common UI patterns`,\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(registry.taskBundles ?? [], null, 2) }],\n }),\n );\n\n server.resource(\n 'components-schema',\n 'hareru-ui://components/schema',\n {\n description: 'JSON Schema for the component registry',\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(loadComponentSchema(), null, 2) }],\n }),\n );\n\n server.resource(\n 'consumer-rules',\n 'hareru-ui://rules/consumer',\n {\n description:\n 'Consumer rules for AI agents — import patterns, styling rules, and token reference',\n mimeType: 'application/json',\n },\n async (uri) => ({\n contents: [{ uri: uri.href, text: JSON.stringify(loadConsumerRules(), null, 2) }],\n }),\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport {\n CSS_MODES,\n CSS_MODE_DESCRIPTIONS,\n loadRegistry,\n loadSchema,\n recommendCssMode,\n} from './utils.js';\nimport type { ComponentEntry } from './utils.js';\n\nfunction escPipe(s: string): string {\n return s.replace(/\\|/g, '\\\\|');\n}\n\nfunction formatVariantsTable(entry: ComponentEntry): string {\n const variants = entry.variants ?? [];\n if (variants.length === 0) return 'No CVA variants defined.';\n\n const lines: string[] = ['| Variant | Options | Default |', '|---------|---------|---------|'];\n for (const v of variants) {\n for (const [key, options] of Object.entries(v.variants)) {\n const defaultVal = v.defaultVariants[key] ?? '-';\n lines.push(\n `| ${escPipe(key)} | ${options.map(escPipe).join(', ')} | ${escPipe(defaultVal)} |`,\n );\n }\n }\n return lines.join('\\n');\n}\n\nfunction formatUsageMarkdown(entry: ComponentEntry): string {\n const parts: string[] = [];\n\n parts.push(`# ${entry.displayName}`);\n parts.push('');\n\n // Description (Phase 3A)\n parts.push(entry.description);\n parts.push('');\n\n // AI Guidance (Phase 3A)\n if (entry.aiHint) {\n parts.push('## AI Guidance');\n parts.push('');\n parts.push(entry.aiHint);\n parts.push('');\n }\n\n // Import section\n parts.push('## Import');\n parts.push('');\n parts.push('```tsx');\n const subs = entry.subcomponents ?? [];\n const allNames = [entry.name, ...subs];\n parts.push(`import { ${allNames.join(', ')} } from '@hareru/ui';`);\n parts.push('```');\n parts.push('');\n\n // CSS section (registry-driven)\n parts.push('## CSS');\n parts.push('');\n parts.push('**Standalone:**');\n parts.push('```css');\n parts.push(`@import '@hareru/ui/styles.css';`);\n parts.push('```');\n parts.push('');\n parts.push('**Per-component:**');\n parts.push('```css');\n parts.push(`@import '@hareru/tokens/css';`);\n for (const dep of entry.requiredCssArtifacts ?? []) {\n parts.push(`@import '@hareru/ui/${dep}';`);\n }\n parts.push(`@import '@hareru/ui/${entry.cssArtifact}';`);\n parts.push('```');\n parts.push('');\n\n const variants = entry.variants ?? [];\n const props = entry.props ?? [];\n\n if (variants.length > 0) {\n parts.push('## Variants');\n parts.push('');\n parts.push(formatVariantsTable(entry));\n parts.push('');\n }\n\n if (props.length > 0) {\n parts.push('## Props');\n parts.push('');\n for (const prop of props) {\n if (prop.extends) {\n parts.push(`- **${prop.name}** extends \\`${prop.extends}\\``);\n } else {\n parts.push(`- **${prop.name}**`);\n }\n }\n parts.push('');\n }\n\n // Also Consider (Phase 3A)\n if (entry.peerComponents) {\n parts.push('## Also Consider');\n parts.push('');\n for (const peer of entry.peerComponents) {\n parts.push(`- ${peer}`);\n }\n parts.push('');\n }\n\n parts.push('## Example');\n parts.push('');\n parts.push('```tsx');\n if (variants.length > 0) {\n const firstVariant = variants[0];\n const propsStr = Object.entries(firstVariant.defaultVariants)\n .map(([k, v]) => `${k}=\"${v}\"`)\n .join(' ');\n parts.push(`<${entry.name} ${propsStr}>Content</${entry.name}>`);\n } else if (subs.length > 0) {\n parts.push(`<${entry.name}>`);\n for (const sub of subs) {\n parts.push(` <${sub}>Content</${sub}>`);\n }\n parts.push(`</${entry.name}>`);\n } else {\n parts.push(`<${entry.name}>Content</${entry.name}>`);\n }\n parts.push('```');\n\n return parts.join('\\n');\n}\n\nexport function registerTools(server: McpServer): void {\n server.tool(\n 'get-component-usage',\n 'Get usage documentation for a Hareru UI component — import, variants, props, and JSX example',\n { componentName: z.string().describe('Component name (e.g. \"Button\", \"Card\", \"Alert\")') },\n async ({ componentName }) => {\n const registry = loadRegistry();\n const entry = registry.components.find(\n (c) => c.name.toLowerCase() === componentName.toLowerCase(),\n );\n\n if (!entry) {\n const available = registry.components.map((c) => c.name).join(', ');\n return {\n content: [\n {\n type: 'text' as const,\n text: `Component \"${componentName}\" not found. Available components: ${available}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [{ type: 'text' as const, text: formatUsageMarkdown(entry) }],\n };\n },\n );\n\n server.tool(\n 'get-bundle-usage',\n 'Get usage documentation for a Hareru UI task bundle — components, CSS imports, and token categories',\n { bundleName: z.string().describe('Bundle name (e.g. \"agent-chat-shell\", \"form-basics\")') },\n async ({ bundleName }) => {\n const registry = loadRegistry();\n const bundles = registry.taskBundles ?? [];\n const bundle = bundles.find((b) => b.name.toLowerCase() === bundleName.toLowerCase());\n\n if (!bundle) {\n const available = bundles.map((b) => b.name).join(', ');\n return {\n content: [\n {\n type: 'text' as const,\n text: `Bundle \"${bundleName}\" not found. Available bundles: ${available}`,\n },\n ],\n isError: true,\n };\n }\n\n const componentMap = new Map(registry.components.map((c) => [c.name, c]));\n\n const parts: string[] = [];\n parts.push(`# Bundle: ${bundle.name}`);\n parts.push('');\n parts.push(bundle.description);\n parts.push('');\n\n // Import section — expand subcomponents so the import is copy-pasteable\n const allImports: string[] = [];\n for (const compName of bundle.components) {\n const comp = componentMap.get(compName);\n allImports.push(compName);\n if (comp?.subcomponents) {\n allImports.push(...comp.subcomponents);\n }\n }\n parts.push('## Import');\n parts.push('');\n parts.push('```tsx');\n parts.push(`import { ${allImports.join(', ')} } from '@hareru/ui';`);\n parts.push('```');\n parts.push('');\n\n // CSS section\n parts.push('## CSS');\n parts.push('');\n parts.push('**Standalone:**');\n parts.push('```css');\n parts.push(`@import '@hareru/ui/styles.css';`);\n parts.push('```');\n parts.push('');\n parts.push('**Per-component:**');\n parts.push('```css');\n parts.push(`@import '@hareru/tokens/css';`);\n for (const artifact of bundle.cssArtifacts) {\n parts.push(`@import '@hareru/ui/${artifact}';`);\n }\n parts.push('```');\n parts.push('');\n\n // Token categories\n parts.push('## Token Categories');\n parts.push('');\n parts.push(bundle.tokenCategories.join(', '));\n parts.push('');\n\n // Components detail\n parts.push('## Components');\n parts.push('');\n for (const compName of bundle.components) {\n const comp = componentMap.get(compName);\n if (comp) {\n parts.push(`- **${comp.name}** — ${comp.description}`);\n } else {\n parts.push(`- **${compName}**`);\n }\n }\n parts.push('');\n\n return {\n content: [{ type: 'text' as const, text: parts.join('\\n') }],\n };\n },\n );\n\n server.tool(\n 'validate-token-value',\n 'Validate a CSS token value against the Hareru UI design token schema',\n {\n tokenType: z\n .string()\n .describe(\n 'Token type: color, dimension, fontFamily, fontWeight, duration, number, shadow, typography, cubicBezier',\n ),\n value: z.string().describe('The value to validate (e.g. \"oklch(0.5 0.2 250)\")'),\n },\n async ({ tokenType, value }) => {\n const schema = loadSchema();\n const constraint =\n schema.properties.typeConstraints.properties[\n tokenType as keyof typeof schema.properties.typeConstraints.properties\n ];\n\n if (!constraint) {\n const availableTypes = Object.keys(schema.properties.typeConstraints.properties).join(', ');\n return {\n content: [\n {\n type: 'text' as const,\n text: `Unknown token type \"${tokenType}\". Available types: ${availableTypes}`,\n },\n ],\n isError: true,\n };\n }\n\n if (!constraint.pattern) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Valid — token type \"${tokenType}\" has no pattern constraint (any ${constraint.type ?? 'string'} value accepted).`,\n },\n ],\n };\n }\n\n let regex: RegExp;\n try {\n regex = new RegExp(constraint.pattern);\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error — invalid pattern for token type \"${tokenType}\": ${constraint.pattern}`,\n },\n ],\n isError: true,\n };\n }\n\n const isValid = regex.test(value);\n\n if (isValid) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Valid — \"${value}\" matches the ${tokenType} pattern: ${constraint.pattern}`,\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Invalid — \"${value}\" does not match the ${tokenType} pattern.\\nExpected: ${constraint.pattern}\\nDescription: ${constraint.description ?? tokenType}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'recommend-css-mode',\n 'Recommend the best CSS import mode for a Hareru UI project based on project context',\n {\n hasTailwind: z.boolean().describe('Whether Tailwind CSS is detected in the project'),\n componentCount: z\n .number()\n .int()\n .min(0)\n .describe('Number of Hareru components used in the project'),\n hasExistingReset: z\n .boolean()\n .optional()\n .describe(\n 'Whether the project already has a CSS reset or framework (e.g. Bootstrap, Pico CSS)',\n ),\n },\n async ({ hasTailwind, componentCount, hasExistingReset }) => {\n const result = recommendCssMode({ hasTailwind, componentCount, hasExistingReset });\n\n const allModes = CSS_MODES.map((m) => {\n const marker = m === result.mode ? ' ← recommended' : '';\n return `- **${m}**: ${CSS_MODE_DESCRIPTIONS[m]}${marker}`;\n }).join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `## Recommended CSS Mode: \\`${result.mode}\\`\\n\\n${result.reason}\\n\\n## All Modes\\n\\n${allModes}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'list-components-by-group',\n 'List Hareru UI components filtered by group',\n {\n group: z\n .enum([\n 'core',\n 'form',\n 'layout',\n 'overlay',\n 'navigation',\n 'feedback',\n 'data-display',\n 'agent',\n 'di-domain',\n ])\n .describe('Component group to filter by'),\n },\n async ({ group }) => {\n const registry = loadRegistry();\n const filtered = registry.components.filter((c) => c.group === group);\n\n if (filtered.length === 0) {\n const groups = [...new Set(registry.components.map((c) => c.group))].sort();\n return {\n content: [\n {\n type: 'text' as const,\n text: `No components in group \"${group}\". Available groups: ${groups.join(', ')}`,\n },\n ],\n isError: true,\n };\n }\n\n const lines = filtered\n .map((c) => {\n const variants = c.variants ?? [];\n const variantInfo =\n variants.length > 0\n ? ` [${variants.flatMap((v) => Object.entries(v.variants).map(([k, opts]) => `${k}(${opts.join('|')})`)).join(', ')}]`\n : '';\n return `- **${c.name}**${variantInfo} — ${c.description}`;\n })\n .join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `## ${group} (${filtered.length} components)\\n\\n${lines}`,\n },\n ],\n };\n },\n );\n}\n"],"mappings":"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","names":["z","z"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@hareru/mcp",
3
+ "version": "0.2.0",
4
+ "description": "MCP server for Hareru UI design system — exposes tokens, schema, and component registry to AI agents",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/hareru-ai/ui",
9
+ "directory": "packages/mcp"
10
+ },
11
+ "homepage": "https://github.com/hareru-ai/ui",
12
+ "keywords": [
13
+ "mcp",
14
+ "model-context-protocol",
15
+ "design-system",
16
+ "hareru",
17
+ "ai"
18
+ ],
19
+ "type": "module",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "bin": {
29
+ "hareru-mcp": "./bin/hareru-mcp.mjs"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "bin",
37
+ "LICENSE"
38
+ ],
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.12.0",
41
+ "zod": "^3.23.0",
42
+ "@hareru/registry": "0.2.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.0.0",
46
+ "tsup": "^8.0.0",
47
+ "typescript": "^5.7.0",
48
+ "vitest": "^2.0.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "dev": "tsup --watch",
53
+ "test": "vitest run"
54
+ }
55
+ }