@prmichaelsen/remember-mcp 3.14.8 → 3.14.9

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.
@@ -1860,22 +1860,22 @@ function buildDocTypeFilters(collection, docType, filters) {
1860
1860
  }
1861
1861
  }
1862
1862
  if (filters?.weight_min !== void 0) {
1863
- filterList.push(collection.filter.byProperty("weight").greaterThanOrEqual(filters.weight_min));
1863
+ filterList.push(collection.filter.byProperty("weight").greaterOrEqual(filters.weight_min));
1864
1864
  }
1865
1865
  if (filters?.weight_max !== void 0) {
1866
- filterList.push(collection.filter.byProperty("weight").lessThanOrEqual(filters.weight_max));
1866
+ filterList.push(collection.filter.byProperty("weight").lessOrEqual(filters.weight_max));
1867
1867
  }
1868
1868
  if (filters?.trust_min !== void 0) {
1869
- filterList.push(collection.filter.byProperty("trust_score").greaterThanOrEqual(filters.trust_min));
1869
+ filterList.push(collection.filter.byProperty("trust_score").greaterOrEqual(filters.trust_min));
1870
1870
  }
1871
1871
  if (filters?.trust_max !== void 0) {
1872
- filterList.push(collection.filter.byProperty("trust_score").lessThanOrEqual(filters.trust_max));
1872
+ filterList.push(collection.filter.byProperty("trust_score").lessOrEqual(filters.trust_max));
1873
1873
  }
1874
1874
  if (filters?.date_from) {
1875
- filterList.push(collection.filter.byProperty("created_at").greaterThanOrEqual(new Date(filters.date_from)));
1875
+ filterList.push(collection.filter.byProperty("created_at").greaterOrEqual(new Date(filters.date_from)));
1876
1876
  }
1877
1877
  if (filters?.date_to) {
1878
- filterList.push(collection.filter.byProperty("created_at").lessThanOrEqual(new Date(filters.date_to)));
1878
+ filterList.push(collection.filter.byProperty("created_at").lessOrEqual(new Date(filters.date_to)));
1879
1879
  }
1880
1880
  if (filters?.tags && filters.tags.length > 0) {
1881
1881
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
@@ -2236,6 +2236,7 @@ var ALL_MEMORY_PROPERTIES = [
2236
2236
  "related_memory_ids",
2237
2237
  "relationships",
2238
2238
  "memory_ids",
2239
+ "relationship_count",
2239
2240
  "relationship_type",
2240
2241
  "observation",
2241
2242
  "strength",
@@ -2281,7 +2282,7 @@ async function fetchMemoryWithAllProperties(collection, memoryId) {
2281
2282
 
2282
2283
  // node_modules/@prmichaelsen/remember-core/dist/services/trust-enforcement.service.js
2283
2284
  function buildTrustFilter(collection, accessorTrustLevel) {
2284
- return collection.filter.byProperty("trust_score").lessThanOrEqual(accessorTrustLevel);
2285
+ return collection.filter.byProperty("trust_score").lessOrEqual(accessorTrustLevel);
2285
2286
  }
2286
2287
 
2287
2288
  // node_modules/@prmichaelsen/remember-core/dist/services/memory.service.js
@@ -2334,6 +2335,7 @@ var MemoryService = class {
2334
2335
  context_summary: input.context_summary || "Memory created",
2335
2336
  context_conversation_id: input.context_conversation_id,
2336
2337
  relationship_ids: [],
2338
+ relationship_count: 0,
2337
2339
  access_count: 0,
2338
2340
  last_accessed_at: now,
2339
2341
  created_at: now,
@@ -2403,6 +2405,52 @@ var MemoryService = class {
2403
2405
  limit
2404
2406
  };
2405
2407
  }
2408
+ // ── By Time (chronological sort) ───────────────────────────────────
2409
+ async byTime(input) {
2410
+ const limit = input.limit ?? 50;
2411
+ const offset = input.offset ?? 0;
2412
+ const direction = input.direction ?? "desc";
2413
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
2414
+ const ghostFilters = [];
2415
+ if (input.ghost_context) {
2416
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2417
+ }
2418
+ if (!input.ghost_context?.include_ghost_content) {
2419
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2420
+ }
2421
+ const executeQuery = async (useDeletedFilter) => {
2422
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
2423
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2424
+ const queryOptions = {
2425
+ limit: limit + offset,
2426
+ sort: [
2427
+ {
2428
+ property: "created_at",
2429
+ order: direction
2430
+ }
2431
+ ]
2432
+ };
2433
+ if (combinedFilters) {
2434
+ queryOptions.filters = combinedFilters;
2435
+ }
2436
+ return this.collection.query.fetchObjects(queryOptions);
2437
+ };
2438
+ const results = await this.retryWithoutDeletedFilter(executeQuery);
2439
+ const paginated = results.objects.slice(offset);
2440
+ const memories = [];
2441
+ for (const obj of paginated) {
2442
+ const doc = { id: obj.uuid, ...obj.properties };
2443
+ if (doc.doc_type === "memory") {
2444
+ memories.push(doc);
2445
+ }
2446
+ }
2447
+ return {
2448
+ memories,
2449
+ total: memories.length,
2450
+ offset,
2451
+ limit
2452
+ };
2453
+ }
2406
2454
  // ── Find Similar (vector) ──────────────────────────────────────────
2407
2455
  async findSimilar(input) {
2408
2456
  if (!input.memory_id && !input.text)
@@ -2619,6 +2667,33 @@ var RelationshipService = class {
2619
2667
  this.userId = userId;
2620
2668
  this.logger = logger2;
2621
2669
  }
2670
+ // ── Helper Methods ──────────────────────────────────────────────────
2671
+ /**
2672
+ * Update relationship_count for a memory by a delta (+1 or -1).
2673
+ * Ensures count never goes negative.
2674
+ */
2675
+ async updateRelationshipCount(memoryId, delta) {
2676
+ try {
2677
+ const memory = await this.collection.query.fetchObjectById(memoryId, {
2678
+ returnProperties: ["relationship_count"]
2679
+ });
2680
+ if (!memory) {
2681
+ this.logger.warn(`Memory ${memoryId} not found, skipping relationship_count update`);
2682
+ return;
2683
+ }
2684
+ const currentCount = memory.properties.relationship_count || 0;
2685
+ const newCount = Math.max(0, currentCount + delta);
2686
+ await this.collection.data.update({
2687
+ id: memoryId,
2688
+ properties: {
2689
+ relationship_count: newCount
2690
+ }
2691
+ });
2692
+ this.logger.debug(`Updated relationship_count for ${memoryId}: ${currentCount} -> ${newCount}`);
2693
+ } catch (error) {
2694
+ this.logger.error(`Failed to update relationship_count for ${memoryId}:`, { error: error?.message || String(error) });
2695
+ }
2696
+ }
2622
2697
  // ── Create ──────────────────────────────────────────────────────────
2623
2698
  async create(input) {
2624
2699
  if (input.memory_ids.length < 2) {
@@ -2658,6 +2733,7 @@ var RelationshipService = class {
2658
2733
  tags: input.tags || []
2659
2734
  };
2660
2735
  const relationshipId = await this.collection.data.insert({ properties });
2736
+ await Promise.all(input.memory_ids.map((memoryId) => this.updateRelationshipCount(memoryId, 1)));
2661
2737
  await Promise.all(checks.filter((c) => !c.error && c.memory).map(async (c) => {
2662
2738
  try {
2663
2739
  await this.collection.data.update({
@@ -2814,6 +2890,7 @@ var RelationshipService = class {
2814
2890
  throw new Error("Not a relationship document");
2815
2891
  const memoryIds = existing.properties.related_memory_ids || [];
2816
2892
  let memoriesUpdated = 0;
2893
+ await Promise.all(memoryIds.map((memoryId) => this.updateRelationshipCount(memoryId, -1)));
2817
2894
  await Promise.all(memoryIds.map(async (memoryId) => {
2818
2895
  try {
2819
2896
  const memory = await this.collection.query.fetchObjectById(memoryId, {
@@ -2911,6 +2988,7 @@ var COMMON_MEMORY_PROPERTIES = [
2911
2988
  // Relationships (v1 compat)
2912
2989
  { name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
2913
2990
  { name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
2991
+ { name: "relationship_count", dataType: configure.dataType.INT },
2914
2992
  // Access tracking
2915
2993
  { name: "access_count", dataType: configure.dataType.NUMBER },
2916
2994
  { name: "last_accessed_at", dataType: configure.dataType.DATE },
package/dist/server.js CHANGED
@@ -1544,22 +1544,22 @@ function buildDocTypeFilters(collection, docType, filters) {
1544
1544
  }
1545
1545
  }
1546
1546
  if (filters?.weight_min !== void 0) {
1547
- filterList.push(collection.filter.byProperty("weight").greaterThanOrEqual(filters.weight_min));
1547
+ filterList.push(collection.filter.byProperty("weight").greaterOrEqual(filters.weight_min));
1548
1548
  }
1549
1549
  if (filters?.weight_max !== void 0) {
1550
- filterList.push(collection.filter.byProperty("weight").lessThanOrEqual(filters.weight_max));
1550
+ filterList.push(collection.filter.byProperty("weight").lessOrEqual(filters.weight_max));
1551
1551
  }
1552
1552
  if (filters?.trust_min !== void 0) {
1553
- filterList.push(collection.filter.byProperty("trust_score").greaterThanOrEqual(filters.trust_min));
1553
+ filterList.push(collection.filter.byProperty("trust_score").greaterOrEqual(filters.trust_min));
1554
1554
  }
1555
1555
  if (filters?.trust_max !== void 0) {
1556
- filterList.push(collection.filter.byProperty("trust_score").lessThanOrEqual(filters.trust_max));
1556
+ filterList.push(collection.filter.byProperty("trust_score").lessOrEqual(filters.trust_max));
1557
1557
  }
1558
1558
  if (filters?.date_from) {
1559
- filterList.push(collection.filter.byProperty("created_at").greaterThanOrEqual(new Date(filters.date_from)));
1559
+ filterList.push(collection.filter.byProperty("created_at").greaterOrEqual(new Date(filters.date_from)));
1560
1560
  }
1561
1561
  if (filters?.date_to) {
1562
- filterList.push(collection.filter.byProperty("created_at").lessThanOrEqual(new Date(filters.date_to)));
1562
+ filterList.push(collection.filter.byProperty("created_at").lessOrEqual(new Date(filters.date_to)));
1563
1563
  }
1564
1564
  if (filters?.tags && filters.tags.length > 0) {
1565
1565
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
@@ -1920,6 +1920,7 @@ var ALL_MEMORY_PROPERTIES = [
1920
1920
  "related_memory_ids",
1921
1921
  "relationships",
1922
1922
  "memory_ids",
1923
+ "relationship_count",
1923
1924
  "relationship_type",
1924
1925
  "observation",
1925
1926
  "strength",
@@ -1965,7 +1966,7 @@ async function fetchMemoryWithAllProperties(collection, memoryId) {
1965
1966
 
1966
1967
  // node_modules/@prmichaelsen/remember-core/dist/services/trust-enforcement.service.js
1967
1968
  function buildTrustFilter(collection, accessorTrustLevel) {
1968
- return collection.filter.byProperty("trust_score").lessThanOrEqual(accessorTrustLevel);
1969
+ return collection.filter.byProperty("trust_score").lessOrEqual(accessorTrustLevel);
1969
1970
  }
1970
1971
 
1971
1972
  // node_modules/@prmichaelsen/remember-core/dist/services/memory.service.js
@@ -2018,6 +2019,7 @@ var MemoryService = class {
2018
2019
  context_summary: input.context_summary || "Memory created",
2019
2020
  context_conversation_id: input.context_conversation_id,
2020
2021
  relationship_ids: [],
2022
+ relationship_count: 0,
2021
2023
  access_count: 0,
2022
2024
  last_accessed_at: now,
2023
2025
  created_at: now,
@@ -2087,6 +2089,52 @@ var MemoryService = class {
2087
2089
  limit
2088
2090
  };
2089
2091
  }
2092
+ // ── By Time (chronological sort) ───────────────────────────────────
2093
+ async byTime(input) {
2094
+ const limit = input.limit ?? 50;
2095
+ const offset = input.offset ?? 0;
2096
+ const direction = input.direction ?? "desc";
2097
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
2098
+ const ghostFilters = [];
2099
+ if (input.ghost_context) {
2100
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2101
+ }
2102
+ if (!input.ghost_context?.include_ghost_content) {
2103
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2104
+ }
2105
+ const executeQuery = async (useDeletedFilter) => {
2106
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
2107
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2108
+ const queryOptions = {
2109
+ limit: limit + offset,
2110
+ sort: [
2111
+ {
2112
+ property: "created_at",
2113
+ order: direction
2114
+ }
2115
+ ]
2116
+ };
2117
+ if (combinedFilters) {
2118
+ queryOptions.filters = combinedFilters;
2119
+ }
2120
+ return this.collection.query.fetchObjects(queryOptions);
2121
+ };
2122
+ const results = await this.retryWithoutDeletedFilter(executeQuery);
2123
+ const paginated = results.objects.slice(offset);
2124
+ const memories = [];
2125
+ for (const obj of paginated) {
2126
+ const doc = { id: obj.uuid, ...obj.properties };
2127
+ if (doc.doc_type === "memory") {
2128
+ memories.push(doc);
2129
+ }
2130
+ }
2131
+ return {
2132
+ memories,
2133
+ total: memories.length,
2134
+ offset,
2135
+ limit
2136
+ };
2137
+ }
2090
2138
  // ── Find Similar (vector) ──────────────────────────────────────────
2091
2139
  async findSimilar(input) {
2092
2140
  if (!input.memory_id && !input.text)
@@ -2303,6 +2351,33 @@ var RelationshipService = class {
2303
2351
  this.userId = userId;
2304
2352
  this.logger = logger2;
2305
2353
  }
2354
+ // ── Helper Methods ──────────────────────────────────────────────────
2355
+ /**
2356
+ * Update relationship_count for a memory by a delta (+1 or -1).
2357
+ * Ensures count never goes negative.
2358
+ */
2359
+ async updateRelationshipCount(memoryId, delta) {
2360
+ try {
2361
+ const memory = await this.collection.query.fetchObjectById(memoryId, {
2362
+ returnProperties: ["relationship_count"]
2363
+ });
2364
+ if (!memory) {
2365
+ this.logger.warn(`Memory ${memoryId} not found, skipping relationship_count update`);
2366
+ return;
2367
+ }
2368
+ const currentCount = memory.properties.relationship_count || 0;
2369
+ const newCount = Math.max(0, currentCount + delta);
2370
+ await this.collection.data.update({
2371
+ id: memoryId,
2372
+ properties: {
2373
+ relationship_count: newCount
2374
+ }
2375
+ });
2376
+ this.logger.debug(`Updated relationship_count for ${memoryId}: ${currentCount} -> ${newCount}`);
2377
+ } catch (error) {
2378
+ this.logger.error(`Failed to update relationship_count for ${memoryId}:`, { error: error?.message || String(error) });
2379
+ }
2380
+ }
2306
2381
  // ── Create ──────────────────────────────────────────────────────────
2307
2382
  async create(input) {
2308
2383
  if (input.memory_ids.length < 2) {
@@ -2342,6 +2417,7 @@ var RelationshipService = class {
2342
2417
  tags: input.tags || []
2343
2418
  };
2344
2419
  const relationshipId = await this.collection.data.insert({ properties });
2420
+ await Promise.all(input.memory_ids.map((memoryId) => this.updateRelationshipCount(memoryId, 1)));
2345
2421
  await Promise.all(checks.filter((c) => !c.error && c.memory).map(async (c) => {
2346
2422
  try {
2347
2423
  await this.collection.data.update({
@@ -2498,6 +2574,7 @@ var RelationshipService = class {
2498
2574
  throw new Error("Not a relationship document");
2499
2575
  const memoryIds = existing.properties.related_memory_ids || [];
2500
2576
  let memoriesUpdated = 0;
2577
+ await Promise.all(memoryIds.map((memoryId) => this.updateRelationshipCount(memoryId, -1)));
2501
2578
  await Promise.all(memoryIds.map(async (memoryId) => {
2502
2579
  try {
2503
2580
  const memory = await this.collection.query.fetchObjectById(memoryId, {
@@ -2595,6 +2672,7 @@ var COMMON_MEMORY_PROPERTIES = [
2595
2672
  // Relationships (v1 compat)
2596
2673
  { name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
2597
2674
  { name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
2675
+ { name: "relationship_count", dataType: configure.dataType.INT },
2598
2676
  // Access tracking
2599
2677
  { name: "access_count", dataType: configure.dataType.NUMBER },
2600
2678
  { name: "last_accessed_at", dataType: configure.dataType.DATE },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "3.14.8",
3
+ "version": "3.14.9",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -50,7 +50,7 @@
50
50
  "@modelcontextprotocol/sdk": "^1.0.4",
51
51
  "@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
52
52
  "@prmichaelsen/mcp-auth": "^7.0.4",
53
- "@prmichaelsen/remember-core": "^0.19.14",
53
+ "@prmichaelsen/remember-core": "^0.22.3",
54
54
  "@prmichaelsen/remember-mcp": "^2.7.3",
55
55
  "dotenv": "^16.4.5",
56
56
  "uuid": "^13.0.0",