agent-recall-mcp 3.4.11 → 3.4.13
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 +28 -13
- package/dist/index.js.map +1 -1
- package/dist/tools/memory-query.d.ts +3 -0
- package/dist/tools/memory-query.d.ts.map +1 -0
- package/dist/tools/memory-query.js +59 -0
- package/dist/tools/memory-query.js.map +1 -0
- package/dist/tools/recall.d.ts.map +1 -1
- package/dist/tools/recall.js +36 -6
- package/dist/tools/recall.js.map +1 -1
- package/dist/tools/remember.d.ts.map +1 -1
- package/dist/tools/remember.js +5 -8
- package/dist/tools/remember.js.map +1 -1
- package/dist/tools/session-start.d.ts.map +1 -1
- package/dist/tools/session-start.js +96 -19
- package/dist/tools/session-start.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { register as registerDigest } from "./tools/digest.js";
|
|
|
12
12
|
import { register as registerProjectBoard } from "./tools/project-board.js";
|
|
13
13
|
import { register as registerProjectStatus } from "./tools/project-status.js";
|
|
14
14
|
import { register as registerBootstrap } from "./tools/bootstrap.js";
|
|
15
|
+
import { register as registerMemoryQuery } from "./tools/memory-query.js";
|
|
15
16
|
// ── Legacy tools (still importable for SDK/CLI, not registered by default) ──
|
|
16
17
|
// DEPRECATED v3.4: use session_start instead
|
|
17
18
|
// import { register as registerJournalColdStart } from "./tools/journal-cold-start.js";
|
|
@@ -53,7 +54,8 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
53
54
|
AI agent memory — session context, persistent memory, cross-project insights.
|
|
54
55
|
|
|
55
56
|
Usage:
|
|
56
|
-
npx agent-recall-mcp Start
|
|
57
|
+
npx agent-recall-mcp Start (6 core tools: session_start, remember, recall, session_end, check, memory_query)
|
|
58
|
+
npx agent-recall-mcp --full Start with all tools (adds project_board, project_status, digest, bootstrap)
|
|
57
59
|
npx agent-recall-mcp --help Show this help
|
|
58
60
|
npx agent-recall-mcp --list-tools List available MCP tools
|
|
59
61
|
|
|
@@ -64,32 +66,45 @@ All data stays local. No cloud, no telemetry.
|
|
|
64
66
|
`);
|
|
65
67
|
process.exit(0);
|
|
66
68
|
}
|
|
69
|
+
// --full: register all tools including setup/advanced tools
|
|
70
|
+
// Default: 6 core tools only (lower token overhead per session)
|
|
71
|
+
const fullMode = args.includes("--full");
|
|
67
72
|
if (args.includes("--list-tools")) {
|
|
68
|
-
const
|
|
69
|
-
{ name: "project_board", description: "Status board across all projects — run this first, before session_start" },
|
|
70
|
-
{ name: "project_status", description: "Quick project health check — trajectory, blockers, room freshness" },
|
|
73
|
+
const coreTools = [
|
|
71
74
|
{ name: "session_start", description: "Load project context for a new session" },
|
|
72
75
|
{ name: "remember", description: "Save a memory — auto-routes to the right store" },
|
|
73
|
-
{ name: "recall", description: "Search all memory stores, return ranked results" },
|
|
76
|
+
{ name: "recall", description: "Search all memory stores, return ranked results with feedback" },
|
|
74
77
|
{ name: "session_end", description: "Save session summary, insights, and trajectory" },
|
|
75
78
|
{ name: "check", description: "Record understanding, get predictive warnings from past corrections" },
|
|
76
|
-
{ name: "
|
|
77
|
-
{ name: "bootstrap_scan", description: "Discover existing projects on this machine — read-only scan" },
|
|
78
|
-
{ name: "bootstrap_import", description: "Import discovered projects into AgentRecall" },
|
|
79
|
+
{ name: "memory_query", description: "Pull-on-demand recall — call mid-task before decisions" },
|
|
79
80
|
];
|
|
81
|
+
const fullTools = [
|
|
82
|
+
{ name: "project_board", description: "Status board across all projects (use --full to enable)" },
|
|
83
|
+
{ name: "project_status", description: "Quick project health check (use --full to enable)" },
|
|
84
|
+
{ name: "digest", description: "Context cache — store/recall/read/invalidate pre-computed analysis (use --full)" },
|
|
85
|
+
{ name: "bootstrap_scan", description: "Discover existing projects on this machine (use --full to enable)" },
|
|
86
|
+
{ name: "bootstrap_import", description: "Import discovered projects into AgentRecall (use --full to enable)" },
|
|
87
|
+
];
|
|
88
|
+
const tools = fullMode ? [...coreTools, ...fullTools] : coreTools;
|
|
80
89
|
process.stdout.write(JSON.stringify(tools, null, 2) + "\n");
|
|
81
90
|
process.exit(0);
|
|
82
91
|
}
|
|
83
|
-
//
|
|
84
|
-
registerProjectBoard(server);
|
|
85
|
-
registerProjectStatus(server);
|
|
92
|
+
// ── Core tools (always registered) ───────────────────────────────────────────
|
|
86
93
|
registerSessionStart(server);
|
|
87
94
|
registerRemember(server);
|
|
88
95
|
registerRecall(server);
|
|
89
96
|
registerSessionEnd(server);
|
|
90
97
|
registerCheck(server);
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
registerMemoryQuery(server);
|
|
99
|
+
// ── Extended tools (--full mode only) ────────────────────────────────────────
|
|
100
|
+
// Use when you need project status boards, context caching, or first-time bootstrap.
|
|
101
|
+
// Start server with: npx agent-recall-mcp --full
|
|
102
|
+
if (fullMode) {
|
|
103
|
+
registerProjectBoard(server);
|
|
104
|
+
registerProjectStatus(server);
|
|
105
|
+
registerDigest(server);
|
|
106
|
+
registerBootstrap(server);
|
|
107
|
+
}
|
|
93
108
|
registerJournalResources(server);
|
|
94
109
|
registerAwarenessResource(server);
|
|
95
110
|
registerSessionPrompts(server);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,4EAA4E;AAC5E,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-query.d.ts","sourceRoot":"","sources":["../../src/tools/memory-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyDhD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
import { memoryQuery } from "agent-recall-core";
|
|
3
|
+
export function register(server) {
|
|
4
|
+
server.registerTool("memory_query", {
|
|
5
|
+
title: "Memory Query",
|
|
6
|
+
description: [
|
|
7
|
+
"On-demand, intent-scoped recall. Call this mid-task when you recognize you're about to make",
|
|
8
|
+
"a decision that may have prior context — e.g. before pushing code, modifying auth, or calling an API.",
|
|
9
|
+
"",
|
|
10
|
+
"Unlike `recall` (general search), memory_query takes a description of what you're ABOUT TO DO",
|
|
11
|
+
"and returns only high/medium confidence results relevant to that intent.",
|
|
12
|
+
"",
|
|
13
|
+
"Examples:",
|
|
14
|
+
" memory_query({ intent: 'push to npm' }) → surfaces 'never publish without approval'",
|
|
15
|
+
" memory_query({ intent: 'modify auth middleware' }) → surfaces past auth gotchas",
|
|
16
|
+
" memory_query({ intent: 'call Novada search API' }) → surfaces API behavior notes",
|
|
17
|
+
"",
|
|
18
|
+
"Use this as a lightweight pre-action check. If empty:true, no prior context exists — proceed normally.",
|
|
19
|
+
].join("\n"),
|
|
20
|
+
inputSchema: {
|
|
21
|
+
intent: z.string().describe("What you are about to do or decide. Be specific: 'push to npm', 'modify the auth middleware', 'call the Novada search API'."),
|
|
22
|
+
project: z.string().default("auto"),
|
|
23
|
+
min_confidence: z.enum(["high", "medium", "low"]).default("medium").describe("Minimum confidence threshold. 'high' = very relevant only. 'low' = broader, more noise."),
|
|
24
|
+
limit: z.number().int().min(1).max(10).default(5),
|
|
25
|
+
},
|
|
26
|
+
}, async ({ intent, project, min_confidence, limit }) => {
|
|
27
|
+
try {
|
|
28
|
+
const result = await memoryQuery({ intent, project, min_confidence, limit });
|
|
29
|
+
if (result.empty) {
|
|
30
|
+
return {
|
|
31
|
+
content: [{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: result.guidance ?? `No relevant memory found for: "${intent}". Proceed normally.`,
|
|
34
|
+
}],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const lines = [];
|
|
38
|
+
for (let i = 0; i < result.results.length; i++) {
|
|
39
|
+
const r = result.results[i];
|
|
40
|
+
const conf = r.confidence.toUpperCase().slice(0, 3);
|
|
41
|
+
const room = r.room ? `/${r.room}` : "";
|
|
42
|
+
const excerpt = r.excerpt ? ` — ${r.excerpt.replace(/\n/g, " ").slice(0, 80)}` : "";
|
|
43
|
+
lines.push(`[${i + 1}][${r.source}${room}][${conf}] ${r.title}${excerpt}`);
|
|
44
|
+
}
|
|
45
|
+
// Feedback nudge
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push("— Rate these on next recall() to improve future ranking:");
|
|
48
|
+
lines.push(` IDs: ${result.results.map((r, i) => `${i + 1}=${r.id}`).join(" ")}`);
|
|
49
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: `memory_query failed: ${err instanceof Error ? err.message : String(err)}` }],
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=memory-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-query.js","sourceRoot":"","sources":["../../src/tools/memory-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqBzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgDhD"}
|
package/dist/tools/recall.js
CHANGED
|
@@ -1,24 +1,54 @@
|
|
|
1
1
|
import * as z from "zod/v4";
|
|
2
2
|
import { smartRecall } from "agent-recall-core";
|
|
3
|
+
/** Truncate to n chars with ellipsis */
|
|
4
|
+
function trunc(s, n) {
|
|
5
|
+
return s.length <= n ? s : s.slice(0, n - 1) + "…";
|
|
6
|
+
}
|
|
7
|
+
function formatResults(items) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
for (let i = 0; i < items.length; i++) {
|
|
10
|
+
const item = items[i];
|
|
11
|
+
const conf = (item.confidence ?? "low").toUpperCase().slice(0, 3);
|
|
12
|
+
const date = item.date ? ` (${item.date})` : "";
|
|
13
|
+
const room = item.room ? `/${item.room}` : "";
|
|
14
|
+
lines.push(`[${i + 1}][${item.source}${room}][${conf}] ${trunc(item.title, 60)} — ${trunc(item.excerpt, 80)}${date}`);
|
|
15
|
+
}
|
|
16
|
+
return lines.join("\n");
|
|
17
|
+
}
|
|
3
18
|
export function register(server) {
|
|
4
19
|
server.registerTool("recall", {
|
|
5
20
|
title: "Recall",
|
|
6
|
-
description: "Search all memory stores at once. Returns ranked results from palace, journal, and insights."
|
|
21
|
+
description: "Search all memory stores at once. Returns ranked results from palace, journal, and insights. " +
|
|
22
|
+
"Results include IDs — pass them as feedback on your NEXT recall() call to improve future ranking: " +
|
|
23
|
+
"`feedback:[{id:'abc123', useful:true}]`. " +
|
|
24
|
+
"Provide feedback when a result was used to make a decision (useful:true) or was irrelevant (useful:false). " +
|
|
25
|
+
"The scoring engine uses a Bayesian Beta distribution — 3+ positive signals meaningfully boost a result.",
|
|
7
26
|
inputSchema: {
|
|
8
27
|
query: z.string().describe("What to search for."),
|
|
9
28
|
project: z.string().default("auto"),
|
|
10
|
-
limit: z.number().int().default(10).describe("Max results
|
|
29
|
+
limit: z.number().int().default(10).describe("Max results after RRF merge."),
|
|
11
30
|
feedback: z.array(z.object({
|
|
12
31
|
id: z.string().optional().describe("Result ID from previous recall (preferred)."),
|
|
13
32
|
title: z.string().optional().describe("Result title (fallback if no ID)."),
|
|
14
|
-
useful: z.boolean(),
|
|
15
|
-
})).optional().describe("Rate previous results
|
|
16
|
-
|
|
33
|
+
useful: z.boolean().describe("Was this result useful? true=boost, false=penalize in future recalls."),
|
|
34
|
+
})).optional().describe("Rate previous recall results to improve future ranking. " +
|
|
35
|
+
"Pass {id, useful:true} for each result you actually used; {id, useful:false} for noise."),
|
|
36
|
+
since: z.string().optional().describe('ISO date ("2026-05-01") or relative duration ("7d"). Filters journal results.'),
|
|
17
37
|
},
|
|
18
38
|
}, async ({ query, project, limit, feedback, since }) => {
|
|
19
39
|
try {
|
|
20
40
|
const result = await smartRecall({ query, project, limit, feedback, since });
|
|
21
|
-
|
|
41
|
+
if (result.results.length === 0) {
|
|
42
|
+
return { content: [{ type: "text", text: `No results for "${query}". Sources searched: ${result.sources_queried.join(", ")}` }] };
|
|
43
|
+
}
|
|
44
|
+
const lines = [formatResults(result.results)];
|
|
45
|
+
// Feedback nudge — show IDs so agents can easily rate on next call
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push("— Rate these results on next recall() to improve future ranking:");
|
|
48
|
+
const idList = result.results.map((r, i) => `${i + 1}=${r.id}`).join(" ");
|
|
49
|
+
lines.push(` IDs: ${idList}`);
|
|
50
|
+
lines.push(` Example: recall(query='...', feedback=[{id:'${result.results[0].id}', useful:true}])`);
|
|
51
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
22
52
|
}
|
|
23
53
|
catch (err) {
|
|
24
54
|
return {
|
package/dist/tools/recall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recall.js","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"recall.js","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remember.d.ts","sourceRoot":"","sources":["../../src/tools/remember.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"remember.d.ts","sourceRoot":"","sources":["../../src/tools/remember.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsChD"}
|
package/dist/tools/remember.js
CHANGED
|
@@ -23,19 +23,16 @@ export function register(server) {
|
|
|
23
23
|
if (!result.success) {
|
|
24
24
|
return { content: [{ type: "text", text: JSON.stringify(result) }], isError: true };
|
|
25
25
|
}
|
|
26
|
-
//
|
|
27
|
-
const
|
|
26
|
+
// Show exactly where the memory was written
|
|
27
|
+
const indicator = result.entry_indicator ? ` [${result.entry_indicator}]` : "";
|
|
28
|
+
const dest = result.file_path ?? result.auto_name;
|
|
29
|
+
const lines = [`Saved → ${dest}${indicator}`];
|
|
28
30
|
if (result.retrieval_hint)
|
|
29
31
|
lines.push(`Find again: ${result.retrieval_hint}`);
|
|
30
|
-
if (result.tags && result.tags.length > 0)
|
|
31
|
-
lines.push(`Tags: ${result.tags.join(", ")}`);
|
|
32
32
|
if (result.consistency_warnings && result.consistency_warnings.length > 0) {
|
|
33
33
|
lines.push(`⚠ Consistency: ${result.consistency_warnings.map(w => w.detail).join("; ")}`);
|
|
34
34
|
}
|
|
35
|
-
return { content: [
|
|
36
|
-
{ type: "text", text: lines.join("\n") },
|
|
37
|
-
{ type: "text", text: JSON.stringify(result) },
|
|
38
|
-
] };
|
|
35
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
39
36
|
});
|
|
40
37
|
}
|
|
41
38
|
//# sourceMappingURL=remember.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remember.js","sourceRoot":"","sources":["../../src/tools/remember.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE;QAC9B,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,gDAAgD;YAC3D,gEAAgE;YAChE,6EAA6E;YAC7E,uCAAuC;YACvC,6CAA6C;QAC/C,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACrC,iFAAiF;gBACjF,iDAAiD;gBACjD,8BAA8B;gBAC9B,qCAAqC;gBACrC,+BAA+B;gBAC/B,+BAA+B,CAChC;YACD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/F,CAAC;QAED,
|
|
1
|
+
{"version":3,"file":"remember.js","sourceRoot":"","sources":["../../src/tools/remember.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE;QAC9B,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,gDAAgD;YAC3D,gEAAgE;YAChE,6EAA6E;YAC7E,uCAAuC;YACvC,6CAA6C;QAC/C,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACrC,iFAAiF;gBACjF,iDAAiD;gBACjD,8BAA8B;gBAC9B,qCAAqC;gBACrC,+BAA+B;gBAC/B,+BAA+B,CAChC;YACD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/F,CAAC;QAED,4CAA4C;QAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC;QAClD,MAAM,KAAK,GAAG,CAAC,WAAW,IAAI,GAAG,SAAS,EAAE,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,cAAc;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,oBAAoB,IAAI,MAAM,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1E,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5F,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2HzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgBhD"}
|
|
@@ -1,47 +1,124 @@
|
|
|
1
1
|
import * as z from "zod/v4";
|
|
2
2
|
import { sessionStart } from "agent-recall-core";
|
|
3
|
-
|
|
3
|
+
/** Truncate to nearest word boundary */
|
|
4
|
+
function trunc(s, n) {
|
|
5
|
+
if (s.length <= n)
|
|
6
|
+
return s;
|
|
7
|
+
const sliced = s.slice(0, n);
|
|
8
|
+
const lastSpace = sliced.lastIndexOf(" ");
|
|
9
|
+
return (lastSpace > n * 0.6 ? sliced.slice(0, lastSpace) : sliced) + "…";
|
|
10
|
+
}
|
|
11
|
+
function formatTerse(result) {
|
|
4
12
|
const lines = [];
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
// ── Header ──────────────────────────────────────────────────────────────
|
|
14
|
+
const sessionCount = result.resume?.sessions_count ?? 0;
|
|
15
|
+
const lastDate = result.resume?.last_date ?? "—";
|
|
16
|
+
lines.push(`AgentRecall — ${result.project} sessions: ${sessionCount} last: ${lastDate}`);
|
|
17
|
+
if (result.identity)
|
|
18
|
+
lines.push(`Intention: ${trunc(result.identity, 80)}`);
|
|
19
|
+
if (result.resume?.last_trajectory) {
|
|
20
|
+
lines.push(`Trajectory: ${trunc(result.resume.last_trajectory, 120)}`);
|
|
21
|
+
}
|
|
22
|
+
// ── Hard rules (P0 corrections) — highest priority ───────────────────
|
|
23
|
+
if (result.corrections && result.corrections.length > 0) {
|
|
12
24
|
lines.push("");
|
|
25
|
+
lines.push("⛔ HARD RULES (always follow, no exceptions):");
|
|
26
|
+
for (const c of result.corrections) {
|
|
27
|
+
const weight = c.weight !== undefined ? ` (w:${c.weight})` : "";
|
|
28
|
+
lines.push(` [${c.severity.toUpperCase()}${weight}] ${trunc(c.rule, 120)}`);
|
|
29
|
+
}
|
|
13
30
|
}
|
|
14
|
-
//
|
|
31
|
+
// ── Predictive warnings ───────────────────────────────────────────────
|
|
15
32
|
if (result.watch_for && result.watch_for.length > 0) {
|
|
16
|
-
lines.push(
|
|
33
|
+
lines.push("");
|
|
34
|
+
lines.push("⚠ Watch for:");
|
|
17
35
|
for (const w of result.watch_for) {
|
|
18
|
-
lines.push(
|
|
36
|
+
lines.push(` - ${trunc(w.pattern, 50)}: ${trunc(w.suggestion, 80)}`);
|
|
19
37
|
}
|
|
38
|
+
}
|
|
39
|
+
// ── Recent activity ───────────────────────────────────────────────────
|
|
40
|
+
if (result.recent.today || result.recent.yesterday || result.recent.older_count > 0) {
|
|
41
|
+
lines.push("");
|
|
42
|
+
if (result.recent.today) {
|
|
43
|
+
lines.push(`📓 Today: ${trunc(result.recent.today, 150)}`);
|
|
44
|
+
}
|
|
45
|
+
if (result.recent.yesterday) {
|
|
46
|
+
lines.push(`📓 Yesterday: ${trunc(result.recent.yesterday, 100)}`);
|
|
47
|
+
}
|
|
48
|
+
if (result.recent.older_count > 0) {
|
|
49
|
+
lines.push(` +${result.recent.older_count} older sessions on record`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ── Top insights ──────────────────────────────────────────────────────
|
|
53
|
+
if (result.insights && result.insights.length > 0) {
|
|
20
54
|
lines.push("");
|
|
55
|
+
const topN = result.insights.slice(0, 5);
|
|
56
|
+
lines.push(`💡 Insights (${result.insights.length} total):`);
|
|
57
|
+
for (const i of topN) {
|
|
58
|
+
const trend = i.trend && i.trend !== "stable" ? ` ↑${i.trend}` : "";
|
|
59
|
+
lines.push(` [${i.confirmed}×${trend}] ${trunc(i.title, 100)}`);
|
|
60
|
+
}
|
|
21
61
|
}
|
|
62
|
+
// ── Active palace rooms ───────────────────────────────────────────────
|
|
63
|
+
if (result.active_rooms && result.active_rooms.length > 0) {
|
|
64
|
+
lines.push("");
|
|
65
|
+
const roomSummary = result.active_rooms
|
|
66
|
+
.map((r) => `${r.name}(${r.salience.toFixed(2)})${r.stale ? "⚠" : ""}`)
|
|
67
|
+
.join(" · ");
|
|
68
|
+
lines.push(`🏛 Palace: ${roomSummary}`);
|
|
69
|
+
}
|
|
70
|
+
// ── Cross-project insights ────────────────────────────────────────────
|
|
71
|
+
if (result.cross_project && result.cross_project.length > 0) {
|
|
72
|
+
lines.push("");
|
|
73
|
+
lines.push("🔗 Cross-project:");
|
|
74
|
+
for (const cp of result.cross_project.slice(0, 3)) {
|
|
75
|
+
lines.push(` [${cp.from_project}] ${trunc(cp.title, 80)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ── Empty state guidance ──────────────────────────────────────────────
|
|
79
|
+
if (result.empty_state) {
|
|
80
|
+
lines.push("");
|
|
81
|
+
lines.push(result.empty_state);
|
|
82
|
+
}
|
|
83
|
+
return lines.join("\n");
|
|
84
|
+
}
|
|
85
|
+
function formatVerbose(result) {
|
|
86
|
+
const lines = [];
|
|
22
87
|
if (result.corrections && result.corrections.length > 0) {
|
|
23
|
-
lines.push(
|
|
88
|
+
lines.push("## ⛔ HARD RULES — always follow, no exceptions");
|
|
89
|
+
lines.push("These are behavioral constraints, not suggestions. Treat violations as errors.");
|
|
24
90
|
for (const c of result.corrections) {
|
|
25
|
-
|
|
91
|
+
const weight = c.weight !== undefined ? ` (weight: ${c.weight})` : "";
|
|
92
|
+
lines.push(`[${c.severity.toUpperCase()}${weight}] ${c.rule}`);
|
|
93
|
+
}
|
|
94
|
+
lines.push("");
|
|
95
|
+
}
|
|
96
|
+
if (result.watch_for && result.watch_for.length > 0) {
|
|
97
|
+
lines.push("## ⚠ Watch For");
|
|
98
|
+
for (const w of result.watch_for) {
|
|
99
|
+
lines.push(`- ${w.pattern}: ${w.suggestion}`);
|
|
26
100
|
}
|
|
27
101
|
lines.push("");
|
|
28
102
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
lines.push(JSON.stringify(
|
|
103
|
+
lines.push("## Context (informational — use to inform, not to constrain)");
|
|
104
|
+
const { corrections: _omit, ...contextWithoutCorrections } = result;
|
|
105
|
+
lines.push(JSON.stringify(contextWithoutCorrections, null, 2));
|
|
32
106
|
return lines.join("\n");
|
|
33
107
|
}
|
|
34
108
|
export function register(server) {
|
|
35
109
|
server.registerTool("session_start", {
|
|
36
110
|
title: "Start Session",
|
|
37
|
-
description: "Load project context for a new session. Returns identity, top insights, active rooms, recent activity, P0 corrections (
|
|
111
|
+
description: "Load project context for a new session. Returns identity, top insights, active rooms, recent activity, P0 corrections (hard rules), and predictive watch_for warnings. " +
|
|
112
|
+
"Default output is terse (~250 tokens). Pass verbose:true for full JSON context.",
|
|
38
113
|
inputSchema: {
|
|
39
114
|
project: z.string().default("auto"),
|
|
40
115
|
context: z.string().optional().describe("Optional context for matching cross-project insights"),
|
|
116
|
+
verbose: z.boolean().default(false).describe("Set true to get full JSON context instead of terse summary"),
|
|
41
117
|
},
|
|
42
|
-
}, async ({ project, context }) => {
|
|
118
|
+
}, async ({ project, context, verbose }) => {
|
|
43
119
|
const result = await sessionStart({ project, context });
|
|
44
|
-
|
|
120
|
+
const text = verbose ? formatVerbose(result) : formatTerse(result);
|
|
121
|
+
return { content: [{ type: "text", text }] };
|
|
45
122
|
});
|
|
46
123
|
}
|
|
47
124
|
//# sourceMappingURL=session-start.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,YAAY,EAA2B,MAAM,mBAAmB,CAAC;AAE1E,SAAS,
|
|
1
|
+
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-recall-mcp",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.13",
|
|
4
4
|
"description": "Memory Palace MCP server for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"test": "node --test test/*.test.mjs"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"agent-recall-core": "3.4.
|
|
19
|
+
"agent-recall-core": "3.4.13",
|
|
20
20
|
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
21
21
|
"zod": "^3.24.0"
|
|
22
22
|
},
|