vplex-memory 2.4.3 → 2.4.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vplex-memory",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "VPLEX Memory MCP Server — persistent cross-session memory for AI coding tools",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1344,6 +1344,8 @@ async function handleRequest(request) {
1344
1344
  };
1345
1345
 
1346
1346
  case "initialized":
1347
+ // After initialization, request workspace roots from the client
1348
+ requestRootsFromClient();
1347
1349
  return null;
1348
1350
 
1349
1351
  case "tools/list":
@@ -1367,6 +1369,38 @@ async function handleRequest(request) {
1367
1369
  }
1368
1370
  }
1369
1371
 
1372
+ // ── Server-to-Client Requests ───────────────────────────────────────
1373
+
1374
+ let nextRequestId = 1;
1375
+ const pendingRequests = new Map(); // id → { resolve, reject, timer }
1376
+
1377
+ function sendClientRequest(method, params = {}) {
1378
+ return new Promise((resolve, reject) => {
1379
+ const id = `srv-${nextRequestId++}`;
1380
+ const timer = setTimeout(() => {
1381
+ pendingRequests.delete(id);
1382
+ reject(new Error(`Client request ${method} timed out`));
1383
+ }, 5000);
1384
+ pendingRequests.set(id, { resolve, reject, timer });
1385
+ process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
1386
+ });
1387
+ }
1388
+
1389
+ async function requestRootsFromClient() {
1390
+ try {
1391
+ const result = await sendClientRequest("roots/list");
1392
+ if (result?.roots?.length > 0) {
1393
+ const rootUri = result.roots[0].uri || result.roots[0];
1394
+ process.stderr.write(`[vplex-mcp] Got root from client: ${typeof rootUri === "string" ? rootUri : JSON.stringify(rootUri)}\n`);
1395
+ if (typeof rootUri === "string" && rootUri.length > 0) {
1396
+ reinitProject(rootUri);
1397
+ }
1398
+ }
1399
+ } catch (err) {
1400
+ process.stderr.write(`[vplex-mcp] roots/list not supported by client: ${err.message}\n`);
1401
+ }
1402
+ }
1403
+
1370
1404
  // ── stdio Communication Loop ────────────────────────────────────────
1371
1405
 
1372
1406
  const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false });
@@ -1375,8 +1409,18 @@ rl.on("line", async (line) => {
1375
1409
  if (!line.trim()) return;
1376
1410
 
1377
1411
  try {
1378
- const request = JSON.parse(line);
1379
- const response = await handleRequest(request);
1412
+ const msg = JSON.parse(line);
1413
+
1414
+ // Check if this is a response to a server-initiated request
1415
+ if (msg.id && pendingRequests.has(msg.id)) {
1416
+ const { resolve, timer } = pendingRequests.get(msg.id);
1417
+ clearTimeout(timer);
1418
+ pendingRequests.delete(msg.id);
1419
+ resolve(msg.result ?? null);
1420
+ return;
1421
+ }
1422
+
1423
+ const response = await handleRequest(msg);
1380
1424
  if (response !== null) {
1381
1425
  // Write to stdout only — stderr is reserved for diagnostics
1382
1426
  process.stdout.write(JSON.stringify(response) + "\n");