@plur-ai/mcp 0.9.11 → 0.9.12
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
|
@@ -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.9.
|
|
8
|
+
var VERSION = "0.9.12";
|
|
9
9
|
var HELP = `plur-mcp v${VERSION} \u2014 persistent memory for AI agents
|
|
10
10
|
|
|
11
11
|
Usage:
|
|
@@ -279,7 +279,7 @@ if (arg === "init") {
|
|
|
279
279
|
process.exit(0);
|
|
280
280
|
}
|
|
281
281
|
if (arg === "serve" || arg === void 0) {
|
|
282
|
-
const { runStdio } = await import("./server-
|
|
282
|
+
const { runStdio } = await import("./server-AZFA22VU.js");
|
|
283
283
|
runStdio().catch((err) => {
|
|
284
284
|
console.error("Failed to start PLUR MCP server:", err);
|
|
285
285
|
process.exit(1);
|
|
@@ -14,10 +14,13 @@ import {
|
|
|
14
14
|
import { Plur as Plur2, checkForUpdate } from "@plur-ai/core";
|
|
15
15
|
|
|
16
16
|
// src/tools.ts
|
|
17
|
-
import {
|
|
17
|
+
import { existsSync, unlinkSync } from "fs";
|
|
18
|
+
import { join } from "path";
|
|
19
|
+
import { homedir } from "os";
|
|
20
|
+
import { extractMetaEngrams, validateMetaEngram, confidenceBand, generateProfile, getProfileForInjection, selectModelForOperation, getCachedUpdateCheck, minorVersionsBehind, scanForTensions, CapabilityCanary, readProjectConfig } from "@plur-ai/core";
|
|
18
21
|
|
|
19
22
|
// src/version.ts
|
|
20
|
-
var VERSION = "0.9.
|
|
23
|
+
var VERSION = "0.9.12";
|
|
21
24
|
|
|
22
25
|
// src/tools.ts
|
|
23
26
|
function makeHttpLlm(baseUrl, apiKey, model = "gpt-4o-mini") {
|
|
@@ -406,7 +409,7 @@ function getToolDefinitions() {
|
|
|
406
409
|
}
|
|
407
410
|
if (!args.id) throw new Error("Provide id (or list:true to list pinned)");
|
|
408
411
|
const target = args.pinned ?? true;
|
|
409
|
-
const updated = plur.
|
|
412
|
+
const updated = await plur.setPinnedAsync(args.id, target);
|
|
410
413
|
if (!updated) throw new Error(`Engram not found: ${args.id}`);
|
|
411
414
|
return {
|
|
412
415
|
id: updated.id,
|
|
@@ -970,7 +973,8 @@ function getToolDefinitions() {
|
|
|
970
973
|
type: "object",
|
|
971
974
|
properties: {
|
|
972
975
|
task: { type: "string", description: "What you are working on (triggers engram injection)" },
|
|
973
|
-
tags: { type: "array", items: { type: "string" }, description: "Tags to filter injected engrams" }
|
|
976
|
+
tags: { type: "array", items: { type: "string" }, description: "Tags to filter injected engrams" },
|
|
977
|
+
default_scope: { type: "string", description: "Default scope for plur_learn calls this session when no explicit scope is provided. Only set this if you want ALL engrams to route to a specific store. Usually, leave unset and pass scope per-engram based on relevance." }
|
|
974
978
|
},
|
|
975
979
|
required: ["task"]
|
|
976
980
|
},
|
|
@@ -986,12 +990,20 @@ function getToolDefinitions() {
|
|
|
986
990
|
outbox_result = await plur.flushOutbox();
|
|
987
991
|
} catch {
|
|
988
992
|
}
|
|
993
|
+
const remote_scopes = plur.getWritableRemoteScopes();
|
|
994
|
+
const projectConfig = readProjectConfig();
|
|
995
|
+
const explicit_default_scope = args.default_scope ?? null;
|
|
996
|
+
const default_scope = explicit_default_scope ?? projectConfig.scope ?? null;
|
|
997
|
+
const scope_source = explicit_default_scope ? "caller" : projectConfig.scope ? "project-config" : "none";
|
|
998
|
+
plur.setSessionScope(default_scope);
|
|
989
999
|
const status = plur.status();
|
|
990
1000
|
const store_stats = {
|
|
991
1001
|
engram_count: status.engram_count,
|
|
992
1002
|
episode_count: status.episode_count,
|
|
993
1003
|
pack_count: status.pack_count
|
|
994
1004
|
};
|
|
1005
|
+
await plur.warmRemoteCaches().catch(() => {
|
|
1006
|
+
});
|
|
995
1007
|
let engrams = null;
|
|
996
1008
|
try {
|
|
997
1009
|
const result = await plur.injectHybrid(task, {
|
|
@@ -1040,11 +1052,31 @@ ${guide}`;
|
|
|
1040
1052
|
version_warning = `Update available: PLUR v${versionCheck.current} \u2192 v${versionCheck.latest}. Run: npx @plur-ai/mcp@latest`;
|
|
1041
1053
|
}
|
|
1042
1054
|
}
|
|
1055
|
+
if (scope_source === "project-config") {
|
|
1056
|
+
guide += `
|
|
1057
|
+
|
|
1058
|
+
Auto-detected project scope: "${default_scope}" (from .plur.yaml in the current project). plur_learn calls without an explicit scope will be tagged with this scope, keeping this project's knowledge separate from your other projects. Pass scope: "global" only for genuinely cross-project knowledge (general coding conventions, language gotchas, tool quirks).`;
|
|
1059
|
+
} else if (scope_source === "none") {
|
|
1060
|
+
guide += `
|
|
1061
|
+
|
|
1062
|
+
\u26A0\uFE0F No project scope detected. plur_learn calls without explicit scope will be tagged "global" and will appear in EVERY project's future sessions. To avoid context bleed across projects, create a .plur.yaml in this project's root with: scope: "project:<your-project-name>"`;
|
|
1063
|
+
}
|
|
1064
|
+
if (remote_scopes.length > 0) {
|
|
1065
|
+
const scopeList = remote_scopes.map((s) => `"${s.scope}"`).join(", ");
|
|
1066
|
+
guide += default_scope ? `
|
|
1067
|
+
|
|
1068
|
+
Session default scope is set to "${default_scope}". To route an engram to a remote enterprise store instead, pass scope explicitly to plur_learn (available remote scopes: ${scopeList}).` : `
|
|
1069
|
+
|
|
1070
|
+
Remote store scopes available: ${scopeList}. When an engram is relevant to the team (engineering patterns, architecture decisions, project conventions), set scope to the matching remote scope in plur_learn. Personal preferences, local project details, and corrections specific to your workflow should stay at default scope (local).`;
|
|
1071
|
+
}
|
|
1043
1072
|
return {
|
|
1044
1073
|
session_id,
|
|
1045
1074
|
engrams: engrams ?? [],
|
|
1046
1075
|
store_stats,
|
|
1047
1076
|
guide,
|
|
1077
|
+
// Remote scope routing info (#229)
|
|
1078
|
+
...remote_scopes.length > 0 ? { remote_scopes } : {},
|
|
1079
|
+
...default_scope ? { default_scope, scope_source } : {},
|
|
1048
1080
|
// Ask LLM to check back — MCP can't push, but we can request a follow-up
|
|
1049
1081
|
follow_up: store_stats.engram_count === 0 ? "This is a fresh store with 0 engrams. After your first exchange with the user, review what you learned and call plur_learn for any corrections, preferences, or patterns. Build the memory from this session." : void 0,
|
|
1050
1082
|
// On fresh install, suggest hook setup for reliable injection
|
|
@@ -1130,6 +1162,19 @@ Include at least one engram_suggestion if ANYTHING was learned. An empty suggest
|
|
|
1130
1162
|
session_id,
|
|
1131
1163
|
channel: "mcp"
|
|
1132
1164
|
});
|
|
1165
|
+
try {
|
|
1166
|
+
const plurDir = process.env.PLUR_PATH ?? join(homedir(), ".plur");
|
|
1167
|
+
const sessionsDir = join(plurDir, "sessions");
|
|
1168
|
+
const keys = [session_id, process.env.CLAUDE_SESSION_ID, String(process.ppid)].filter(Boolean).map((k) => k.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64));
|
|
1169
|
+
for (const key of keys) {
|
|
1170
|
+
const cp = join(sessionsDir, `${key}.checkpoint.json`);
|
|
1171
|
+
if (existsSync(cp)) {
|
|
1172
|
+
unlinkSync(cp);
|
|
1173
|
+
break;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
} catch {
|
|
1177
|
+
}
|
|
1133
1178
|
const status = plur.status();
|
|
1134
1179
|
return {
|
|
1135
1180
|
engrams_created,
|
|
@@ -1451,9 +1496,9 @@ Include at least one engram_suggestion if ANYTHING was learned. An empty suggest
|
|
|
1451
1496
|
if (filterType) {
|
|
1452
1497
|
engrams = engrams.filter((e) => e.type === filterType);
|
|
1453
1498
|
}
|
|
1454
|
-
const { homedir } = await import("os");
|
|
1455
|
-
const { join } = await import("path");
|
|
1456
|
-
const outputDir = args.output_dir ||
|
|
1499
|
+
const { homedir: homedir2 } = await import("os");
|
|
1500
|
+
const { join: join2 } = await import("path");
|
|
1501
|
+
const outputDir = args.output_dir || join2(homedir2(), "plur-packs", name);
|
|
1457
1502
|
const result = plur.exportPack(engrams, outputDir, {
|
|
1458
1503
|
name,
|
|
1459
1504
|
version: "1.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plur-ai/mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"plur-mcp": "dist/index.js"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
15
15
|
"zod": "^3.23.0",
|
|
16
|
-
"@plur-ai/core": "0.9.
|
|
16
|
+
"@plur-ai/core": "0.9.12"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/node": "^25.5.0"
|