@mohityadav0903/branintelle-mcp 2.2.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 +231 -0
- package/mcp-server.js +297 -5
- package/package.json +1 -1
- package/screen-patterns.json +392 -0
- package/test-image-tool.js +88 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# š MCP v3.1 - Enhanced with Base64 Image Support for LLM Vision
|
|
2
|
+
|
|
3
|
+
## ā
What Was Completed
|
|
4
|
+
|
|
5
|
+
### 1. **6 Figma Screenshots Uploaded to S3**
|
|
6
|
+
```
|
|
7
|
+
ā
screen_001_briefs_listing_drafts.png (184 KB)
|
|
8
|
+
ā
screen_002_rfp_triage_assign_buyer.png (198 KB)
|
|
9
|
+
ā
screen_003_rfp_in_progress_all_status.png (153 KB)
|
|
10
|
+
ā
screen_004_brief_creation_step2_supporting.png (98 KB)
|
|
11
|
+
ā
screen_005_brief_creation_step4_vendor_recommendation.png (116 KB)
|
|
12
|
+
ā
screen_006_provisions_listing_grouped.png (140 KB)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Base URL:** `https://figr-branintelle-assets.s3.amazonaws.com/screens/`
|
|
16
|
+
|
|
17
|
+
### 2. **Created `screen-patterns.json`**
|
|
18
|
+
Comprehensive screen pattern database including:
|
|
19
|
+
- Screen metadata (type, route, module)
|
|
20
|
+
- Workflow patterns
|
|
21
|
+
- Components used
|
|
22
|
+
- Features (bulk selection, tabs, filters, etc.)
|
|
23
|
+
- Design patterns
|
|
24
|
+
- Key interactions
|
|
25
|
+
- **Screenshot URLs** šÆ
|
|
26
|
+
|
|
27
|
+
### 3. **Enhanced MCP Server (v3.1.0)**
|
|
28
|
+
|
|
29
|
+
#### š New Tools Added:
|
|
30
|
+
|
|
31
|
+
**`get_screen_patterns`**
|
|
32
|
+
```typescript
|
|
33
|
+
// Get all listing page patterns
|
|
34
|
+
get_screen_patterns({ screen_type: "listing_page" })
|
|
35
|
+
|
|
36
|
+
// Filter by workflow
|
|
37
|
+
get_screen_patterns({ workflow: "triage_assignment" })
|
|
38
|
+
|
|
39
|
+
// Filter by module
|
|
40
|
+
get_screen_patterns({ module: "P2P" })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**`get_screen_details`**
|
|
44
|
+
```typescript
|
|
45
|
+
// Get full details of a specific screen with screenshot
|
|
46
|
+
get_screen_details({
|
|
47
|
+
screen_id: "screen_001",
|
|
48
|
+
include_components: true
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Returns:
|
|
52
|
+
{
|
|
53
|
+
screen: {
|
|
54
|
+
name: "Briefs Listing - Drafts Tab",
|
|
55
|
+
screenshot_url: "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_001_briefs_listing_drafts.png",
|
|
56
|
+
components_used: ["stats-cards", "tabs", "scrollable-data-table"],
|
|
57
|
+
features: { has_bulk_selection: true, has_tabs: true }
|
|
58
|
+
},
|
|
59
|
+
components_breakdown: [...]
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**`search_by_pattern`**
|
|
64
|
+
```typescript
|
|
65
|
+
// Find screens with specific features
|
|
66
|
+
search_by_pattern({
|
|
67
|
+
features: ["bulk_selection", "inline_actions"],
|
|
68
|
+
components: ["stats-cards", "data-table"]
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// Find by workflow
|
|
72
|
+
search_by_pattern({ workflow: "active_management" })
|
|
73
|
+
```
|
|
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
|
+
|
|
90
|
+
### 4. **All Existing Tools Still Work**
|
|
91
|
+
ā
`list_components`
|
|
92
|
+
ā
`get_component_docs`
|
|
93
|
+
ā
`get_design_tokens`
|
|
94
|
+
ā
`search_components`
|
|
95
|
+
ā
`get_usage_pattern`
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## šÆ **How LLMs Can Use This**
|
|
100
|
+
|
|
101
|
+
### Example 1: "Show me how to build a listing page"
|
|
102
|
+
```typescript
|
|
103
|
+
// Step 1: Get pattern with screenshot URL
|
|
104
|
+
get_screen_patterns({ screen_type: "listing_page" })
|
|
105
|
+
|
|
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!
|
|
110
|
+
|
|
111
|
+
// Step 3: Get component documentation
|
|
112
|
+
get_component_docs({ components: ["StatsCards", "Tabs", "ScrollableDataTable"] })
|
|
113
|
+
|
|
114
|
+
// And implement the exact pattern with visual context!
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Example 2: "What does the RFP triage screen look like?"
|
|
118
|
+
```typescript
|
|
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
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Example 3: "Show me wizard form examples"
|
|
130
|
+
```typescript
|
|
131
|
+
get_screen_patterns({ screen_type: "form_wizard" })
|
|
132
|
+
// Returns screen_004 and screen_005
|
|
133
|
+
|
|
134
|
+
get_screen_image({ screen_id: "screen_004" })
|
|
135
|
+
// LLM sees the step-by-step wizard with visual stepper
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## š **Screen Types Available**
|
|
141
|
+
|
|
142
|
+
| Type | Count | Examples |
|
|
143
|
+
|------|-------|----------|
|
|
144
|
+
| `listing_page` | 1 | Briefs Listing |
|
|
145
|
+
| `listing_page_workflow` | 1 | RFP Triage |
|
|
146
|
+
| `listing_page_complex` | 1 | RFP In Progress |
|
|
147
|
+
| `listing_page_grouped` | 1 | Provisions Listing |
|
|
148
|
+
| `form_wizard` | 2 | Brief Creation Steps |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## š **Workflow Patterns**
|
|
153
|
+
|
|
154
|
+
- `classic_list_index` - Standard listing with tabs
|
|
155
|
+
- `triage_assignment` - Items awaiting assignment
|
|
156
|
+
- `active_management` - Complex status management
|
|
157
|
+
- `grouped_listing_readonly` - Collapsible vendor groups
|
|
158
|
+
- `multi_step_form` - Wizard-based forms
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## š **Publishing**
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cd /Users/mohityadav/Downloads/branintelle-mcp
|
|
166
|
+
npm publish
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Version: **3.1.0**
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## š **Benefits**
|
|
174
|
+
|
|
175
|
+
ā
**Visual Context** - LLMs can SEE actual screens via base64 images
|
|
176
|
+
ā
**Pattern-Based** - Find by workflow, not just components
|
|
177
|
+
ā
**Feature-Driven** - Search by capabilities (bulk ops, filters, etc.)
|
|
178
|
+
ā
**Base64 Data URLs** - Direct image analysis for vision-enabled LLMs
|
|
179
|
+
ā
**Component Mapping** - Know exactly which components to use
|
|
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
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## š **Next Steps**
|
|
203
|
+
|
|
204
|
+
1. ā
Publish MCP v3.1.0
|
|
205
|
+
2. ā
Test with Claude/LLMs with vision
|
|
206
|
+
3. ā³ Add more screens as they're designed
|
|
207
|
+
4. ā³ Consider image caching for performance
|
|
208
|
+
5. ā³ Add thumbnail versions for faster previews
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## š **Quick Test**
|
|
213
|
+
|
|
214
|
+
Try these in your MCP-enabled LLM:
|
|
215
|
+
|
|
216
|
+
```
|
|
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
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The LLM will now get back **visual references as base64 images** + component documentation! šÆš
|
|
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
|
|
5
|
-
* Enhanced with
|
|
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);
|
|
@@ -26,11 +27,38 @@ const designTokens = JSON.parse(
|
|
|
26
27
|
// Load component data
|
|
27
28
|
import { COMPONENTS_DATA, COMPONENT_CATEGORIES, USAGE_PATTERNS } from './components-data.js';
|
|
28
29
|
|
|
30
|
+
// Load screen patterns
|
|
31
|
+
const screenPatterns = JSON.parse(
|
|
32
|
+
readFileSync(join(__dirname, 'screen-patterns.json'), 'utf-8')
|
|
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
|
+
|
|
29
57
|
// Create server instance
|
|
30
58
|
const server = new Server(
|
|
31
59
|
{
|
|
32
60
|
name: 'branintelle-ui-lib',
|
|
33
|
-
version: '
|
|
61
|
+
version: '3.1.0',
|
|
34
62
|
},
|
|
35
63
|
{
|
|
36
64
|
capabilities: {
|
|
@@ -127,6 +155,84 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
127
155
|
},
|
|
128
156
|
},
|
|
129
157
|
},
|
|
158
|
+
{
|
|
159
|
+
name: 'get_screen_patterns',
|
|
160
|
+
description: 'Get Figma screen patterns with screenshots. Filter by screen type, workflow, or module to find relevant UI patterns.',
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: 'object',
|
|
163
|
+
properties: {
|
|
164
|
+
screen_type: {
|
|
165
|
+
type: 'string',
|
|
166
|
+
description: 'Filter by screen type',
|
|
167
|
+
enum: ['listing_page', 'listing_page_workflow', 'listing_page_complex', 'listing_page_grouped', 'form_wizard', 'all'],
|
|
168
|
+
},
|
|
169
|
+
workflow: {
|
|
170
|
+
type: 'string',
|
|
171
|
+
description: 'Filter by workflow pattern (e.g., triage_assignment, active_management)',
|
|
172
|
+
},
|
|
173
|
+
module: {
|
|
174
|
+
type: 'string',
|
|
175
|
+
description: 'Filter by module (e.g., P2P, Plan to Impact)',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'get_screen_details',
|
|
182
|
+
description: 'Get detailed information about a specific screen including screenshot URL, components used, and interactions',
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
screen_id: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'Screen ID (screen_001, screen_002, etc.)',
|
|
189
|
+
},
|
|
190
|
+
include_components: {
|
|
191
|
+
type: 'boolean',
|
|
192
|
+
description: 'Include full component documentation',
|
|
193
|
+
default: true
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
required: ['screen_id'],
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: 'search_by_pattern',
|
|
201
|
+
description: 'Search screens and components by workflow pattern or features (bulk_selection, inline_actions, etc.)',
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: 'object',
|
|
204
|
+
properties: {
|
|
205
|
+
workflow: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'Workflow pattern to search for',
|
|
208
|
+
},
|
|
209
|
+
features: {
|
|
210
|
+
type: 'array',
|
|
211
|
+
items: { type: 'string' },
|
|
212
|
+
description: 'Required features (e.g., bulk_selection, tabs, filters)',
|
|
213
|
+
},
|
|
214
|
+
components: {
|
|
215
|
+
type: 'array',
|
|
216
|
+
items: { type: 'string' },
|
|
217
|
+
description: 'Required components (e.g., stats-cards, data-table)',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
},
|
|
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
|
+
},
|
|
130
236
|
],
|
|
131
237
|
};
|
|
132
238
|
});
|
|
@@ -366,6 +472,191 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
366
472
|
};
|
|
367
473
|
}
|
|
368
474
|
|
|
475
|
+
// GET SCREEN PATTERNS
|
|
476
|
+
if (name === 'get_screen_patterns') {
|
|
477
|
+
const screen_type = args?.screen_type;
|
|
478
|
+
const workflow = args?.workflow;
|
|
479
|
+
const module = args?.module;
|
|
480
|
+
|
|
481
|
+
let screens = Object.values(screenPatterns.screens);
|
|
482
|
+
|
|
483
|
+
if (screen_type && screen_type !== 'all') {
|
|
484
|
+
screens = screens.filter(s => s.type === screen_type);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (workflow) {
|
|
488
|
+
screens = screens.filter(s => s.workflow_pattern === workflow);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (module) {
|
|
492
|
+
screens = screens.filter(s => s.module === module);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
return {
|
|
496
|
+
content: [
|
|
497
|
+
{
|
|
498
|
+
type: 'text',
|
|
499
|
+
text: JSON.stringify({
|
|
500
|
+
filters: { screen_type, workflow, module },
|
|
501
|
+
count: screens.length,
|
|
502
|
+
screens: screens,
|
|
503
|
+
screen_types: Object.keys(screenPatterns.screenTypes || {}),
|
|
504
|
+
}, null, 2),
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// GET SCREEN DETAILS
|
|
511
|
+
if (name === 'get_screen_details') {
|
|
512
|
+
const screen_id = args?.screen_id;
|
|
513
|
+
const include_components = args?.include_components !== false;
|
|
514
|
+
|
|
515
|
+
const screen = screenPatterns.screens[screen_id];
|
|
516
|
+
|
|
517
|
+
if (!screen) {
|
|
518
|
+
return {
|
|
519
|
+
content: [
|
|
520
|
+
{
|
|
521
|
+
type: 'text',
|
|
522
|
+
text: JSON.stringify({
|
|
523
|
+
error: 'Screen not found',
|
|
524
|
+
available_screens: Object.keys(screenPatterns.screens)
|
|
525
|
+
}, null, 2),
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const result = { screen };
|
|
532
|
+
|
|
533
|
+
if (include_components) {
|
|
534
|
+
result.components_breakdown = screen.components_used
|
|
535
|
+
.map(name => COMPONENTS_DATA[name + 'Component'])
|
|
536
|
+
.filter(Boolean);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return {
|
|
540
|
+
content: [
|
|
541
|
+
{
|
|
542
|
+
type: 'text',
|
|
543
|
+
text: JSON.stringify(result, null, 2),
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// SEARCH BY PATTERN
|
|
550
|
+
if (name === 'search_by_pattern') {
|
|
551
|
+
const workflow = args?.workflow;
|
|
552
|
+
const features = args?.features || [];
|
|
553
|
+
const components = args?.components || [];
|
|
554
|
+
|
|
555
|
+
let screens = Object.values(screenPatterns.screens);
|
|
556
|
+
|
|
557
|
+
if (workflow) {
|
|
558
|
+
screens = screens.filter(s => s.workflow_pattern === workflow);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (features.length > 0) {
|
|
562
|
+
screens = screens.filter(s =>
|
|
563
|
+
features.every(f => s.features[f] === true)
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (components.length > 0) {
|
|
568
|
+
screens = screens.filter(s =>
|
|
569
|
+
components.every(c => s.components_used.includes(c))
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Get recommended components based on matching screens
|
|
574
|
+
const allComponents = new Set();
|
|
575
|
+
screens.forEach(s => s.components_used.forEach(c => allComponents.add(c)));
|
|
576
|
+
|
|
577
|
+
return {
|
|
578
|
+
content: [
|
|
579
|
+
{
|
|
580
|
+
type: 'text',
|
|
581
|
+
text: JSON.stringify({
|
|
582
|
+
filters: { workflow, features, components },
|
|
583
|
+
matching_screens: screens,
|
|
584
|
+
count: screens.length,
|
|
585
|
+
recommended_components: Array.from(allComponents),
|
|
586
|
+
}, null, 2),
|
|
587
|
+
},
|
|
588
|
+
],
|
|
589
|
+
};
|
|
590
|
+
}
|
|
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
|
+
|
|
369
660
|
return {
|
|
370
661
|
content: [
|
|
371
662
|
{
|
|
@@ -390,8 +681,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
390
681
|
async function main() {
|
|
391
682
|
const transport = new StdioServerTransport();
|
|
392
683
|
await server.connect(transport);
|
|
393
|
-
console.error('Branintelle UI Library MCP Server
|
|
394
|
-
console.error('Enhanced with
|
|
684
|
+
console.error('Branintelle UI Library MCP Server v3.1 running on stdio');
|
|
685
|
+
console.error('⨠Enhanced with screen patterns and Figma screenshots');
|
|
686
|
+
console.error('šø 6 screens with base64 image support for LLM vision');
|
|
395
687
|
}
|
|
396
688
|
|
|
397
689
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
{
|
|
2
|
+
"screens": {
|
|
3
|
+
"screen_001": {
|
|
4
|
+
"id": "screen_001",
|
|
5
|
+
"name": "Briefs Listing - Drafts Tab",
|
|
6
|
+
"type": "listing_page",
|
|
7
|
+
"route": "/briefs",
|
|
8
|
+
"module": "Plan to Impact",
|
|
9
|
+
"workflow_pattern": "classic_list_index",
|
|
10
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_001_briefs_listing_drafts.png",
|
|
11
|
+
"components_used": [
|
|
12
|
+
"stats-cards",
|
|
13
|
+
"tabs",
|
|
14
|
+
"action-bar",
|
|
15
|
+
"scrollable-data-table"
|
|
16
|
+
],
|
|
17
|
+
"features": {
|
|
18
|
+
"has_bulk_selection": true,
|
|
19
|
+
"has_row_actions": true,
|
|
20
|
+
"has_tabs": true,
|
|
21
|
+
"has_filters": true,
|
|
22
|
+
"has_search": true,
|
|
23
|
+
"has_export": true,
|
|
24
|
+
"has_wizard": false,
|
|
25
|
+
"has_grouping": false
|
|
26
|
+
},
|
|
27
|
+
"design_patterns": [
|
|
28
|
+
"Stats cards",
|
|
29
|
+
"Tab navigation",
|
|
30
|
+
"Data table with sorting",
|
|
31
|
+
"Bulk selection",
|
|
32
|
+
"Row actions menu",
|
|
33
|
+
"Search and filter",
|
|
34
|
+
"Primary/secondary CTAs"
|
|
35
|
+
],
|
|
36
|
+
"key_interactions": [
|
|
37
|
+
"Bulk select briefs via checkboxes",
|
|
38
|
+
"Filter briefs using filter button",
|
|
39
|
+
"Search briefs by keyword",
|
|
40
|
+
"Sort columns by clicking headers",
|
|
41
|
+
"Access row actions via 3-dot menu",
|
|
42
|
+
"Create new brief via primary CTA",
|
|
43
|
+
"Export data via Export Report button",
|
|
44
|
+
"Click on brief ID to view details",
|
|
45
|
+
"Switch between tabs to filter by status"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"screen_002": {
|
|
49
|
+
"id": "screen_002",
|
|
50
|
+
"name": "RFP Listing - Assign Buyer (Triage)",
|
|
51
|
+
"type": "listing_page_workflow",
|
|
52
|
+
"route": "/rfp/triage",
|
|
53
|
+
"module": "P2P",
|
|
54
|
+
"workflow_pattern": "triage_assignment",
|
|
55
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_002_rfp_triage_assign_buyer.png",
|
|
56
|
+
"components_used": [
|
|
57
|
+
"stats-cards",
|
|
58
|
+
"action-bar",
|
|
59
|
+
"scrollable-data-table",
|
|
60
|
+
"inline-actions"
|
|
61
|
+
],
|
|
62
|
+
"features": {
|
|
63
|
+
"has_bulk_selection": true,
|
|
64
|
+
"has_row_actions": true,
|
|
65
|
+
"has_tabs": false,
|
|
66
|
+
"has_filters": true,
|
|
67
|
+
"has_search": true,
|
|
68
|
+
"has_export": true,
|
|
69
|
+
"has_wizard": false,
|
|
70
|
+
"has_grouping": false
|
|
71
|
+
},
|
|
72
|
+
"design_patterns": [
|
|
73
|
+
"Stats cards with multi-label",
|
|
74
|
+
"Inline action buttons",
|
|
75
|
+
"Time urgency indicators",
|
|
76
|
+
"Bulk selection with disabled-until-selection CTA",
|
|
77
|
+
"Helper text for workflow guidance",
|
|
78
|
+
"No tabs for single-state listings",
|
|
79
|
+
"Relative time display"
|
|
80
|
+
],
|
|
81
|
+
"key_interactions": [
|
|
82
|
+
"Bulk select briefs via checkboxes",
|
|
83
|
+
"Click inline 'Assign Buyer' button on any row",
|
|
84
|
+
"Select multiple and use bulk 'Assign Buyer' action",
|
|
85
|
+
"Filter briefs using filter button",
|
|
86
|
+
"Search briefs by keyword",
|
|
87
|
+
"Sort columns by clicking headers",
|
|
88
|
+
"Export data via Export Report button",
|
|
89
|
+
"View time urgency indicators"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"screen_003": {
|
|
93
|
+
"id": "screen_003",
|
|
94
|
+
"name": "RFP Listing - In Progress (All Status)",
|
|
95
|
+
"type": "listing_page_complex",
|
|
96
|
+
"route": "/rfp/in-progress",
|
|
97
|
+
"module": "P2P",
|
|
98
|
+
"workflow_pattern": "active_management",
|
|
99
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_003_rfp_in_progress_all_status.png",
|
|
100
|
+
"components_used": [
|
|
101
|
+
"stats-cards",
|
|
102
|
+
"action-bar",
|
|
103
|
+
"scrollable-data-table",
|
|
104
|
+
"inline-actions"
|
|
105
|
+
],
|
|
106
|
+
"features": {
|
|
107
|
+
"has_bulk_selection": false,
|
|
108
|
+
"has_row_actions": true,
|
|
109
|
+
"has_tabs": false,
|
|
110
|
+
"has_filters": true,
|
|
111
|
+
"has_search": true,
|
|
112
|
+
"has_export": false,
|
|
113
|
+
"has_wizard": false,
|
|
114
|
+
"has_grouping": false
|
|
115
|
+
},
|
|
116
|
+
"design_patterns": [
|
|
117
|
+
"Stats cards with state",
|
|
118
|
+
"Dropdown filters (status and user)",
|
|
119
|
+
"Inline action buttons",
|
|
120
|
+
"Progress bars with fractions",
|
|
121
|
+
"Status badges with semantic colors",
|
|
122
|
+
"Icon badges for round types",
|
|
123
|
+
"User avatar with name",
|
|
124
|
+
"No bulk selection",
|
|
125
|
+
"Row-level management"
|
|
126
|
+
],
|
|
127
|
+
"key_interactions": [
|
|
128
|
+
"Filter by status via dropdown",
|
|
129
|
+
"Filter by buyer lead via user dropdown",
|
|
130
|
+
"Add new rounds via inline + button",
|
|
131
|
+
"Expand round details via expand button",
|
|
132
|
+
"Access more options via 3-dot menu",
|
|
133
|
+
"Sort columns by clicking headers",
|
|
134
|
+
"Click RFP ID to view details",
|
|
135
|
+
"Monitor vendor participation progress",
|
|
136
|
+
"Track submission deadlines"
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
"screen_004": {
|
|
140
|
+
"id": "screen_004",
|
|
141
|
+
"name": "Brief Creation - Supporting Documents (Step 2)",
|
|
142
|
+
"type": "form_wizard",
|
|
143
|
+
"route": "/briefs/create/supporting",
|
|
144
|
+
"module": "Plan to Impact",
|
|
145
|
+
"workflow_pattern": "multi_step_form",
|
|
146
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_004_brief_creation_step2_supporting.png",
|
|
147
|
+
"components_used": [
|
|
148
|
+
"stats-cards",
|
|
149
|
+
"action-bar",
|
|
150
|
+
"scrollable-data-table",
|
|
151
|
+
"form-sections"
|
|
152
|
+
],
|
|
153
|
+
"features": {
|
|
154
|
+
"has_bulk_selection": false,
|
|
155
|
+
"has_row_actions": false,
|
|
156
|
+
"has_tabs": false,
|
|
157
|
+
"has_filters": true,
|
|
158
|
+
"has_search": true,
|
|
159
|
+
"has_export": false,
|
|
160
|
+
"has_wizard": true,
|
|
161
|
+
"has_grouping": false
|
|
162
|
+
},
|
|
163
|
+
"design_patterns": [
|
|
164
|
+
"Wizard stepper",
|
|
165
|
+
"Sub-step indicators",
|
|
166
|
+
"File upload dropzone",
|
|
167
|
+
"File cards with actions",
|
|
168
|
+
"Error states",
|
|
169
|
+
"Confidential badge/lock",
|
|
170
|
+
"Progress tracking",
|
|
171
|
+
"Draft saving",
|
|
172
|
+
"Navigation buttons (Prev/Next)"
|
|
173
|
+
],
|
|
174
|
+
"key_interactions": [
|
|
175
|
+
"Navigate between wizard steps via left sidebar",
|
|
176
|
+
"Upload files via drag-drop or click",
|
|
177
|
+
"Mark files as confidential via lock icon",
|
|
178
|
+
"Edit file metadata via edit icon",
|
|
179
|
+
"Delete uploaded files via delete icon",
|
|
180
|
+
"Save progress as draft",
|
|
181
|
+
"Navigate to previous step",
|
|
182
|
+
"Proceed to next step (KPI's)",
|
|
183
|
+
"Go back to brief listing"
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
"screen_005": {
|
|
187
|
+
"id": "screen_005",
|
|
188
|
+
"name": "Brief Creation - Vendor Recommendation (Step 4)",
|
|
189
|
+
"type": "form_wizard",
|
|
190
|
+
"route": "/briefs/create/vendor-recommendation",
|
|
191
|
+
"module": "Plan to Impact",
|
|
192
|
+
"workflow_pattern": "multi_step_form",
|
|
193
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_005_brief_creation_step4_vendor_recommendation.png",
|
|
194
|
+
"components_used": [
|
|
195
|
+
"stats-cards",
|
|
196
|
+
"action-bar",
|
|
197
|
+
"scrollable-data-table",
|
|
198
|
+
"form-sections"
|
|
199
|
+
],
|
|
200
|
+
"features": {
|
|
201
|
+
"has_bulk_selection": false,
|
|
202
|
+
"has_row_actions": false,
|
|
203
|
+
"has_tabs": false,
|
|
204
|
+
"has_filters": true,
|
|
205
|
+
"has_search": true,
|
|
206
|
+
"has_export": false,
|
|
207
|
+
"has_wizard": true,
|
|
208
|
+
"has_grouping": false
|
|
209
|
+
},
|
|
210
|
+
"design_patterns": [
|
|
211
|
+
"Wizard stepper",
|
|
212
|
+
"Preference cards (highlighted for top choice)",
|
|
213
|
+
"Vendor status badges",
|
|
214
|
+
"MSME type badge",
|
|
215
|
+
"Attachment count indicator",
|
|
216
|
+
"Comments section",
|
|
217
|
+
"Card actions (edit, lock, delete)",
|
|
218
|
+
"Secondary table for additional items",
|
|
219
|
+
"Add button (top-right)",
|
|
220
|
+
"Status icons (user_check, user_group)",
|
|
221
|
+
"Highlight border for active selection"
|
|
222
|
+
],
|
|
223
|
+
"key_interactions": [
|
|
224
|
+
"Add new vendors via '+ Add Vendor' button",
|
|
225
|
+
"Reorder vendor preferences (drag-drop or edit)",
|
|
226
|
+
"Mark vendors as Registered/Unregistered",
|
|
227
|
+
"Add/edit vendor comments",
|
|
228
|
+
"Attach supporting documents to vendor cards (count: 3)",
|
|
229
|
+
"Edit vendor details via edit icon",
|
|
230
|
+
"Lock vendor information via lock icon (for registered)",
|
|
231
|
+
"Delete vendors via delete icon",
|
|
232
|
+
"Move vendors between preference levels and 'Other Considerations'",
|
|
233
|
+
"View more details via 3-dot menu in table",
|
|
234
|
+
"Save progress as draft",
|
|
235
|
+
"Navigate to previous step (Cost Details)",
|
|
236
|
+
"Proceed to next step (Review and Save)"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
"screen_006": {
|
|
240
|
+
"id": "screen_006",
|
|
241
|
+
"name": "Provisions Listing - Grouped by Vendor",
|
|
242
|
+
"type": "listing_page_grouped",
|
|
243
|
+
"route": "/p2p/provisions",
|
|
244
|
+
"module": "P2P",
|
|
245
|
+
"workflow_pattern": "grouped_listing_readonly",
|
|
246
|
+
"screenshot_url": "https://figr-branintelle-assets.s3.amazonaws.com/screens/screen_006_provisions_listing_grouped.png",
|
|
247
|
+
"components_used": [
|
|
248
|
+
"stats-cards",
|
|
249
|
+
"tabs",
|
|
250
|
+
"action-bar",
|
|
251
|
+
"scrollable-data-table"
|
|
252
|
+
],
|
|
253
|
+
"features": {
|
|
254
|
+
"has_bulk_selection": false,
|
|
255
|
+
"has_row_actions": false,
|
|
256
|
+
"has_tabs": true,
|
|
257
|
+
"has_filters": true,
|
|
258
|
+
"has_search": true,
|
|
259
|
+
"has_export": false,
|
|
260
|
+
"has_wizard": false,
|
|
261
|
+
"has_grouping": true
|
|
262
|
+
},
|
|
263
|
+
"design_patterns": [
|
|
264
|
+
"Grouped/collapsible table",
|
|
265
|
+
"View switching tabs",
|
|
266
|
+
"Stats cards with time filters",
|
|
267
|
+
"MSME vendor badges",
|
|
268
|
+
"Clickable links (PO) vs static text (WC)",
|
|
269
|
+
"Currency formatting",
|
|
270
|
+
"Date range display",
|
|
271
|
+
"Search and filter",
|
|
272
|
+
"Export report",
|
|
273
|
+
"Auto-sync indicator"
|
|
274
|
+
],
|
|
275
|
+
"key_interactions": [
|
|
276
|
+
"Switch between Vendor/Brand/PO views via tabs",
|
|
277
|
+
"Expand/collapse vendor groups",
|
|
278
|
+
"Click PO links to view details",
|
|
279
|
+
"Filter provisions",
|
|
280
|
+
"Search across provisions",
|
|
281
|
+
"Sort columns",
|
|
282
|
+
"Download Provision Report",
|
|
283
|
+
"Switch between Current Month and All Months views"
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"workflowPatterns": {
|
|
288
|
+
"stats_cards": {
|
|
289
|
+
"count": 4,
|
|
290
|
+
"position": "top_of_page",
|
|
291
|
+
"contains": [
|
|
292
|
+
"count",
|
|
293
|
+
"budget",
|
|
294
|
+
"filter_option"
|
|
295
|
+
],
|
|
296
|
+
"interactive": true
|
|
297
|
+
},
|
|
298
|
+
"action_bar": {
|
|
299
|
+
"layout": "split",
|
|
300
|
+
"left": [
|
|
301
|
+
"filters",
|
|
302
|
+
"add",
|
|
303
|
+
"search"
|
|
304
|
+
],
|
|
305
|
+
"right": [
|
|
306
|
+
"secondary_action",
|
|
307
|
+
"primary_cta"
|
|
308
|
+
]
|
|
309
|
+
},
|
|
310
|
+
"data_table": {
|
|
311
|
+
"features": [
|
|
312
|
+
"sorting",
|
|
313
|
+
"bulk_selection",
|
|
314
|
+
"row_actions"
|
|
315
|
+
],
|
|
316
|
+
"frozen_columns": [
|
|
317
|
+
"checkbox",
|
|
318
|
+
"actions_or_id"
|
|
319
|
+
]
|
|
320
|
+
},
|
|
321
|
+
"color_coding": {
|
|
322
|
+
"brief_ids": "orange",
|
|
323
|
+
"status_badges": "semantic_colors",
|
|
324
|
+
"action_buttons": "blue"
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
"screenTypes": {
|
|
328
|
+
"listing_page": {
|
|
329
|
+
"examples": [
|
|
330
|
+
"screen_001"
|
|
331
|
+
],
|
|
332
|
+
"characteristics": [
|
|
333
|
+
"stats cards",
|
|
334
|
+
"tabs",
|
|
335
|
+
"data table",
|
|
336
|
+
"bulk actions",
|
|
337
|
+
"row actions menu"
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
"listing_page_workflow": {
|
|
341
|
+
"examples": [
|
|
342
|
+
"screen_002"
|
|
343
|
+
],
|
|
344
|
+
"characteristics": [
|
|
345
|
+
"stats cards",
|
|
346
|
+
"no tabs",
|
|
347
|
+
"inline actions",
|
|
348
|
+
"helper text",
|
|
349
|
+
"disabled CTAs"
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
"listing_page_complex": {
|
|
353
|
+
"examples": [
|
|
354
|
+
"screen_003"
|
|
355
|
+
],
|
|
356
|
+
"characteristics": [
|
|
357
|
+
"stats cards",
|
|
358
|
+
"dropdown filters",
|
|
359
|
+
"inline actions",
|
|
360
|
+
"progress bars",
|
|
361
|
+
"status badges"
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
"listing_page_grouped": {
|
|
365
|
+
"examples": [
|
|
366
|
+
"screen_006"
|
|
367
|
+
],
|
|
368
|
+
"characteristics": [
|
|
369
|
+
"stats cards",
|
|
370
|
+
"view tabs",
|
|
371
|
+
"grouped/collapsible rows",
|
|
372
|
+
"read-only",
|
|
373
|
+
"auto-sync"
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
"form_wizard": {
|
|
377
|
+
"examples": [
|
|
378
|
+
"screen_004",
|
|
379
|
+
"screen_005"
|
|
380
|
+
],
|
|
381
|
+
"characteristics": [
|
|
382
|
+
"stepper",
|
|
383
|
+
"sub-steps",
|
|
384
|
+
"prev/next nav",
|
|
385
|
+
"draft saving",
|
|
386
|
+
"validation",
|
|
387
|
+
"progress tracking"
|
|
388
|
+
]
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
"useCases": {}
|
|
392
|
+
}
|
|
@@ -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);
|