@gostudent/shared-ui-library-mcp 1.23.2-DT-16968
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/library-manifest.json +1569 -0
- package/package.json +21 -0
- package/server.mjs +161 -0
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gostudent/shared-ui-library-mcp",
|
|
3
|
+
"version": "1.23.2-DT-16968",
|
|
4
|
+
"description": "MCP server for @gostudent/shared-ui-library — exposes components, icons, and tokens to Claude",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"shared-ui-library-mcp": "./server.mjs"
|
|
8
|
+
},
|
|
9
|
+
"main": "./server.mjs",
|
|
10
|
+
"files": [
|
|
11
|
+
"server.mjs",
|
|
12
|
+
"library-manifest.json"
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
16
|
+
"zod": "^3.25.0 || ^4.0.0"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20.0.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/server.mjs
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Library MCP server for @gostudent/shared-ui-library.
|
|
4
|
+
* Exposes components, icons, and tokens to Claude via stdio.
|
|
5
|
+
*
|
|
6
|
+
* Usage: npx @gostudent/shared-ui-library-mcp@latest
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
import { join, dirname } from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
|
|
18
|
+
let manifest;
|
|
19
|
+
try {
|
|
20
|
+
manifest = JSON.parse(readFileSync(join(__dirname, 'library-manifest.json'), 'utf8'));
|
|
21
|
+
} catch (err) {
|
|
22
|
+
process.stderr.write(
|
|
23
|
+
'shared-ui-library-mcp: could not read library-manifest.json.\n' +
|
|
24
|
+
'If running from source, run `npm run build:mcp-manifest` first.\n'
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const server = new McpServer({
|
|
30
|
+
name: 'shared-ui-library',
|
|
31
|
+
version: manifest.libraryVersion,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// ─── list_components ──────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
server.registerTool(
|
|
37
|
+
'list_components',
|
|
38
|
+
{
|
|
39
|
+
description: 'List all available components with their descriptions.',
|
|
40
|
+
inputSchema: {},
|
|
41
|
+
},
|
|
42
|
+
async () => {
|
|
43
|
+
const list = manifest.components.map(c => ({
|
|
44
|
+
name: c.name,
|
|
45
|
+
description: c.description,
|
|
46
|
+
}));
|
|
47
|
+
return {
|
|
48
|
+
content: [{ type: 'text', text: JSON.stringify(list, null, 2) }],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// ─── get_component ────────────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
server.registerTool(
|
|
56
|
+
'get_component',
|
|
57
|
+
{
|
|
58
|
+
description: 'Get full details for a component: props, variants, and usage examples.',
|
|
59
|
+
inputSchema: {
|
|
60
|
+
name: z.string().describe('Component name, e.g. "Button"'),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
async ({ name }) => {
|
|
64
|
+
const component = manifest.components.find(
|
|
65
|
+
c => c.name.toLowerCase() === name.toLowerCase(),
|
|
66
|
+
);
|
|
67
|
+
if (!component) {
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: 'text', text: `Component "${name}" not found. Use list_components to see available components.` }],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [{ type: 'text', text: JSON.stringify(component, null, 2) }],
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// ─── list_icons ───────────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
server.registerTool(
|
|
81
|
+
'list_icons',
|
|
82
|
+
{
|
|
83
|
+
description: 'List all available icon names and their supported sizes.',
|
|
84
|
+
inputSchema: {},
|
|
85
|
+
},
|
|
86
|
+
async () => {
|
|
87
|
+
return {
|
|
88
|
+
content: [{ type: 'text', text: JSON.stringify(manifest.icons, null, 2) }],
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// ─── get_tokens ───────────────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
server.registerTool(
|
|
96
|
+
'get_tokens',
|
|
97
|
+
{
|
|
98
|
+
description: 'Get design tokens. Optionally filter by category (e.g. "spacing", "color", "font") and brand ("base", "gs", "sk").',
|
|
99
|
+
inputSchema: {
|
|
100
|
+
category: z.string().optional().describe('Token category prefix, e.g. "spacing", "color", "font", "radius"'),
|
|
101
|
+
brand: z.enum(['base', 'gs', 'sk']).optional().describe('Brand token set. Defaults to "base".'),
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
async ({ category, brand = 'base' }) => {
|
|
105
|
+
const brandTokens = manifest.tokens[brand];
|
|
106
|
+
if (!brandTokens) {
|
|
107
|
+
return {
|
|
108
|
+
content: [{ type: 'text', text: `Unknown brand "${brand}". Use "base", "gs", or "sk".` }],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const result = category
|
|
112
|
+
? { [category]: brandTokens[category] ?? {} }
|
|
113
|
+
: brandTokens;
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// ─── search_components ────────────────────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
server.registerTool(
|
|
123
|
+
'search_components',
|
|
124
|
+
{
|
|
125
|
+
description: 'Search components by name, description, or prop names.',
|
|
126
|
+
inputSchema: {
|
|
127
|
+
query: z.string().describe('Search term, e.g. "button", "dropdown", "size"'),
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
async ({ query }) => {
|
|
131
|
+
const q = query.toLowerCase();
|
|
132
|
+
const matches = manifest.components.filter(c => {
|
|
133
|
+
if (c.name.toLowerCase().includes(q)) return true;
|
|
134
|
+
if (c.description.toLowerCase().includes(q)) return true;
|
|
135
|
+
if (c.props.some(p => p.name.toLowerCase().includes(q) || p.description.toLowerCase().includes(q))) return true;
|
|
136
|
+
return false;
|
|
137
|
+
}).map(c => ({ name: c.name, description: c.description }));
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
content: [{
|
|
141
|
+
type: 'text',
|
|
142
|
+
text: matches.length
|
|
143
|
+
? JSON.stringify(matches, null, 2)
|
|
144
|
+
: `No components found matching "${query}".`,
|
|
145
|
+
}],
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// ─── Start ────────────────────────────────────────────────────────────────────
|
|
151
|
+
|
|
152
|
+
async function main() {
|
|
153
|
+
const transport = new StdioServerTransport();
|
|
154
|
+
await server.connect(transport);
|
|
155
|
+
console.error(`shared-ui-library MCP v${manifest.libraryVersion} running on stdio`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
main().catch(err => {
|
|
159
|
+
console.error('Fatal error:', err);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|