exovault-mcp-server 1.0.0

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.
Files changed (305) hide show
  1. package/dist/auth.d.ts +41 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +236 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/auto-session.d.ts +39 -0
  6. package/dist/auto-session.d.ts.map +1 -0
  7. package/dist/auto-session.js +128 -0
  8. package/dist/auto-session.js.map +1 -0
  9. package/dist/buffer-persistence.d.ts +35 -0
  10. package/dist/buffer-persistence.d.ts.map +1 -0
  11. package/dist/buffer-persistence.js +110 -0
  12. package/dist/buffer-persistence.js.map +1 -0
  13. package/dist/coerce-params.d.ts +36 -0
  14. package/dist/coerce-params.d.ts.map +1 -0
  15. package/dist/coerce-params.js +120 -0
  16. package/dist/coerce-params.js.map +1 -0
  17. package/dist/crypto.d.ts +39 -0
  18. package/dist/crypto.d.ts.map +1 -0
  19. package/dist/crypto.js +119 -0
  20. package/dist/crypto.js.map +1 -0
  21. package/dist/db.d.ts +350 -0
  22. package/dist/db.d.ts.map +1 -0
  23. package/dist/db.js +866 -0
  24. package/dist/db.js.map +1 -0
  25. package/dist/embedding-config.d.ts +11 -0
  26. package/dist/embedding-config.d.ts.map +1 -0
  27. package/dist/embedding-config.js +24 -0
  28. package/dist/embedding-config.js.map +1 -0
  29. package/dist/entity-extraction.d.ts +22 -0
  30. package/dist/entity-extraction.d.ts.map +1 -0
  31. package/dist/entity-extraction.js +140 -0
  32. package/dist/entity-extraction.js.map +1 -0
  33. package/dist/episodic-headline.d.ts +6 -0
  34. package/dist/episodic-headline.d.ts.map +1 -0
  35. package/dist/episodic-headline.js +62 -0
  36. package/dist/episodic-headline.js.map +1 -0
  37. package/dist/error-sanitizer.d.ts +20 -0
  38. package/dist/error-sanitizer.d.ts.map +1 -0
  39. package/dist/error-sanitizer.js +54 -0
  40. package/dist/error-sanitizer.js.map +1 -0
  41. package/dist/extraction-budget.d.ts +39 -0
  42. package/dist/extraction-budget.d.ts.map +1 -0
  43. package/dist/extraction-budget.js +122 -0
  44. package/dist/extraction-budget.js.map +1 -0
  45. package/dist/extraction-llm.d.ts +22 -0
  46. package/dist/extraction-llm.d.ts.map +1 -0
  47. package/dist/extraction-llm.js +32 -0
  48. package/dist/extraction-llm.js.map +1 -0
  49. package/dist/extraction-prompt.d.ts +40 -0
  50. package/dist/extraction-prompt.d.ts.map +1 -0
  51. package/dist/extraction-prompt.js +176 -0
  52. package/dist/extraction-prompt.js.map +1 -0
  53. package/dist/gateway-client.d.ts +303 -0
  54. package/dist/gateway-client.d.ts.map +1 -0
  55. package/dist/gateway-client.js +285 -0
  56. package/dist/gateway-client.js.map +1 -0
  57. package/dist/gateway-init.d.ts +32 -0
  58. package/dist/gateway-init.d.ts.map +1 -0
  59. package/dist/gateway-init.js +71 -0
  60. package/dist/gateway-init.js.map +1 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +1242 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/infer-task-status.d.ts +7 -0
  66. package/dist/infer-task-status.d.ts.map +1 -0
  67. package/dist/infer-task-status.js +23 -0
  68. package/dist/infer-task-status.js.map +1 -0
  69. package/dist/normalize-agent-id.d.ts +21 -0
  70. package/dist/normalize-agent-id.d.ts.map +1 -0
  71. package/dist/normalize-agent-id.js +54 -0
  72. package/dist/normalize-agent-id.js.map +1 -0
  73. package/dist/openai.d.ts +14 -0
  74. package/dist/openai.d.ts.map +1 -0
  75. package/dist/openai.js +43 -0
  76. package/dist/openai.js.map +1 -0
  77. package/dist/rlm/actions.d.ts +31 -0
  78. package/dist/rlm/actions.d.ts.map +1 -0
  79. package/dist/rlm/actions.js +241 -0
  80. package/dist/rlm/actions.js.map +1 -0
  81. package/dist/rlm/benchmark.d.ts +2 -0
  82. package/dist/rlm/benchmark.d.ts.map +1 -0
  83. package/dist/rlm/benchmark.js +215 -0
  84. package/dist/rlm/benchmark.js.map +1 -0
  85. package/dist/rlm/execute.d.ts +13 -0
  86. package/dist/rlm/execute.d.ts.map +1 -0
  87. package/dist/rlm/execute.js +366 -0
  88. package/dist/rlm/execute.js.map +1 -0
  89. package/dist/rlm/index.d.ts +6 -0
  90. package/dist/rlm/index.d.ts.map +1 -0
  91. package/dist/rlm/index.js +147 -0
  92. package/dist/rlm/index.js.map +1 -0
  93. package/dist/rlm/profiles.d.ts +9 -0
  94. package/dist/rlm/profiles.d.ts.map +1 -0
  95. package/dist/rlm/profiles.js +46 -0
  96. package/dist/rlm/profiles.js.map +1 -0
  97. package/dist/rlm/types.d.ts +98 -0
  98. package/dist/rlm/types.d.ts.map +1 -0
  99. package/dist/rlm/types.js +6 -0
  100. package/dist/rlm/types.js.map +1 -0
  101. package/dist/rlm/verify.d.ts +13 -0
  102. package/dist/rlm/verify.d.ts.map +1 -0
  103. package/dist/rlm/verify.js +58 -0
  104. package/dist/rlm/verify.js.map +1 -0
  105. package/dist/rlm/writeback.d.ts +7 -0
  106. package/dist/rlm/writeback.d.ts.map +1 -0
  107. package/dist/rlm/writeback.js +77 -0
  108. package/dist/rlm/writeback.js.map +1 -0
  109. package/dist/scripts/backfill-memory-embeddings.d.ts +2 -0
  110. package/dist/scripts/backfill-memory-embeddings.d.ts.map +1 -0
  111. package/dist/scripts/backfill-memory-embeddings.js +153 -0
  112. package/dist/scripts/backfill-memory-embeddings.js.map +1 -0
  113. package/dist/session-buffer.d.ts +104 -0
  114. package/dist/session-buffer.d.ts.map +1 -0
  115. package/dist/session-buffer.js +466 -0
  116. package/dist/session-buffer.js.map +1 -0
  117. package/dist/session-dedup.d.ts +30 -0
  118. package/dist/session-dedup.d.ts.map +1 -0
  119. package/dist/session-dedup.js +67 -0
  120. package/dist/session-dedup.js.map +1 -0
  121. package/dist/session-flush.d.ts +81 -0
  122. package/dist/session-flush.d.ts.map +1 -0
  123. package/dist/session-flush.js +169 -0
  124. package/dist/session-flush.js.map +1 -0
  125. package/dist/session-lifecycle.d.ts +72 -0
  126. package/dist/session-lifecycle.d.ts.map +1 -0
  127. package/dist/session-lifecycle.js +247 -0
  128. package/dist/session-lifecycle.js.map +1 -0
  129. package/dist/setup.d.ts +2 -0
  130. package/dist/setup.d.ts.map +1 -0
  131. package/dist/setup.js +260 -0
  132. package/dist/setup.js.map +1 -0
  133. package/dist/stopwords.d.ts +2 -0
  134. package/dist/stopwords.d.ts.map +1 -0
  135. package/dist/stopwords.js +20 -0
  136. package/dist/stopwords.js.map +1 -0
  137. package/dist/strip-html.d.ts +5 -0
  138. package/dist/strip-html.d.ts.map +1 -0
  139. package/dist/strip-html.js +35 -0
  140. package/dist/strip-html.js.map +1 -0
  141. package/dist/task-completion-flush.d.ts +36 -0
  142. package/dist/task-completion-flush.d.ts.map +1 -0
  143. package/dist/task-completion-flush.js +97 -0
  144. package/dist/task-completion-flush.js.map +1 -0
  145. package/dist/task-lifecycle-types.d.ts +13 -0
  146. package/dist/task-lifecycle-types.d.ts.map +1 -0
  147. package/dist/task-lifecycle-types.js +12 -0
  148. package/dist/task-lifecycle-types.js.map +1 -0
  149. package/dist/task-lifecycle.d.ts +78 -0
  150. package/dist/task-lifecycle.d.ts.map +1 -0
  151. package/dist/task-lifecycle.js +256 -0
  152. package/dist/task-lifecycle.js.map +1 -0
  153. package/dist/tools/agent-messages.d.ts +26 -0
  154. package/dist/tools/agent-messages.d.ts.map +1 -0
  155. package/dist/tools/agent-messages.js +123 -0
  156. package/dist/tools/agent-messages.js.map +1 -0
  157. package/dist/tools/agent-tasks.d.ts +24 -0
  158. package/dist/tools/agent-tasks.d.ts.map +1 -0
  159. package/dist/tools/agent-tasks.js +162 -0
  160. package/dist/tools/agent-tasks.js.map +1 -0
  161. package/dist/tools/archive-memory.d.ts +2 -0
  162. package/dist/tools/archive-memory.d.ts.map +1 -0
  163. package/dist/tools/archive-memory.js +19 -0
  164. package/dist/tools/archive-memory.js.map +1 -0
  165. package/dist/tools/blind-index.d.ts +29 -0
  166. package/dist/tools/blind-index.d.ts.map +1 -0
  167. package/dist/tools/blind-index.js +53 -0
  168. package/dist/tools/blind-index.js.map +1 -0
  169. package/dist/tools/cleanup-memories.d.ts +44 -0
  170. package/dist/tools/cleanup-memories.d.ts.map +1 -0
  171. package/dist/tools/cleanup-memories.js +126 -0
  172. package/dist/tools/cleanup-memories.js.map +1 -0
  173. package/dist/tools/context-checkpoint.d.ts +28 -0
  174. package/dist/tools/context-checkpoint.d.ts.map +1 -0
  175. package/dist/tools/context-checkpoint.js +140 -0
  176. package/dist/tools/context-checkpoint.js.map +1 -0
  177. package/dist/tools/context-profiles.d.ts +67 -0
  178. package/dist/tools/context-profiles.d.ts.map +1 -0
  179. package/dist/tools/context-profiles.js +30 -0
  180. package/dist/tools/context-profiles.js.map +1 -0
  181. package/dist/tools/create-note.d.ts +2 -0
  182. package/dist/tools/create-note.d.ts.map +1 -0
  183. package/dist/tools/create-note.js +60 -0
  184. package/dist/tools/create-note.js.map +1 -0
  185. package/dist/tools/create-vault.d.ts +5 -0
  186. package/dist/tools/create-vault.d.ts.map +1 -0
  187. package/dist/tools/create-vault.js +121 -0
  188. package/dist/tools/create-vault.js.map +1 -0
  189. package/dist/tools/decrypt-helpers.d.ts +31 -0
  190. package/dist/tools/decrypt-helpers.d.ts.map +1 -0
  191. package/dist/tools/decrypt-helpers.js +33 -0
  192. package/dist/tools/decrypt-helpers.js.map +1 -0
  193. package/dist/tools/delete-note.d.ts +2 -0
  194. package/dist/tools/delete-note.d.ts.map +1 -0
  195. package/dist/tools/delete-note.js +21 -0
  196. package/dist/tools/delete-note.js.map +1 -0
  197. package/dist/tools/explore-graph.d.ts +11 -0
  198. package/dist/tools/explore-graph.d.ts.map +1 -0
  199. package/dist/tools/explore-graph.js +169 -0
  200. package/dist/tools/explore-graph.js.map +1 -0
  201. package/dist/tools/get-related-memories.d.ts +2 -0
  202. package/dist/tools/get-related-memories.d.ts.map +1 -0
  203. package/dist/tools/get-related-memories.js +59 -0
  204. package/dist/tools/get-related-memories.js.map +1 -0
  205. package/dist/tools/knowledge-links.d.ts +17 -0
  206. package/dist/tools/knowledge-links.d.ts.map +1 -0
  207. package/dist/tools/knowledge-links.js +102 -0
  208. package/dist/tools/knowledge-links.js.map +1 -0
  209. package/dist/tools/list-active-agents.d.ts +5 -0
  210. package/dist/tools/list-active-agents.d.ts.map +1 -0
  211. package/dist/tools/list-active-agents.js +15 -0
  212. package/dist/tools/list-active-agents.js.map +1 -0
  213. package/dist/tools/list-notes.d.ts +2 -0
  214. package/dist/tools/list-notes.d.ts.map +1 -0
  215. package/dist/tools/list-notes.js +19 -0
  216. package/dist/tools/list-notes.js.map +1 -0
  217. package/dist/tools/list-vaults.d.ts +2 -0
  218. package/dist/tools/list-vaults.d.ts.map +1 -0
  219. package/dist/tools/list-vaults.js +19 -0
  220. package/dist/tools/list-vaults.js.map +1 -0
  221. package/dist/tools/mmr.d.ts +18 -0
  222. package/dist/tools/mmr.d.ts.map +1 -0
  223. package/dist/tools/mmr.js +67 -0
  224. package/dist/tools/mmr.js.map +1 -0
  225. package/dist/tools/read-memories.d.ts +2 -0
  226. package/dist/tools/read-memories.d.ts.map +1 -0
  227. package/dist/tools/read-memories.js +46 -0
  228. package/dist/tools/read-memories.js.map +1 -0
  229. package/dist/tools/read-note.d.ts +2 -0
  230. package/dist/tools/read-note.d.ts.map +1 -0
  231. package/dist/tools/read-note.js +35 -0
  232. package/dist/tools/read-note.js.map +1 -0
  233. package/dist/tools/read-notes.d.ts +6 -0
  234. package/dist/tools/read-notes.d.ts.map +1 -0
  235. package/dist/tools/read-notes.js +45 -0
  236. package/dist/tools/read-notes.js.map +1 -0
  237. package/dist/tools/resolve-vault-id.d.ts +6 -0
  238. package/dist/tools/resolve-vault-id.d.ts.map +1 -0
  239. package/dist/tools/resolve-vault-id.js +7 -0
  240. package/dist/tools/resolve-vault-id.js.map +1 -0
  241. package/dist/tools/rrf.d.ts +28 -0
  242. package/dist/tools/rrf.d.ts.map +1 -0
  243. package/dist/tools/rrf.js +19 -0
  244. package/dist/tools/rrf.js.map +1 -0
  245. package/dist/tools/search-and-read.d.ts +11 -0
  246. package/dist/tools/search-and-read.d.ts.map +1 -0
  247. package/dist/tools/search-and-read.js +208 -0
  248. package/dist/tools/search-and-read.js.map +1 -0
  249. package/dist/tools/search-memories.d.ts +13 -0
  250. package/dist/tools/search-memories.d.ts.map +1 -0
  251. package/dist/tools/search-memories.js +272 -0
  252. package/dist/tools/search-memories.js.map +1 -0
  253. package/dist/tools/search-notes.d.ts +2 -0
  254. package/dist/tools/search-notes.d.ts.map +1 -0
  255. package/dist/tools/search-notes.js +94 -0
  256. package/dist/tools/search-notes.js.map +1 -0
  257. package/dist/tools/semantic-search.d.ts +7 -0
  258. package/dist/tools/semantic-search.d.ts.map +1 -0
  259. package/dist/tools/semantic-search.js +85 -0
  260. package/dist/tools/semantic-search.js.map +1 -0
  261. package/dist/tools/session-start.d.ts +24 -0
  262. package/dist/tools/session-start.d.ts.map +1 -0
  263. package/dist/tools/session-start.js +256 -0
  264. package/dist/tools/session-start.js.map +1 -0
  265. package/dist/tools/stale-tasks.d.ts +22 -0
  266. package/dist/tools/stale-tasks.d.ts.map +1 -0
  267. package/dist/tools/stale-tasks.js +39 -0
  268. package/dist/tools/stale-tasks.js.map +1 -0
  269. package/dist/tools/temporal-decay.d.ts +21 -0
  270. package/dist/tools/temporal-decay.d.ts.map +1 -0
  271. package/dist/tools/temporal-decay.js +32 -0
  272. package/dist/tools/temporal-decay.js.map +1 -0
  273. package/dist/tools/update-memory.d.ts +19 -0
  274. package/dist/tools/update-memory.d.ts.map +1 -0
  275. package/dist/tools/update-memory.js +230 -0
  276. package/dist/tools/update-memory.js.map +1 -0
  277. package/dist/tools/update-note.d.ts +2 -0
  278. package/dist/tools/update-note.d.ts.map +1 -0
  279. package/dist/tools/update-note.js +79 -0
  280. package/dist/tools/update-note.js.map +1 -0
  281. package/dist/tools/vault-instruction-template.d.ts +17 -0
  282. package/dist/tools/vault-instruction-template.d.ts.map +1 -0
  283. package/dist/tools/vault-instruction-template.js +77 -0
  284. package/dist/tools/vault-instruction-template.js.map +1 -0
  285. package/dist/tools/wiki-link-sync.d.ts +34 -0
  286. package/dist/tools/wiki-link-sync.d.ts.map +1 -0
  287. package/dist/tools/wiki-link-sync.js +132 -0
  288. package/dist/tools/wiki-link-sync.js.map +1 -0
  289. package/dist/tools/wrap-tool-handler.d.ts +8 -0
  290. package/dist/tools/wrap-tool-handler.d.ts.map +1 -0
  291. package/dist/tools/wrap-tool-handler.js +32 -0
  292. package/dist/tools/wrap-tool-handler.js.map +1 -0
  293. package/dist/tools/write-memory.d.ts +34 -0
  294. package/dist/tools/write-memory.d.ts.map +1 -0
  295. package/dist/tools/write-memory.js +359 -0
  296. package/dist/tools/write-memory.js.map +1 -0
  297. package/dist/usage.d.ts +11 -0
  298. package/dist/usage.d.ts.map +1 -0
  299. package/dist/usage.js +38 -0
  300. package/dist/usage.js.map +1 -0
  301. package/dist/wiki-link-parser.d.ts +27 -0
  302. package/dist/wiki-link-parser.d.ts.map +1 -0
  303. package/dist/wiki-link-parser.js +93 -0
  304. package/dist/wiki-link-parser.js.map +1 -0
  305. package/package.json +38 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/tools/semantic-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7C;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,EACb,IAAI,SAAK,EACT,SAAS,SAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAyFjB"}
@@ -0,0 +1,85 @@
1
+ import { matchNoteEmbeddings, getNotesByIds } from "../db.js";
2
+ import { generateQueryEmbedding } from "../openai.js";
3
+ import { decrypt } from "../crypto.js";
4
+ import { stripHtml } from "../strip-html.js";
5
+ import { logMcpUsageEvent } from "../usage.js";
6
+ /**
7
+ * Semantic search: generates an embedding for the query, finds similar note
8
+ * chunks via pgvector, deduplicates to note level (keeping best similarity),
9
+ * and returns previews with similarity scores.
10
+ */
11
+ export async function semanticSearch(ctx, query, topK = 10, threshold = 0.5) {
12
+ if (!ctx.openaiApiKey) {
13
+ return JSON.stringify({
14
+ error: "No OpenAI API key configured. Run 'npx exovault-mcp setup' to add one, or add \"openaiApiKey\" to ~/.exovault-mcp/config.json.",
15
+ });
16
+ }
17
+ // 1. Generate query embedding
18
+ const embedding = await generateQueryEmbedding(query, ctx.openaiApiKey);
19
+ // 2. Find matching chunks via Supabase RPC
20
+ const matches = await matchNoteEmbeddings(ctx.supabase, embedding, ctx.userId, threshold, topK * 3 // fetch extra chunks since multiple chunks can belong to one note
21
+ );
22
+ if (matches.length === 0) {
23
+ const payload = JSON.stringify([]);
24
+ await logMcpUsageEvent({
25
+ supabase: ctx.supabase,
26
+ userId: ctx.userId,
27
+ operationType: "mcp_semantic_search",
28
+ modelId: "text-embedding-3-small",
29
+ inputText: query,
30
+ outputText: payload,
31
+ embeddingTokens: Math.ceil(query.length / 4),
32
+ });
33
+ return payload;
34
+ }
35
+ // 3. Deduplicate chunks to note level — keep highest similarity per note
36
+ const bestByNote = new Map();
37
+ for (const m of matches) {
38
+ const existing = bestByNote.get(m.note_id);
39
+ if (existing === undefined || m.similarity > existing) {
40
+ bestByNote.set(m.note_id, m.similarity);
41
+ }
42
+ }
43
+ // 4. Fetch the actual notes
44
+ const noteIds = Array.from(bestByNote.keys());
45
+ const notes = await getNotesByIds(ctx.supabase, ctx.userId, noteIds);
46
+ // 5. Decrypt and build results
47
+ const results = await Promise.all(notes.map(async (note) => {
48
+ const [title, content] = await Promise.all([
49
+ decrypt(note.encrypted_title, note.title_iv, ctx.masterKey),
50
+ decrypt(note.encrypted_content, note.content_iv, ctx.masterKey),
51
+ ]);
52
+ let tags = [];
53
+ if (note.encrypted_tags && note.tags_iv) {
54
+ try {
55
+ const tagsJson = await decrypt(note.encrypted_tags, note.tags_iv, ctx.masterKey);
56
+ tags = JSON.parse(tagsJson);
57
+ }
58
+ catch {
59
+ // ignore
60
+ }
61
+ }
62
+ return {
63
+ id: note.id,
64
+ title,
65
+ tags,
66
+ preview: stripHtml(content).slice(0, 300),
67
+ similarity: bestByNote.get(note.id) ?? 0,
68
+ vaultId: note.vault_id,
69
+ updatedAt: note.updated_at,
70
+ };
71
+ }));
72
+ // Sort by similarity descending and limit to topK
73
+ results.sort((a, b) => b.similarity - a.similarity);
74
+ const payload = JSON.stringify(results.slice(0, topK), null, 2);
75
+ await logMcpUsageEvent({
76
+ supabase: ctx.supabase,
77
+ userId: ctx.userId,
78
+ operationType: "mcp_semantic_search",
79
+ modelId: "text-embedding-3-small",
80
+ inputText: query,
81
+ outputText: payload,
82
+ embeddingTokens: Math.ceil(query.length / 4),
83
+ });
84
+ return payload;
85
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/tools/semantic-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { McpContext } from "../auth.js";
2
+ /**
3
+ * Session start tool: returns recent context so an agent can resume
4
+ * where a previous session left off.
5
+ *
6
+ * Composes existing tools to return:
7
+ * 1. Recent episodic memories (session summaries)
8
+ * 2. High-importance facts and constraints
9
+ * 3. Active tasks
10
+ * 4. Available vaults
11
+ * 5. Recently active agents
12
+ * 6. Optional query-scoped context
13
+ */
14
+ export declare function sessionStart(ctx: McpContext, input: {
15
+ vaultId?: string;
16
+ query?: string;
17
+ summaryOnly?: boolean;
18
+ mode?: string;
19
+ maxEpisodic?: number;
20
+ maxFacts?: number;
21
+ maxTasks?: number;
22
+ maxConstraints?: number;
23
+ agentId?: string;
24
+ }): Promise<string>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAU7C;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE;IACL,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,MAAM,CAAC,CA4SjB"}
@@ -0,0 +1,256 @@
1
+ import { getMemories, getVaults, countNotesByVault, getActiveAgents, getMemoryHealthStats, getPendingMessages, bulkUpdateMessageStatus } from "../db.js";
2
+ import { decrypt } from "../crypto.js";
3
+ import { searchMemories } from "./search-memories.js";
4
+ import { logMcpUsageEvent } from "../usage.js";
5
+ import { resolveContextLimits } from "./context-profiles.js";
6
+ import { compactAndDedup } from "../session-dedup.js";
7
+ import { runCleanup } from "./cleanup-memories.js";
8
+ import { flagStaleTasks } from "./stale-tasks.js";
9
+ /**
10
+ * Session start tool: returns recent context so an agent can resume
11
+ * where a previous session left off.
12
+ *
13
+ * Composes existing tools to return:
14
+ * 1. Recent episodic memories (session summaries)
15
+ * 2. High-importance facts and constraints
16
+ * 3. Active tasks
17
+ * 4. Available vaults
18
+ * 5. Recently active agents
19
+ * 6. Optional query-scoped context
20
+ */
21
+ export async function sessionStart(ctx, input) {
22
+ const limits = resolveContextLimits({
23
+ mode: input.mode,
24
+ maxEpisodic: input.maxEpisodic,
25
+ maxFacts: input.maxFacts,
26
+ maxTasks: input.maxTasks,
27
+ maxConstraints: input.maxConstraints,
28
+ });
29
+ // ── None mode: skip all memory queries, return only vault metadata + agents ──
30
+ const allZero = limits.maxEpisodic === 0 &&
31
+ limits.maxFacts === 0 &&
32
+ limits.maxTasks === 0 &&
33
+ limits.maxConstraints === 0;
34
+ if (allZero) {
35
+ const [vaults, noteCounts, agents] = await Promise.all([
36
+ getVaults(ctx.supabase, ctx.userId),
37
+ countNotesByVault(ctx.supabase, ctx.userId),
38
+ getActiveAgents(ctx.supabase, ctx.userId, 7, 5),
39
+ ]);
40
+ const vaultList = await Promise.all(vaults.map(async (v) => {
41
+ const name = await decrypt(v.encrypted_name, v.name_iv, ctx.masterKey);
42
+ return { id: v.id, name, noteCount: noteCounts[v.id] ?? 0 };
43
+ }));
44
+ const payload = JSON.stringify({
45
+ sessionContext: {
46
+ recentSessions: [],
47
+ importantFacts: [],
48
+ activeTasks: [],
49
+ constraints: [],
50
+ },
51
+ vaults: vaultList,
52
+ recentAgents: agents,
53
+ }, null, 2);
54
+ await logMcpUsageEvent({
55
+ supabase: ctx.supabase,
56
+ userId: ctx.userId,
57
+ operationType: "mcp_session_start",
58
+ vaultId: input.vaultId,
59
+ outputText: payload,
60
+ });
61
+ return payload;
62
+ }
63
+ // Run independent fetches in parallel with DB-level type filtering
64
+ const [episodicRows, factRows, taskRows, constraintRows, vaults, noteCounts, agents, healthStats, cleanupResult, pendingMsgRows,] = await Promise.all([
65
+ // Recent episodic memories (session summaries)
66
+ getMemories(ctx.supabase, ctx.userId, {
67
+ vaultId: input.vaultId,
68
+ memoryType: "episodic",
69
+ limit: limits.maxEpisodic,
70
+ }),
71
+ // High-importance facts, ordered by importance
72
+ getMemories(ctx.supabase, ctx.userId, {
73
+ vaultId: input.vaultId,
74
+ memoryType: "fact",
75
+ minImportance: 3,
76
+ orderBy: "importance",
77
+ limit: limits.maxFacts,
78
+ }),
79
+ // Active tasks
80
+ getMemories(ctx.supabase, ctx.userId, {
81
+ vaultId: input.vaultId,
82
+ memoryType: "task",
83
+ limit: limits.maxTasks,
84
+ }),
85
+ // Constraints — importance >= 3 (consistent with facts filter)
86
+ getMemories(ctx.supabase, ctx.userId, {
87
+ vaultId: input.vaultId,
88
+ memoryType: "constraint",
89
+ minImportance: 3,
90
+ orderBy: "importance",
91
+ limit: limits.maxConstraints,
92
+ }),
93
+ // Available vaults
94
+ getVaults(ctx.supabase, ctx.userId),
95
+ // Note counts per vault
96
+ countNotesByVault(ctx.supabase, ctx.userId),
97
+ // Recently active agents (last 7 days, cap to 5)
98
+ getActiveAgents(ctx.supabase, ctx.userId, 7, 5),
99
+ // Memory health stats (embedding indexing status)
100
+ getMemoryHealthStats(ctx.supabase, ctx.userId, input.vaultId),
101
+ // Auto-cleanup: safe rules only (failed indexing + superseded), non-blocking
102
+ runCleanup(ctx, input.vaultId, { safeOnly: true }).catch((e) => {
103
+ process.stderr.write(`[session-start] auto-cleanup failed: ${e.message}\n`);
104
+ return null;
105
+ }),
106
+ // Pending agent messages (budget: 5 on session_start)
107
+ input.agentId
108
+ ? getPendingMessages(ctx.supabase, ctx.userId, input.agentId, 5).catch(() => [])
109
+ : Promise.resolve([]),
110
+ ]);
111
+ // Decrypt all memory rows in parallel
112
+ // Default to summaryOnly=true to reduce token usage (~40-50% reduction)
113
+ const useSummaryOnly = input.summaryOnly !== false;
114
+ const SUMMARY_MAX_CHARS = 120;
115
+ async function decryptMemory(m) {
116
+ let summary = null;
117
+ if (m.encrypted_summary && m.summary_iv) {
118
+ summary = await decrypt(m.encrypted_summary, m.summary_iv, ctx.masterKey).catch(() => null);
119
+ }
120
+ // In summaryOnly mode: clipped summary + ID. Agent calls read_memories for full content.
121
+ if (useSummaryOnly) {
122
+ let label = summary;
123
+ if (!label) {
124
+ // Fallback: decrypt and clip content
125
+ label = await decrypt(m.encrypted_content, m.content_iv, ctx.masterKey).catch(() => "");
126
+ }
127
+ // Always clip — both summary and content can be long
128
+ if (label && label.length > SUMMARY_MAX_CHARS) {
129
+ label = label.slice(0, SUMMARY_MAX_CHARS) + "...";
130
+ }
131
+ return {
132
+ id: m.id,
133
+ memoryType: m.memory_type,
134
+ summary: label,
135
+ importance: m.importance,
136
+ };
137
+ }
138
+ const content = await decrypt(m.encrypted_content, m.content_iv, ctx.masterKey);
139
+ return {
140
+ id: m.id,
141
+ memoryType: m.memory_type,
142
+ content,
143
+ summary,
144
+ importance: m.importance,
145
+ confidence: m.confidence,
146
+ vaultId: m.vault_id,
147
+ agentId: m.agent_id,
148
+ entities: m.entities,
149
+ updatedAt: m.updated_at,
150
+ };
151
+ }
152
+ const [episodic, facts, tasks, constraints] = await Promise.all([
153
+ Promise.all(episodicRows.map(decryptMemory)),
154
+ Promise.all(factRows.map(decryptMemory)),
155
+ Promise.all(taskRows.map(decryptMemory)),
156
+ Promise.all(constraintRows.map(decryptMemory)),
157
+ ]);
158
+ // Decrypt vault names
159
+ const vaultList = await Promise.all(vaults.map(async (v) => {
160
+ const name = await decrypt(v.encrypted_name, v.name_iv, ctx.masterKey);
161
+ return {
162
+ id: v.id,
163
+ name,
164
+ noteCount: noteCounts[v.id] ?? 0,
165
+ };
166
+ }));
167
+ // Optional: query-scoped context via semantic search
168
+ let queryContext = null;
169
+ if (input.query) {
170
+ const searchResult = await searchMemories(ctx, {
171
+ query: input.query,
172
+ vaultId: input.vaultId,
173
+ topK: 5,
174
+ });
175
+ queryContext = JSON.parse(searchResult);
176
+ }
177
+ // Deduplicate and compact memories before returning
178
+ const compactedTasks = compactAndDedup(tasks, useSummaryOnly);
179
+ // Flag stale tasks and enrich with metadata fields (doneWhen, planGroupId, completionSource)
180
+ const taskMetaMap = new Map(taskRows.map((r) => {
181
+ const meta = r.metadata ?? {};
182
+ return [r.id, meta];
183
+ }));
184
+ // Enrich compacted tasks with metadata fields relevant to task lifecycle
185
+ const enrichedTasks = compactedTasks.map((t) => {
186
+ const task = t;
187
+ const meta = taskMetaMap.get(task.id) ?? {};
188
+ return {
189
+ ...task,
190
+ ...(meta.doneWhen ? { doneWhen: meta.doneWhen } : {}),
191
+ ...(meta.planGroupId ? { planGroupId: meta.planGroupId } : {}),
192
+ ...(meta.completionSource ? { completionSource: meta.completionSource } : {}),
193
+ };
194
+ });
195
+ const tasksWithStaleness = flagStaleTasks(enrichedTasks, {
196
+ getStatus: (t) => {
197
+ const meta = taskMetaMap.get(t.id);
198
+ return meta?.taskStatus;
199
+ },
200
+ });
201
+ const result = {
202
+ sessionContext: {
203
+ recentSessions: compactAndDedup(episodic, useSummaryOnly),
204
+ importantFacts: compactAndDedup(facts, useSummaryOnly),
205
+ activeTasks: tasksWithStaleness,
206
+ constraints: compactAndDedup(constraints, useSummaryOnly),
207
+ },
208
+ memoryHealth: healthStats,
209
+ vaults: vaultList,
210
+ recentAgents: agents,
211
+ };
212
+ if (queryContext) {
213
+ result.queryResults = queryContext;
214
+ }
215
+ // Include auto-cleanup results when items were archived
216
+ if (cleanupResult && cleanupResult.archivedCount > 0) {
217
+ result.autoCleanup = {
218
+ archivedCount: cleanupResult.archivedCount,
219
+ reasons: cleanupResult.candidates.map((c) => c.reason),
220
+ };
221
+ }
222
+ // Decrypt and attach pending messages
223
+ if (pendingMsgRows.length > 0) {
224
+ try {
225
+ const pendingMessages = await Promise.all(pendingMsgRows.map(async (m) => {
226
+ const content = await decrypt(m.encrypted_content, m.content_iv, ctx.masterKey);
227
+ return {
228
+ id: m.id,
229
+ senderId: m.sender_id,
230
+ senderType: m.sender_type,
231
+ category: m.category,
232
+ priority: m.priority,
233
+ subject: m.subject,
234
+ content,
235
+ createdAt: m.created_at,
236
+ };
237
+ }));
238
+ result.pendingMessages = pendingMessages;
239
+ // Mark as delivered (best-effort)
240
+ await bulkUpdateMessageStatus(ctx.supabase, pendingMsgRows.map((m) => m.id), ctx.userId, "delivered", { delivered_at: new Date().toISOString() }).catch(() => { });
241
+ }
242
+ catch {
243
+ // Best-effort — never block session_start
244
+ }
245
+ }
246
+ const payload = JSON.stringify(result);
247
+ await logMcpUsageEvent({
248
+ supabase: ctx.supabase,
249
+ userId: ctx.userId,
250
+ operationType: "mcp_session_start",
251
+ vaultId: input.vaultId,
252
+ inputText: input.query,
253
+ outputText: payload,
254
+ });
255
+ return payload;
256
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/tools/session-start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Stale task detection — pure function that annotates tasks with staleness warnings.
3
+ *
4
+ * When a session crashes or an agent disconnects, tasks may remain as `in_progress`
5
+ * indefinitely. This function flags those tasks so the next session can address them.
6
+ */
7
+ export declare const DEFAULT_STALE_HOURS = 48;
8
+ export interface FlagStaleTasksOptions<T> {
9
+ /** Hours after which an in_progress task is considered stale. Default: 48. */
10
+ staleAfterHours?: number;
11
+ /** Extract the task status from a task object. Default: checks metadata.taskStatus. */
12
+ getStatus?: (task: T) => string | undefined;
13
+ /** Current time for testing. Default: new Date(). */
14
+ now?: Date;
15
+ }
16
+ /**
17
+ * Pure function: annotates tasks that have been `in_progress` longer than the threshold.
18
+ * Does NOT mutate input — returns a new array with `staleWarning` added where applicable.
19
+ */
20
+ export declare function flagStaleTasks<T extends Record<string, unknown>>(tasks: T[], options?: FlagStaleTasksOptions<T>): (T & {
21
+ staleWarning?: string;
22
+ })[];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/stale-tasks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5C,qDAAqD;IACrD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9D,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACjC,CAAC,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAgCnC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Stale task detection — pure function that annotates tasks with staleness warnings.
3
+ *
4
+ * When a session crashes or an agent disconnects, tasks may remain as `in_progress`
5
+ * indefinitely. This function flags those tasks so the next session can address them.
6
+ */
7
+ export const DEFAULT_STALE_HOURS = 48;
8
+ /**
9
+ * Pure function: annotates tasks that have been `in_progress` longer than the threshold.
10
+ * Does NOT mutate input — returns a new array with `staleWarning` added where applicable.
11
+ */
12
+ export function flagStaleTasks(tasks, options) {
13
+ const staleAfterHours = options?.staleAfterHours ?? DEFAULT_STALE_HOURS;
14
+ const staleAfterMs = staleAfterHours * 60 * 60 * 1000;
15
+ const now = options?.now ?? new Date();
16
+ const getStatus = options?.getStatus ??
17
+ ((task) => {
18
+ const meta = task.metadata;
19
+ return meta?.taskStatus ?? undefined;
20
+ });
21
+ return tasks.map((task) => {
22
+ const status = getStatus(task);
23
+ if (status !== "in_progress")
24
+ return { ...task };
25
+ const updatedAt = task.updatedAt;
26
+ if (!updatedAt)
27
+ return { ...task };
28
+ const updatedTime = new Date(updatedAt).getTime();
29
+ const ageMs = now.getTime() - updatedTime;
30
+ if (ageMs <= staleAfterMs)
31
+ return { ...task };
32
+ const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
33
+ return {
34
+ ...task,
35
+ staleWarning: `This task has been in_progress for ${ageHours}h without updates. ` +
36
+ `It may have been abandoned by a previous session. Consider updating its status.`,
37
+ };
38
+ });
39
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-tasks.js","sourceRoot":"","sources":["../../src/tools/stale-tasks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAWtC;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAU,EACV,OAAkC;IAElC,MAAM,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,mBAAmB,CAAC;IACxE,MAAM,YAAY,GAAG,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IAEvC,MAAM,SAAS,GACb,OAAO,EAAE,SAAS;QAClB,CAAC,CAAC,IAAO,EAAE,EAAE;YACX,MAAM,IAAI,GAAG,IAAI,CAAC,QAA+C,CAAC;YAClE,OAAQ,IAAI,EAAE,UAAqB,IAAI,SAAS,CAAC;QACnD,CAAC,CAAC,CAAC;IAEL,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;QAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAsC,CAAC;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;QAEnC,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC;QAE1C,IAAI,KAAK,IAAI,YAAY;YAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;QAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO;YACL,GAAG,IAAI;YACP,YAAY,EACV,sCAAsC,QAAQ,qBAAqB;gBACnE,iFAAiF;SACpF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Temporal decay for memory search results (MCP server copy).
3
+ *
4
+ * Keep in sync with src/lib/search/temporal-decay.ts in the Next.js app.
5
+ *
6
+ * Formula: decayedScore = rrfScore × e^(-λ × ageInDays)
7
+ * where λ = ln(2) / halfLifeDays
8
+ */
9
+ export interface ScoredCandidate {
10
+ id: string;
11
+ score: number;
12
+ updatedAt: Date;
13
+ importance: number;
14
+ }
15
+ export interface DecayedCandidate {
16
+ id: string;
17
+ score: number;
18
+ }
19
+ export declare function computeDecayMultiplier(ageInDays: number, halfLifeDays: number): number;
20
+ export declare function applyTemporalDecay(score: number, updatedAt: Date, importance: number, halfLifeDays: number, now?: Date): number;
21
+ export declare function applyTemporalDecayBatch(candidates: ScoredCandidate[], halfLifeDays: number, now?: Date): DecayedCandidate[];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal-decay.d.ts","sourceRoot":"","sources":["../../src/tools/temporal-decay.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAItF;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,IAAI,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,GAAE,IAAiB,GACrB,MAAM,CAKR;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,eAAe,EAAE,EAC7B,YAAY,EAAE,MAAM,EACpB,GAAG,GAAE,IAAiB,GACrB,gBAAgB,EAAE,CASpB"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Temporal decay for memory search results (MCP server copy).
3
+ *
4
+ * Keep in sync with src/lib/search/temporal-decay.ts in the Next.js app.
5
+ *
6
+ * Formula: decayedScore = rrfScore × e^(-λ × ageInDays)
7
+ * where λ = ln(2) / halfLifeDays
8
+ */
9
+ const EVERGREEN_MIN_IMPORTANCE = 4;
10
+ export function computeDecayMultiplier(ageInDays, halfLifeDays) {
11
+ if (ageInDays <= 0)
12
+ return 1.0;
13
+ const lambda = Math.LN2 / halfLifeDays;
14
+ return Math.exp(-lambda * ageInDays);
15
+ }
16
+ export function applyTemporalDecay(score, updatedAt, importance, halfLifeDays, now = new Date()) {
17
+ if (importance >= EVERGREEN_MIN_IMPORTANCE)
18
+ return score;
19
+ const ageMs = now.getTime() - updatedAt.getTime();
20
+ const ageInDays = Math.max(0, ageMs / (1000 * 60 * 60 * 24));
21
+ return score * computeDecayMultiplier(ageInDays, halfLifeDays);
22
+ }
23
+ export function applyTemporalDecayBatch(candidates, halfLifeDays, now = new Date()) {
24
+ if (candidates.length === 0)
25
+ return [];
26
+ return candidates
27
+ .map((c) => ({
28
+ id: c.id,
29
+ score: applyTemporalDecay(c.score, c.updatedAt, c.importance, halfLifeDays, now),
30
+ }))
31
+ .sort((a, b) => b.score - a.score);
32
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal-decay.js","sourceRoot":"","sources":["../../src/tools/temporal-decay.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAcnC,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,YAAoB;IAC5E,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,SAAe,EACf,UAAkB,EAClB,YAAoB,EACpB,MAAY,IAAI,IAAI,EAAE;IAEtB,IAAI,UAAU,IAAI,wBAAwB;QAAE,OAAO,KAAK,CAAC;IACzD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,KAAK,GAAG,sBAAsB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAA6B,EAC7B,YAAoB,EACpB,MAAY,IAAI,IAAI,EAAE;IAEtB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,CAAC;KACjF,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { McpContext } from "../auth.js";
2
+ interface MemoryRelation {
3
+ memoryId: string;
4
+ relationType: "derived_from" | "contradicts" | "refines" | "part_of" | "supersedes";
5
+ }
6
+ export declare function updateMemoryTool(ctx: McpContext, input: {
7
+ memoryId: string;
8
+ content?: string;
9
+ summary?: string;
10
+ memoryType?: string;
11
+ importance?: number;
12
+ confidence?: number;
13
+ entities?: string[];
14
+ relatedMemoryIds?: MemoryRelation[];
15
+ sourceNoteIds?: string[];
16
+ isArchived?: boolean;
17
+ metadata?: Record<string, unknown>;
18
+ }): Promise<string>;
19
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-memory.d.ts","sourceRoot":"","sources":["../../src/tools/update-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA0C7C,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,cAAc,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;CACrF;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GACA,OAAO,CAAC,MAAM,CAAC,CA2NjB"}