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 +1 -1
- package/vplex-mcp-server.mjs +46 -2
package/package.json
CHANGED
package/vplex-mcp-server.mjs
CHANGED
|
@@ -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
|
|
1379
|
-
|
|
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");
|