@prmichaelsen/remember-mcp 3.14.19 → 3.14.20

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.
@@ -886,7 +886,7 @@ var DEFAULT_PREFERENCES = {
886
886
  share_with_memories: true
887
887
  },
888
888
  privacy: {
889
- default_trust_level: 0.25,
889
+ default_trust_level: 2,
890
890
  allow_cross_user_access: false,
891
891
  auto_approve_requests: false,
892
892
  audit_logging: true
@@ -905,6 +905,14 @@ var DEFAULT_PREFERENCES = {
905
905
  }
906
906
  };
907
907
 
908
+ // node_modules/@prmichaelsen/remember-core/dist/types/rating.types.js
909
+ var RATING_MIN_THRESHOLD = 5;
910
+ function computeRatingAvg(ratingSum, ratingCount) {
911
+ if (ratingCount < RATING_MIN_THRESHOLD)
912
+ return null;
913
+ return ratingSum / ratingCount;
914
+ }
915
+
908
916
  // node_modules/@prmichaelsen/remember-core/dist/types/space.types.js
909
917
  var SUPPORTED_SPACES = [
910
918
  "the_void",
@@ -1361,6 +1369,35 @@ var DebugLevel2;
1361
1369
  DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
1362
1370
  })(DebugLevel2 || (DebugLevel2 = {}));
1363
1371
 
1372
+ // node_modules/@prmichaelsen/remember-core/dist/errors/base.error.js
1373
+ var AppError = class extends Error {
1374
+ context;
1375
+ constructor(message, context = {}) {
1376
+ super(message);
1377
+ this.context = context;
1378
+ this.name = this.constructor.name;
1379
+ Object.setPrototypeOf(this, new.target.prototype);
1380
+ }
1381
+ toJSON() {
1382
+ return {
1383
+ kind: this.kind,
1384
+ name: this.name,
1385
+ message: this.message,
1386
+ context: this.context
1387
+ };
1388
+ }
1389
+ };
1390
+
1391
+ // node_modules/@prmichaelsen/remember-core/dist/errors/app-errors.js
1392
+ var ValidationError = class extends AppError {
1393
+ fields;
1394
+ kind = "validation";
1395
+ constructor(message, fields = {}) {
1396
+ super(message, { fields });
1397
+ this.fields = fields;
1398
+ }
1399
+ };
1400
+
1364
1401
  // node_modules/@prmichaelsen/remember-core/node_modules/uuid/dist/esm/regex.js
1365
1402
  var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
1366
1403
 
@@ -1637,6 +1674,9 @@ function buildDocTypeFilters(collection, docType, filters) {
1637
1674
  if (filters?.relationship_count_max !== void 0) {
1638
1675
  filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
1639
1676
  }
1677
+ if (filters?.rating_min !== void 0) {
1678
+ filterList.push(collection.filter.byProperty("rating_bayesian").greaterOrEqual(filters.rating_min));
1679
+ }
1640
1680
  if (filters?.tags && filters.tags.length > 0) {
1641
1681
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
1642
1682
  }
@@ -2004,6 +2044,9 @@ var ALL_MEMORY_PROPERTIES = [
2004
2044
  "observation",
2005
2045
  "strength",
2006
2046
  "source",
2047
+ "rating_sum",
2048
+ "rating_count",
2049
+ "rating_bayesian",
2007
2050
  "access_count",
2008
2051
  "last_accessed_at",
2009
2052
  "tags",
@@ -2053,6 +2096,11 @@ function normalizeDoc(doc) {
2053
2096
  if ("trust_score" in doc) {
2054
2097
  doc.trust_score = normalizeTrustScore(doc.trust_score);
2055
2098
  }
2099
+ const ratingSum = doc.rating_sum;
2100
+ const ratingCount = doc.rating_count;
2101
+ if (ratingSum !== void 0 && ratingCount !== void 0) {
2102
+ doc.rating_avg = computeRatingAvg(ratingSum, ratingCount);
2103
+ }
2056
2104
  return doc;
2057
2105
  }
2058
2106
  var MemoryService = class {
@@ -2125,12 +2173,16 @@ var MemoryService = class {
2125
2173
  summary: input.title,
2126
2174
  content_type: contentType,
2127
2175
  weight: input.weight ?? 0.5,
2128
- trust_score: input.trust ?? TrustLevel.INTERNAL,
2176
+ trust_score: normalizeTrustScore(input.trust ?? TrustLevel.INTERNAL),
2129
2177
  confidence: 1,
2130
2178
  context_summary: input.context_summary || "Memory created",
2131
2179
  context_conversation_id: input.context_conversation_id,
2132
2180
  relationship_ids: [],
2133
2181
  relationship_count: 0,
2182
+ rating_sum: 0,
2183
+ rating_count: 0,
2184
+ rating_bayesian: 3,
2185
+ // (0 + 15) / (0 + 5) = 3.0 (prior mean)
2134
2186
  access_count: 0,
2135
2187
  last_accessed_at: now,
2136
2188
  created_at: now,
@@ -2294,6 +2346,47 @@ var MemoryService = class {
2294
2346
  limit
2295
2347
  };
2296
2348
  }
2349
+ // ── By Rating (Bayesian average) ─────────────────────────────────
2350
+ async byRating(input) {
2351
+ const limit = input.limit ?? 50;
2352
+ const offset = input.offset ?? 0;
2353
+ const direction = input.direction ?? "desc";
2354
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
2355
+ const ghostFilters = [];
2356
+ if (input.ghost_context) {
2357
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2358
+ }
2359
+ if (!input.ghost_context?.include_ghost_content) {
2360
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2361
+ }
2362
+ const executeQuery = async (useDeletedFilter) => {
2363
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
2364
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2365
+ const queryOptions = {
2366
+ limit: limit + offset,
2367
+ sort: this.collection.sort.byProperty("rating_bayesian", direction === "asc")
2368
+ };
2369
+ if (combinedFilters) {
2370
+ queryOptions.filters = combinedFilters;
2371
+ }
2372
+ return this.collection.query.fetchObjects(queryOptions);
2373
+ };
2374
+ const results = await this.retryWithoutDeletedFilter(executeQuery);
2375
+ const paginated = results.objects.slice(offset);
2376
+ const memories = [];
2377
+ for (const obj of paginated) {
2378
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
2379
+ if (doc.doc_type === "memory") {
2380
+ memories.push(doc);
2381
+ }
2382
+ }
2383
+ return {
2384
+ memories,
2385
+ total: memories.length,
2386
+ offset,
2387
+ limit
2388
+ };
2389
+ }
2297
2390
  // ── Find Similar (vector) ──────────────────────────────────────────
2298
2391
  async findSimilar(input) {
2299
2392
  if (!input.memory_id && !input.text)
@@ -2869,6 +2962,10 @@ var COMMON_MEMORY_PROPERTIES = [
2869
2962
  { name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
2870
2963
  { name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
2871
2964
  { name: "relationship_count", dataType: configure.dataType.INT },
2965
+ // Rating aggregates (denormalized from Firestore individual ratings)
2966
+ { name: "rating_sum", dataType: configure.dataType.INT },
2967
+ { name: "rating_count", dataType: configure.dataType.INT },
2968
+ { name: "rating_bayesian", dataType: configure.dataType.NUMBER },
2872
2969
  // Access tracking
2873
2970
  { name: "access_count", dataType: configure.dataType.NUMBER },
2874
2971
  { name: "last_accessed_at", dataType: configure.dataType.DATE },
@@ -3045,12 +3142,26 @@ var SpaceService = class {
3045
3142
  userId;
3046
3143
  confirmationTokenService;
3047
3144
  logger;
3048
- constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2) {
3145
+ moderationClient;
3146
+ constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2, options) {
3049
3147
  this.weaviateClient = weaviateClient;
3050
3148
  this.userCollection = userCollection;
3051
3149
  this.userId = userId;
3052
3150
  this.confirmationTokenService = confirmationTokenService;
3053
3151
  this.logger = logger2;
3152
+ this.moderationClient = options?.moderationClient;
3153
+ }
3154
+ // ── Content moderation helper ────────────────────────────────────────
3155
+ async checkModeration(content) {
3156
+ if (!this.moderationClient)
3157
+ return;
3158
+ const result = await this.moderationClient.moderate(content);
3159
+ if (!result.pass) {
3160
+ throw new ValidationError(result.reason, {
3161
+ moderation: ["blocked"],
3162
+ ...result.category ? { category: [result.category] } : {}
3163
+ });
3164
+ }
3054
3165
  }
3055
3166
  // ── Publish (phase 1: generate confirmation token) ──────────────────
3056
3167
  async publish(input) {
@@ -3085,6 +3196,7 @@ var SpaceService = class {
3085
3196
  throw new Error(`Space '${spaceId}' only accepts content_type '${requiredType}', got '${memoryContentType ?? "undefined"}'`);
3086
3197
  }
3087
3198
  }
3199
+ await this.checkModeration(memory.properties.content);
3088
3200
  const { token } = await this.confirmationTokenService.createRequest(this.userId, "publish_memory", {
3089
3201
  memory_id: input.memory_id,
3090
3202
  spaces,
@@ -3151,6 +3263,7 @@ var SpaceService = class {
3151
3263
  if (spaceIds.length === 0 && groupIds.length === 0) {
3152
3264
  throw new Error("Memory has no published copies to revise. Publish first with publish().");
3153
3265
  }
3266
+ await this.checkModeration(memory.properties.content);
3154
3267
  const { token } = await this.confirmationTokenService.createRequest(this.userId, "revise_memory", {
3155
3268
  memory_id: input.memory_id,
3156
3269
  space_ids: spaceIds,
package/dist/server.js CHANGED
@@ -890,7 +890,7 @@ var DEFAULT_PREFERENCES = {
890
890
  share_with_memories: true
891
891
  },
892
892
  privacy: {
893
- default_trust_level: 0.25,
893
+ default_trust_level: 2,
894
894
  allow_cross_user_access: false,
895
895
  auto_approve_requests: false,
896
896
  audit_logging: true
@@ -909,6 +909,14 @@ var DEFAULT_PREFERENCES = {
909
909
  }
910
910
  };
911
911
 
912
+ // node_modules/@prmichaelsen/remember-core/dist/types/rating.types.js
913
+ var RATING_MIN_THRESHOLD = 5;
914
+ function computeRatingAvg(ratingSum, ratingCount) {
915
+ if (ratingCount < RATING_MIN_THRESHOLD)
916
+ return null;
917
+ return ratingSum / ratingCount;
918
+ }
919
+
912
920
  // node_modules/@prmichaelsen/remember-core/dist/types/space.types.js
913
921
  var SUPPORTED_SPACES = [
914
922
  "the_void",
@@ -1365,6 +1373,35 @@ var DebugLevel2;
1365
1373
  DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
1366
1374
  })(DebugLevel2 || (DebugLevel2 = {}));
1367
1375
 
1376
+ // node_modules/@prmichaelsen/remember-core/dist/errors/base.error.js
1377
+ var AppError = class extends Error {
1378
+ context;
1379
+ constructor(message, context = {}) {
1380
+ super(message);
1381
+ this.context = context;
1382
+ this.name = this.constructor.name;
1383
+ Object.setPrototypeOf(this, new.target.prototype);
1384
+ }
1385
+ toJSON() {
1386
+ return {
1387
+ kind: this.kind,
1388
+ name: this.name,
1389
+ message: this.message,
1390
+ context: this.context
1391
+ };
1392
+ }
1393
+ };
1394
+
1395
+ // node_modules/@prmichaelsen/remember-core/dist/errors/app-errors.js
1396
+ var ValidationError = class extends AppError {
1397
+ fields;
1398
+ kind = "validation";
1399
+ constructor(message, fields = {}) {
1400
+ super(message, { fields });
1401
+ this.fields = fields;
1402
+ }
1403
+ };
1404
+
1368
1405
  // node_modules/@prmichaelsen/remember-core/node_modules/uuid/dist/esm/regex.js
1369
1406
  var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
1370
1407
 
@@ -1641,6 +1678,9 @@ function buildDocTypeFilters(collection, docType, filters) {
1641
1678
  if (filters?.relationship_count_max !== void 0) {
1642
1679
  filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
1643
1680
  }
1681
+ if (filters?.rating_min !== void 0) {
1682
+ filterList.push(collection.filter.byProperty("rating_bayesian").greaterOrEqual(filters.rating_min));
1683
+ }
1644
1684
  if (filters?.tags && filters.tags.length > 0) {
1645
1685
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
1646
1686
  }
@@ -2008,6 +2048,9 @@ var ALL_MEMORY_PROPERTIES = [
2008
2048
  "observation",
2009
2049
  "strength",
2010
2050
  "source",
2051
+ "rating_sum",
2052
+ "rating_count",
2053
+ "rating_bayesian",
2011
2054
  "access_count",
2012
2055
  "last_accessed_at",
2013
2056
  "tags",
@@ -2057,6 +2100,11 @@ function normalizeDoc(doc) {
2057
2100
  if ("trust_score" in doc) {
2058
2101
  doc.trust_score = normalizeTrustScore(doc.trust_score);
2059
2102
  }
2103
+ const ratingSum = doc.rating_sum;
2104
+ const ratingCount = doc.rating_count;
2105
+ if (ratingSum !== void 0 && ratingCount !== void 0) {
2106
+ doc.rating_avg = computeRatingAvg(ratingSum, ratingCount);
2107
+ }
2060
2108
  return doc;
2061
2109
  }
2062
2110
  var MemoryService = class {
@@ -2129,12 +2177,16 @@ var MemoryService = class {
2129
2177
  summary: input.title,
2130
2178
  content_type: contentType,
2131
2179
  weight: input.weight ?? 0.5,
2132
- trust_score: input.trust ?? TrustLevel.INTERNAL,
2180
+ trust_score: normalizeTrustScore(input.trust ?? TrustLevel.INTERNAL),
2133
2181
  confidence: 1,
2134
2182
  context_summary: input.context_summary || "Memory created",
2135
2183
  context_conversation_id: input.context_conversation_id,
2136
2184
  relationship_ids: [],
2137
2185
  relationship_count: 0,
2186
+ rating_sum: 0,
2187
+ rating_count: 0,
2188
+ rating_bayesian: 3,
2189
+ // (0 + 15) / (0 + 5) = 3.0 (prior mean)
2138
2190
  access_count: 0,
2139
2191
  last_accessed_at: now,
2140
2192
  created_at: now,
@@ -2298,6 +2350,47 @@ var MemoryService = class {
2298
2350
  limit
2299
2351
  };
2300
2352
  }
2353
+ // ── By Rating (Bayesian average) ─────────────────────────────────
2354
+ async byRating(input) {
2355
+ const limit = input.limit ?? 50;
2356
+ const offset = input.offset ?? 0;
2357
+ const direction = input.direction ?? "desc";
2358
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
2359
+ const ghostFilters = [];
2360
+ if (input.ghost_context) {
2361
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2362
+ }
2363
+ if (!input.ghost_context?.include_ghost_content) {
2364
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2365
+ }
2366
+ const executeQuery = async (useDeletedFilter) => {
2367
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
2368
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2369
+ const queryOptions = {
2370
+ limit: limit + offset,
2371
+ sort: this.collection.sort.byProperty("rating_bayesian", direction === "asc")
2372
+ };
2373
+ if (combinedFilters) {
2374
+ queryOptions.filters = combinedFilters;
2375
+ }
2376
+ return this.collection.query.fetchObjects(queryOptions);
2377
+ };
2378
+ const results = await this.retryWithoutDeletedFilter(executeQuery);
2379
+ const paginated = results.objects.slice(offset);
2380
+ const memories = [];
2381
+ for (const obj of paginated) {
2382
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
2383
+ if (doc.doc_type === "memory") {
2384
+ memories.push(doc);
2385
+ }
2386
+ }
2387
+ return {
2388
+ memories,
2389
+ total: memories.length,
2390
+ offset,
2391
+ limit
2392
+ };
2393
+ }
2301
2394
  // ── Find Similar (vector) ──────────────────────────────────────────
2302
2395
  async findSimilar(input) {
2303
2396
  if (!input.memory_id && !input.text)
@@ -2873,6 +2966,10 @@ var COMMON_MEMORY_PROPERTIES = [
2873
2966
  { name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
2874
2967
  { name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
2875
2968
  { name: "relationship_count", dataType: configure.dataType.INT },
2969
+ // Rating aggregates (denormalized from Firestore individual ratings)
2970
+ { name: "rating_sum", dataType: configure.dataType.INT },
2971
+ { name: "rating_count", dataType: configure.dataType.INT },
2972
+ { name: "rating_bayesian", dataType: configure.dataType.NUMBER },
2876
2973
  // Access tracking
2877
2974
  { name: "access_count", dataType: configure.dataType.NUMBER },
2878
2975
  { name: "last_accessed_at", dataType: configure.dataType.DATE },
@@ -3049,12 +3146,26 @@ var SpaceService = class {
3049
3146
  userId;
3050
3147
  confirmationTokenService;
3051
3148
  logger;
3052
- constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2) {
3149
+ moderationClient;
3150
+ constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2, options) {
3053
3151
  this.weaviateClient = weaviateClient;
3054
3152
  this.userCollection = userCollection;
3055
3153
  this.userId = userId;
3056
3154
  this.confirmationTokenService = confirmationTokenService;
3057
3155
  this.logger = logger2;
3156
+ this.moderationClient = options?.moderationClient;
3157
+ }
3158
+ // ── Content moderation helper ────────────────────────────────────────
3159
+ async checkModeration(content) {
3160
+ if (!this.moderationClient)
3161
+ return;
3162
+ const result = await this.moderationClient.moderate(content);
3163
+ if (!result.pass) {
3164
+ throw new ValidationError(result.reason, {
3165
+ moderation: ["blocked"],
3166
+ ...result.category ? { category: [result.category] } : {}
3167
+ });
3168
+ }
3058
3169
  }
3059
3170
  // ── Publish (phase 1: generate confirmation token) ──────────────────
3060
3171
  async publish(input) {
@@ -3089,6 +3200,7 @@ var SpaceService = class {
3089
3200
  throw new Error(`Space '${spaceId}' only accepts content_type '${requiredType}', got '${memoryContentType ?? "undefined"}'`);
3090
3201
  }
3091
3202
  }
3203
+ await this.checkModeration(memory.properties.content);
3092
3204
  const { token } = await this.confirmationTokenService.createRequest(this.userId, "publish_memory", {
3093
3205
  memory_id: input.memory_id,
3094
3206
  spaces,
@@ -3155,6 +3267,7 @@ var SpaceService = class {
3155
3267
  if (spaceIds.length === 0 && groupIds.length === 0) {
3156
3268
  throw new Error("Memory has no published copies to revise. Publish first with publish().");
3157
3269
  }
3270
+ await this.checkModeration(memory.properties.content);
3158
3271
  const { token } = await this.confirmationTokenService.createRequest(this.userId, "revise_memory", {
3159
3272
  memory_id: input.memory_id,
3160
3273
  space_ids: spaceIds,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "3.14.19",
3
+ "version": "3.14.20",
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.30.0",
53
+ "@prmichaelsen/remember-core": "^0.32.1",
54
54
  "dotenv": "^16.4.5",
55
55
  "uuid": "^13.0.0",
56
56
  "weaviate-client": "^3.2.0"