@plur-ai/mcp 0.18.0 → 0.19.1
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.
|
@@ -10,7 +10,7 @@ function recordTelemetry(event) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
// src/version.ts
|
|
13
|
-
var VERSION = "0.
|
|
13
|
+
var VERSION = "0.19.1";
|
|
14
14
|
|
|
15
15
|
// src/tools.ts
|
|
16
16
|
import { existsSync, unlinkSync } from "fs";
|
|
@@ -1889,12 +1889,12 @@ You have ${store_stats.engram_count} engrams but none matched this task. Call pl
|
|
|
1889
1889
|
if (versionCheck?.updateAvailable && versionCheck.latest) {
|
|
1890
1890
|
const behind = minorVersionsBehind(versionCheck.current, versionCheck.latest);
|
|
1891
1891
|
if (behind > 2) {
|
|
1892
|
-
version_warning = `CRITICAL: Running PLUR v${versionCheck.current} \u2014 latest is v${versionCheck.latest} (${behind} minor versions behind). Known bugs may be present. Update immediately:
|
|
1892
|
+
version_warning = `CRITICAL: Running PLUR v${versionCheck.current} \u2014 latest is v${versionCheck.latest} (${behind} minor versions behind). Known bugs may be present. Update immediately: upgrade @plur-ai/cli and re-run plur init (configs pin versions; running @latest no longer updates them)`;
|
|
1893
1893
|
guide = `\u26A0\uFE0F ${version_warning}
|
|
1894
1894
|
|
|
1895
1895
|
${guide}`;
|
|
1896
1896
|
} else {
|
|
1897
|
-
version_warning = `Update available: PLUR v${versionCheck.current} \u2192 v${versionCheck.latest}. Run:
|
|
1897
|
+
version_warning = `Update available: PLUR v${versionCheck.current} \u2192 v${versionCheck.latest}. Run: npm i -g @plur-ai/cli@latest && plur init (configs pin versions)`;
|
|
1898
1898
|
}
|
|
1899
1899
|
}
|
|
1900
1900
|
if (scope_source === "project-config") {
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, statSy
|
|
|
5
5
|
import { join } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { homedir, platform } from "os";
|
|
8
|
-
var VERSION = "0.
|
|
8
|
+
var VERSION = "0.19.1";
|
|
9
9
|
var HELP = `plur-mcp v${VERSION} \u2014 persistent memory for AI agents
|
|
10
10
|
|
|
11
11
|
Usage:
|
|
@@ -27,7 +27,7 @@ Docs: https://plur.ai \xB7 https://github.com/plur-ai/plur
|
|
|
27
27
|
`;
|
|
28
28
|
var MCP_SERVER_CONFIG = {
|
|
29
29
|
command: "npx",
|
|
30
|
-
args: ["-y",
|
|
30
|
+
args: ["-y", `@plur-ai/mcp@${VERSION}`]
|
|
31
31
|
};
|
|
32
32
|
function compareSemver(a, b) {
|
|
33
33
|
const stripPrerelease = (v) => v.split("-")[0].split("+")[0];
|
|
@@ -143,16 +143,37 @@ function findMcpConfig() {
|
|
|
143
143
|
if (existsSync(globalMcp)) return globalMcp;
|
|
144
144
|
return projectMcp;
|
|
145
145
|
}
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
function readJsonObjectForWrite(path) {
|
|
147
|
+
if (!existsSync(path)) return { data: {}, ok: true };
|
|
148
|
+
try {
|
|
149
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
150
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
151
|
+
return { data: parsed, ok: true };
|
|
152
152
|
}
|
|
153
|
+
} catch {
|
|
153
154
|
}
|
|
155
|
+
return { data: {}, ok: false };
|
|
156
|
+
}
|
|
157
|
+
function writeMcpConfig(configPath) {
|
|
158
|
+
const { data, ok } = readJsonObjectForWrite(configPath);
|
|
159
|
+
if (!ok) {
|
|
160
|
+
return `skipped \u2014 ${configPath} exists but is not a JSON object; writing would discard your other MCP servers. Fix it by hand, then re-run \`plur-mcp init\``;
|
|
161
|
+
}
|
|
162
|
+
const config = data;
|
|
154
163
|
const servers = config.mcpServers ?? {};
|
|
155
|
-
|
|
164
|
+
const existing = servers.plur;
|
|
165
|
+
if (existing) {
|
|
166
|
+
const args = existing.args ?? [];
|
|
167
|
+
const spec = args.filter((a) => a !== "-y" && !a.startsWith("-"))[0] ?? "";
|
|
168
|
+
if (existing.command === "npx" && /^@plur-ai\/mcp(@latest)?$/.test(spec)) {
|
|
169
|
+
const healed = { ...existing, ...MCP_SERVER_CONFIG };
|
|
170
|
+
if (JSON.stringify(healed) !== JSON.stringify(existing)) {
|
|
171
|
+
servers.plur = healed;
|
|
172
|
+
config.mcpServers = servers;
|
|
173
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
174
|
+
return `upgraded stale npx entry in ${configPath}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
156
177
|
return `already configured in ${configPath}`;
|
|
157
178
|
}
|
|
158
179
|
servers.plur = MCP_SERVER_CONFIG;
|
|
@@ -166,13 +187,11 @@ function installHooks() {
|
|
|
166
187
|
const projectSettings = join(process.cwd(), ".claude", "settings.json");
|
|
167
188
|
const globalSettings = join(homedir(), ".claude", "settings.json");
|
|
168
189
|
const settingsPath = existsSync(join(process.cwd(), ".claude")) ? projectSettings : globalSettings;
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
173
|
-
} catch {
|
|
174
|
-
}
|
|
190
|
+
const settingsRead = readJsonObjectForWrite(settingsPath);
|
|
191
|
+
if (!settingsRead.ok) {
|
|
192
|
+
return `skipped \u2014 ${settingsPath} exists but is not a JSON object; writing would discard your other settings. Fix it by hand, then re-run \`plur-mcp init\``;
|
|
175
193
|
}
|
|
194
|
+
const settings = settingsRead.data;
|
|
176
195
|
const hooks = settings.hooks ?? {};
|
|
177
196
|
for (const entries of Object.values(hooks)) {
|
|
178
197
|
for (const entry of entries) {
|
|
@@ -302,7 +321,7 @@ if (arg === "packs") {
|
|
|
302
321
|
process.exit(0);
|
|
303
322
|
}
|
|
304
323
|
if (arg === "serve" || arg === void 0) {
|
|
305
|
-
const { runStdio } = await import("./server-
|
|
324
|
+
const { runStdio } = await import("./server-4JQ4LH5S.js");
|
|
306
325
|
runStdio().catch((err) => {
|
|
307
326
|
console.error("Failed to start PLUR MCP server:", err);
|
|
308
327
|
process.exit(1);
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
resolveToolProfile,
|
|
8
8
|
setActiveToolProfile,
|
|
9
9
|
validateToolArgs
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WKGNAQGB.js";
|
|
11
11
|
|
|
12
12
|
// src/server.ts
|
|
13
13
|
import { Server, ProtocolError, ProtocolErrorCode } from "@modelcontextprotocol/server";
|
|
@@ -192,7 +192,7 @@ async function createServer(plur, options) {
|
|
|
192
192
|
const tools = getToolDefinitions(profile);
|
|
193
193
|
const announceUpdate = (r) => {
|
|
194
194
|
if (r.updateAvailable) {
|
|
195
|
-
console.error(`[plur] Update available: ${r.current} \u2192 ${r.latest}. Run:
|
|
195
|
+
console.error(`[plur] Update available: ${r.current} \u2192 ${r.latest}. Run: npm i -g @plur-ai/cli@latest && plur init (configs pin versions)`);
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
198
|
checkForUpdate("@plur-ai/mcp", VERSION, announceUpdate);
|
|
@@ -412,6 +412,48 @@ Please:
|
|
|
412
412
|
return server;
|
|
413
413
|
}
|
|
414
414
|
async function runStdio() {
|
|
415
|
+
const LOG_WINDOW_MS = 6e4;
|
|
416
|
+
const LOG_MAX_PER_WINDOW = 20;
|
|
417
|
+
let logWindowStart = 0;
|
|
418
|
+
let logCount = 0;
|
|
419
|
+
let suppressed = 0;
|
|
420
|
+
const logFault = (kind, err) => {
|
|
421
|
+
const now = Date.now();
|
|
422
|
+
if (now - logWindowStart > LOG_WINDOW_MS) {
|
|
423
|
+
if (suppressed > 0) {
|
|
424
|
+
process.stderr.write(`[plur:mcp] (${suppressed} further fault log lines suppressed in the last minute)
|
|
425
|
+
`);
|
|
426
|
+
}
|
|
427
|
+
logWindowStart = now;
|
|
428
|
+
logCount = 0;
|
|
429
|
+
suppressed = 0;
|
|
430
|
+
}
|
|
431
|
+
if (logCount >= LOG_MAX_PER_WINDOW) {
|
|
432
|
+
suppressed++;
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
logCount++;
|
|
436
|
+
const detail = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
437
|
+
process.stderr.write(`[plur:mcp] ${kind} (#1070): ${detail}
|
|
438
|
+
`);
|
|
439
|
+
};
|
|
440
|
+
process.on("unhandledRejection", (err) => logFault("unhandled rejection \u2014 server stays up", err));
|
|
441
|
+
process.on("uncaughtException", (err) => {
|
|
442
|
+
logFault("UNCAUGHT EXCEPTION \u2014 exiting so lock recovery and the harness can see the failure", err);
|
|
443
|
+
setTimeout(() => process.exit(1), 100);
|
|
444
|
+
});
|
|
445
|
+
const induceMs = Number(process.env.PLUR_TEST_INDUCE_UNHANDLED_REJECTION_MS ?? "");
|
|
446
|
+
if (Number.isFinite(induceMs) && induceMs > 0) {
|
|
447
|
+
setTimeout(() => {
|
|
448
|
+
void Promise.reject(new Error("induced test rejection (#1070)"));
|
|
449
|
+
}, induceMs);
|
|
450
|
+
}
|
|
451
|
+
const induceThrowMs = Number(process.env.PLUR_TEST_INDUCE_UNCAUGHT_EXCEPTION_MS ?? "");
|
|
452
|
+
if (Number.isFinite(induceThrowMs) && induceThrowMs > 0) {
|
|
453
|
+
setTimeout(() => {
|
|
454
|
+
throw new Error("induced test exception (#1070)");
|
|
455
|
+
}, induceThrowMs);
|
|
456
|
+
}
|
|
415
457
|
const profile = resolveToolProfile();
|
|
416
458
|
const server = await createServer(void 0, { profile });
|
|
417
459
|
registerFlushOnExit({});
|
package/dist/tools-export.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plur-ai/mcp",
|
|
3
3
|
"mcpName": "io.github.plur-ai/plur",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"plur-mcp": "dist/index.js"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@modelcontextprotocol/client": "2.0.0-beta.4",
|
|
17
17
|
"@modelcontextprotocol/core": "2.0.0-beta.4",
|
|
18
18
|
"zod": "^3.23.0",
|
|
19
|
-
"@plur-ai/core": "0.
|
|
19
|
+
"@plur-ai/core": "0.19.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^25.5.0"
|