@mohityadav0903/branintelle-mcp 3.0.0 ā 3.1.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/mcp-server.js +109 -0
- package/package.json +1 -1
- package/test-image-tool.js +88 -0
package/mcp-server.js
CHANGED
|
@@ -14,10 +14,31 @@ 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);
|
|
20
21
|
|
|
22
|
+
// Helper function to fetch image from URL and convert to base64
|
|
23
|
+
async function fetchImageAsBase64(url) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
https.get(url, (response) => {
|
|
26
|
+
if (response.statusCode !== 200) {
|
|
27
|
+
reject(new Error(`Failed to fetch image: ${response.statusCode}`));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const chunks = [];
|
|
32
|
+
response.on('data', (chunk) => chunks.push(chunk));
|
|
33
|
+
response.on('end', () => {
|
|
34
|
+
const buffer = Buffer.concat(chunks);
|
|
35
|
+
const base64 = buffer.toString('base64');
|
|
36
|
+
resolve(base64);
|
|
37
|
+
});
|
|
38
|
+
}).on('error', reject);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
21
42
|
// Load design tokens
|
|
22
43
|
const designTokens = JSON.parse(
|
|
23
44
|
readFileSync(join(__dirname, 'design-tokens.json'), 'utf-8')
|
|
@@ -196,6 +217,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
196
217
|
},
|
|
197
218
|
},
|
|
198
219
|
},
|
|
220
|
+
{
|
|
221
|
+
name: 'get_screen_image',
|
|
222
|
+
description: 'Fetch a screen screenshot as base64 data URL so LLMs can see the actual UI. Returns image in data:image/png;base64,... format.',
|
|
223
|
+
inputSchema: {
|
|
224
|
+
type: 'object',
|
|
225
|
+
properties: {
|
|
226
|
+
screen_id: {
|
|
227
|
+
type: 'string',
|
|
228
|
+
description: 'Screen ID (screen_001, screen_002, etc.)',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ['screen_id'],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
199
234
|
],
|
|
200
235
|
};
|
|
201
236
|
});
|
|
@@ -552,6 +587,80 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
552
587
|
};
|
|
553
588
|
}
|
|
554
589
|
|
|
590
|
+
// GET SCREEN IMAGE
|
|
591
|
+
if (name === 'get_screen_image') {
|
|
592
|
+
const screen_id = args?.screen_id;
|
|
593
|
+
|
|
594
|
+
if (!screen_id) {
|
|
595
|
+
return {
|
|
596
|
+
content: [
|
|
597
|
+
{
|
|
598
|
+
type: 'text',
|
|
599
|
+
text: JSON.stringify({
|
|
600
|
+
error: 'screen_id is required',
|
|
601
|
+
available_screens: Object.keys(screenPatterns.screens)
|
|
602
|
+
}, null, 2),
|
|
603
|
+
},
|
|
604
|
+
],
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const screen = screenPatterns.screens[screen_id];
|
|
609
|
+
|
|
610
|
+
if (!screen) {
|
|
611
|
+
return {
|
|
612
|
+
content: [
|
|
613
|
+
{
|
|
614
|
+
type: 'text',
|
|
615
|
+
text: JSON.stringify({
|
|
616
|
+
error: 'Screen not found',
|
|
617
|
+
available_screens: Object.keys(screenPatterns.screens)
|
|
618
|
+
}, null, 2),
|
|
619
|
+
},
|
|
620
|
+
],
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
try {
|
|
625
|
+
// Fetch image from S3 and convert to base64
|
|
626
|
+
const base64Data = await fetchImageAsBase64(screen.screenshot_url);
|
|
627
|
+
|
|
628
|
+
return {
|
|
629
|
+
content: [
|
|
630
|
+
{
|
|
631
|
+
type: 'text',
|
|
632
|
+
text: JSON.stringify({
|
|
633
|
+
screen_id: screen.id,
|
|
634
|
+
screen_name: screen.name,
|
|
635
|
+
screen_type: screen.type,
|
|
636
|
+
module: screen.module,
|
|
637
|
+
url: screen.screenshot_url,
|
|
638
|
+
message: 'Image fetched successfully. See image below.'
|
|
639
|
+
}, null, 2),
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
type: 'image',
|
|
643
|
+
data: base64Data,
|
|
644
|
+
mimeType: 'image/png'
|
|
645
|
+
}
|
|
646
|
+
],
|
|
647
|
+
};
|
|
648
|
+
} catch (error) {
|
|
649
|
+
return {
|
|
650
|
+
content: [
|
|
651
|
+
{
|
|
652
|
+
type: 'text',
|
|
653
|
+
text: JSON.stringify({
|
|
654
|
+
error: 'Failed to fetch image',
|
|
655
|
+
details: error.message,
|
|
656
|
+
url: screen.screenshot_url
|
|
657
|
+
}, null, 2),
|
|
658
|
+
},
|
|
659
|
+
],
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
555
664
|
return {
|
|
556
665
|
content: [
|
|
557
666
|
{
|
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);
|