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 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 statuses = 'pending,bug_fixing';
155
- const response = await fetch(`${BACKEND_URL}/api/mcp/annotations?status=${statuses}`, {
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 hasSource = source && source !== 'unknown:0';
199
- const [file, line] = hasSource ? source.split(':') : [null, null];
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
- const response = await fetch(`${BACKEND_URL}/api/mcp/annotations/batch-ready`, {
263
- method: 'PATCH',
264
- headers: {
265
- 'Content-Type': 'application/json',
266
- 'x-api-key': apiKey,
267
- ...(personalKey ? { 'x-personal-key': personalKey } : {})
268
- },
269
- body: JSON.stringify({ results: args.results })
270
- });
271
- if (!response.ok) {
272
- throw new Error(`Backend responded with ${response.status} when updating annotations`);
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
- const result = await response.json();
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viewgate-mcp",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "viewgate-mcp": "./dist/index.js"
@@ -37,4 +37,4 @@
37
37
  "tsx": "^4.21.0",
38
38
  "typescript": "^5.9.3"
39
39
  }
40
- }
40
+ }
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();