@prmichaelsen/remember-mcp 3.14.0 → 3.14.1

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/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.14.0] - 2026-02-28
9
+
10
+ ### Changed
11
+
12
+ **remember-core Migration (M17)**
13
+
14
+ - Migrate 18 tool handlers to `@prmichaelsen/remember-core` service layer — tools are now thin adapters delegating to core services
15
+ - Replace local services (ConfirmationTokenService, PreferencesDatabaseService, SpaceConfigService) with remember-core equivalents
16
+ - Replace local utilities (dot-notation, composite-ids, tracking-arrays, content-types) with remember-core exports
17
+
18
+ ### Removed
19
+
20
+ - `src/services/confirmation-token.service.ts` — now provided by remember-core
21
+ - `src/services/preferences-database.service.ts` — now provided by remember-core
22
+ - `src/services/space-config.service.ts` — now provided by remember-core
23
+ - `src/constants/content-types.ts` — now provided by remember-core
24
+ - `src/collections/` directory (dot-notation, composite-ids, tracking-arrays) — now provided by remember-core
25
+
26
+ ### Fixed
27
+
28
+ - Add `uuid` as direct dependency to resolve esbuild bundling error from remember-core transitive dependency
29
+
8
30
  ## [3.13.0] - 2026-02-28
9
31
 
10
32
  ### Changed
@@ -117,7 +117,7 @@ var require_main = __commonJS({
117
117
  var packageJson = require_package();
118
118
  var version = packageJson.version;
119
119
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
120
- function parse(src) {
120
+ function parse2(src) {
121
121
  const obj = {};
122
122
  let lines = src.toString();
123
123
  lines = lines.replace(/\r\n?/mg, "\n");
@@ -383,7 +383,7 @@ var require_main = __commonJS({
383
383
  _parseVault,
384
384
  config: config2,
385
385
  decrypt,
386
- parse,
386
+ parse: parse2,
387
387
  populate
388
388
  };
389
389
  module.exports.configDotenv = DotenvModule.configDotenv;
@@ -1585,7 +1585,92 @@ var DebugLevel2;
1585
1585
  DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
1586
1586
  })(DebugLevel2 || (DebugLevel2 = {}));
1587
1587
 
1588
+ // node_modules/uuid/dist-node/regex.js
1589
+ 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;
1590
+
1591
+ // node_modules/uuid/dist-node/validate.js
1592
+ function validate(uuid) {
1593
+ return typeof uuid === "string" && regex_default.test(uuid);
1594
+ }
1595
+ var validate_default = validate;
1596
+
1597
+ // node_modules/uuid/dist-node/parse.js
1598
+ function parse(uuid) {
1599
+ if (!validate_default(uuid)) {
1600
+ throw TypeError("Invalid UUID");
1601
+ }
1602
+ let v;
1603
+ return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, v >>> 16 & 255, v >>> 8 & 255, v & 255, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255, v / 4294967296 & 255, v >>> 24 & 255, v >>> 16 & 255, v >>> 8 & 255, v & 255);
1604
+ }
1605
+ var parse_default = parse;
1606
+
1607
+ // node_modules/uuid/dist-node/stringify.js
1608
+ var byteToHex = [];
1609
+ for (let i = 0; i < 256; ++i) {
1610
+ byteToHex.push((i + 256).toString(16).slice(1));
1611
+ }
1612
+ function unsafeStringify(arr, offset = 0) {
1613
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
1614
+ }
1615
+
1616
+ // node_modules/uuid/dist-node/v35.js
1617
+ function stringToBytes(str) {
1618
+ str = unescape(encodeURIComponent(str));
1619
+ const bytes = new Uint8Array(str.length);
1620
+ for (let i = 0; i < str.length; ++i) {
1621
+ bytes[i] = str.charCodeAt(i);
1622
+ }
1623
+ return bytes;
1624
+ }
1625
+ var DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
1626
+ var URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
1627
+ function v35(version, hash, value, namespace, buf, offset) {
1628
+ const valueBytes = typeof value === "string" ? stringToBytes(value) : value;
1629
+ const namespaceBytes = typeof namespace === "string" ? parse_default(namespace) : namespace;
1630
+ if (typeof namespace === "string") {
1631
+ namespace = parse_default(namespace);
1632
+ }
1633
+ if (namespace?.length !== 16) {
1634
+ throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");
1635
+ }
1636
+ let bytes = new Uint8Array(16 + valueBytes.length);
1637
+ bytes.set(namespaceBytes);
1638
+ bytes.set(valueBytes, namespaceBytes.length);
1639
+ bytes = hash(bytes);
1640
+ bytes[6] = bytes[6] & 15 | version;
1641
+ bytes[8] = bytes[8] & 63 | 128;
1642
+ if (buf) {
1643
+ offset = offset || 0;
1644
+ for (let i = 0; i < 16; ++i) {
1645
+ buf[offset + i] = bytes[i];
1646
+ }
1647
+ return buf;
1648
+ }
1649
+ return unsafeStringify(bytes);
1650
+ }
1651
+
1652
+ // node_modules/uuid/dist-node/sha1.js
1653
+ import { createHash } from "node:crypto";
1654
+ function sha1(bytes) {
1655
+ if (Array.isArray(bytes)) {
1656
+ bytes = Buffer.from(bytes);
1657
+ } else if (typeof bytes === "string") {
1658
+ bytes = Buffer.from(bytes, "utf8");
1659
+ }
1660
+ return createHash("sha1").update(bytes).digest();
1661
+ }
1662
+ var sha1_default = sha1;
1663
+
1664
+ // node_modules/uuid/dist-node/v5.js
1665
+ function v5(value, namespace, buf, offset) {
1666
+ return v35(80, sha1_default, value, namespace, buf, offset);
1667
+ }
1668
+ v5.DNS = DNS;
1669
+ v5.URL = URL2;
1670
+ var v5_default = v5;
1671
+
1588
1672
  // node_modules/@prmichaelsen/remember-core/dist/collections/composite-ids.js
1673
+ var WEAVIATE_UUID_NAMESPACE = v5_default.DNS;
1589
1674
  var InvalidCompositeIdError = class extends Error {
1590
1675
  constructor(message) {
1591
1676
  super(message);
@@ -1607,6 +1692,28 @@ function generateCompositeId(userId, memoryId) {
1607
1692
  }
1608
1693
  return `${userId}.${memoryId}`;
1609
1694
  }
1695
+ function parseCompositeId(compositeId) {
1696
+ const parts = compositeId.split(".");
1697
+ if (parts.length !== 2) {
1698
+ throw new InvalidCompositeIdError(`Invalid composite ID format: ${compositeId}. Expected format: {userId}.{memoryId}`);
1699
+ }
1700
+ const [userId, memoryId] = parts;
1701
+ if (!userId.trim()) {
1702
+ throw new InvalidCompositeIdError(`Invalid composite ID: ${compositeId}. User ID is empty`);
1703
+ }
1704
+ if (!memoryId.trim()) {
1705
+ throw new InvalidCompositeIdError(`Invalid composite ID: ${compositeId}. Memory ID is empty`);
1706
+ }
1707
+ return { userId, memoryId };
1708
+ }
1709
+ function validateCompositeId(id) {
1710
+ parseCompositeId(id);
1711
+ return true;
1712
+ }
1713
+ function compositeIdToUuid(compositeId) {
1714
+ validateCompositeId(compositeId);
1715
+ return v5_default(compositeId, WEAVIATE_UUID_NAMESPACE);
1716
+ }
1610
1717
 
1611
1718
  // node_modules/@prmichaelsen/remember-core/dist/collections/dot-notation.js
1612
1719
  var CollectionType;
@@ -2134,6 +2241,11 @@ async function fetchMemoryWithAllProperties(collection, memoryId) {
2134
2241
  }
2135
2242
  }
2136
2243
 
2244
+ // node_modules/@prmichaelsen/remember-core/dist/services/trust-enforcement.service.js
2245
+ function buildTrustFilter(collection, accessorTrustLevel) {
2246
+ return collection.filter.byProperty("trust_score").lessThanOrEqual(accessorTrustLevel);
2247
+ }
2248
+
2137
2249
  // node_modules/@prmichaelsen/remember-core/dist/services/memory.service.js
2138
2250
  var MemoryService = class {
2139
2251
  collection;
@@ -2191,7 +2303,14 @@ var MemoryService = class {
2191
2303
  const offset = input.offset ?? 0;
2192
2304
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
2193
2305
  const searchFilters = includeRelationships ? buildCombinedSearchFilters(this.collection, input.filters) : buildMemoryOnlyFilters(this.collection, input.filters);
2194
- const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters].filter((f) => f !== null));
2306
+ const ghostFilters = [];
2307
+ if (input.ghost_context) {
2308
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2309
+ }
2310
+ if (!input.ghost_context?.include_ghost_content) {
2311
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2312
+ }
2313
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
2195
2314
  const searchOptions = { alpha, limit: limit + offset };
2196
2315
  if (combinedFilters)
2197
2316
  searchOptions.filters = combinedFilters;
@@ -2223,6 +2342,14 @@ var MemoryService = class {
2223
2342
  const limit = input.limit ?? 10;
2224
2343
  const minSimilarity = input.min_similarity ?? 0.7;
2225
2344
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
2345
+ const ghostFilters = [];
2346
+ if (input.ghost_context) {
2347
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2348
+ }
2349
+ if (!input.ghost_context?.include_ghost_content) {
2350
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2351
+ }
2352
+ const combinedFilter = combineFiltersWithAnd([deletedFilter, ...ghostFilters].filter((f) => f !== null));
2226
2353
  let results;
2227
2354
  if (input.memory_id) {
2228
2355
  const memory = await this.collection.query.fetchObjectById(input.memory_id, {
@@ -2235,14 +2362,14 @@ var MemoryService = class {
2235
2362
  if (memory.properties.doc_type !== "memory")
2236
2363
  throw new Error("Can only find similar for memory documents");
2237
2364
  const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
2238
- if (deletedFilter)
2239
- opts.filters = deletedFilter;
2365
+ if (combinedFilter)
2366
+ opts.filters = combinedFilter;
2240
2367
  results = await this.collection.query.nearObject(input.memory_id, opts);
2241
2368
  results.objects = results.objects.filter((o) => o.uuid !== input.memory_id);
2242
2369
  } else {
2243
2370
  const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
2244
- if (deletedFilter)
2245
- opts.filters = deletedFilter;
2371
+ if (combinedFilter)
2372
+ opts.filters = combinedFilter;
2246
2373
  results = await this.collection.query.nearText(input.text, opts);
2247
2374
  }
2248
2375
  if (!input.include_relationships) {
@@ -2263,7 +2390,14 @@ var MemoryService = class {
2263
2390
  const minRelevance = input.min_relevance ?? 0.6;
2264
2391
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
2265
2392
  const searchFilters = buildCombinedSearchFilters(this.collection, input.filters);
2266
- const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters].filter((f) => f !== null));
2393
+ const ghostFilters = [];
2394
+ if (input.ghost_context) {
2395
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2396
+ }
2397
+ if (!input.ghost_context?.include_ghost_content) {
2398
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2399
+ }
2400
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
2267
2401
  const opts = { limit, distance: 1 - minRelevance, returnMetadata: ["distance"] };
2268
2402
  if (combinedFilters)
2269
2403
  opts.filters = combinedFilters;
@@ -3112,6 +3246,7 @@ var SpaceService = class {
3112
3246
  if (originalMemory.properties.user_id !== this.userId)
3113
3247
  throw new Error("Permission denied");
3114
3248
  const compositeId = generateCompositeId(this.userId, request.payload.memory_id);
3249
+ const weaviateId = compositeIdToUuid(compositeId);
3115
3250
  const existingSpaceIds = Array.isArray(originalMemory.properties.space_ids) ? originalMemory.properties.space_ids : [];
3116
3251
  const existingGroupIds = Array.isArray(originalMemory.properties.group_ids) ? originalMemory.properties.group_ids : [];
3117
3252
  const originalTags = Array.isArray(originalMemory.properties.tags) ? originalMemory.properties.tags : [];
@@ -3124,7 +3259,7 @@ var SpaceService = class {
3124
3259
  const publicCollection = await ensurePublicCollection(this.weaviateClient);
3125
3260
  let existingSpaceMemory = null;
3126
3261
  try {
3127
- existingSpaceMemory = await fetchMemoryWithAllProperties(publicCollection, compositeId);
3262
+ existingSpaceMemory = await fetchMemoryWithAllProperties(publicCollection, weaviateId);
3128
3263
  } catch {
3129
3264
  }
3130
3265
  const newSpaceIds = [.../* @__PURE__ */ new Set([...existingSpaceIds, ...spaces])];
@@ -3138,7 +3273,7 @@ var SpaceService = class {
3138
3273
  }
3139
3274
  const publishedMemory = {
3140
3275
  ...originalMemory.properties,
3141
- id: compositeId,
3276
+ composite_id: compositeId,
3142
3277
  space_ids: newSpaceIds,
3143
3278
  group_ids: existingGroupIds,
3144
3279
  spaces,
@@ -3151,9 +3286,9 @@ var SpaceService = class {
3151
3286
  };
3152
3287
  delete publishedMemory._additional;
3153
3288
  if (existingSpaceMemory) {
3154
- await publicCollection.data.update({ id: compositeId, properties: publishedMemory });
3289
+ await publicCollection.data.update({ id: weaviateId, properties: publishedMemory });
3155
3290
  } else {
3156
- await publicCollection.data.insert({ id: compositeId, properties: publishedMemory });
3291
+ await publicCollection.data.insert({ id: weaviateId, properties: publishedMemory });
3157
3292
  }
3158
3293
  successfulPublications.push(`spaces: ${spaces.join(", ")}`);
3159
3294
  } catch (err2) {
@@ -3166,7 +3301,7 @@ var SpaceService = class {
3166
3301
  const groupCollection = this.weaviateClient.collections.get(groupCollectionName);
3167
3302
  let existingGroupMemory = null;
3168
3303
  try {
3169
- existingGroupMemory = await fetchMemoryWithAllProperties(groupCollection, compositeId);
3304
+ existingGroupMemory = await fetchMemoryWithAllProperties(groupCollection, weaviateId);
3170
3305
  } catch {
3171
3306
  }
3172
3307
  const newGroupIds = [.../* @__PURE__ */ new Set([...existingGroupIds, groupId])];
@@ -3174,7 +3309,7 @@ var SpaceService = class {
3174
3309
  const groupModerationStatus = groupConfig.require_moderation ? "pending" : "approved";
3175
3310
  const groupMemory = {
3176
3311
  ...originalMemory.properties,
3177
- id: compositeId,
3312
+ composite_id: compositeId,
3178
3313
  space_ids: existingSpaceIds,
3179
3314
  group_ids: newGroupIds,
3180
3315
  author_id: this.userId,
@@ -3186,9 +3321,9 @@ var SpaceService = class {
3186
3321
  };
3187
3322
  delete groupMemory._additional;
3188
3323
  if (existingGroupMemory) {
3189
- await groupCollection.data.update({ id: compositeId, properties: groupMemory });
3324
+ await groupCollection.data.update({ id: weaviateId, properties: groupMemory });
3190
3325
  } else {
3191
- await groupCollection.data.insert({ id: compositeId, properties: groupMemory });
3326
+ await groupCollection.data.insert({ id: weaviateId, properties: groupMemory });
3192
3327
  }
3193
3328
  successfulPublications.push(`group: ${groupId}`);
3194
3329
  } catch (err2) {
@@ -3236,17 +3371,18 @@ var SpaceService = class {
3236
3371
  const currentSpaceIds = Array.isArray(sourceMemory.properties.space_ids) ? sourceMemory.properties.space_ids : [];
3237
3372
  const currentGroupIds = Array.isArray(sourceMemory.properties.group_ids) ? sourceMemory.properties.group_ids : [];
3238
3373
  const compositeId = generateCompositeId(this.userId, request.payload.memory_id);
3374
+ const weaviateId = compositeIdToUuid(compositeId);
3239
3375
  const successfulRetractions = [];
3240
3376
  const failedRetractions = [];
3241
3377
  if (spaces.length > 0) {
3242
3378
  try {
3243
3379
  const spacesCollectionName = getCollectionName(CollectionType.SPACES);
3244
3380
  const publicCollection = this.weaviateClient.collections.get(spacesCollectionName);
3245
- const publishedMemory = await fetchMemoryWithAllProperties(publicCollection, compositeId);
3381
+ const publishedMemory = await fetchMemoryWithAllProperties(publicCollection, weaviateId);
3246
3382
  if (publishedMemory) {
3247
3383
  const newSpaceIds = currentSpaceIds.filter((id) => !spaces.includes(id));
3248
3384
  await publicCollection.data.update({
3249
- id: compositeId,
3385
+ id: weaviateId,
3250
3386
  properties: { space_ids: newSpaceIds, retracted_at: (/* @__PURE__ */ new Date()).toISOString() }
3251
3387
  });
3252
3388
  successfulRetractions.push(`spaces: ${spaces.join(", ")}`);
@@ -3261,12 +3397,12 @@ var SpaceService = class {
3261
3397
  const groupCollectionName = getCollectionName(CollectionType.GROUPS, groupId);
3262
3398
  try {
3263
3399
  const groupCollection = this.weaviateClient.collections.get(groupCollectionName);
3264
- const groupMemory = await fetchMemoryWithAllProperties(groupCollection, compositeId);
3400
+ const groupMemory = await fetchMemoryWithAllProperties(groupCollection, weaviateId);
3265
3401
  if (groupMemory) {
3266
3402
  const groupMemoryGroupIds = Array.isArray(groupMemory.properties.group_ids) ? groupMemory.properties.group_ids : [];
3267
3403
  const newGroupIds = groupMemoryGroupIds.filter((id) => id !== groupId);
3268
3404
  await groupCollection.data.update({
3269
- id: compositeId,
3405
+ id: weaviateId,
3270
3406
  properties: { group_ids: newGroupIds, retracted_at: (/* @__PURE__ */ new Date()).toISOString() }
3271
3407
  });
3272
3408
  successfulRetractions.push(`group: ${groupId}`);
@@ -3317,11 +3453,12 @@ var SpaceService = class {
3317
3453
  const newContent = String(sourceMemory.properties.content ?? "");
3318
3454
  const revisedAt = (/* @__PURE__ */ new Date()).toISOString();
3319
3455
  const compositeId = generateCompositeId(this.userId, memory_id);
3456
+ const weaviateId = compositeIdToUuid(compositeId);
3320
3457
  const results = [];
3321
3458
  const reviseInCollection = async (collectionName, locationLabel) => {
3322
3459
  try {
3323
3460
  const collection = this.weaviateClient.collections.get(collectionName);
3324
- const publishedMemory = await fetchMemoryWithAllProperties(collection, compositeId);
3461
+ const publishedMemory = await fetchMemoryWithAllProperties(collection, weaviateId);
3325
3462
  if (!publishedMemory) {
3326
3463
  results.push({ location: locationLabel, status: "skipped", error: "Published copy not found" });
3327
3464
  return;
@@ -3333,7 +3470,7 @@ var SpaceService = class {
3333
3470
  }
3334
3471
  const currentRevisionCount = typeof publishedMemory.properties.revision_count === "number" ? publishedMemory.properties.revision_count : 0;
3335
3472
  await collection.data.update({
3336
- id: compositeId,
3473
+ id: weaviateId,
3337
3474
  properties: {
3338
3475
  content: newContent,
3339
3476
  revised_at: revisedAt,
package/dist/server.js CHANGED
@@ -118,7 +118,7 @@ var require_main = __commonJS({
118
118
  var packageJson = require_package();
119
119
  var version = packageJson.version;
120
120
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
121
- function parse(src) {
121
+ function parse2(src) {
122
122
  const obj = {};
123
123
  let lines = src.toString();
124
124
  lines = lines.replace(/\r\n?/mg, "\n");
@@ -384,7 +384,7 @@ var require_main = __commonJS({
384
384
  _parseVault,
385
385
  config: config3,
386
386
  decrypt,
387
- parse,
387
+ parse: parse2,
388
388
  populate
389
389
  };
390
390
  module.exports.configDotenv = DotenvModule.configDotenv;
@@ -1269,7 +1269,92 @@ var DebugLevel2;
1269
1269
  DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
1270
1270
  })(DebugLevel2 || (DebugLevel2 = {}));
1271
1271
 
1272
+ // node_modules/uuid/dist-node/regex.js
1273
+ 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;
1274
+
1275
+ // node_modules/uuid/dist-node/validate.js
1276
+ function validate(uuid) {
1277
+ return typeof uuid === "string" && regex_default.test(uuid);
1278
+ }
1279
+ var validate_default = validate;
1280
+
1281
+ // node_modules/uuid/dist-node/parse.js
1282
+ function parse(uuid) {
1283
+ if (!validate_default(uuid)) {
1284
+ throw TypeError("Invalid UUID");
1285
+ }
1286
+ let v;
1287
+ return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, v >>> 16 & 255, v >>> 8 & 255, v & 255, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255, v / 4294967296 & 255, v >>> 24 & 255, v >>> 16 & 255, v >>> 8 & 255, v & 255);
1288
+ }
1289
+ var parse_default = parse;
1290
+
1291
+ // node_modules/uuid/dist-node/stringify.js
1292
+ var byteToHex = [];
1293
+ for (let i = 0; i < 256; ++i) {
1294
+ byteToHex.push((i + 256).toString(16).slice(1));
1295
+ }
1296
+ function unsafeStringify(arr, offset = 0) {
1297
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
1298
+ }
1299
+
1300
+ // node_modules/uuid/dist-node/v35.js
1301
+ function stringToBytes(str) {
1302
+ str = unescape(encodeURIComponent(str));
1303
+ const bytes = new Uint8Array(str.length);
1304
+ for (let i = 0; i < str.length; ++i) {
1305
+ bytes[i] = str.charCodeAt(i);
1306
+ }
1307
+ return bytes;
1308
+ }
1309
+ var DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
1310
+ var URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
1311
+ function v35(version, hash, value, namespace, buf, offset) {
1312
+ const valueBytes = typeof value === "string" ? stringToBytes(value) : value;
1313
+ const namespaceBytes = typeof namespace === "string" ? parse_default(namespace) : namespace;
1314
+ if (typeof namespace === "string") {
1315
+ namespace = parse_default(namespace);
1316
+ }
1317
+ if (namespace?.length !== 16) {
1318
+ throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");
1319
+ }
1320
+ let bytes = new Uint8Array(16 + valueBytes.length);
1321
+ bytes.set(namespaceBytes);
1322
+ bytes.set(valueBytes, namespaceBytes.length);
1323
+ bytes = hash(bytes);
1324
+ bytes[6] = bytes[6] & 15 | version;
1325
+ bytes[8] = bytes[8] & 63 | 128;
1326
+ if (buf) {
1327
+ offset = offset || 0;
1328
+ for (let i = 0; i < 16; ++i) {
1329
+ buf[offset + i] = bytes[i];
1330
+ }
1331
+ return buf;
1332
+ }
1333
+ return unsafeStringify(bytes);
1334
+ }
1335
+
1336
+ // node_modules/uuid/dist-node/sha1.js
1337
+ import { createHash } from "node:crypto";
1338
+ function sha1(bytes) {
1339
+ if (Array.isArray(bytes)) {
1340
+ bytes = Buffer.from(bytes);
1341
+ } else if (typeof bytes === "string") {
1342
+ bytes = Buffer.from(bytes, "utf8");
1343
+ }
1344
+ return createHash("sha1").update(bytes).digest();
1345
+ }
1346
+ var sha1_default = sha1;
1347
+
1348
+ // node_modules/uuid/dist-node/v5.js
1349
+ function v5(value, namespace, buf, offset) {
1350
+ return v35(80, sha1_default, value, namespace, buf, offset);
1351
+ }
1352
+ v5.DNS = DNS;
1353
+ v5.URL = URL2;
1354
+ var v5_default = v5;
1355
+
1272
1356
  // node_modules/@prmichaelsen/remember-core/dist/collections/composite-ids.js
1357
+ var WEAVIATE_UUID_NAMESPACE = v5_default.DNS;
1273
1358
  var InvalidCompositeIdError = class extends Error {
1274
1359
  constructor(message) {
1275
1360
  super(message);
@@ -1291,6 +1376,28 @@ function generateCompositeId(userId, memoryId) {
1291
1376
  }
1292
1377
  return `${userId}.${memoryId}`;
1293
1378
  }
1379
+ function parseCompositeId(compositeId) {
1380
+ const parts = compositeId.split(".");
1381
+ if (parts.length !== 2) {
1382
+ throw new InvalidCompositeIdError(`Invalid composite ID format: ${compositeId}. Expected format: {userId}.{memoryId}`);
1383
+ }
1384
+ const [userId, memoryId] = parts;
1385
+ if (!userId.trim()) {
1386
+ throw new InvalidCompositeIdError(`Invalid composite ID: ${compositeId}. User ID is empty`);
1387
+ }
1388
+ if (!memoryId.trim()) {
1389
+ throw new InvalidCompositeIdError(`Invalid composite ID: ${compositeId}. Memory ID is empty`);
1390
+ }
1391
+ return { userId, memoryId };
1392
+ }
1393
+ function validateCompositeId(id) {
1394
+ parseCompositeId(id);
1395
+ return true;
1396
+ }
1397
+ function compositeIdToUuid(compositeId) {
1398
+ validateCompositeId(compositeId);
1399
+ return v5_default(compositeId, WEAVIATE_UUID_NAMESPACE);
1400
+ }
1294
1401
 
1295
1402
  // node_modules/@prmichaelsen/remember-core/dist/collections/dot-notation.js
1296
1403
  var CollectionType;
@@ -1818,6 +1925,11 @@ async function fetchMemoryWithAllProperties(collection, memoryId) {
1818
1925
  }
1819
1926
  }
1820
1927
 
1928
+ // node_modules/@prmichaelsen/remember-core/dist/services/trust-enforcement.service.js
1929
+ function buildTrustFilter(collection, accessorTrustLevel) {
1930
+ return collection.filter.byProperty("trust_score").lessThanOrEqual(accessorTrustLevel);
1931
+ }
1932
+
1821
1933
  // node_modules/@prmichaelsen/remember-core/dist/services/memory.service.js
1822
1934
  var MemoryService = class {
1823
1935
  collection;
@@ -1875,7 +1987,14 @@ var MemoryService = class {
1875
1987
  const offset = input.offset ?? 0;
1876
1988
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
1877
1989
  const searchFilters = includeRelationships ? buildCombinedSearchFilters(this.collection, input.filters) : buildMemoryOnlyFilters(this.collection, input.filters);
1878
- const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters].filter((f) => f !== null));
1990
+ const ghostFilters = [];
1991
+ if (input.ghost_context) {
1992
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
1993
+ }
1994
+ if (!input.ghost_context?.include_ghost_content) {
1995
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
1996
+ }
1997
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
1879
1998
  const searchOptions = { alpha, limit: limit + offset };
1880
1999
  if (combinedFilters)
1881
2000
  searchOptions.filters = combinedFilters;
@@ -1907,6 +2026,14 @@ var MemoryService = class {
1907
2026
  const limit = input.limit ?? 10;
1908
2027
  const minSimilarity = input.min_similarity ?? 0.7;
1909
2028
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
2029
+ const ghostFilters = [];
2030
+ if (input.ghost_context) {
2031
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2032
+ }
2033
+ if (!input.ghost_context?.include_ghost_content) {
2034
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2035
+ }
2036
+ const combinedFilter = combineFiltersWithAnd([deletedFilter, ...ghostFilters].filter((f) => f !== null));
1910
2037
  let results;
1911
2038
  if (input.memory_id) {
1912
2039
  const memory = await this.collection.query.fetchObjectById(input.memory_id, {
@@ -1919,14 +2046,14 @@ var MemoryService = class {
1919
2046
  if (memory.properties.doc_type !== "memory")
1920
2047
  throw new Error("Can only find similar for memory documents");
1921
2048
  const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
1922
- if (deletedFilter)
1923
- opts.filters = deletedFilter;
2049
+ if (combinedFilter)
2050
+ opts.filters = combinedFilter;
1924
2051
  results = await this.collection.query.nearObject(input.memory_id, opts);
1925
2052
  results.objects = results.objects.filter((o) => o.uuid !== input.memory_id);
1926
2053
  } else {
1927
2054
  const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
1928
- if (deletedFilter)
1929
- opts.filters = deletedFilter;
2055
+ if (combinedFilter)
2056
+ opts.filters = combinedFilter;
1930
2057
  results = await this.collection.query.nearText(input.text, opts);
1931
2058
  }
1932
2059
  if (!input.include_relationships) {
@@ -1947,7 +2074,14 @@ var MemoryService = class {
1947
2074
  const minRelevance = input.min_relevance ?? 0.6;
1948
2075
  const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
1949
2076
  const searchFilters = buildCombinedSearchFilters(this.collection, input.filters);
1950
- const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters].filter((f) => f !== null));
2077
+ const ghostFilters = [];
2078
+ if (input.ghost_context) {
2079
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
2080
+ }
2081
+ if (!input.ghost_context?.include_ghost_content) {
2082
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
2083
+ }
2084
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
1951
2085
  const opts = { limit, distance: 1 - minRelevance, returnMetadata: ["distance"] };
1952
2086
  if (combinedFilters)
1953
2087
  opts.filters = combinedFilters;
@@ -2796,6 +2930,7 @@ var SpaceService = class {
2796
2930
  if (originalMemory.properties.user_id !== this.userId)
2797
2931
  throw new Error("Permission denied");
2798
2932
  const compositeId = generateCompositeId(this.userId, request.payload.memory_id);
2933
+ const weaviateId = compositeIdToUuid(compositeId);
2799
2934
  const existingSpaceIds = Array.isArray(originalMemory.properties.space_ids) ? originalMemory.properties.space_ids : [];
2800
2935
  const existingGroupIds = Array.isArray(originalMemory.properties.group_ids) ? originalMemory.properties.group_ids : [];
2801
2936
  const originalTags = Array.isArray(originalMemory.properties.tags) ? originalMemory.properties.tags : [];
@@ -2808,7 +2943,7 @@ var SpaceService = class {
2808
2943
  const publicCollection = await ensurePublicCollection(this.weaviateClient);
2809
2944
  let existingSpaceMemory = null;
2810
2945
  try {
2811
- existingSpaceMemory = await fetchMemoryWithAllProperties(publicCollection, compositeId);
2946
+ existingSpaceMemory = await fetchMemoryWithAllProperties(publicCollection, weaviateId);
2812
2947
  } catch {
2813
2948
  }
2814
2949
  const newSpaceIds = [.../* @__PURE__ */ new Set([...existingSpaceIds, ...spaces])];
@@ -2822,7 +2957,7 @@ var SpaceService = class {
2822
2957
  }
2823
2958
  const publishedMemory = {
2824
2959
  ...originalMemory.properties,
2825
- id: compositeId,
2960
+ composite_id: compositeId,
2826
2961
  space_ids: newSpaceIds,
2827
2962
  group_ids: existingGroupIds,
2828
2963
  spaces,
@@ -2835,9 +2970,9 @@ var SpaceService = class {
2835
2970
  };
2836
2971
  delete publishedMemory._additional;
2837
2972
  if (existingSpaceMemory) {
2838
- await publicCollection.data.update({ id: compositeId, properties: publishedMemory });
2973
+ await publicCollection.data.update({ id: weaviateId, properties: publishedMemory });
2839
2974
  } else {
2840
- await publicCollection.data.insert({ id: compositeId, properties: publishedMemory });
2975
+ await publicCollection.data.insert({ id: weaviateId, properties: publishedMemory });
2841
2976
  }
2842
2977
  successfulPublications.push(`spaces: ${spaces.join(", ")}`);
2843
2978
  } catch (err2) {
@@ -2850,7 +2985,7 @@ var SpaceService = class {
2850
2985
  const groupCollection = this.weaviateClient.collections.get(groupCollectionName);
2851
2986
  let existingGroupMemory = null;
2852
2987
  try {
2853
- existingGroupMemory = await fetchMemoryWithAllProperties(groupCollection, compositeId);
2988
+ existingGroupMemory = await fetchMemoryWithAllProperties(groupCollection, weaviateId);
2854
2989
  } catch {
2855
2990
  }
2856
2991
  const newGroupIds = [.../* @__PURE__ */ new Set([...existingGroupIds, groupId])];
@@ -2858,7 +2993,7 @@ var SpaceService = class {
2858
2993
  const groupModerationStatus = groupConfig.require_moderation ? "pending" : "approved";
2859
2994
  const groupMemory = {
2860
2995
  ...originalMemory.properties,
2861
- id: compositeId,
2996
+ composite_id: compositeId,
2862
2997
  space_ids: existingSpaceIds,
2863
2998
  group_ids: newGroupIds,
2864
2999
  author_id: this.userId,
@@ -2870,9 +3005,9 @@ var SpaceService = class {
2870
3005
  };
2871
3006
  delete groupMemory._additional;
2872
3007
  if (existingGroupMemory) {
2873
- await groupCollection.data.update({ id: compositeId, properties: groupMemory });
3008
+ await groupCollection.data.update({ id: weaviateId, properties: groupMemory });
2874
3009
  } else {
2875
- await groupCollection.data.insert({ id: compositeId, properties: groupMemory });
3010
+ await groupCollection.data.insert({ id: weaviateId, properties: groupMemory });
2876
3011
  }
2877
3012
  successfulPublications.push(`group: ${groupId}`);
2878
3013
  } catch (err2) {
@@ -2920,17 +3055,18 @@ var SpaceService = class {
2920
3055
  const currentSpaceIds = Array.isArray(sourceMemory.properties.space_ids) ? sourceMemory.properties.space_ids : [];
2921
3056
  const currentGroupIds = Array.isArray(sourceMemory.properties.group_ids) ? sourceMemory.properties.group_ids : [];
2922
3057
  const compositeId = generateCompositeId(this.userId, request.payload.memory_id);
3058
+ const weaviateId = compositeIdToUuid(compositeId);
2923
3059
  const successfulRetractions = [];
2924
3060
  const failedRetractions = [];
2925
3061
  if (spaces.length > 0) {
2926
3062
  try {
2927
3063
  const spacesCollectionName = getCollectionName(CollectionType.SPACES);
2928
3064
  const publicCollection = this.weaviateClient.collections.get(spacesCollectionName);
2929
- const publishedMemory = await fetchMemoryWithAllProperties(publicCollection, compositeId);
3065
+ const publishedMemory = await fetchMemoryWithAllProperties(publicCollection, weaviateId);
2930
3066
  if (publishedMemory) {
2931
3067
  const newSpaceIds = currentSpaceIds.filter((id) => !spaces.includes(id));
2932
3068
  await publicCollection.data.update({
2933
- id: compositeId,
3069
+ id: weaviateId,
2934
3070
  properties: { space_ids: newSpaceIds, retracted_at: (/* @__PURE__ */ new Date()).toISOString() }
2935
3071
  });
2936
3072
  successfulRetractions.push(`spaces: ${spaces.join(", ")}`);
@@ -2945,12 +3081,12 @@ var SpaceService = class {
2945
3081
  const groupCollectionName = getCollectionName(CollectionType.GROUPS, groupId);
2946
3082
  try {
2947
3083
  const groupCollection = this.weaviateClient.collections.get(groupCollectionName);
2948
- const groupMemory = await fetchMemoryWithAllProperties(groupCollection, compositeId);
3084
+ const groupMemory = await fetchMemoryWithAllProperties(groupCollection, weaviateId);
2949
3085
  if (groupMemory) {
2950
3086
  const groupMemoryGroupIds = Array.isArray(groupMemory.properties.group_ids) ? groupMemory.properties.group_ids : [];
2951
3087
  const newGroupIds = groupMemoryGroupIds.filter((id) => id !== groupId);
2952
3088
  await groupCollection.data.update({
2953
- id: compositeId,
3089
+ id: weaviateId,
2954
3090
  properties: { group_ids: newGroupIds, retracted_at: (/* @__PURE__ */ new Date()).toISOString() }
2955
3091
  });
2956
3092
  successfulRetractions.push(`group: ${groupId}`);
@@ -3001,11 +3137,12 @@ var SpaceService = class {
3001
3137
  const newContent = String(sourceMemory.properties.content ?? "");
3002
3138
  const revisedAt = (/* @__PURE__ */ new Date()).toISOString();
3003
3139
  const compositeId = generateCompositeId(this.userId, memory_id);
3140
+ const weaviateId = compositeIdToUuid(compositeId);
3004
3141
  const results = [];
3005
3142
  const reviseInCollection = async (collectionName, locationLabel) => {
3006
3143
  try {
3007
3144
  const collection = this.weaviateClient.collections.get(collectionName);
3008
- const publishedMemory = await fetchMemoryWithAllProperties(collection, compositeId);
3145
+ const publishedMemory = await fetchMemoryWithAllProperties(collection, weaviateId);
3009
3146
  if (!publishedMemory) {
3010
3147
  results.push({ location: locationLabel, status: "skipped", error: "Published copy not found" });
3011
3148
  return;
@@ -3017,7 +3154,7 @@ var SpaceService = class {
3017
3154
  }
3018
3155
  const currentRevisionCount = typeof publishedMemory.properties.revision_count === "number" ? publishedMemory.properties.revision_count : 0;
3019
3156
  await collection.data.update({
3020
- id: compositeId,
3157
+ id: weaviateId,
3021
3158
  properties: {
3022
3159
  content: newContent,
3023
3160
  revised_at: revisedAt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "3.14.0",
3
+ "version": "3.14.1",
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,9 +50,10 @@
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.13.0",
53
+ "@prmichaelsen/remember-core": "^0.16.0",
54
54
  "@prmichaelsen/remember-mcp": "^2.7.3",
55
55
  "dotenv": "^16.4.5",
56
+ "uuid": "^13.0.0",
56
57
  "weaviate-client": "^3.2.0"
57
58
  },
58
59
  "devDependencies": {