viewgate-mcp 1.0.20 → 1.0.22
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/dist/index.js +113 -21
- package/package.json +2 -2
- package/dist/test_fix.js +0 -59
- package/dist/test_sse.js +0 -23
package/dist/index.js
CHANGED
|
@@ -51,7 +51,10 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
51
51
|
description: "Retrieves all feedback annotations. WORKFLOW: 1. Read these annotations, 2. Open the source files and apply SURGICAL fixes based on '_ia_fix_instruction'. 3. IMMEDIATELY call 'mark_annotation_ready' with the results for EACH ticket you fixed. Use 'outerHtml' and 'source' (file:line) to locate the exact code block without manual searching. IMPORTANT: All AI analysis and comments MUST be in the 'preferredLanguage' specified in the output. Failure to follow the language setting is UNACCEPTABLE.",
|
|
52
52
|
inputSchema: {
|
|
53
53
|
type: "object",
|
|
54
|
-
properties: {
|
|
54
|
+
properties: {
|
|
55
|
+
limit: { type: "number", description: "Maximum number of annotations to retrieve (default: 3)", default: 3 },
|
|
56
|
+
status: { type: "string", description: "Comma-separated list of statuses to fetch (default: 'pending,bug_fixing')", default: "pending,bug_fixing" }
|
|
57
|
+
},
|
|
55
58
|
},
|
|
56
59
|
},
|
|
57
60
|
{
|
|
@@ -143,6 +146,25 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
143
146
|
type: "object",
|
|
144
147
|
properties: {},
|
|
145
148
|
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: "get_optimizations",
|
|
152
|
+
description: "Retrieves reported JSON payload optimizations (unused fields). WORKFLOW: 1. Get optimizations, 2. Locate the backend code for the endpoint, 3. Remove unused fields from the response, 4. Call 'mark_optimization_applied' with the ID.",
|
|
153
|
+
inputSchema: {
|
|
154
|
+
type: "object",
|
|
155
|
+
properties: {},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "mark_optimization_applied",
|
|
160
|
+
description: "Marks a payload optimization as applied in the backend after you have modified the code to remove unused fields.",
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: "object",
|
|
163
|
+
properties: {
|
|
164
|
+
id: { type: "string", description: "The ID of the optimization report to mark as applied" }
|
|
165
|
+
},
|
|
166
|
+
required: ["id"]
|
|
167
|
+
},
|
|
146
168
|
}
|
|
147
169
|
],
|
|
148
170
|
};
|
|
@@ -151,8 +173,10 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
151
173
|
switch (request.params.name) {
|
|
152
174
|
case "get_annotations": {
|
|
153
175
|
try {
|
|
154
|
-
const
|
|
155
|
-
const
|
|
176
|
+
const args = request.params.arguments;
|
|
177
|
+
const limit = args.limit || 3;
|
|
178
|
+
const statuses = args.status || 'pending,bug_fixing';
|
|
179
|
+
const response = await fetch(`${BACKEND_URL}/api/mcp/annotations?status=${statuses}&limit=${limit}&lock=true`, {
|
|
156
180
|
headers: {
|
|
157
181
|
'x-api-key': apiKey,
|
|
158
182
|
...(personalKey ? { 'x-personal-key': personalKey } : {})
|
|
@@ -194,9 +218,12 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
194
218
|
return prioB - prioA;
|
|
195
219
|
});
|
|
196
220
|
const annotationsWithTips = sortedAnnotations.map((ann) => {
|
|
221
|
+
const file = ann.reference?.source?.split(':')[0];
|
|
222
|
+
const line = ann.reference?.source?.split(':')[1];
|
|
197
223
|
const source = ann.reference?.source;
|
|
198
|
-
const
|
|
199
|
-
|
|
224
|
+
const pendingCorrection = Array.isArray(ann.corrections)
|
|
225
|
+
? ann.corrections.find((c) => c.status === 'pending')
|
|
226
|
+
: (typeof ann.corrections === 'string' ? { text: ann.corrections } : null);
|
|
200
227
|
// Essential fields for the AI to perform a surgical fix
|
|
201
228
|
return {
|
|
202
229
|
id: ann._id,
|
|
@@ -204,6 +231,7 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
204
231
|
priority: ann.priority,
|
|
205
232
|
status: ann.status,
|
|
206
233
|
message: ann.message,
|
|
234
|
+
corrections: ann.corrections, // Include full history
|
|
207
235
|
source: source,
|
|
208
236
|
filePath: ann.filePath || file,
|
|
209
237
|
line: ann.line || (line ? parseInt(line) : undefined),
|
|
@@ -220,6 +248,12 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
220
248
|
_ia_fix_instruction: `### 🎨 DESIGN CONTEXT (Figma)
|
|
221
249
|
${ann.figmaReference ? `A design reference is available: ${ann.figmaReference}. Use the Figma link to understand the UX requirements.` : 'No explicit figma design linked.'}
|
|
222
250
|
|
|
251
|
+
${pendingCorrection ? `### ⚠️ PENDING CORRECTION (FEEDBACK)
|
|
252
|
+
The user has requested the following corrections:
|
|
253
|
+
"${pendingCorrection.text}"
|
|
254
|
+
${pendingCorrection.author ? `Requested by: ${pendingCorrection.author.name}` : ''}
|
|
255
|
+
PLEASE ENSURE THESE SPECIFIC ISSUES ARE ADDRESSED IN YOUR FIX.` : ''}
|
|
256
|
+
|
|
223
257
|
### 🔬 SURGICAL FIX PROTOCOL (Language: ${data.preferredLanguage || 'en'})
|
|
224
258
|
1. **PRIMARY**: Search for \`data-vg-id="${ann.reference?.vgId}"\`.
|
|
225
259
|
2. **SECONDARY**: Check \`${file}\` L${line} (Fiber Source).
|
|
@@ -229,7 +263,7 @@ ${ann.figmaReference ? `A design reference is available: ${ann.figmaReference}.
|
|
|
229
263
|
IMPORTANT: All your analysis and implementation comments MUST BE IN ${data.preferredLanguage === 'es' ? 'SPANISH' : 'ENGLISH'}.
|
|
230
264
|
|
|
231
265
|
Confidence: [vgId: ${ann.reference?.confidence?.vgId || 0}, Fiber: ${ann.reference?.confidence?.fiber || 0}, Fingerprint: ${ann.reference?.confidence?.fingerprint || 0}]
|
|
232
|
-
Instruction: ${ann.message}`
|
|
266
|
+
Instruction: ${ann.message}${pendingCorrection ? `\nCorrection Needed: ${pendingCorrection.text}` : ''}`
|
|
233
267
|
};
|
|
234
268
|
});
|
|
235
269
|
return {
|
|
@@ -259,22 +293,34 @@ Instruction: ${ann.message}`
|
|
|
259
293
|
case "mark_annotation_ready": {
|
|
260
294
|
try {
|
|
261
295
|
const args = request.params.arguments;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
296
|
+
let lastError = null;
|
|
297
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
298
|
+
try {
|
|
299
|
+
const response = await fetch(`${BACKEND_URL}/api/mcp/annotations/batch-ready`, {
|
|
300
|
+
method: 'PATCH',
|
|
301
|
+
headers: {
|
|
302
|
+
'Content-Type': 'application/json',
|
|
303
|
+
'x-api-key': apiKey,
|
|
304
|
+
...(personalKey ? { 'x-personal-key': personalKey } : {})
|
|
305
|
+
},
|
|
306
|
+
body: JSON.stringify({ results: args.results })
|
|
307
|
+
});
|
|
308
|
+
if (!response.ok) {
|
|
309
|
+
throw new Error(`Backend responded with ${response.status}`);
|
|
310
|
+
}
|
|
311
|
+
const result = await response.json();
|
|
312
|
+
return {
|
|
313
|
+
content: [{ type: "text", text: `Successfully processed batch update: ${JSON.stringify(result, null, 2)}` }],
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
lastError = error;
|
|
318
|
+
console.error(`[MCP] mark_annotation_ready attempt ${attempt} failed:`, error.message);
|
|
319
|
+
if (attempt < 3)
|
|
320
|
+
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
|
321
|
+
}
|
|
273
322
|
}
|
|
274
|
-
|
|
275
|
-
return {
|
|
276
|
-
content: [{ type: "text", text: `Successfully processed batch update: ${JSON.stringify(result, null, 2)}` }],
|
|
277
|
-
};
|
|
323
|
+
throw lastError || new Error('Unknown error during batch update');
|
|
278
324
|
}
|
|
279
325
|
catch (error) {
|
|
280
326
|
return {
|
|
@@ -395,6 +441,52 @@ Instruction: ${ann.message}`
|
|
|
395
441
|
};
|
|
396
442
|
}
|
|
397
443
|
}
|
|
444
|
+
case "get_optimizations": {
|
|
445
|
+
try {
|
|
446
|
+
const response = await fetch(`${BACKEND_URL}/api/mcp/optimizations`, {
|
|
447
|
+
headers: {
|
|
448
|
+
'x-api-key': apiKey,
|
|
449
|
+
...(personalKey ? { 'x-personal-key': personalKey } : {})
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
if (!response.ok)
|
|
453
|
+
throw new Error(`Backend responded with ${response.status}`);
|
|
454
|
+
const data = await response.json();
|
|
455
|
+
return {
|
|
456
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
return {
|
|
461
|
+
content: [{ type: "text", text: `Error fetching optimizations: ${error.message}` }],
|
|
462
|
+
isError: true
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
case "mark_optimization_applied": {
|
|
467
|
+
try {
|
|
468
|
+
const args = request.params.arguments;
|
|
469
|
+
const response = await fetch(`${BACKEND_URL}/api/mcp/optimizations/${args.id}/applied`, {
|
|
470
|
+
method: 'PATCH',
|
|
471
|
+
headers: {
|
|
472
|
+
'x-api-key': apiKey,
|
|
473
|
+
...(personalKey ? { 'x-personal-key': personalKey } : {})
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
if (!response.ok)
|
|
477
|
+
throw new Error(`Backend responded with ${response.status}`);
|
|
478
|
+
const result = await response.json();
|
|
479
|
+
return {
|
|
480
|
+
content: [{ type: "text", text: `Optimization marked as applied: ${JSON.stringify(result)}` }]
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
return {
|
|
485
|
+
content: [{ type: "text", text: `Error marking optimization: ${error.message}` }],
|
|
486
|
+
isError: true
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
}
|
|
398
490
|
default:
|
|
399
491
|
throw new Error("Unknown tool");
|
|
400
492
|
}
|
package/package.json
CHANGED
package/dist/test_fix.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import fetch from "node-fetch";
|
|
2
|
-
async function test() {
|
|
3
|
-
console.log("1. Connecting to http://localhost:3333/sse...");
|
|
4
|
-
const response = await fetch("http://localhost:3333/sse?apiKey=2af5628c9442f10b93cfe6970897d4de26578d958ba43a4e3bcb684fe0f92668");
|
|
5
|
-
if (!response.ok) {
|
|
6
|
-
console.error("Failed to connect to SSE:", response.status, await response.text());
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
console.log("SSE connected. Reading stream for sessionId...");
|
|
10
|
-
const body = response.body;
|
|
11
|
-
let sessionId = null;
|
|
12
|
-
body.on("data", async (chunk) => {
|
|
13
|
-
const text = chunk.toString();
|
|
14
|
-
console.log("SSE Data:", text);
|
|
15
|
-
// Example event:
|
|
16
|
-
// event: endpoint
|
|
17
|
-
// data: /message?sessionId=...
|
|
18
|
-
const match = text.match(/sessionId=([a-f0-9-]+)/);
|
|
19
|
-
if (match && !sessionId) {
|
|
20
|
-
sessionId = match[1];
|
|
21
|
-
console.log("FOUND SESSION ID:", sessionId);
|
|
22
|
-
// 2. Test POST to /message
|
|
23
|
-
console.log(`2. Testing POST to /message?sessionId=${sessionId}...`);
|
|
24
|
-
const postResponse = await fetch(`http://localhost:3333/message?sessionId=${sessionId}`, {
|
|
25
|
-
method: 'POST',
|
|
26
|
-
headers: {
|
|
27
|
-
'Content-Type': 'application/json'
|
|
28
|
-
},
|
|
29
|
-
body: JSON.stringify({
|
|
30
|
-
jsonrpc: "2.0",
|
|
31
|
-
id: 1,
|
|
32
|
-
method: "initialize",
|
|
33
|
-
params: {
|
|
34
|
-
clientInfo: { name: "test-client", version: "1.0.0" },
|
|
35
|
-
protocolVersion: "2024-11-05",
|
|
36
|
-
capabilities: {}
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
});
|
|
40
|
-
console.log("POST Response Status:", postResponse.status);
|
|
41
|
-
const responseText = await postResponse.text();
|
|
42
|
-
console.log("POST Response Body:", responseText);
|
|
43
|
-
if (postResponse.status === 200 || postResponse.status === 202) {
|
|
44
|
-
console.log("SUCCESS: Stream was readable and message was accepted.");
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.error("FAILURE: Server returned error status.");
|
|
48
|
-
}
|
|
49
|
-
process.exit(0);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
if (!sessionId) {
|
|
54
|
-
console.error("TIMEOUT: Did not receive sessionId from SSE.");
|
|
55
|
-
process.exit(1);
|
|
56
|
-
}
|
|
57
|
-
}, 10000);
|
|
58
|
-
}
|
|
59
|
-
test();
|
package/dist/test_sse.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import fetch from "node-fetch";
|
|
2
|
-
async function test() {
|
|
3
|
-
console.log("Connecting to http://localhost:3333/sse...");
|
|
4
|
-
const response = await fetch("http://localhost:3333/sse?apiKey=test-key");
|
|
5
|
-
if (!response.ok) {
|
|
6
|
-
console.error("Failed to connect:", response.status, await response.text());
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
console.log("Headers:", response.headers.raw());
|
|
10
|
-
const body = response.body;
|
|
11
|
-
body.on("data", (chunk) => {
|
|
12
|
-
console.log("Chunk received:", chunk.toString());
|
|
13
|
-
if (chunk.toString().includes("event: endpoint")) {
|
|
14
|
-
console.log("FOUND ENDPOINT EVENT!");
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
body.on("end", () => console.log("Connection closed"));
|
|
18
|
-
setTimeout(() => {
|
|
19
|
-
console.log("Closing test...");
|
|
20
|
-
process.exit(0);
|
|
21
|
-
}, 5000);
|
|
22
|
-
}
|
|
23
|
-
test();
|