agent-recall-mcp 3.3.2 → 3.3.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/dist/index.js +6 -13
- package/dist/index.js.map +1 -1
- package/dist/resources/journal-resources.d.ts.map +1 -1
- package/dist/resources/journal-resources.js +5 -29
- package/dist/resources/journal-resources.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/alignment-check.d.ts.map +1 -1
- package/dist/tools/alignment-check.js +3 -54
- package/dist/tools/alignment-check.js.map +1 -1
- package/dist/tools/awareness-update.d.ts +2 -8
- package/dist/tools/awareness-update.d.ts.map +1 -1
- package/dist/tools/awareness-update.js +3 -66
- package/dist/tools/awareness-update.js.map +1 -1
- package/dist/tools/context-synthesize.d.ts.map +1 -1
- package/dist/tools/context-synthesize.js +6 -187
- package/dist/tools/context-synthesize.js.map +1 -1
- package/dist/tools/journal-archive.d.ts.map +1 -1
- package/dist/tools/journal-archive.js +3 -48
- package/dist/tools/journal-archive.js.map +1 -1
- package/dist/tools/journal-capture.d.ts.map +1 -1
- package/dist/tools/journal-capture.js +3 -60
- package/dist/tools/journal-capture.js.map +1 -1
- package/dist/tools/journal-cold-start.d.ts.map +1 -1
- package/dist/tools/journal-cold-start.js +10 -52
- package/dist/tools/journal-cold-start.js.map +1 -1
- package/dist/tools/journal-list.d.ts.map +1 -1
- package/dist/tools/journal-list.js +3 -23
- package/dist/tools/journal-list.js.map +1 -1
- package/dist/tools/journal-projects.d.ts.map +1 -1
- package/dist/tools/journal-projects.js +3 -16
- package/dist/tools/journal-projects.js.map +1 -1
- package/dist/tools/journal-read.d.ts.map +1 -1
- package/dist/tools/journal-read.js +5 -45
- package/dist/tools/journal-read.js.map +1 -1
- package/dist/tools/journal-rollup.d.ts +3 -0
- package/dist/tools/journal-rollup.d.ts.map +1 -0
- package/dist/tools/journal-rollup.js +21 -0
- package/dist/tools/journal-rollup.js.map +1 -0
- package/dist/tools/journal-search.d.ts.map +1 -1
- package/dist/tools/journal-search.js +3 -91
- package/dist/tools/journal-search.js.map +1 -1
- package/dist/tools/journal-state.d.ts +0 -3
- package/dist/tools/journal-state.d.ts.map +1 -1
- package/dist/tools/journal-state.js +5 -93
- package/dist/tools/journal-state.js.map +1 -1
- package/dist/tools/journal-write.d.ts.map +1 -1
- package/dist/tools/journal-write.js +3 -62
- package/dist/tools/journal-write.js.map +1 -1
- package/dist/tools/knowledge-read.d.ts.map +1 -1
- package/dist/tools/knowledge-read.js +3 -100
- package/dist/tools/knowledge-read.js.map +1 -1
- package/dist/tools/knowledge-write.d.ts.map +1 -1
- package/dist/tools/knowledge-write.js +3 -66
- package/dist/tools/knowledge-write.js.map +1 -1
- package/dist/tools/nudge.d.ts.map +1 -1
- package/dist/tools/nudge.js +3 -25
- package/dist/tools/nudge.js.map +1 -1
- package/dist/tools/palace-lint.d.ts +2 -6
- package/dist/tools/palace-lint.d.ts.map +1 -1
- package/dist/tools/palace-lint.js +3 -135
- package/dist/tools/palace-lint.js.map +1 -1
- package/dist/tools/palace-read.d.ts +2 -5
- package/dist/tools/palace-read.d.ts.map +1 -1
- package/dist/tools/palace-read.js +5 -62
- package/dist/tools/palace-read.js.map +1 -1
- package/dist/tools/palace-search.d.ts +2 -5
- package/dist/tools/palace-search.d.ts.map +1 -1
- package/dist/tools/palace-search.js +3 -66
- package/dist/tools/palace-search.js.map +1 -1
- package/dist/tools/palace-walk.d.ts +2 -11
- package/dist/tools/palace-walk.d.ts.map +1 -1
- package/dist/tools/palace-walk.js +3 -149
- package/dist/tools/palace-walk.js.map +1 -1
- package/dist/tools/palace-write.d.ts +2 -5
- package/dist/tools/palace-write.d.ts.map +1 -1
- package/dist/tools/palace-write.js +3 -90
- package/dist/tools/palace-write.js.map +1 -1
- package/dist/tools/recall-insight.d.ts +2 -8
- package/dist/tools/recall-insight.d.ts.map +1 -1
- package/dist/tools/recall-insight.js +3 -35
- package/dist/tools/recall-insight.js.map +1 -1
- package/package.json +9 -46
- package/README.md +0 -435
- package/dist/helpers/journal-files.d.ts +0 -30
- package/dist/helpers/journal-files.d.ts.map +0 -1
- package/dist/helpers/journal-files.js +0 -96
- package/dist/helpers/journal-files.js.map +0 -1
- package/dist/helpers/sections.d.ts +0 -12
- package/dist/helpers/sections.d.ts.map +0 -1
- package/dist/helpers/sections.js +0 -84
- package/dist/helpers/sections.js.map +0 -1
- package/dist/palace/awareness.d.ts +0 -67
- package/dist/palace/awareness.d.ts.map +0 -1
- package/dist/palace/awareness.js +0 -231
- package/dist/palace/awareness.js.map +0 -1
- package/dist/palace/consolidate.d.ts +0 -28
- package/dist/palace/consolidate.d.ts.map +0 -1
- package/dist/palace/consolidate.js +0 -129
- package/dist/palace/consolidate.js.map +0 -1
- package/dist/palace/fan-out.d.ts +0 -15
- package/dist/palace/fan-out.d.ts.map +0 -1
- package/dist/palace/fan-out.js +0 -78
- package/dist/palace/fan-out.js.map +0 -1
- package/dist/palace/graph.d.ts +0 -11
- package/dist/palace/graph.d.ts.map +0 -1
- package/dist/palace/graph.js +0 -59
- package/dist/palace/graph.js.map +0 -1
- package/dist/palace/identity.d.ts +0 -6
- package/dist/palace/identity.d.ts.map +0 -1
- package/dist/palace/identity.js +0 -18
- package/dist/palace/identity.js.map +0 -1
- package/dist/palace/index-manager.d.ts +0 -7
- package/dist/palace/index-manager.d.ts.map +0 -1
- package/dist/palace/index-manager.js +0 -46
- package/dist/palace/index-manager.js.map +0 -1
- package/dist/palace/insights-index.d.ts +0 -39
- package/dist/palace/insights-index.d.ts.map +0 -1
- package/dist/palace/insights-index.js +0 -101
- package/dist/palace/insights-index.js.map +0 -1
- package/dist/palace/log.d.ts +0 -9
- package/dist/palace/log.d.ts.map +0 -1
- package/dist/palace/log.js +0 -28
- package/dist/palace/log.js.map +0 -1
- package/dist/palace/obsidian.d.ts +0 -12
- package/dist/palace/obsidian.d.ts.map +0 -1
- package/dist/palace/obsidian.js +0 -76
- package/dist/palace/obsidian.js.map +0 -1
- package/dist/palace/rooms.d.ts +0 -14
- package/dist/palace/rooms.d.ts.map +0 -1
- package/dist/palace/rooms.js +0 -117
- package/dist/palace/rooms.js.map +0 -1
- package/dist/palace/salience.d.ts +0 -15
- package/dist/palace/salience.d.ts.map +0 -1
- package/dist/palace/salience.js +0 -33
- package/dist/palace/salience.js.map +0 -1
- package/dist/storage/fs-utils.d.ts +0 -8
- package/dist/storage/fs-utils.d.ts.map +0 -1
- package/dist/storage/fs-utils.js +0 -28
- package/dist/storage/fs-utils.js.map +0 -1
- package/dist/storage/paths.d.ts +0 -21
- package/dist/storage/paths.d.ts.map +0 -1
- package/dist/storage/paths.js +0 -59
- package/dist/storage/paths.js.map +0 -1
- package/dist/storage/project.d.ts +0 -17
- package/dist/storage/project.d.ts.map +0 -1
- package/dist/storage/project.js +0 -130
- package/dist/storage/project.js.map +0 -1
- package/dist/types.d.ts +0 -112
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -31
- package/dist/types.js.map +0 -1
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool: palace_lint — Health check for the Memory Palace.
|
|
3
|
-
* Detects contradictions, stale memories, orphan rooms, missing cross-refs.
|
|
4
|
-
*/
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
import * as path from "node:path";
|
|
7
1
|
import * as z from "zod/v4";
|
|
8
|
-
import {
|
|
9
|
-
import { palaceDir } from "../storage/paths.js";
|
|
10
|
-
import { ensurePalaceInitialized, listRooms } from "../palace/rooms.js";
|
|
11
|
-
import { getConnectionCount } from "../palace/graph.js";
|
|
12
|
-
import { computeSalience, ARCHIVE_THRESHOLD } from "../palace/salience.js";
|
|
13
|
-
import { updatePalaceIndex } from "../palace/index-manager.js";
|
|
14
|
-
import { appendToLog } from "../palace/log.js";
|
|
2
|
+
import { palaceLint } from "agent-recall-core";
|
|
15
3
|
export function register(server) {
|
|
16
4
|
server.registerTool("palace_lint", {
|
|
17
5
|
title: "Lint Memory Palace",
|
|
@@ -22,128 +10,8 @@ export function register(server) {
|
|
|
22
10
|
project: z.string().default("auto"),
|
|
23
11
|
},
|
|
24
12
|
}, async ({ fix, project }) => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const rooms = listRooms(slug);
|
|
28
|
-
const pd = palaceDir(slug);
|
|
29
|
-
const issues = [];
|
|
30
|
-
let fixed = 0;
|
|
31
|
-
for (const room of rooms) {
|
|
32
|
-
const roomPath = path.join(pd, "rooms", room.slug);
|
|
33
|
-
// Check: orphan rooms (no connections)
|
|
34
|
-
const connCount = getConnectionCount(pd, room.slug);
|
|
35
|
-
if (connCount === 0 && room.connections.length === 0) {
|
|
36
|
-
issues.push({
|
|
37
|
-
type: "orphan",
|
|
38
|
-
severity: "warning",
|
|
39
|
-
room: room.slug,
|
|
40
|
-
description: `Room '${room.name}' has no connections to other rooms`,
|
|
41
|
-
suggestion: `Add connections via palace_write with [[wikilinks]] or connections param`,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// Check: stale rooms (not accessed in 30+ days)
|
|
45
|
-
const daysSinceAccess = (Date.now() - new Date(room.last_accessed).getTime()) / (1000 * 60 * 60 * 24);
|
|
46
|
-
if (daysSinceAccess > 30) {
|
|
47
|
-
issues.push({
|
|
48
|
-
type: "stale",
|
|
49
|
-
severity: "info",
|
|
50
|
-
room: room.slug,
|
|
51
|
-
description: `Room '${room.name}' not accessed in ${Math.floor(daysSinceAccess)} days`,
|
|
52
|
-
suggestion: `Review if still relevant. Access it to refresh salience.`,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
// Check: low salience
|
|
56
|
-
const salience = computeSalience({
|
|
57
|
-
importance: "medium",
|
|
58
|
-
lastUpdated: room.updated,
|
|
59
|
-
accessCount: room.access_count,
|
|
60
|
-
connectionCount: connCount,
|
|
61
|
-
});
|
|
62
|
-
if (salience < ARCHIVE_THRESHOLD) {
|
|
63
|
-
issues.push({
|
|
64
|
-
type: "low_salience",
|
|
65
|
-
severity: "warning",
|
|
66
|
-
room: room.slug,
|
|
67
|
-
description: `Room '${room.name}' salience is ${salience.toFixed(3)} (below ${ARCHIVE_THRESHOLD})`,
|
|
68
|
-
suggestion: fix ? "Auto-archiving..." : "Consider archiving or refreshing with new content",
|
|
69
|
-
});
|
|
70
|
-
if (fix) {
|
|
71
|
-
// Move room to archive
|
|
72
|
-
const archiveDir = path.join(pd, "archive", room.slug);
|
|
73
|
-
if (!fs.existsSync(archiveDir)) {
|
|
74
|
-
fs.mkdirSync(archiveDir, { recursive: true });
|
|
75
|
-
}
|
|
76
|
-
// Copy files
|
|
77
|
-
if (fs.existsSync(roomPath)) {
|
|
78
|
-
const files = fs.readdirSync(roomPath);
|
|
79
|
-
for (const file of files) {
|
|
80
|
-
fs.copyFileSync(path.join(roomPath, file), path.join(archiveDir, file));
|
|
81
|
-
}
|
|
82
|
-
// Remove original room
|
|
83
|
-
fs.rmSync(roomPath, { recursive: true });
|
|
84
|
-
fixed++;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Check: empty rooms (no content files beyond README.md)
|
|
89
|
-
if (fs.existsSync(roomPath)) {
|
|
90
|
-
const files = fs.readdirSync(roomPath)
|
|
91
|
-
.filter((f) => f.endsWith(".md") && f !== "README.md");
|
|
92
|
-
if (files.length === 0) {
|
|
93
|
-
issues.push({
|
|
94
|
-
type: "empty",
|
|
95
|
-
severity: "info",
|
|
96
|
-
room: room.slug,
|
|
97
|
-
description: `Room '${room.name}' has no topic files (only README)`,
|
|
98
|
-
suggestion: "Add content with palace_write(room='${room.slug}', topic='...')",
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// Check: missing README.md
|
|
103
|
-
if (!fs.existsSync(path.join(roomPath, "README.md"))) {
|
|
104
|
-
issues.push({
|
|
105
|
-
type: "missing_readme",
|
|
106
|
-
severity: "warning",
|
|
107
|
-
room: room.slug,
|
|
108
|
-
description: `Room '${room.name}' is missing README.md`,
|
|
109
|
-
suggestion: "Recreate with palace_write",
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Update palace index after potential changes
|
|
114
|
-
if (fix && fixed > 0) {
|
|
115
|
-
updatePalaceIndex(slug);
|
|
116
|
-
}
|
|
117
|
-
// Update last_lint timestamp
|
|
118
|
-
const indexPath = path.join(pd, "palace-index.json");
|
|
119
|
-
if (fs.existsSync(indexPath)) {
|
|
120
|
-
try {
|
|
121
|
-
const index = JSON.parse(fs.readFileSync(indexPath, "utf-8"));
|
|
122
|
-
index.last_lint = new Date().toISOString();
|
|
123
|
-
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
// ignore
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
// Log lint operation
|
|
130
|
-
appendToLog(slug, "palace_lint", {
|
|
131
|
-
issues_found: issues.length,
|
|
132
|
-
fixed,
|
|
133
|
-
rooms_checked: rooms.length,
|
|
134
|
-
});
|
|
135
|
-
return {
|
|
136
|
-
content: [{
|
|
137
|
-
type: "text",
|
|
138
|
-
text: JSON.stringify({
|
|
139
|
-
project: slug,
|
|
140
|
-
issues,
|
|
141
|
-
total_issues: issues.length,
|
|
142
|
-
fixed,
|
|
143
|
-
rooms_checked: rooms.length,
|
|
144
|
-
}),
|
|
145
|
-
}],
|
|
146
|
-
};
|
|
13
|
+
const result = await palaceLint({ fix, project });
|
|
14
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
147
15
|
});
|
|
148
16
|
}
|
|
149
17
|
//# sourceMappingURL=palace-lint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-lint.js","sourceRoot":"","sources":["../../src/tools/palace-lint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"palace-lint.js","sourceRoot":"","sources":["../../src/tools/palace-lint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACjC,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,0FAA0F;YAC1F,kFAAkF;QACpF,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,yDAAyD,CAAC;YACnG,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import type { ServerType } from "../server.js";
|
|
5
|
-
export declare function register(server: ServerType): void;
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function register(server: McpServer): void;
|
|
6
3
|
//# sourceMappingURL=palace-read.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-read.d.ts","sourceRoot":"","sources":["../../src/tools/palace-read.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"palace-read.d.ts","sourceRoot":"","sources":["../../src/tools/palace-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkBhD"}
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool: palace_read — Read a room overview or specific topic from the palace.
|
|
3
|
-
*/
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import * as path from "node:path";
|
|
6
1
|
import * as z from "zod/v4";
|
|
7
|
-
import {
|
|
8
|
-
import { palaceDir } from "../storage/paths.js";
|
|
9
|
-
import { ensurePalaceInitialized, getRoomMeta, listRooms, recordAccess } from "../palace/rooms.js";
|
|
2
|
+
import { palaceRead } from "agent-recall-core";
|
|
10
3
|
export function register(server) {
|
|
11
4
|
server.registerTool("palace_read", {
|
|
12
5
|
title: "Read Palace Room",
|
|
@@ -18,61 +11,11 @@ export function register(server) {
|
|
|
18
11
|
project: z.string().default("auto"),
|
|
19
12
|
},
|
|
20
13
|
}, async ({ room, topic, project }) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// List all rooms
|
|
25
|
-
const rooms = listRooms(slug);
|
|
26
|
-
return {
|
|
27
|
-
content: [{
|
|
28
|
-
type: "text",
|
|
29
|
-
text: JSON.stringify({
|
|
30
|
-
project: slug,
|
|
31
|
-
rooms: rooms.map((r) => ({
|
|
32
|
-
slug: r.slug,
|
|
33
|
-
name: r.name,
|
|
34
|
-
description: r.description,
|
|
35
|
-
salience: r.salience,
|
|
36
|
-
connections: r.connections,
|
|
37
|
-
tags: r.tags,
|
|
38
|
-
})),
|
|
39
|
-
}),
|
|
40
|
-
}],
|
|
41
|
-
};
|
|
14
|
+
const result = await palaceRead({ room, topic, project });
|
|
15
|
+
if (result.error) {
|
|
16
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], isError: true };
|
|
42
17
|
}
|
|
43
|
-
|
|
44
|
-
const meta = getRoomMeta(slug, room);
|
|
45
|
-
if (!meta) {
|
|
46
|
-
return {
|
|
47
|
-
content: [{ type: "text", text: JSON.stringify({ error: `Room '${room}' not found in project '${slug}'` }) }],
|
|
48
|
-
isError: true,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
recordAccess(slug, room);
|
|
52
|
-
const pd = palaceDir(slug);
|
|
53
|
-
const targetFile = topic
|
|
54
|
-
? path.join(pd, "rooms", room, `${topic}.md`)
|
|
55
|
-
: path.join(pd, "rooms", room, "README.md");
|
|
56
|
-
if (!fs.existsSync(targetFile)) {
|
|
57
|
-
return {
|
|
58
|
-
content: [{ type: "text", text: JSON.stringify({ error: `File not found: ${topic ? topic + '.md' : 'README.md'} in room '${room}'` }) }],
|
|
59
|
-
isError: true,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
const content = fs.readFileSync(targetFile, "utf-8");
|
|
63
|
-
return {
|
|
64
|
-
content: [{
|
|
65
|
-
type: "text",
|
|
66
|
-
text: JSON.stringify({
|
|
67
|
-
room: room,
|
|
68
|
-
topic: topic ?? "README",
|
|
69
|
-
project: slug,
|
|
70
|
-
salience: meta.salience,
|
|
71
|
-
connections: meta.connections,
|
|
72
|
-
content,
|
|
73
|
-
}),
|
|
74
|
-
}],
|
|
75
|
-
};
|
|
18
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
76
19
|
});
|
|
77
20
|
}
|
|
78
21
|
//# sourceMappingURL=palace-read.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-read.js","sourceRoot":"","sources":["../../src/tools/palace-read.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"palace-read.js","sourceRoot":"","sources":["../../src/tools/palace-read.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACjC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,iEAAiE;YACjE,+EAA+E;QACjF,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;YAC1G,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0FAA0F,CAAC;YACjI,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,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;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import type { ServerType } from "../server.js";
|
|
5
|
-
export declare function register(server: ServerType): void;
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function register(server: McpServer): void;
|
|
6
3
|
//# sourceMappingURL=palace-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-search.d.ts","sourceRoot":"","sources":["../../src/tools/palace-search.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"palace-search.d.ts","sourceRoot":"","sources":["../../src/tools/palace-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAehD"}
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool: palace_search — Search across palace rooms, ranked by salience.
|
|
3
|
-
*/
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import * as path from "node:path";
|
|
6
1
|
import * as z from "zod/v4";
|
|
7
|
-
import {
|
|
8
|
-
import { palaceDir } from "../storage/paths.js";
|
|
9
|
-
import { ensurePalaceInitialized, listRooms, recordAccess } from "../palace/rooms.js";
|
|
2
|
+
import { palaceSearch } from "agent-recall-core";
|
|
10
3
|
export function register(server) {
|
|
11
4
|
server.registerTool("palace_search", {
|
|
12
5
|
title: "Search Memory Palace",
|
|
@@ -18,64 +11,8 @@ export function register(server) {
|
|
|
18
11
|
project: z.string().default("auto"),
|
|
19
12
|
},
|
|
20
13
|
}, async ({ query, room, project }) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const rooms = listRooms(slug);
|
|
24
|
-
const pd = palaceDir(slug);
|
|
25
|
-
const queryLower = query.toLowerCase();
|
|
26
|
-
const results = [];
|
|
27
|
-
const targetRooms = room
|
|
28
|
-
? rooms.filter((r) => r.slug === room)
|
|
29
|
-
: rooms;
|
|
30
|
-
for (const roomMeta of targetRooms) {
|
|
31
|
-
const roomPath = path.join(pd, "rooms", roomMeta.slug);
|
|
32
|
-
if (!fs.existsSync(roomPath))
|
|
33
|
-
continue;
|
|
34
|
-
const files = fs.readdirSync(roomPath).filter((f) => f.endsWith(".md"));
|
|
35
|
-
for (const file of files) {
|
|
36
|
-
const filePath = path.join(roomPath, file);
|
|
37
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
38
|
-
const lines = content.split("\n");
|
|
39
|
-
for (let i = 0; i < lines.length; i++) {
|
|
40
|
-
if (lines[i].toLowerCase().includes(queryLower)) {
|
|
41
|
-
const line = lines[i];
|
|
42
|
-
const matchIdx = line.toLowerCase().indexOf(queryLower);
|
|
43
|
-
const start = Math.max(0, matchIdx - 40);
|
|
44
|
-
const end = Math.min(line.length, matchIdx + query.length + 40);
|
|
45
|
-
let excerpt = line.slice(start, end).trim();
|
|
46
|
-
if (start > 0)
|
|
47
|
-
excerpt = "..." + excerpt;
|
|
48
|
-
if (end < line.length)
|
|
49
|
-
excerpt = excerpt + "...";
|
|
50
|
-
results.push({
|
|
51
|
-
room: roomMeta.slug,
|
|
52
|
-
file: file.replace(".md", ""),
|
|
53
|
-
salience: roomMeta.salience,
|
|
54
|
-
excerpt,
|
|
55
|
-
line: i + 1,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (results.some((r) => r.room === roomMeta.slug)) {
|
|
61
|
-
recordAccess(slug, roomMeta.slug);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// Sort by salience descending, then by line number
|
|
65
|
-
results.sort((a, b) => b.salience - a.salience || a.line - b.line);
|
|
66
|
-
// Limit to 20 results
|
|
67
|
-
const limited = results.slice(0, 20);
|
|
68
|
-
return {
|
|
69
|
-
content: [{
|
|
70
|
-
type: "text",
|
|
71
|
-
text: JSON.stringify({
|
|
72
|
-
project: slug,
|
|
73
|
-
query,
|
|
74
|
-
results: limited,
|
|
75
|
-
total_matches: results.length,
|
|
76
|
-
}),
|
|
77
|
-
}],
|
|
78
|
-
};
|
|
14
|
+
const result = await palaceSearch({ query, room, project });
|
|
15
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
79
16
|
});
|
|
80
17
|
}
|
|
81
18
|
//# sourceMappingURL=palace-search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-search.js","sourceRoot":"","sources":["../../src/tools/palace-search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"palace-search.js","sourceRoot":"","sources":["../../src/tools/palace-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;QACnC,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,iFAAiF;YACjF,uCAAuC;QACzC,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YACvE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Depths:
|
|
5
|
-
* identity (~50 tokens): project name, purpose, last session
|
|
6
|
-
* active (~200 tokens): identity + top 3 rooms by salience
|
|
7
|
-
* relevant (~500 tokens): active + rooms matching focus query + key memories
|
|
8
|
-
* full (~2000 tokens): all rooms with full content
|
|
9
|
-
*/
|
|
10
|
-
import type { ServerType } from "../server.js";
|
|
11
|
-
export declare function register(server: ServerType): void;
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function register(server: McpServer): void;
|
|
12
3
|
//# sourceMappingURL=palace-walk.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-walk.d.ts","sourceRoot":"","sources":["../../src/tools/palace-walk.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"palace-walk.d.ts","sourceRoot":"","sources":["../../src/tools/palace-walk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkBhD"}
|
|
@@ -1,41 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool: palace_walk — Progressive context loading for cold-start.
|
|
3
|
-
*
|
|
4
|
-
* Depths:
|
|
5
|
-
* identity (~50 tokens): project name, purpose, last session
|
|
6
|
-
* active (~200 tokens): identity + top 3 rooms by salience
|
|
7
|
-
* relevant (~500 tokens): active + rooms matching focus query + key memories
|
|
8
|
-
* full (~2000 tokens): all rooms with full content
|
|
9
|
-
*/
|
|
10
|
-
import * as fs from "node:fs";
|
|
11
|
-
import * as path from "node:path";
|
|
12
1
|
import * as z from "zod/v4";
|
|
13
|
-
import {
|
|
14
|
-
import { palaceDir } from "../storage/paths.js";
|
|
15
|
-
import { ensurePalaceInitialized, listRooms, recordAccess } from "../palace/rooms.js";
|
|
16
|
-
import { readIdentity } from "../palace/identity.js";
|
|
17
|
-
import { readAwareness } from "../palace/awareness.js";
|
|
18
|
-
function roomSummary(meta) {
|
|
19
|
-
return `- **${meta.name}** (salience: ${meta.salience}) — ${meta.description}`;
|
|
20
|
-
}
|
|
21
|
-
function readRoomContent(project, room) {
|
|
22
|
-
const pd = palaceDir(project);
|
|
23
|
-
const roomPath = path.join(pd, "rooms", room.slug);
|
|
24
|
-
if (!fs.existsSync(roomPath))
|
|
25
|
-
return "";
|
|
26
|
-
const files = fs.readdirSync(roomPath)
|
|
27
|
-
.filter((f) => f.endsWith(".md"))
|
|
28
|
-
.sort();
|
|
29
|
-
let content = `### ${room.name}\n\n`;
|
|
30
|
-
for (const file of files) {
|
|
31
|
-
const filePath = path.join(roomPath, file);
|
|
32
|
-
const text = fs.readFileSync(filePath, "utf-8");
|
|
33
|
-
// Truncate individual files at 500 chars for full depth
|
|
34
|
-
const truncated = text.length > 500 ? text.slice(0, 500) + "\n...(truncated)" : text;
|
|
35
|
-
content += truncated + "\n\n";
|
|
36
|
-
}
|
|
37
|
-
return content;
|
|
38
|
-
}
|
|
2
|
+
import { palaceWalk } from "agent-recall-core";
|
|
39
3
|
export function register(server) {
|
|
40
4
|
server.registerTool("palace_walk", {
|
|
41
5
|
title: "Walk the Memory Palace",
|
|
@@ -50,118 +14,8 @@ export function register(server) {
|
|
|
50
14
|
project: z.string().default("auto"),
|
|
51
15
|
},
|
|
52
16
|
}, async ({ depth, focus, project }) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const rooms = listRooms(slug);
|
|
56
|
-
let output = "";
|
|
57
|
-
// Identity: always included
|
|
58
|
-
const identity = readIdentity(slug);
|
|
59
|
-
// Strip YAML frontmatter for token efficiency
|
|
60
|
-
const identityContent = identity.replace(/^---[\s\S]*?---\n*/, "").trim();
|
|
61
|
-
output += identityContent + "\n\n";
|
|
62
|
-
// Awareness: always included (compact — top insights only)
|
|
63
|
-
const awarenessRaw = readAwareness();
|
|
64
|
-
if (awarenessRaw) {
|
|
65
|
-
// Extract just the top insights section (compact)
|
|
66
|
-
const awarenessLines = awarenessRaw.split("\n");
|
|
67
|
-
const topIdx = awarenessLines.findIndex((l) => l.startsWith("## Top Insights"));
|
|
68
|
-
const compIdx = awarenessLines.findIndex((l) => l.startsWith("## Compound") || l.startsWith("## Trajectory"));
|
|
69
|
-
if (topIdx >= 0) {
|
|
70
|
-
const end = compIdx > topIdx ? compIdx : Math.min(topIdx + 30, awarenessLines.length);
|
|
71
|
-
output += awarenessLines.slice(topIdx, end).join("\n").trim() + "\n\n";
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (depth === "identity") {
|
|
75
|
-
return {
|
|
76
|
-
content: [{
|
|
77
|
-
type: "text",
|
|
78
|
-
text: JSON.stringify({
|
|
79
|
-
project: slug,
|
|
80
|
-
depth,
|
|
81
|
-
rooms_count: rooms.length,
|
|
82
|
-
content: output.trim(),
|
|
83
|
-
}),
|
|
84
|
-
}],
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
// Active: top 3 rooms by salience
|
|
88
|
-
const topRooms = rooms.slice(0, 3);
|
|
89
|
-
output += "## Active Rooms\n\n";
|
|
90
|
-
for (const room of topRooms) {
|
|
91
|
-
output += roomSummary(room) + "\n";
|
|
92
|
-
recordAccess(slug, room.slug);
|
|
93
|
-
}
|
|
94
|
-
output += "\n";
|
|
95
|
-
if (depth === "active") {
|
|
96
|
-
return {
|
|
97
|
-
content: [{
|
|
98
|
-
type: "text",
|
|
99
|
-
text: JSON.stringify({
|
|
100
|
-
project: slug,
|
|
101
|
-
depth,
|
|
102
|
-
rooms_count: rooms.length,
|
|
103
|
-
top_rooms: topRooms.map((r) => r.slug),
|
|
104
|
-
content: output.trim(),
|
|
105
|
-
}),
|
|
106
|
-
}],
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
// Relevant: active + rooms matching focus
|
|
110
|
-
if (focus) {
|
|
111
|
-
const focusLower = focus.toLowerCase();
|
|
112
|
-
const matchingRooms = rooms.filter((r) => !topRooms.includes(r) &&
|
|
113
|
-
(r.name.toLowerCase().includes(focusLower) ||
|
|
114
|
-
r.description.toLowerCase().includes(focusLower) ||
|
|
115
|
-
r.tags.some((t) => t.toLowerCase().includes(focusLower))));
|
|
116
|
-
if (matchingRooms.length > 0) {
|
|
117
|
-
output += "## Relevant Rooms\n\n";
|
|
118
|
-
for (const room of matchingRooms.slice(0, 5)) {
|
|
119
|
-
output += roomSummary(room) + "\n";
|
|
120
|
-
// Include key content (first 200 chars of README)
|
|
121
|
-
const pd = palaceDir(slug);
|
|
122
|
-
const readmePath = path.join(pd, "rooms", room.slug, "README.md");
|
|
123
|
-
if (fs.existsSync(readmePath)) {
|
|
124
|
-
const readme = fs.readFileSync(readmePath, "utf-8")
|
|
125
|
-
.replace(/^---[\s\S]*?---\n*/, "")
|
|
126
|
-
.trim();
|
|
127
|
-
output += " " + readme.slice(0, 200) + "\n";
|
|
128
|
-
}
|
|
129
|
-
recordAccess(slug, room.slug);
|
|
130
|
-
}
|
|
131
|
-
output += "\n";
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
if (depth === "relevant") {
|
|
135
|
-
return {
|
|
136
|
-
content: [{
|
|
137
|
-
type: "text",
|
|
138
|
-
text: JSON.stringify({
|
|
139
|
-
project: slug,
|
|
140
|
-
depth,
|
|
141
|
-
focus: focus ?? null,
|
|
142
|
-
rooms_count: rooms.length,
|
|
143
|
-
content: output.trim(),
|
|
144
|
-
}),
|
|
145
|
-
}],
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
// Full: all rooms with content
|
|
149
|
-
output += "## All Rooms\n\n";
|
|
150
|
-
for (const room of rooms) {
|
|
151
|
-
output += readRoomContent(slug, room);
|
|
152
|
-
recordAccess(slug, room.slug);
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
content: [{
|
|
156
|
-
type: "text",
|
|
157
|
-
text: JSON.stringify({
|
|
158
|
-
project: slug,
|
|
159
|
-
depth,
|
|
160
|
-
rooms_count: rooms.length,
|
|
161
|
-
content: output.trim(),
|
|
162
|
-
}),
|
|
163
|
-
}],
|
|
164
|
-
};
|
|
17
|
+
const result = await palaceWalk({ depth, focus, project });
|
|
18
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
165
19
|
});
|
|
166
20
|
}
|
|
167
21
|
//# sourceMappingURL=palace-walk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-walk.js","sourceRoot":"","sources":["../../src/tools/palace-walk.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"palace-walk.js","sourceRoot":"","sources":["../../src/tools/palace-walk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACjC,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,8CAA8C;YAC9C,0EAA0E;YAC1E,2CAA2C;QAC7C,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;iBACxE,QAAQ,CAAC,sDAAsD,CAAC;YACnE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;iBACzB,QAAQ,CAAC,yFAAyF,CAAC;YACtG,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC;KACF,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import type { ServerType } from "../server.js";
|
|
5
|
-
export declare function register(server: ServerType): void;
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function register(server: McpServer): void;
|
|
6
3
|
//# sourceMappingURL=palace-write.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palace-write.d.ts","sourceRoot":"","sources":["../../src/tools/palace-write.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"palace-write.d.ts","sourceRoot":"","sources":["../../src/tools/palace-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkBhD"}
|