@mohityadav0903/branintelle-mcp 1.0.0 → 2.0.1
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 +172 -96
- package/components-data.js +1107 -0
- package/design-tokens.json +1300 -0
- package/mcp-server.js +230 -110
- package/package.json +1 -1
package/mcp-server.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Branintelle UI Library - MCP Server
|
|
5
|
-
*
|
|
4
|
+
* Branintelle UI Library - MCP Server v2.0
|
|
5
|
+
* Enhanced with full component metadata, design tokens, and usage patterns
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
@@ -11,95 +11,26 @@ import {
|
|
|
11
11
|
CallToolRequestSchema,
|
|
12
12
|
ListToolsRequestSchema,
|
|
13
13
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
+
import { readFileSync } from 'fs';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
import { dirname, join } from 'path';
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
{ name: 'CustomButton', category: 'Buttons', description: 'Primary action button with loading states' },
|
|
18
|
-
{ name: 'ApproveButton', category: 'Buttons', description: 'Approve action button with icon' },
|
|
19
|
-
{ name: 'CancelButton', category: 'Buttons', description: 'Cancel/dismiss button' },
|
|
20
|
-
{ name: 'BackButton', category: 'Buttons', description: 'Navigation back button' },
|
|
21
|
-
{ name: 'ButtonImage', category: 'Buttons', description: 'Button with image icon' },
|
|
22
|
-
|
|
23
|
-
{ name: 'StatusPill', category: 'Status', description: 'Status indicator with color and icon' },
|
|
24
|
-
{ name: 'PillBadge', category: 'Status', description: 'Small badge for counts' },
|
|
25
|
-
{ name: 'PillBox', category: 'Status', description: 'Tag-style pill component' },
|
|
26
|
-
|
|
27
|
-
{ name: 'ProgressBar', category: 'Progress', description: 'Linear progress indicator' },
|
|
28
|
-
{ name: 'SegmentedProgressBar', category: 'Progress', description: 'Multi-segment progress bar' },
|
|
29
|
-
|
|
30
|
-
{ name: 'VerticalStepper', category: 'Navigation', description: 'Vertical step indicator' },
|
|
31
|
-
{ name: 'CustomBreadcrumb', category: 'Navigation', description: 'Breadcrumb navigation' },
|
|
32
|
-
{ name: 'HeaderTabs', category: 'Navigation', description: 'Tab navigation with status counts' },
|
|
33
|
-
|
|
34
|
-
{ name: 'TitleHeaderSubtext', category: 'Text', description: 'Title with subtitle component' },
|
|
35
|
-
{ name: 'HelpText', category: 'Text', description: 'Helper text with icon' },
|
|
36
|
-
|
|
37
|
-
{ name: 'SearchBar', category: 'Forms', description: 'Search input with icon' },
|
|
38
|
-
{ name: 'Checklist', category: 'Forms', description: 'Checklist with items' },
|
|
39
|
-
|
|
40
|
-
{ name: 'HorizontalCard', category: 'Cards', description: 'Horizontal layout card' },
|
|
41
|
-
{ name: 'InfoActionCard', category: 'Cards', description: 'Card with action buttons' },
|
|
42
|
-
{ name: 'ProgressDisplayCard', category: 'Cards', description: 'Card showing progress' },
|
|
43
|
-
{ name: 'ProfileImageList', category: 'Cards', description: 'Avatar stack component' },
|
|
44
|
-
|
|
45
|
-
{ name: 'SingleSelectDropdown', category: 'Dropdowns', description: 'Single selection dropdown' },
|
|
46
|
-
{ name: 'MultiSelectDropdown', category: 'Dropdowns', description: 'Multi-selection dropdown' },
|
|
47
|
-
{ name: 'DropdownWithStatus', category: 'Dropdowns', description: 'Dropdown with status indicators' },
|
|
48
|
-
{ name: 'MultilineOptionDropdown', category: 'Dropdowns', description: 'Dropdown with multiline options' },
|
|
49
|
-
{ name: 'ExpandableMenuDropdown', category: 'Dropdowns', description: 'Nested menu dropdown' },
|
|
50
|
-
|
|
51
|
-
{ name: 'CustomTooltip', category: 'Overlays', description: 'Tooltip component' },
|
|
52
|
-
{ name: 'ConfirmWarning', category: 'Overlays', description: 'Confirmation dialog' },
|
|
53
|
-
|
|
54
|
-
{ name: 'VerticalStages', category: 'Workflows', description: 'Vertical stage indicator' },
|
|
55
|
-
{ name: 'UserSelection', category: 'Workflows', description: 'User selection component' },
|
|
56
|
-
{ name: 'Accordion', category: 'Workflows', description: 'Collapsible accordion' },
|
|
57
|
-
|
|
58
|
-
{ name: 'GeoTagFilter', category: 'Filters', description: 'Geographic tag filter' },
|
|
59
|
-
{ name: 'TableActionMenu', category: 'Filters', description: 'Table action menu' },
|
|
60
|
-
|
|
61
|
-
{ name: 'ScrollableDataTable', category: 'Tables', description: 'Scrollable data table with sorting' },
|
|
62
|
-
{ name: 'CollapsableTable', category: 'Tables', description: 'Budget table with collapsible rows' },
|
|
63
|
-
{ name: 'CollapsableTableSmall', category: 'Tables', description: 'Compact collapsible table' },
|
|
64
|
-
];
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
65
20
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
text: {
|
|
74
|
-
'text-500': '#262728',
|
|
75
|
-
'text-400': '#515253',
|
|
76
|
-
'text-300': '#6e6e6f',
|
|
77
|
-
'text-200': '#9b9c9c',
|
|
78
|
-
},
|
|
79
|
-
feedback: {
|
|
80
|
-
'positive-high': '#2c9148',
|
|
81
|
-
'negative-high': '#ce2d4f',
|
|
82
|
-
'notification-high': '#ffac4e',
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
typography: {
|
|
86
|
-
fontFamily: 'Lato',
|
|
87
|
-
sizes: {
|
|
88
|
-
'heading-large': '24px',
|
|
89
|
-
'heading-medium': '20px',
|
|
90
|
-
'heading-small': '18px',
|
|
91
|
-
'body-large': '16px',
|
|
92
|
-
'body-medium': '14px',
|
|
93
|
-
'body-small': '12px',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
};
|
|
21
|
+
// Load design tokens
|
|
22
|
+
const designTokens = JSON.parse(
|
|
23
|
+
readFileSync(join(__dirname, 'design-tokens.json'), 'utf-8')
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Load component data
|
|
27
|
+
import { COMPONENTS_DATA, COMPONENT_CATEGORIES, USAGE_PATTERNS } from './components-data.js';
|
|
97
28
|
|
|
98
29
|
// Create server instance
|
|
99
30
|
const server = new Server(
|
|
100
31
|
{
|
|
101
32
|
name: 'branintelle-ui-lib',
|
|
102
|
-
version: '
|
|
33
|
+
version: '2.0.0',
|
|
103
34
|
},
|
|
104
35
|
{
|
|
105
36
|
capabilities: {
|
|
@@ -114,7 +45,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
114
45
|
tools: [
|
|
115
46
|
{
|
|
116
47
|
name: 'list_components',
|
|
117
|
-
description: 'List all available UI components
|
|
48
|
+
description: 'List all available UI components with detailed metadata (inputs, outputs, examples)',
|
|
118
49
|
inputSchema: {
|
|
119
50
|
type: 'object',
|
|
120
51
|
properties: {
|
|
@@ -122,12 +53,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
122
53
|
type: 'string',
|
|
123
54
|
description: 'Filter by category (Buttons, Tables, Dropdowns, etc.)',
|
|
124
55
|
},
|
|
56
|
+
detailed: {
|
|
57
|
+
type: 'boolean',
|
|
58
|
+
description: 'Include full component details (inputs, outputs, examples)',
|
|
59
|
+
default: false
|
|
60
|
+
}
|
|
125
61
|
},
|
|
126
62
|
},
|
|
127
63
|
},
|
|
128
64
|
{
|
|
129
65
|
name: 'get_component_docs',
|
|
130
|
-
description: 'Get
|
|
66
|
+
description: 'Get comprehensive documentation for specific components including props, types, and code examples',
|
|
131
67
|
inputSchema: {
|
|
132
68
|
type: 'object',
|
|
133
69
|
properties: {
|
|
@@ -142,14 +78,51 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
142
78
|
},
|
|
143
79
|
{
|
|
144
80
|
name: 'get_design_tokens',
|
|
145
|
-
description: 'Get design system tokens
|
|
81
|
+
description: 'Get design system tokens with context and usage examples from Figma',
|
|
146
82
|
inputSchema: {
|
|
147
83
|
type: 'object',
|
|
148
84
|
properties: {
|
|
149
85
|
category: {
|
|
150
86
|
type: 'string',
|
|
151
87
|
description: 'Token category (colors, typography, all)',
|
|
152
|
-
enum: ['colors', 'typography', 'all'],
|
|
88
|
+
enum: ['colors', 'typography', 'spacing', 'all'],
|
|
89
|
+
},
|
|
90
|
+
includeContexts: {
|
|
91
|
+
type: 'boolean',
|
|
92
|
+
description: 'Include usage contexts from Figma',
|
|
93
|
+
default: true
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'search_components',
|
|
100
|
+
description: 'Search components by keyword, use case, or pattern',
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
query: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
description: 'Search query (e.g., "button", "dropdown", "table")',
|
|
107
|
+
},
|
|
108
|
+
useCase: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
description: 'Filter by use case (e.g., "forms", "status", "navigation")',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
required: ['query'],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'get_usage_pattern',
|
|
118
|
+
description: 'Get recommended usage patterns and best practices for common UI scenarios',
|
|
119
|
+
inputSchema: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: {
|
|
122
|
+
pattern: {
|
|
123
|
+
type: 'string',
|
|
124
|
+
description: 'Pattern name (primary-actions, status-indicators, multi-step-forms, data-display, form-inputs)',
|
|
125
|
+
enum: Object.keys(USAGE_PATTERNS)
|
|
153
126
|
},
|
|
154
127
|
},
|
|
155
128
|
},
|
|
@@ -163,49 +136,71 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
163
136
|
const { name, arguments: args } = request.params;
|
|
164
137
|
|
|
165
138
|
try {
|
|
139
|
+
// LIST COMPONENTS
|
|
166
140
|
if (name === 'list_components') {
|
|
167
141
|
const category = args?.category;
|
|
168
|
-
|
|
142
|
+
const detailed = args?.detailed || false;
|
|
143
|
+
|
|
144
|
+
let componentsList = [];
|
|
169
145
|
|
|
170
146
|
if (category) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
147
|
+
const categoryComps = COMPONENT_CATEGORIES[category] || [];
|
|
148
|
+
componentsList = categoryComps.map(name => ({
|
|
149
|
+
name,
|
|
150
|
+
...COMPONENTS_DATA[name]
|
|
151
|
+
}));
|
|
152
|
+
} else {
|
|
153
|
+
// All components grouped by category
|
|
154
|
+
for (const [cat, comps] of Object.entries(COMPONENT_CATEGORIES)) {
|
|
155
|
+
componentsList.push({
|
|
156
|
+
category: cat,
|
|
157
|
+
components: comps.map(name => ({
|
|
158
|
+
name,
|
|
159
|
+
...(detailed ? COMPONENTS_DATA[name] : {
|
|
160
|
+
category: COMPONENTS_DATA[name]?.category,
|
|
161
|
+
description: COMPONENTS_DATA[name]?.description,
|
|
162
|
+
selector: COMPONENTS_DATA[name]?.selector
|
|
163
|
+
})
|
|
164
|
+
}))
|
|
165
|
+
});
|
|
166
|
+
}
|
|
174
167
|
}
|
|
175
168
|
|
|
176
|
-
const grouped = filtered.reduce((acc, comp) => {
|
|
177
|
-
if (!acc[comp.category]) acc[comp.category] = [];
|
|
178
|
-
acc[comp.category].push(comp);
|
|
179
|
-
return acc;
|
|
180
|
-
}, {});
|
|
181
|
-
|
|
182
169
|
return {
|
|
183
170
|
content: [
|
|
184
171
|
{
|
|
185
172
|
type: 'text',
|
|
186
173
|
text: JSON.stringify({
|
|
187
|
-
total:
|
|
188
|
-
components:
|
|
189
|
-
categories: Object.keys(
|
|
174
|
+
total: Object.keys(COMPONENTS_DATA).length,
|
|
175
|
+
components: componentsList,
|
|
176
|
+
categories: Object.keys(COMPONENT_CATEGORIES),
|
|
190
177
|
}, null, 2),
|
|
191
178
|
},
|
|
192
179
|
],
|
|
193
180
|
};
|
|
194
181
|
}
|
|
195
182
|
|
|
183
|
+
// GET COMPONENT DOCS
|
|
196
184
|
if (name === 'get_component_docs') {
|
|
197
185
|
const componentNames = args?.components || [];
|
|
198
186
|
const docs = componentNames.map(name => {
|
|
199
|
-
const comp =
|
|
187
|
+
const comp = COMPONENTS_DATA[name];
|
|
200
188
|
if (!comp) return { name, error: 'Component not found' };
|
|
201
189
|
|
|
202
190
|
return {
|
|
203
191
|
name: comp.name,
|
|
204
192
|
category: comp.category,
|
|
193
|
+
selector: comp.selector,
|
|
205
194
|
description: comp.description,
|
|
206
|
-
import: `import { ${comp.name} } from '@mohityadav0903/branintelle-ui-lib';`,
|
|
207
|
-
|
|
195
|
+
import: `import { ${comp.name}Component } from '@mohityadav0903/branintelle-ui-lib';`,
|
|
196
|
+
inputs: comp.inputs,
|
|
197
|
+
outputs: comp.outputs,
|
|
198
|
+
interfaces: comp.interfaces,
|
|
199
|
+
example: comp.example,
|
|
200
|
+
usagePattern: comp.usagePattern,
|
|
201
|
+
designTokens: comp.tokens,
|
|
208
202
|
package: '@mohityadav0903/branintelle-ui-lib',
|
|
203
|
+
version: '1.7.0'
|
|
209
204
|
};
|
|
210
205
|
});
|
|
211
206
|
|
|
@@ -219,12 +214,40 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
219
214
|
};
|
|
220
215
|
}
|
|
221
216
|
|
|
217
|
+
// GET DESIGN TOKENS
|
|
222
218
|
if (name === 'get_design_tokens') {
|
|
223
219
|
const category = args?.category || 'all';
|
|
224
|
-
|
|
220
|
+
const includeContexts = args?.includeContexts !== false;
|
|
221
|
+
|
|
222
|
+
let tokens = {};
|
|
223
|
+
|
|
224
|
+
if (category === 'all') {
|
|
225
|
+
tokens = designTokens;
|
|
226
|
+
} else if (category === 'colors') {
|
|
227
|
+
tokens = { colors: designTokens.colors };
|
|
228
|
+
} else if (category === 'typography') {
|
|
229
|
+
tokens = { typography: designTokens.typography };
|
|
230
|
+
}
|
|
225
231
|
|
|
226
|
-
|
|
227
|
-
|
|
232
|
+
// Optionally strip contexts to reduce size
|
|
233
|
+
if (!includeContexts && tokens.colors) {
|
|
234
|
+
tokens.colors = {
|
|
235
|
+
primary: tokens.colors.primary.map(t => ({
|
|
236
|
+
token: t.token,
|
|
237
|
+
hex: t.hex,
|
|
238
|
+
usage: t.usage
|
|
239
|
+
})),
|
|
240
|
+
text: tokens.colors.text.map(t => ({
|
|
241
|
+
token: t.token,
|
|
242
|
+
hex: t.hex,
|
|
243
|
+
usage: t.usage
|
|
244
|
+
})),
|
|
245
|
+
feedback: tokens.colors.feedback.map(t => ({
|
|
246
|
+
token: t.token,
|
|
247
|
+
hex: t.hex,
|
|
248
|
+
usage: t.usage
|
|
249
|
+
}))
|
|
250
|
+
};
|
|
228
251
|
}
|
|
229
252
|
|
|
230
253
|
return {
|
|
@@ -232,9 +255,106 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
232
255
|
{
|
|
233
256
|
type: 'text',
|
|
234
257
|
text: JSON.stringify({
|
|
258
|
+
brand: designTokens.brand,
|
|
235
259
|
tokens,
|
|
260
|
+
cssVariables: 'Available in demo app at src/styles/tokens.css',
|
|
236
261
|
usage: 'Use CSS variables: var(--violet-500), var(--body-medium-size), etc.',
|
|
237
|
-
|
|
262
|
+
}, null, 2),
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// SEARCH COMPONENTS
|
|
269
|
+
if (name === 'search_components') {
|
|
270
|
+
const query = args?.query?.toLowerCase() || '';
|
|
271
|
+
const useCase = args?.useCase?.toLowerCase();
|
|
272
|
+
|
|
273
|
+
const results = [];
|
|
274
|
+
|
|
275
|
+
for (const [name, comp] of Object.entries(COMPONENTS_DATA)) {
|
|
276
|
+
const matchesQuery =
|
|
277
|
+
comp.name.toLowerCase().includes(query) ||
|
|
278
|
+
comp.description.toLowerCase().includes(query) ||
|
|
279
|
+
comp.category.toLowerCase().includes(query);
|
|
280
|
+
|
|
281
|
+
const matchesUseCase = !useCase ||
|
|
282
|
+
comp.usagePattern?.includes(useCase) ||
|
|
283
|
+
comp.category.toLowerCase().includes(useCase);
|
|
284
|
+
|
|
285
|
+
if (matchesQuery && matchesUseCase) {
|
|
286
|
+
results.push({
|
|
287
|
+
name: comp.name,
|
|
288
|
+
category: comp.category,
|
|
289
|
+
description: comp.description,
|
|
290
|
+
selector: comp.selector,
|
|
291
|
+
usagePattern: comp.usagePattern
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
content: [
|
|
298
|
+
{
|
|
299
|
+
type: 'text',
|
|
300
|
+
text: JSON.stringify({
|
|
301
|
+
query,
|
|
302
|
+
useCase,
|
|
303
|
+
results,
|
|
304
|
+
count: results.length
|
|
305
|
+
}, null, 2),
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// GET USAGE PATTERN
|
|
312
|
+
if (name === 'get_usage_pattern') {
|
|
313
|
+
const patternName = args?.pattern;
|
|
314
|
+
|
|
315
|
+
if (!patternName) {
|
|
316
|
+
return {
|
|
317
|
+
content: [
|
|
318
|
+
{
|
|
319
|
+
type: 'text',
|
|
320
|
+
text: JSON.stringify({
|
|
321
|
+
availablePatterns: Object.keys(USAGE_PATTERNS),
|
|
322
|
+
patterns: USAGE_PATTERNS
|
|
323
|
+
}, null, 2),
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const pattern = USAGE_PATTERNS[patternName];
|
|
330
|
+
if (!pattern) {
|
|
331
|
+
return {
|
|
332
|
+
content: [
|
|
333
|
+
{
|
|
334
|
+
type: 'text',
|
|
335
|
+
text: JSON.stringify({
|
|
336
|
+
error: 'Pattern not found',
|
|
337
|
+
availablePatterns: Object.keys(USAGE_PATTERNS)
|
|
338
|
+
}, null, 2),
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Get full component details for pattern
|
|
345
|
+
const componentDetails = pattern.components.map(name => ({
|
|
346
|
+
name,
|
|
347
|
+
...COMPONENTS_DATA[name]
|
|
348
|
+
}));
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
content: [
|
|
352
|
+
{
|
|
353
|
+
type: 'text',
|
|
354
|
+
text: JSON.stringify({
|
|
355
|
+
pattern: patternName,
|
|
356
|
+
...pattern,
|
|
357
|
+
componentDetails
|
|
238
358
|
}, null, 2),
|
|
239
359
|
},
|
|
240
360
|
],
|
|
@@ -265,11 +385,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
265
385
|
async function main() {
|
|
266
386
|
const transport = new StdioServerTransport();
|
|
267
387
|
await server.connect(transport);
|
|
268
|
-
console.error('Branintelle UI Library MCP Server running on stdio');
|
|
388
|
+
console.error('Branintelle UI Library MCP Server v2.0 running on stdio');
|
|
389
|
+
console.error('Enhanced with full component metadata and design tokens');
|
|
269
390
|
}
|
|
270
391
|
|
|
271
392
|
main().catch((error) => {
|
|
272
393
|
console.error('Server error:', error);
|
|
273
394
|
process.exit(1);
|
|
274
395
|
});
|
|
275
|
-
|
package/package.json
CHANGED