@prmichaelsen/remember-mcp 3.14.14 → 3.14.16

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.
@@ -851,24 +851,7 @@ var DEFAULT_PREFERENCES = {
851
851
  var SUPPORTED_SPACES = [
852
852
  "the_void",
853
853
  "profiles",
854
- "spaces",
855
- "ghosts",
856
- "poems",
857
- "recipes",
858
- "quotes",
859
- "dreams",
860
- "travel",
861
- "music",
862
- "pets",
863
- "books",
864
- "funny",
865
- "ideas",
866
- "art",
867
- "fitness",
868
- "how_to",
869
- "movies",
870
- "nature",
871
- "journal"
854
+ "ghosts"
872
855
  ];
873
856
  var SPACE_CONTENT_TYPE_RESTRICTIONS = {
874
857
  profiles: "profile",
@@ -931,7 +914,9 @@ var CONTENT_TYPES = [
931
914
  "ghost",
932
915
  "comment",
933
916
  // Profile
934
- "profile"
917
+ "profile",
918
+ // Agent
919
+ "agent"
935
920
  ];
936
921
  var CONTENT_TYPE_METADATA = {
937
922
  // Core Types
@@ -1247,6 +1232,25 @@ var CONTENT_TYPE_METADATA = {
1247
1232
  category: "cross_user",
1248
1233
  description: "User profile published to the profiles space for people discovery",
1249
1234
  examples: ["User bio", "About me", "Profile introduction"]
1235
+ },
1236
+ // Agent
1237
+ agent: {
1238
+ name: "agent",
1239
+ category: "system",
1240
+ description: "Agent working memory \u2014 observations, preferences, session notes, project tracking",
1241
+ examples: [
1242
+ "User responds well to concise, bulleted answers",
1243
+ "User prefers seeing full code context rather than snippets",
1244
+ 'When user says "fix it", they mean fix and commit without asking',
1245
+ "User is a senior engineer working primarily in TypeScript",
1246
+ "User timezone is US Central, typically active 9am-11pm",
1247
+ "User is building agentbase.me \u2014 an AI integration platform on Cloudflare Workers",
1248
+ "Auth system redesign planned for Q2 \u2014 user wants JWT replaced with session cookies",
1249
+ "User tracking 3 active projects: agentbase.me, remember-core, agentbase-mobile",
1250
+ "Milestone M36 (Notifications) nearly complete \u2014 4 tasks remaining as of March 2026",
1251
+ "Follow up March 10: revisit subscription tier pricing discussion"
1252
+ ],
1253
+ common_fields: ["observations", "preferences", "summaries", "follow_ups"]
1250
1254
  }
1251
1255
  };
1252
1256
  function isValidContentType(type) {
@@ -1532,11 +1536,23 @@ function buildCombinedSearchFilters(collection, filters) {
1532
1536
  function buildDocTypeFilters(collection, docType, filters) {
1533
1537
  const filterList = [];
1534
1538
  filterList.push(collection.filter.byProperty("doc_type").equal(docType));
1535
- if (docType === "memory" && filters?.types && filters.types.length > 0) {
1536
- if (filters.types.length === 1) {
1537
- filterList.push(collection.filter.byProperty("content_type").equal(filters.types[0]));
1539
+ if (docType === "memory") {
1540
+ const DEFAULT_EXCLUDED_TYPES = ["agent"];
1541
+ if (filters?.types && filters.types.length > 0) {
1542
+ if (filters.types.length === 1) {
1543
+ filterList.push(collection.filter.byProperty("content_type").equal(filters.types[0]));
1544
+ } else {
1545
+ filterList.push(collection.filter.byProperty("content_type").containsAny(filters.types));
1546
+ }
1538
1547
  } else {
1539
- filterList.push(collection.filter.byProperty("content_type").containsAny(filters.types));
1548
+ for (const excludedType of DEFAULT_EXCLUDED_TYPES) {
1549
+ filterList.push(collection.filter.byProperty("content_type").notEqual(excludedType));
1550
+ }
1551
+ }
1552
+ if (filters?.exclude_types && filters.exclude_types.length > 0) {
1553
+ for (const excludedType of filters.exclude_types) {
1554
+ filterList.push(collection.filter.byProperty("content_type").notEqual(excludedType));
1555
+ }
1540
1556
  }
1541
1557
  }
1542
1558
  if (filters?.weight_min !== void 0) {
@@ -1557,6 +1573,12 @@ function buildDocTypeFilters(collection, docType, filters) {
1557
1573
  if (filters?.date_to) {
1558
1574
  filterList.push(collection.filter.byProperty("created_at").lessOrEqual(new Date(filters.date_to)));
1559
1575
  }
1576
+ if (filters?.relationship_count_min !== void 0) {
1577
+ filterList.push(collection.filter.byProperty("relationship_count").greaterOrEqual(filters.relationship_count_min));
1578
+ }
1579
+ if (filters?.relationship_count_max !== void 0) {
1580
+ filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
1581
+ }
1560
1582
  if (filters?.tags && filters.tags.length > 0) {
1561
1583
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
1562
1584
  }
@@ -1727,7 +1749,7 @@ var PreferencesDatabaseService = class {
1727
1749
  };
1728
1750
 
1729
1751
  // node_modules/@prmichaelsen/remember-core/dist/services/confirmation-token.service.js
1730
- import { randomUUID } from "crypto";
1752
+ var randomUUID = () => globalThis.crypto.randomUUID();
1731
1753
  var ConfirmationTokenService = class {
1732
1754
  EXPIRY_MINUTES = 5;
1733
1755
  logger;
@@ -2029,6 +2051,7 @@ var MemoryService = class {
2029
2051
  parent_id: input.parent_id ?? null,
2030
2052
  thread_root_id: input.thread_root_id ?? null,
2031
2053
  moderation_flags: input.moderation_flags ?? [],
2054
+ follow_up_at: input.follow_up_at || null,
2032
2055
  space_ids: [],
2033
2056
  group_ids: []
2034
2057
  };
@@ -2103,12 +2126,7 @@ var MemoryService = class {
2103
2126
  const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2104
2127
  const queryOptions = {
2105
2128
  limit: limit + offset,
2106
- sort: [
2107
- {
2108
- property: "created_at",
2109
- order: direction
2110
- }
2111
- ]
2129
+ sort: this.collection.sort.byProperty("created_at", direction === "asc")
2112
2130
  };
2113
2131
  if (combinedFilters) {
2114
2132
  queryOptions.filters = combinedFilters;
@@ -2152,13 +2170,7 @@ var MemoryService = class {
2152
2170
  const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters, ...densityFilters].filter((f) => f !== null));
2153
2171
  const queryOptions = {
2154
2172
  limit: limit + offset,
2155
- sort: [
2156
- {
2157
- property: "relationship_count",
2158
- order: "desc"
2159
- // Highest first
2160
- }
2161
- ]
2173
+ sort: this.collection.sort.byProperty("relationship_count", false)
2162
2174
  };
2163
2175
  if (combinedFilters) {
2164
2176
  queryOptions.filters = combinedFilters;
@@ -2660,6 +2672,18 @@ async function registerCollection(entry) {
2660
2672
  }
2661
2673
 
2662
2674
  // node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
2675
+ var collectionCache = /* @__PURE__ */ new Map();
2676
+ var COLLECTION_CACHE_TTL_MS = 6e4;
2677
+ function isCollectionCached(collectionName) {
2678
+ const expiresAt = collectionCache.get(collectionName);
2679
+ if (expiresAt !== void 0 && Date.now() < expiresAt)
2680
+ return true;
2681
+ collectionCache.delete(collectionName);
2682
+ return false;
2683
+ }
2684
+ function cacheCollection(collectionName) {
2685
+ collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
2686
+ }
2663
2687
  var COMMON_MEMORY_PROPERTIES = [
2664
2688
  // Core content
2665
2689
  { name: "content", dataType: configure.dataType.TEXT },
@@ -2729,6 +2753,8 @@ var COMMON_MEMORY_PROPERTIES = [
2729
2753
  { name: "parent_id", dataType: configure.dataType.TEXT },
2730
2754
  { name: "thread_root_id", dataType: configure.dataType.TEXT },
2731
2755
  { name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
2756
+ // Agent follow-up tracking
2757
+ { name: "follow_up_at", dataType: configure.dataType.DATE },
2732
2758
  // Soft delete
2733
2759
  { name: "deleted_at", dataType: configure.dataType.DATE },
2734
2760
  { name: "deleted_by", dataType: configure.dataType.TEXT },
@@ -2818,9 +2844,12 @@ async function reconcileCollectionProperties(client2, collectionName, expectedPr
2818
2844
  }
2819
2845
  async function ensureGroupCollection(client2, groupId) {
2820
2846
  const collectionName = `Memory_groups_${groupId}`;
2847
+ if (isCollectionCached(collectionName))
2848
+ return false;
2821
2849
  const exists = await client2.collections.exists(collectionName);
2822
2850
  if (exists) {
2823
2851
  await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
2852
+ cacheCollection(collectionName);
2824
2853
  return false;
2825
2854
  }
2826
2855
  const schema = createGroupCollectionSchema(groupId);
@@ -2831,6 +2860,7 @@ async function ensureGroupCollection(client2, groupId) {
2831
2860
  owner_id: groupId,
2832
2861
  created_at: (/* @__PURE__ */ new Date()).toISOString()
2833
2862
  });
2863
+ cacheCollection(collectionName);
2834
2864
  return true;
2835
2865
  }
2836
2866
 
@@ -2841,10 +2871,13 @@ function isValidSpaceId(spaceId) {
2841
2871
  }
2842
2872
  async function ensurePublicCollection(client2) {
2843
2873
  const collectionName = PUBLIC_COLLECTION_NAME;
2844
- const exists = await client2.collections.exists(collectionName);
2845
- if (!exists) {
2846
- const schema = createSpaceCollectionSchema();
2847
- await client2.collections.create(schema);
2874
+ if (!isCollectionCached(collectionName)) {
2875
+ const exists = await client2.collections.exists(collectionName);
2876
+ if (!exists) {
2877
+ const schema = createSpaceCollectionSchema();
2878
+ await client2.collections.create(schema);
2879
+ }
2880
+ cacheCollection(collectionName);
2848
2881
  }
2849
2882
  return client2.collections.get(collectionName);
2850
2883
  }
package/dist/server.js CHANGED
@@ -855,24 +855,7 @@ var DEFAULT_PREFERENCES = {
855
855
  var SUPPORTED_SPACES = [
856
856
  "the_void",
857
857
  "profiles",
858
- "spaces",
859
- "ghosts",
860
- "poems",
861
- "recipes",
862
- "quotes",
863
- "dreams",
864
- "travel",
865
- "music",
866
- "pets",
867
- "books",
868
- "funny",
869
- "ideas",
870
- "art",
871
- "fitness",
872
- "how_to",
873
- "movies",
874
- "nature",
875
- "journal"
858
+ "ghosts"
876
859
  ];
877
860
  var SPACE_CONTENT_TYPE_RESTRICTIONS = {
878
861
  profiles: "profile",
@@ -935,7 +918,9 @@ var CONTENT_TYPES = [
935
918
  "ghost",
936
919
  "comment",
937
920
  // Profile
938
- "profile"
921
+ "profile",
922
+ // Agent
923
+ "agent"
939
924
  ];
940
925
  var CONTENT_TYPE_METADATA = {
941
926
  // Core Types
@@ -1251,6 +1236,25 @@ var CONTENT_TYPE_METADATA = {
1251
1236
  category: "cross_user",
1252
1237
  description: "User profile published to the profiles space for people discovery",
1253
1238
  examples: ["User bio", "About me", "Profile introduction"]
1239
+ },
1240
+ // Agent
1241
+ agent: {
1242
+ name: "agent",
1243
+ category: "system",
1244
+ description: "Agent working memory \u2014 observations, preferences, session notes, project tracking",
1245
+ examples: [
1246
+ "User responds well to concise, bulleted answers",
1247
+ "User prefers seeing full code context rather than snippets",
1248
+ 'When user says "fix it", they mean fix and commit without asking',
1249
+ "User is a senior engineer working primarily in TypeScript",
1250
+ "User timezone is US Central, typically active 9am-11pm",
1251
+ "User is building agentbase.me \u2014 an AI integration platform on Cloudflare Workers",
1252
+ "Auth system redesign planned for Q2 \u2014 user wants JWT replaced with session cookies",
1253
+ "User tracking 3 active projects: agentbase.me, remember-core, agentbase-mobile",
1254
+ "Milestone M36 (Notifications) nearly complete \u2014 4 tasks remaining as of March 2026",
1255
+ "Follow up March 10: revisit subscription tier pricing discussion"
1256
+ ],
1257
+ common_fields: ["observations", "preferences", "summaries", "follow_ups"]
1254
1258
  }
1255
1259
  };
1256
1260
  function isValidContentType(type) {
@@ -1536,11 +1540,23 @@ function buildCombinedSearchFilters(collection, filters) {
1536
1540
  function buildDocTypeFilters(collection, docType, filters) {
1537
1541
  const filterList = [];
1538
1542
  filterList.push(collection.filter.byProperty("doc_type").equal(docType));
1539
- if (docType === "memory" && filters?.types && filters.types.length > 0) {
1540
- if (filters.types.length === 1) {
1541
- filterList.push(collection.filter.byProperty("content_type").equal(filters.types[0]));
1543
+ if (docType === "memory") {
1544
+ const DEFAULT_EXCLUDED_TYPES = ["agent"];
1545
+ if (filters?.types && filters.types.length > 0) {
1546
+ if (filters.types.length === 1) {
1547
+ filterList.push(collection.filter.byProperty("content_type").equal(filters.types[0]));
1548
+ } else {
1549
+ filterList.push(collection.filter.byProperty("content_type").containsAny(filters.types));
1550
+ }
1542
1551
  } else {
1543
- filterList.push(collection.filter.byProperty("content_type").containsAny(filters.types));
1552
+ for (const excludedType of DEFAULT_EXCLUDED_TYPES) {
1553
+ filterList.push(collection.filter.byProperty("content_type").notEqual(excludedType));
1554
+ }
1555
+ }
1556
+ if (filters?.exclude_types && filters.exclude_types.length > 0) {
1557
+ for (const excludedType of filters.exclude_types) {
1558
+ filterList.push(collection.filter.byProperty("content_type").notEqual(excludedType));
1559
+ }
1544
1560
  }
1545
1561
  }
1546
1562
  if (filters?.weight_min !== void 0) {
@@ -1561,6 +1577,12 @@ function buildDocTypeFilters(collection, docType, filters) {
1561
1577
  if (filters?.date_to) {
1562
1578
  filterList.push(collection.filter.byProperty("created_at").lessOrEqual(new Date(filters.date_to)));
1563
1579
  }
1580
+ if (filters?.relationship_count_min !== void 0) {
1581
+ filterList.push(collection.filter.byProperty("relationship_count").greaterOrEqual(filters.relationship_count_min));
1582
+ }
1583
+ if (filters?.relationship_count_max !== void 0) {
1584
+ filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
1585
+ }
1564
1586
  if (filters?.tags && filters.tags.length > 0) {
1565
1587
  filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
1566
1588
  }
@@ -1731,7 +1753,7 @@ var PreferencesDatabaseService = class {
1731
1753
  };
1732
1754
 
1733
1755
  // node_modules/@prmichaelsen/remember-core/dist/services/confirmation-token.service.js
1734
- import { randomUUID } from "crypto";
1756
+ var randomUUID = () => globalThis.crypto.randomUUID();
1735
1757
  var ConfirmationTokenService = class {
1736
1758
  EXPIRY_MINUTES = 5;
1737
1759
  logger;
@@ -2033,6 +2055,7 @@ var MemoryService = class {
2033
2055
  parent_id: input.parent_id ?? null,
2034
2056
  thread_root_id: input.thread_root_id ?? null,
2035
2057
  moderation_flags: input.moderation_flags ?? [],
2058
+ follow_up_at: input.follow_up_at || null,
2036
2059
  space_ids: [],
2037
2060
  group_ids: []
2038
2061
  };
@@ -2107,12 +2130,7 @@ var MemoryService = class {
2107
2130
  const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
2108
2131
  const queryOptions = {
2109
2132
  limit: limit + offset,
2110
- sort: [
2111
- {
2112
- property: "created_at",
2113
- order: direction
2114
- }
2115
- ]
2133
+ sort: this.collection.sort.byProperty("created_at", direction === "asc")
2116
2134
  };
2117
2135
  if (combinedFilters) {
2118
2136
  queryOptions.filters = combinedFilters;
@@ -2156,13 +2174,7 @@ var MemoryService = class {
2156
2174
  const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters, ...densityFilters].filter((f) => f !== null));
2157
2175
  const queryOptions = {
2158
2176
  limit: limit + offset,
2159
- sort: [
2160
- {
2161
- property: "relationship_count",
2162
- order: "desc"
2163
- // Highest first
2164
- }
2165
- ]
2177
+ sort: this.collection.sort.byProperty("relationship_count", false)
2166
2178
  };
2167
2179
  if (combinedFilters) {
2168
2180
  queryOptions.filters = combinedFilters;
@@ -2664,6 +2676,18 @@ async function registerCollection(entry) {
2664
2676
  }
2665
2677
 
2666
2678
  // node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
2679
+ var collectionCache = /* @__PURE__ */ new Map();
2680
+ var COLLECTION_CACHE_TTL_MS = 6e4;
2681
+ function isCollectionCached(collectionName) {
2682
+ const expiresAt = collectionCache.get(collectionName);
2683
+ if (expiresAt !== void 0 && Date.now() < expiresAt)
2684
+ return true;
2685
+ collectionCache.delete(collectionName);
2686
+ return false;
2687
+ }
2688
+ function cacheCollection(collectionName) {
2689
+ collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
2690
+ }
2667
2691
  var COMMON_MEMORY_PROPERTIES = [
2668
2692
  // Core content
2669
2693
  { name: "content", dataType: configure.dataType.TEXT },
@@ -2733,6 +2757,8 @@ var COMMON_MEMORY_PROPERTIES = [
2733
2757
  { name: "parent_id", dataType: configure.dataType.TEXT },
2734
2758
  { name: "thread_root_id", dataType: configure.dataType.TEXT },
2735
2759
  { name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
2760
+ // Agent follow-up tracking
2761
+ { name: "follow_up_at", dataType: configure.dataType.DATE },
2736
2762
  // Soft delete
2737
2763
  { name: "deleted_at", dataType: configure.dataType.DATE },
2738
2764
  { name: "deleted_by", dataType: configure.dataType.TEXT },
@@ -2822,9 +2848,12 @@ async function reconcileCollectionProperties(client2, collectionName, expectedPr
2822
2848
  }
2823
2849
  async function ensureGroupCollection(client2, groupId) {
2824
2850
  const collectionName = `Memory_groups_${groupId}`;
2851
+ if (isCollectionCached(collectionName))
2852
+ return false;
2825
2853
  const exists = await client2.collections.exists(collectionName);
2826
2854
  if (exists) {
2827
2855
  await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
2856
+ cacheCollection(collectionName);
2828
2857
  return false;
2829
2858
  }
2830
2859
  const schema = createGroupCollectionSchema(groupId);
@@ -2835,6 +2864,7 @@ async function ensureGroupCollection(client2, groupId) {
2835
2864
  owner_id: groupId,
2836
2865
  created_at: (/* @__PURE__ */ new Date()).toISOString()
2837
2866
  });
2867
+ cacheCollection(collectionName);
2838
2868
  return true;
2839
2869
  }
2840
2870
 
@@ -2845,10 +2875,13 @@ function isValidSpaceId(spaceId) {
2845
2875
  }
2846
2876
  async function ensurePublicCollection(client2) {
2847
2877
  const collectionName = PUBLIC_COLLECTION_NAME;
2848
- const exists = await client2.collections.exists(collectionName);
2849
- if (!exists) {
2850
- const schema = createSpaceCollectionSchema();
2851
- await client2.collections.create(schema);
2878
+ if (!isCollectionCached(collectionName)) {
2879
+ const exists = await client2.collections.exists(collectionName);
2880
+ if (!exists) {
2881
+ const schema = createSpaceCollectionSchema();
2882
+ await client2.collections.create(schema);
2883
+ }
2884
+ cacheCollection(collectionName);
2852
2885
  }
2853
2886
  return client2.collections.get(collectionName);
2854
2887
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "3.14.14",
3
+ "version": "3.14.16",
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.22.5",
53
+ "@prmichaelsen/remember-core": "^0.26.1",
54
54
  "dotenv": "^16.4.5",
55
55
  "uuid": "^13.0.0",
56
56
  "weaviate-client": "^3.2.0"