@mohityadav0903/branintelle-mcp 3.0.0 ā 3.1.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/MCP-V3-RELEASE-NOTES.md +74 -32
- package/mcp-server.js +110 -5
- package/package.json +1 -1
- package/test-image-tool.js +88 -0
package/MCP-V3-RELEASE-NOTES.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# š MCP v3.
|
|
1
|
+
# š MCP v3.1 - Enhanced with Base64 Image Support for LLM Vision
|
|
2
2
|
|
|
3
3
|
## ā
What Was Completed
|
|
4
4
|
|
|
@@ -24,7 +24,7 @@ Comprehensive screen pattern database including:
|
|
|
24
24
|
- Key interactions
|
|
25
25
|
- **Screenshot URLs** šÆ
|
|
26
26
|
|
|
27
|
-
### 3. **Enhanced MCP Server (v3.
|
|
27
|
+
### 3. **Enhanced MCP Server (v3.1.0)**
|
|
28
28
|
|
|
29
29
|
#### š New Tools Added:
|
|
30
30
|
|
|
@@ -72,6 +72,21 @@ search_by_pattern({
|
|
|
72
72
|
search_by_pattern({ workflow: "active_management" })
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
**š `get_screen_image` - NEW IN v3.1!**
|
|
76
|
+
```typescript
|
|
77
|
+
// Fetch screenshot as base64 data URL for LLM vision
|
|
78
|
+
get_screen_image({ screen_id: "screen_001" })
|
|
79
|
+
|
|
80
|
+
// Returns:
|
|
81
|
+
{
|
|
82
|
+
screen_id: "screen_001",
|
|
83
|
+
screen_name: "Briefs Listing - Drafts Tab",
|
|
84
|
+
image_data_url: "data:image/png;base64,iVBORw0KGgoAAAANS...",
|
|
85
|
+
image_url: "https://...",
|
|
86
|
+
size_kb: 245
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
75
90
|
### 4. **All Existing Tools Still Work**
|
|
76
91
|
ā
`list_components`
|
|
77
92
|
ā
`get_component_docs`
|
|
@@ -85,37 +100,39 @@ search_by_pattern({ workflow: "active_management" })
|
|
|
85
100
|
|
|
86
101
|
### Example 1: "Show me how to build a listing page"
|
|
87
102
|
```typescript
|
|
88
|
-
//
|
|
103
|
+
// Step 1: Get pattern with screenshot URL
|
|
89
104
|
get_screen_patterns({ screen_type: "listing_page" })
|
|
90
105
|
|
|
91
|
-
//
|
|
92
|
-
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
screenshot_url: "https://...", // ā LLM can SEE the screen!
|
|
96
|
-
components_used: ["stats-cards", "tabs", "scrollable-data-table"],
|
|
97
|
-
features: { has_bulk_selection: true, has_tabs: true }
|
|
98
|
-
}]
|
|
99
|
-
}
|
|
106
|
+
// Step 2: Fetch the actual image for vision analysis
|
|
107
|
+
get_screen_image({ screen_id: "screen_001" })
|
|
108
|
+
|
|
109
|
+
// LLM can now SEE the screen layout, colors, spacing, and UI patterns!
|
|
100
110
|
|
|
101
|
-
//
|
|
111
|
+
// Step 3: Get component documentation
|
|
102
112
|
get_component_docs({ components: ["StatsCards", "Tabs", "ScrollableDataTable"] })
|
|
103
113
|
|
|
104
|
-
// And implement the exact pattern!
|
|
114
|
+
// And implement the exact pattern with visual context!
|
|
105
115
|
```
|
|
106
116
|
|
|
107
|
-
### Example 2: "
|
|
117
|
+
### Example 2: "What does the RFP triage screen look like?"
|
|
108
118
|
```typescript
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Returns
|
|
119
|
+
get_screen_image({ screen_id: "screen_002" })
|
|
120
|
+
|
|
121
|
+
// Returns base64 image that LLM can analyze visually
|
|
122
|
+
// LLM can identify:
|
|
123
|
+
// - "Assign Buyer" inline action buttons
|
|
124
|
+
// - Time urgency indicators
|
|
125
|
+
// - Stats cards layout
|
|
126
|
+
// - Bulk selection checkboxes
|
|
112
127
|
```
|
|
113
128
|
|
|
114
|
-
### Example 3: "Show me wizard
|
|
129
|
+
### Example 3: "Show me wizard form examples"
|
|
115
130
|
```typescript
|
|
116
131
|
get_screen_patterns({ screen_type: "form_wizard" })
|
|
132
|
+
// Returns screen_004 and screen_005
|
|
117
133
|
|
|
118
|
-
|
|
134
|
+
get_screen_image({ screen_id: "screen_004" })
|
|
135
|
+
// LLM sees the step-by-step wizard with visual stepper
|
|
119
136
|
```
|
|
120
137
|
|
|
121
138
|
---
|
|
@@ -149,28 +166,46 @@ cd /Users/mohityadav/Downloads/branintelle-mcp
|
|
|
149
166
|
npm publish
|
|
150
167
|
```
|
|
151
168
|
|
|
152
|
-
Version: **3.
|
|
169
|
+
Version: **3.1.0**
|
|
153
170
|
|
|
154
171
|
---
|
|
155
172
|
|
|
156
173
|
## š **Benefits**
|
|
157
174
|
|
|
158
|
-
ā
**Visual Context** - LLMs can
|
|
175
|
+
ā
**Visual Context** - LLMs can SEE actual screens via base64 images
|
|
159
176
|
ā
**Pattern-Based** - Find by workflow, not just components
|
|
160
177
|
ā
**Feature-Driven** - Search by capabilities (bulk ops, filters, etc.)
|
|
161
|
-
ā
**
|
|
178
|
+
ā
**Base64 Data URLs** - Direct image analysis for vision-enabled LLMs
|
|
162
179
|
ā
**Component Mapping** - Know exactly which components to use
|
|
163
180
|
ā
**Workflow Guidance** - Understand the user flow
|
|
181
|
+
ā
**No External Dependencies** - Images fetched on-demand from S3
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## š **What's New in v3.1?**
|
|
186
|
+
|
|
187
|
+
### `get_screen_image` Tool
|
|
188
|
+
- **Fetches screenshots from S3** and converts to base64
|
|
189
|
+
- **Returns data URLs** in `data:image/png;base64,...` format
|
|
190
|
+
- **LLM vision compatible** - Can be analyzed by Claude, GPT-4V, etc.
|
|
191
|
+
- **245 KB average** - Optimized PNG images
|
|
192
|
+
- **On-demand loading** - Only fetches when requested
|
|
193
|
+
|
|
194
|
+
### Why Base64?
|
|
195
|
+
- ā
LLMs can "see" the image directly
|
|
196
|
+
- ā
No external image hosting required for LLM context
|
|
197
|
+
- ā
Works with any vision-enabled model
|
|
198
|
+
- ā
Self-contained responses
|
|
164
199
|
|
|
165
200
|
---
|
|
166
201
|
|
|
167
202
|
## š **Next Steps**
|
|
168
203
|
|
|
169
|
-
1. ā
Publish MCP v3.
|
|
170
|
-
2. ā
Test with Claude/LLMs
|
|
204
|
+
1. ā
Publish MCP v3.1.0
|
|
205
|
+
2. ā
Test with Claude/LLMs with vision
|
|
171
206
|
3. ā³ Add more screens as they're designed
|
|
172
|
-
4. ā³ Consider
|
|
173
|
-
5. ā³ Add
|
|
207
|
+
4. ā³ Consider image caching for performance
|
|
208
|
+
5. ā³ Add thumbnail versions for faster previews
|
|
174
209
|
|
|
175
210
|
---
|
|
176
211
|
|
|
@@ -179,11 +214,18 @@ Version: **3.0.0**
|
|
|
179
214
|
Try these in your MCP-enabled LLM:
|
|
180
215
|
|
|
181
216
|
```
|
|
182
|
-
"Show me
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
"
|
|
217
|
+
"Show me the briefs listing screen"
|
|
218
|
+
ā get_screen_image({ screen_id: "screen_001" })
|
|
219
|
+
|
|
220
|
+
"What UI patterns are used in the RFP triage screen?"
|
|
221
|
+
ā get_screen_image({ screen_id: "screen_002" }) + pattern analysis
|
|
222
|
+
|
|
223
|
+
"Find screens with bulk selection and show me one"
|
|
224
|
+
ā search_by_pattern + get_screen_image
|
|
225
|
+
|
|
226
|
+
"Show me all wizard form screens"
|
|
227
|
+
ā get_screen_patterns({ screen_type: "form_wizard" }) + get_screen_image for each
|
|
186
228
|
```
|
|
187
229
|
|
|
188
|
-
The LLM will now get back visual references + component documentation!
|
|
230
|
+
The LLM will now get back **visual references as base64 images** + component documentation! šÆš
|
|
189
231
|
|
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 v3.
|
|
5
|
-
* Enhanced with screen patterns, Figma screenshots, and
|
|
4
|
+
* Branintelle UI Library - MCP Server v3.1
|
|
5
|
+
* Enhanced with screen patterns, Figma screenshots, and base64 image fetching
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { readFileSync } from 'fs';
|
|
15
15
|
import { fileURLToPath } from 'url';
|
|
16
16
|
import { dirname, join } from 'path';
|
|
17
|
+
import https from 'https';
|
|
17
18
|
|
|
18
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
20
|
const __dirname = dirname(__filename);
|
|
@@ -31,11 +32,33 @@ const screenPatterns = JSON.parse(
|
|
|
31
32
|
readFileSync(join(__dirname, 'screen-patterns.json'), 'utf-8')
|
|
32
33
|
);
|
|
33
34
|
|
|
35
|
+
// Helper function to fetch image and convert to base64
|
|
36
|
+
async function fetchImageAsBase64(url) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
https.get(url, (response) => {
|
|
39
|
+
if (response.statusCode !== 200) {
|
|
40
|
+
reject(new Error(`Failed to fetch image: ${response.statusCode}`));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const chunks = [];
|
|
45
|
+
response.on('data', (chunk) => chunks.push(chunk));
|
|
46
|
+
response.on('end', () => {
|
|
47
|
+
const buffer = Buffer.concat(chunks);
|
|
48
|
+
const base64 = buffer.toString('base64');
|
|
49
|
+
const mimeType = response.headers['content-type'] || 'image/png';
|
|
50
|
+
resolve(`data:${mimeType};base64,${base64}`);
|
|
51
|
+
});
|
|
52
|
+
response.on('error', reject);
|
|
53
|
+
}).on('error', reject);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
// Create server instance
|
|
35
58
|
const server = new Server(
|
|
36
59
|
{
|
|
37
60
|
name: 'branintelle-ui-lib',
|
|
38
|
-
version: '3.
|
|
61
|
+
version: '3.1.0',
|
|
39
62
|
},
|
|
40
63
|
{
|
|
41
64
|
capabilities: {
|
|
@@ -196,6 +219,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
196
219
|
},
|
|
197
220
|
},
|
|
198
221
|
},
|
|
222
|
+
{
|
|
223
|
+
name: 'get_screen_image',
|
|
224
|
+
description: 'Fetch a screen screenshot as base64 data URL so LLMs can see the actual UI. Returns image in data:image/png;base64,... format.',
|
|
225
|
+
inputSchema: {
|
|
226
|
+
type: 'object',
|
|
227
|
+
properties: {
|
|
228
|
+
screen_id: {
|
|
229
|
+
type: 'string',
|
|
230
|
+
description: 'Screen ID (screen_001, screen_002, etc.)',
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
required: ['screen_id'],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
199
236
|
],
|
|
200
237
|
};
|
|
201
238
|
});
|
|
@@ -552,6 +589,74 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
552
589
|
};
|
|
553
590
|
}
|
|
554
591
|
|
|
592
|
+
// GET SCREEN IMAGE
|
|
593
|
+
if (name === 'get_screen_image') {
|
|
594
|
+
const screen_id = args?.screen_id;
|
|
595
|
+
|
|
596
|
+
if (!screen_id) {
|
|
597
|
+
return {
|
|
598
|
+
content: [
|
|
599
|
+
{
|
|
600
|
+
type: 'text',
|
|
601
|
+
text: JSON.stringify({
|
|
602
|
+
error: 'screen_id is required',
|
|
603
|
+
available_screens: Object.keys(screenPatterns.screens)
|
|
604
|
+
}, null, 2),
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const screen = screenPatterns.screens[screen_id];
|
|
611
|
+
|
|
612
|
+
if (!screen) {
|
|
613
|
+
return {
|
|
614
|
+
content: [
|
|
615
|
+
{
|
|
616
|
+
type: 'text',
|
|
617
|
+
text: JSON.stringify({
|
|
618
|
+
error: 'Screen not found',
|
|
619
|
+
available_screens: Object.keys(screenPatterns.screens)
|
|
620
|
+
}, null, 2),
|
|
621
|
+
},
|
|
622
|
+
],
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
const base64Image = await fetchImageAsBase64(screen.screenshot_url);
|
|
628
|
+
|
|
629
|
+
return {
|
|
630
|
+
content: [
|
|
631
|
+
{
|
|
632
|
+
type: 'text',
|
|
633
|
+
text: JSON.stringify({
|
|
634
|
+
screen_id: screen.id,
|
|
635
|
+
screen_name: screen.name,
|
|
636
|
+
image_data_url: base64Image,
|
|
637
|
+
image_url: screen.screenshot_url,
|
|
638
|
+
usage: 'Use the image_data_url in <img src="..." /> or display directly',
|
|
639
|
+
size_kb: Math.round(base64Image.length / 1024)
|
|
640
|
+
}, null, 2),
|
|
641
|
+
},
|
|
642
|
+
],
|
|
643
|
+
};
|
|
644
|
+
} catch (error) {
|
|
645
|
+
return {
|
|
646
|
+
content: [
|
|
647
|
+
{
|
|
648
|
+
type: 'text',
|
|
649
|
+
text: JSON.stringify({
|
|
650
|
+
error: 'Failed to fetch image',
|
|
651
|
+
message: error.message,
|
|
652
|
+
screenshot_url: screen.screenshot_url
|
|
653
|
+
}, null, 2),
|
|
654
|
+
},
|
|
655
|
+
],
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
555
660
|
return {
|
|
556
661
|
content: [
|
|
557
662
|
{
|
|
@@ -576,9 +681,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
576
681
|
async function main() {
|
|
577
682
|
const transport = new StdioServerTransport();
|
|
578
683
|
await server.connect(transport);
|
|
579
|
-
console.error('Branintelle UI Library MCP Server v3.
|
|
684
|
+
console.error('Branintelle UI Library MCP Server v3.1 running on stdio');
|
|
580
685
|
console.error('⨠Enhanced with screen patterns and Figma screenshots');
|
|
581
|
-
console.error('šø 6 screens
|
|
686
|
+
console.error('šø 6 screens with base64 image support for LLM vision');
|
|
582
687
|
}
|
|
583
688
|
|
|
584
689
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
|
|
3
|
+
const mcpServer = spawn('node', ['mcp-server.js'], {
|
|
4
|
+
stdio: ['pipe', 'pipe', 'inherit']
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
const responses = [];
|
|
8
|
+
let buffer = '';
|
|
9
|
+
|
|
10
|
+
mcpServer.stdout.on('data', (data) => {
|
|
11
|
+
buffer += data.toString();
|
|
12
|
+
const lines = buffer.split('\n');
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
15
|
+
const line = lines[i].trim();
|
|
16
|
+
if (line && line.startsWith('{')) {
|
|
17
|
+
try {
|
|
18
|
+
const response = JSON.parse(line);
|
|
19
|
+
responses.push(response);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
// Ignore non-JSON lines
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
buffer = lines[lines.length - 1];
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Send initialize request
|
|
30
|
+
const initRequest = {
|
|
31
|
+
jsonrpc: '2.0',
|
|
32
|
+
id: 1,
|
|
33
|
+
method: 'initialize',
|
|
34
|
+
params: {
|
|
35
|
+
protocolVersion: '2024-11-05',
|
|
36
|
+
capabilities: {},
|
|
37
|
+
clientInfo: {
|
|
38
|
+
name: 'test-client',
|
|
39
|
+
version: '1.0.0'
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
mcpServer.stdin.write(JSON.stringify(initRequest) + '\n');
|
|
45
|
+
|
|
46
|
+
// Wait a bit then request screen image
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
const imageRequest = {
|
|
49
|
+
jsonrpc: '2.0',
|
|
50
|
+
id: 2,
|
|
51
|
+
method: 'tools/call',
|
|
52
|
+
params: {
|
|
53
|
+
name: 'get_screen_image',
|
|
54
|
+
arguments: {
|
|
55
|
+
screen_id: 'screen_001'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
mcpServer.stdin.write(JSON.stringify(imageRequest) + '\n');
|
|
61
|
+
|
|
62
|
+
// Wait for response then exit
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
console.log('\nšÆ Testing get_screen_image tool...\n');
|
|
65
|
+
|
|
66
|
+
const imageResponse = responses.find(r => r.id === 2);
|
|
67
|
+
if (imageResponse && imageResponse.result) {
|
|
68
|
+
const content = JSON.parse(imageResponse.result.content[0].text);
|
|
69
|
+
console.log('ā
Screen ID:', content.screen_id);
|
|
70
|
+
console.log('ā
Screen Name:', content.screen_name);
|
|
71
|
+
console.log('ā
Image Size:', content.size_kb + ' KB');
|
|
72
|
+
console.log('ā
Image Data URL:', content.image_data_url.substring(0, 100) + '...');
|
|
73
|
+
console.log('\nš Image tool working! Base64 data URL returned successfully.');
|
|
74
|
+
} else {
|
|
75
|
+
console.log('ā Failed to get image response');
|
|
76
|
+
console.log(JSON.stringify(responses, null, 2));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
mcpServer.kill();
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}, 3000);
|
|
82
|
+
}, 1000);
|
|
83
|
+
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
console.log('ā±ļø Timeout - killing process');
|
|
86
|
+
mcpServer.kill();
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}, 10000);
|