@prmichaelsen/remember-mcp 3.15.7 → 3.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.github/workflows/publish.yml +55 -0
  2. package/CHANGELOG.md +20 -0
  3. package/agent/design/local.unified-internal-memory-tools.md +325 -0
  4. package/agent/milestones/milestone-20-unified-internal-memory-tools.md +58 -0
  5. package/agent/progress.yaml +115 -1
  6. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md +54 -0
  7. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-213-update-server-factory-internal-context.md +117 -0
  8. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-214-create-tag-builder-utility.md +50 -0
  9. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-215-create-unified-internal-memory-tools.md +65 -0
  10. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-216-update-default-search-filters.md +46 -0
  11. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-217-delete-standalone-ghost-tools.md +46 -0
  12. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-218-add-tests-unified-internal-tools.md +66 -0
  13. package/dist/e2e-helpers.d.ts +1 -1
  14. package/dist/server-factory.d.ts +17 -41
  15. package/dist/server-factory.js +420 -149
  16. package/dist/server.js +202 -20
  17. package/dist/tools/{create-ghost-memory.d.ts → create-internal-memory.d.ts} +7 -9
  18. package/dist/tools/internal-tools.spec.d.ts +2 -0
  19. package/dist/tools/{query-ghost-memory.d.ts → query-internal-memory.d.ts} +6 -6
  20. package/dist/tools/{search-ghost-memory-by.d.ts → search-internal-memory-by.d.ts} +6 -6
  21. package/dist/tools/{search-ghost-memory.d.ts → search-internal-memory.d.ts} +6 -6
  22. package/dist/tools/{update-ghost-memory.d.ts → update-internal-memory.d.ts} +6 -6
  23. package/dist/types/auth.d.ts +22 -8
  24. package/dist/utils/internal-tags.d.ts +14 -0
  25. package/dist/utils/internal-tags.spec.d.ts +2 -0
  26. package/package.json +2 -3
  27. package/src/e2e-helpers.ts +4 -2
  28. package/src/ghost-persona.e2e.ts +18 -17
  29. package/src/server-factory.ts +117 -55
  30. package/src/tools/create-internal-memory.ts +105 -0
  31. package/src/tools/find-similar.ts +2 -2
  32. package/src/tools/internal-tools.spec.ts +312 -0
  33. package/src/tools/query-internal-memory.ts +73 -0
  34. package/src/tools/query-memory.ts +15 -12
  35. package/src/tools/search-by.spec.ts +6 -2
  36. package/src/tools/search-by.ts +6 -6
  37. package/src/tools/{search-ghost-memory-by.ts → search-internal-memory-by.ts} +34 -27
  38. package/src/tools/search-internal-memory.ts +87 -0
  39. package/src/tools/search-memory.ts +15 -12
  40. package/src/tools/search-space.ts +1 -0
  41. package/src/tools/{update-ghost-memory.ts → update-internal-memory.ts} +23 -17
  42. package/src/types/auth.ts +22 -8
  43. package/src/utils/internal-tags.spec.ts +104 -0
  44. package/src/utils/internal-tags.ts +46 -0
  45. package/dist/tools/ghost-tools.spec.d.ts +0 -2
  46. package/src/tools/create-ghost-memory.ts +0 -103
  47. package/src/tools/ghost-tools.spec.ts +0 -361
  48. package/src/tools/query-ghost-memory.ts +0 -63
  49. package/src/tools/search-ghost-memory.ts +0 -73
package/dist/server.js CHANGED
@@ -1935,7 +1935,13 @@ var COMMON_MEMORY_PROPERTIES = [
1935
1935
  { name: "total_significance", dataType: configure.dataType.NUMBER },
1936
1936
  // REM metadata
1937
1937
  { name: "rem_touched_at", dataType: configure.dataType.TEXT },
1938
- { name: "rem_visits", dataType: configure.dataType.INT }
1938
+ { name: "rem_visits", dataType: configure.dataType.INT },
1939
+ // Curation scoring (M36)
1940
+ { name: "curated_score", dataType: configure.dataType.NUMBER },
1941
+ { name: "editorial_score", dataType: configure.dataType.NUMBER },
1942
+ { name: "click_count", dataType: configure.dataType.INT },
1943
+ { name: "share_count", dataType: configure.dataType.INT },
1944
+ { name: "comment_count", dataType: configure.dataType.INT }
1939
1945
  ];
1940
1946
  var PUBLISHED_MEMORY_PROPERTIES = [
1941
1947
  // Publication metadata
@@ -2586,7 +2592,13 @@ var ALL_MEMORY_PROPERTIES = [
2586
2592
  "functional_significance",
2587
2593
  "total_significance",
2588
2594
  "rem_touched_at",
2589
- "rem_visits"
2595
+ "rem_visits",
2596
+ // Curation scoring (M36)
2597
+ "curated_score",
2598
+ "editorial_score",
2599
+ "click_count",
2600
+ "share_count",
2601
+ "comment_count"
2590
2602
  ];
2591
2603
  async function fetchMemoryWithAllProperties(collection, memoryId) {
2592
2604
  try {
@@ -3362,6 +3374,99 @@ var MemoryService = class {
3362
3374
  total_pool_size: totalPoolSize
3363
3375
  };
3364
3376
  }
3377
+ // ── By Curated (composite quality score) ──────────────────────────
3378
+ async byCurated(input) {
3379
+ const limit = input.limit ?? 50;
3380
+ const offset = input.offset ?? 0;
3381
+ const direction = input.direction ?? "desc";
3382
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
3383
+ const ghostFilters = [];
3384
+ if (input.ghost_context) {
3385
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
3386
+ }
3387
+ if (!input.ghost_context?.include_ghost_content && !input.filters?.types?.includes("ghost")) {
3388
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
3389
+ }
3390
+ if (!input.filters?.types?.includes("rem")) {
3391
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
3392
+ }
3393
+ const hasQuery = input.query?.trim();
3394
+ const fetchLimit = (limit + offset) * 2;
3395
+ const executeScoredQuery = async (useDeletedFilter) => {
3396
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
3397
+ const scoredFilter = this.collection.filter.byProperty("curated_score").greaterThan(0);
3398
+ const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, scoredFilter, ...ghostFilters].filter((f) => f !== null));
3399
+ if (hasQuery) {
3400
+ const queryOptions2 = {
3401
+ limit: fetchLimit,
3402
+ alpha: 0.7,
3403
+ query: hasQuery
3404
+ };
3405
+ if (combined)
3406
+ queryOptions2.filters = combined;
3407
+ return this.collection.query.hybrid(hasQuery, queryOptions2);
3408
+ }
3409
+ const queryOptions = {
3410
+ limit: fetchLimit,
3411
+ sort: this.collection.sort.byProperty("curated_score", direction === "asc")
3412
+ };
3413
+ if (combined)
3414
+ queryOptions.filters = combined;
3415
+ return this.collection.query.fetchObjects(queryOptions);
3416
+ };
3417
+ const executeUnscoredQuery = async (useDeletedFilter) => {
3418
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
3419
+ const unscoredFilters = [];
3420
+ const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
3421
+ const queryOptions = {
3422
+ limit: Math.ceil(fetchLimit / 4),
3423
+ sort: this.collection.sort.byProperty("created_at", false)
3424
+ // newest first
3425
+ };
3426
+ if (combined)
3427
+ queryOptions.filters = combined;
3428
+ return this.collection.query.fetchObjects(queryOptions);
3429
+ };
3430
+ const scoredResults = await this.retryWithoutDeletedFilter(executeScoredQuery);
3431
+ const unscoredResults = await this.retryWithoutDeletedFilter(executeUnscoredQuery);
3432
+ const scored = [];
3433
+ for (const obj of scoredResults.objects) {
3434
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
3435
+ if (doc.doc_type === "memory" && doc.curated_score > 0) {
3436
+ scored.push(doc);
3437
+ }
3438
+ }
3439
+ if (hasQuery) {
3440
+ scored.sort((a, b) => {
3441
+ const aScore = a.curated_score ?? 0;
3442
+ const bScore = b.curated_score ?? 0;
3443
+ return direction === "asc" ? aScore - bScore : bScore - aScore;
3444
+ });
3445
+ }
3446
+ const unscored = [];
3447
+ for (const obj of unscoredResults.objects) {
3448
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
3449
+ if (doc.doc_type === "memory" && !doc.curated_score) {
3450
+ unscored.push(doc);
3451
+ }
3452
+ }
3453
+ const interleaved = interleaveDiscovery({
3454
+ rated: scored,
3455
+ discovery: unscored,
3456
+ offset,
3457
+ limit
3458
+ });
3459
+ const memories = interleaved.map((item) => ({
3460
+ ...item.item,
3461
+ ...item.is_discovery ? { is_discovery: true } : {}
3462
+ }));
3463
+ return {
3464
+ memories,
3465
+ total: memories.length,
3466
+ offset,
3467
+ limit
3468
+ };
3469
+ }
3365
3470
  // ── Find Similar (vector) ──────────────────────────────────────────
3366
3471
  async findSimilar(input) {
3367
3472
  if (!input.memory_id && !input.text)
@@ -3378,6 +3483,7 @@ var MemoryService = class {
3378
3483
  ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
3379
3484
  }
3380
3485
  ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
3486
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("comment"));
3381
3487
  let memoryObj = null;
3382
3488
  if (input.memory_id) {
3383
3489
  memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
@@ -3569,6 +3675,28 @@ var MemoryService = class {
3569
3675
  orphaned_relationship_ids: orphanedIds
3570
3676
  };
3571
3677
  }
3678
+ // ── Engagement Counters ───────────────────────────────────────────
3679
+ async incrementClick(memoryId) {
3680
+ await this.incrementCounter(memoryId, "click_count");
3681
+ }
3682
+ async incrementShare(memoryId) {
3683
+ await this.incrementCounter(memoryId, "share_count");
3684
+ }
3685
+ async incrementComment(memoryId) {
3686
+ await this.incrementCounter(memoryId, "comment_count");
3687
+ }
3688
+ async incrementCounter(memoryId, field) {
3689
+ const existing = await this.collection.query.fetchObjectById(memoryId, {
3690
+ returnProperties: [field]
3691
+ });
3692
+ if (!existing)
3693
+ throw new Error(`Memory not found: ${memoryId}`);
3694
+ const current = existing.properties?.[field] ?? 0;
3695
+ await this.collection.data.update({
3696
+ id: memoryId,
3697
+ properties: { [field]: current + 1 }
3698
+ });
3699
+ }
3572
3700
  };
3573
3701
 
3574
3702
  // node_modules/@prmichaelsen/remember-core/dist/services/relationship.service.js
@@ -5010,6 +5138,42 @@ var SpaceService = class {
5010
5138
  });
5011
5139
  return { spaces_searched: spacesSearched, groups_searched: groupsSearched, results, total_pool_size: totalPoolSize };
5012
5140
  }
5141
+ // ── By Curated (composite quality score) ──────────────────────────
5142
+ async byCurated(input, authContext) {
5143
+ const spaces = input.spaces || [];
5144
+ const groups = input.groups || [];
5145
+ const limit = input.limit ?? 50;
5146
+ const offset = input.offset ?? 0;
5147
+ const direction = input.direction ?? "desc";
5148
+ this.validateSpaceGroupInput(spaces, groups, input.moderation_filter || "approved", authContext);
5149
+ const fetchLimit = (limit + offset) * 2;
5150
+ const hasQuery = input.query?.trim();
5151
+ const { allResults, spacesSearched, groupsSearched } = await this.fetchAcrossCollections(input, spaces, groups, async (collection, baseFilters) => {
5152
+ const combined = baseFilters.length > 0 ? Filters4.and(...baseFilters) : void 0;
5153
+ if (hasQuery) {
5154
+ const opts2 = { limit: fetchLimit, alpha: 0.7, query: hasQuery };
5155
+ if (combined)
5156
+ opts2.filters = combined;
5157
+ return (await collection.query.hybrid(hasQuery, opts2)).objects;
5158
+ }
5159
+ const opts = {
5160
+ limit: fetchLimit,
5161
+ sort: collection.sort.byProperty("curated_score", direction === "asc")
5162
+ };
5163
+ if (combined)
5164
+ opts.filters = combined;
5165
+ return (await collection.query.fetchObjects(opts)).objects;
5166
+ });
5167
+ const deduped = dedupeBySourceId(allResults, input.dedupe);
5168
+ deduped.sort((a, b) => {
5169
+ const aVal = a.properties?.curated_score ?? 0;
5170
+ const bVal = b.properties?.curated_score ?? 0;
5171
+ return direction === "desc" ? bVal - aVal : aVal - bVal;
5172
+ });
5173
+ const paginated = deduped.slice(offset, offset + limit);
5174
+ const memories = paginated.filter((obj) => obj.properties?.doc_type === "memory").map((obj) => ({ id: obj.uuid, ...obj.properties }));
5175
+ return { spaces_searched: spacesSearched, groups_searched: groupsSearched, memories, total: memories.length, offset, limit };
5176
+ }
5013
5177
  // ── Private: Validate Space/Group Input ───────────────────────────
5014
5178
  validateSpaceGroupInput(spaces, groups, moderationFilter, authContext) {
5015
5179
  if (spaces.length > 0) {
@@ -5154,6 +5318,18 @@ var REM_STATE_COLLECTION = `${BASE}.rem_state`;
5154
5318
  // node_modules/@prmichaelsen/remember-core/dist/services/rem.clustering.js
5155
5319
  import { Filters as Filters5 } from "weaviate-client";
5156
5320
 
5321
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.service.js
5322
+ import { Filters as Filters9 } from "weaviate-client";
5323
+
5324
+ // node_modules/@prmichaelsen/remember-core/dist/services/scoring-context.service.js
5325
+ import { Filters as Filters6 } from "weaviate-client";
5326
+
5327
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.pruning.js
5328
+ import { Filters as Filters7 } from "weaviate-client";
5329
+
5330
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.reconciliation.js
5331
+ import { Filters as Filters8 } from "weaviate-client";
5332
+
5157
5333
  // node_modules/@prmichaelsen/remember-core/dist/services/classification.service.js
5158
5334
  var GENRES = [
5159
5335
  "short_story",
@@ -5789,12 +5965,12 @@ var searchMemoryTool = {
5789
5965
  }
5790
5966
  };
5791
5967
  async function handleSearchMemory(args, userId, authContext) {
5792
- const ghostMode = authContext?.ghostMode;
5793
- const searchUserId = ghostMode?.owner_user_id ?? userId;
5794
- const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation: ghostMode ? "ghost search" : "search memory" });
5968
+ const internalContext = authContext?.internalContext;
5969
+ const searchUserId = internalContext?.owner_user_id ?? userId;
5970
+ const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation: internalContext ? "internal search" : "search memory" });
5795
5971
  try {
5796
5972
  debug.info("Tool invoked");
5797
- debug.trace("Arguments", { args, ghostMode: !!ghostMode });
5973
+ debug.trace("Arguments", { args, internalContext: !!internalContext });
5798
5974
  if (!args.query || args.query.trim() === "") {
5799
5975
  throw new Error("Query cannot be empty");
5800
5976
  }
@@ -5803,18 +5979,21 @@ async function handleSearchMemory(args, userId, authContext) {
5803
5979
  userId: searchUserId,
5804
5980
  query: args.query,
5805
5981
  includeRelationships,
5806
- ghostMode: !!ghostMode
5982
+ internalContext: !!internalContext
5807
5983
  });
5808
5984
  const collection = getMemoryCollection2(searchUserId);
5809
5985
  const alpha = args.alpha ?? 0.7;
5810
5986
  const limit = args.limit ?? 10;
5811
5987
  const offset = args.offset ?? 0;
5812
5988
  const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
5813
- const trustFilter = ghostMode ? buildTrustFilter(collection, ghostMode.accessor_trust_level) : null;
5989
+ const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
5814
5990
  const searchFilters = includeRelationships ? buildCombinedSearchFilters(collection, args.filters) : buildMemoryOnlyFilters(collection, args.filters);
5815
5991
  const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
5816
- const ghostExclusionFilter = !hasExplicitTypeFilter ? collection.filter.byProperty("content_type").notEqual("ghost") : null;
5817
- const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, ghostExclusionFilter, searchFilters].filter((f) => f !== null));
5992
+ const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
5993
+ collection.filter.byProperty("content_type").notEqual("ghost"),
5994
+ collection.filter.byProperty("content_type").notEqual("agent")
5995
+ ]) : null;
5996
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
5818
5997
  const searchOptions = {
5819
5998
  alpha,
5820
5999
  limit,
@@ -6160,7 +6339,7 @@ async function handleFindSimilar(args, userId, authContext) {
6160
6339
  deleted_filter: args.deleted_filter
6161
6340
  });
6162
6341
  const filteredMemories = coreResult.similar_memories.filter(
6163
- (m) => m.content_type !== "ghost"
6342
+ (m) => m.content_type !== "ghost" && m.content_type !== "agent"
6164
6343
  );
6165
6344
  const result = {
6166
6345
  query: {
@@ -6303,27 +6482,30 @@ var queryMemoryTool = {
6303
6482
  }
6304
6483
  };
6305
6484
  async function handleQueryMemory(args, userId, authContext) {
6306
- const ghostMode = authContext?.ghostMode;
6307
- const searchUserId = ghostMode?.owner_user_id ?? userId;
6308
- const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation: ghostMode ? "ghost query" : "query memory" });
6485
+ const internalContext = authContext?.internalContext;
6486
+ const searchUserId = internalContext?.owner_user_id ?? userId;
6487
+ const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation: internalContext ? "internal query" : "query memory" });
6309
6488
  try {
6310
6489
  debug.info("Tool invoked");
6311
- debug.trace("Arguments", { args, ghostMode: !!ghostMode });
6490
+ debug.trace("Arguments", { args, internalContext: !!internalContext });
6312
6491
  if (!args.query || args.query.trim() === "") {
6313
6492
  throw new Error("Query cannot be empty");
6314
6493
  }
6315
- logger.info("Querying memories", { userId: searchUserId, query: args.query, ghostMode: !!ghostMode });
6494
+ logger.info("Querying memories", { userId: searchUserId, query: args.query, internalContext: !!internalContext });
6316
6495
  const collection = getMemoryCollection2(searchUserId);
6317
6496
  const limit = args.limit ?? 5;
6318
6497
  const minRelevance = args.min_relevance ?? 0.6;
6319
6498
  const includeContext = args.include_context ?? true;
6320
6499
  const format = args.format ?? "detailed";
6321
6500
  const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
6322
- const trustFilter = ghostMode ? buildTrustFilter(collection, ghostMode.accessor_trust_level) : null;
6501
+ const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
6323
6502
  const searchFilters = buildCombinedSearchFilters(collection, args.filters);
6324
6503
  const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
6325
- const ghostExclusionFilter = !hasExplicitTypeFilter ? collection.filter.byProperty("content_type").notEqual("ghost") : null;
6326
- const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, ghostExclusionFilter, searchFilters].filter((f) => f !== null));
6504
+ const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
6505
+ collection.filter.byProperty("content_type").notEqual("ghost"),
6506
+ collection.filter.byProperty("content_type").notEqual("agent")
6507
+ ]) : null;
6508
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
6327
6509
  const searchOptions = {
6328
6510
  limit,
6329
6511
  distance: 1 - minRelevance,
@@ -7435,7 +7617,7 @@ async function handleDeny(args, userId, authContext) {
7435
7617
  }
7436
7618
 
7437
7619
  // src/tools/search-space.ts
7438
- import { Filters as Filters6 } from "weaviate-client";
7620
+ import { Filters as Filters10 } from "weaviate-client";
7439
7621
  var searchSpaceTool = {
7440
7622
  name: "remember_search_space",
7441
7623
  description: `Search shared spaces and/or groups to discover memories from other users.
@@ -1,9 +1,10 @@
1
1
  /**
2
- * remember_create_ghost_memory tool
3
- * Creates a ghost memory with hardcoded content_type and ghost-specific tags
2
+ * remember_create_internal_memory tool
3
+ * Creates a ghost or agent memory based on the current session's InternalContext.
4
+ * Content type and tags are derived from platform HTTP headers, not tool args.
4
5
  */
5
6
  import type { AuthContext } from '../types/auth.js';
6
- export declare const createGhostMemoryTool: {
7
+ export declare const createInternalMemoryTool: {
7
8
  name: string;
8
9
  description: string;
9
10
  inputSchema: {
@@ -40,25 +41,22 @@ export declare const createGhostMemoryTool: {
40
41
  type: string;
41
42
  minimum: number;
42
43
  maximum: number;
43
- description: string;
44
44
  };
45
45
  feel_social_weight: {
46
46
  type: string;
47
47
  minimum: number;
48
48
  maximum: number;
49
- description: string;
50
49
  };
51
50
  feel_narrative_importance: {
52
51
  type: string;
53
52
  minimum: number;
54
53
  maximum: number;
55
- description: string;
56
54
  };
57
55
  };
58
56
  required: string[];
59
57
  };
60
58
  };
61
- export interface CreateGhostMemoryArgs {
59
+ export interface CreateInternalMemoryArgs {
62
60
  content: string;
63
61
  title?: string;
64
62
  tags?: string[];
@@ -66,5 +64,5 @@ export interface CreateGhostMemoryArgs {
66
64
  trust?: number;
67
65
  [key: string]: any;
68
66
  }
69
- export declare function handleCreateGhostMemory(args: CreateGhostMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
70
- //# sourceMappingURL=create-ghost-memory.d.ts.map
67
+ export declare function handleCreateInternalMemory(args: CreateInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
68
+ //# sourceMappingURL=create-internal-memory.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=internal-tools.spec.d.ts.map
@@ -1,9 +1,9 @@
1
1
  /**
2
- * remember_query_ghost_memory tool
3
- * Wraps query_memory with hardcoded ghost type filter
2
+ * remember_query_internal_memory tool
3
+ * Wraps query_memory with auto-scoped content type and ghost source filters.
4
4
  */
5
5
  import type { AuthContext } from '../types/auth.js';
6
- export declare const queryGhostMemoryTool: {
6
+ export declare const queryInternalMemoryTool: {
7
7
  name: string;
8
8
  description: string;
9
9
  inputSchema: {
@@ -25,10 +25,10 @@ export declare const queryGhostMemoryTool: {
25
25
  required: string[];
26
26
  };
27
27
  };
28
- export interface QueryGhostMemoryArgs {
28
+ export interface QueryInternalMemoryArgs {
29
29
  query: string;
30
30
  limit?: number;
31
31
  min_relevance?: number;
32
32
  }
33
- export declare function handleQueryGhostMemory(args: QueryGhostMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
34
- //# sourceMappingURL=query-ghost-memory.d.ts.map
33
+ export declare function handleQueryInternalMemory(args: QueryInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
34
+ //# sourceMappingURL=query-internal-memory.d.ts.map
@@ -1,10 +1,10 @@
1
1
  /**
2
- * remember_search_ghost_memory_by tool
3
- * Wraps search_by with hardcoded ghost type filter
2
+ * remember_search_internal_memory_by tool
3
+ * Wraps search_by with auto-scoped content type and ghost source filters.
4
4
  */
5
5
  import type { AuthContext } from '../types/auth.js';
6
6
  import type { SearchByMode } from './search-by.js';
7
- export declare const searchGhostMemoryByTool: {
7
+ export declare const searchInternalMemoryByTool: {
8
8
  name: string;
9
9
  description: string;
10
10
  inputSchema: {
@@ -41,7 +41,7 @@ export declare const searchGhostMemoryByTool: {
41
41
  required: string[];
42
42
  };
43
43
  };
44
- export interface SearchGhostMemoryByArgs {
44
+ export interface SearchInternalMemoryByArgs {
45
45
  mode: SearchByMode;
46
46
  query?: string;
47
47
  sort_order?: 'asc' | 'desc';
@@ -50,5 +50,5 @@ export interface SearchGhostMemoryByArgs {
50
50
  offset?: number;
51
51
  deleted_filter?: 'exclude' | 'include' | 'only';
52
52
  }
53
- export declare function handleSearchGhostMemoryBy(args: SearchGhostMemoryByArgs, userId: string, authContext?: AuthContext): Promise<string>;
54
- //# sourceMappingURL=search-ghost-memory-by.d.ts.map
53
+ export declare function handleSearchInternalMemoryBy(args: SearchInternalMemoryByArgs, userId: string, authContext?: AuthContext): Promise<string>;
54
+ //# sourceMappingURL=search-internal-memory-by.d.ts.map
@@ -1,9 +1,9 @@
1
1
  /**
2
- * remember_search_ghost_memory tool
3
- * Wraps search_memory with hardcoded ghost type filter
2
+ * remember_search_internal_memory tool
3
+ * Wraps search_memory with auto-scoped content type and ghost source filters.
4
4
  */
5
5
  import type { AuthContext } from '../types/auth.js';
6
- export declare const searchGhostMemoryTool: {
6
+ export declare const searchInternalMemoryTool: {
7
7
  name: string;
8
8
  description: string;
9
9
  inputSchema: {
@@ -41,7 +41,7 @@ export declare const searchGhostMemoryTool: {
41
41
  required: string[];
42
42
  };
43
43
  };
44
- export interface SearchGhostMemoryArgs {
44
+ export interface SearchInternalMemoryArgs {
45
45
  query: string;
46
46
  alpha?: number;
47
47
  tags?: string[];
@@ -49,5 +49,5 @@ export interface SearchGhostMemoryArgs {
49
49
  offset?: number;
50
50
  deleted_filter?: 'exclude' | 'include' | 'only';
51
51
  }
52
- export declare function handleSearchGhostMemory(args: SearchGhostMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
53
- //# sourceMappingURL=search-ghost-memory.d.ts.map
52
+ export declare function handleSearchInternalMemory(args: SearchInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
53
+ //# sourceMappingURL=search-internal-memory.d.ts.map
@@ -1,9 +1,9 @@
1
1
  /**
2
- * remember_update_ghost_memory tool
3
- * Updates a ghost memory after validating content_type
2
+ * remember_update_internal_memory tool
3
+ * Updates a ghost or agent memory after validating content_type matches session context.
4
4
  */
5
5
  import type { AuthContext } from '../types/auth.js';
6
- export declare const updateGhostMemoryTool: {
6
+ export declare const updateInternalMemoryTool: {
7
7
  name: string;
8
8
  description: string;
9
9
  inputSchema: {
@@ -39,7 +39,7 @@ export declare const updateGhostMemoryTool: {
39
39
  required: string[];
40
40
  };
41
41
  };
42
- export interface UpdateGhostMemoryArgs {
42
+ export interface UpdateInternalMemoryArgs {
43
43
  memory_id: string;
44
44
  content?: string;
45
45
  title?: string;
@@ -47,5 +47,5 @@ export interface UpdateGhostMemoryArgs {
47
47
  weight?: number;
48
48
  trust?: number;
49
49
  }
50
- export declare function handleUpdateGhostMemory(args: UpdateGhostMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
51
- //# sourceMappingURL=update-ghost-memory.d.ts.map
50
+ export declare function handleUpdateInternalMemory(args: UpdateInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
51
+ //# sourceMappingURL=update-internal-memory.d.ts.map
@@ -24,20 +24,34 @@ export interface UserCredentials {
24
24
  user_id: string;
25
25
  group_memberships: GroupMembership[];
26
26
  }
27
- /** Ghost conversation context — resolved server-side, never from tool args */
28
- export interface GhostModeContext {
29
- /** The ghost owner's user ID (whose memories are being searched) */
30
- owner_user_id: string;
31
- /** The accessor's user ID (who is chatting with the ghost) */
27
+ /**
28
+ * Internal context for ghost/agent sessions — resolved server-side from
29
+ * platform HTTP headers, never from tool args.
30
+ *
31
+ * Replaces the former GhostModeContext. All ghost identity, trust, and
32
+ * agent context is unified here.
33
+ */
34
+ export interface InternalContext {
35
+ /** Whether this is a ghost or agent session */
36
+ type: 'ghost' | 'agent';
37
+ /** Ghost sub-type (required when type is 'ghost') */
38
+ ghost_type?: 'user' | 'space' | 'group';
39
+ /** Space ID (space ghosts only) */
40
+ ghost_space?: string;
41
+ /** Group ID (group ghosts only) */
42
+ ghost_group?: string;
43
+ /** The ghost owner's user ID (user ghosts — whose memories are searched) */
44
+ owner_user_id?: string;
45
+ /** The accessor's user ID (who is conversing) */
32
46
  accessor_user_id: string;
33
47
  /** Resolved trust level (looked up from GhostConfig, not user-supplied) */
34
- accessor_trust_level: number;
48
+ accessor_trust_level?: number;
35
49
  }
36
50
  export interface AuthContext {
37
51
  accessToken: string | null;
38
52
  credentials: UserCredentials | null;
39
- /** Present when the server is running in ghost conversation mode */
40
- ghostMode?: GhostModeContext;
53
+ /** Present when the server is running in ghost or agent mode */
54
+ internalContext?: InternalContext;
41
55
  }
42
56
  export type WriteMode = 'owner_only' | 'group_editors' | 'anyone';
43
57
  export interface CredentialsProvider {
@@ -0,0 +1,14 @@
1
+ import type { AuthContext } from '../types/auth.js';
2
+ /**
3
+ * Build tags for internal (ghost/agent) memories based on the current
4
+ * session's InternalContext. These tags implement ghost source isolation
5
+ * so memories from different ghost conversations are distinguishable.
6
+ *
7
+ * Tag scheme:
8
+ * User ghost (alice): ['ghost', 'ghost_type:user', 'ghost_owner:user:alice']
9
+ * Space ghost (music-lovers): ['ghost', 'ghost_type:space', 'ghost_owner:space:music-lovers']
10
+ * Group ghost (band-mates): ['ghost', 'ghost_type:group', 'ghost_owner:group:band-mates']
11
+ * Agent: ['agent']
12
+ */
13
+ export declare function buildInternalTags(authContext: AuthContext): string[];
14
+ //# sourceMappingURL=internal-tags.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=internal-tags.spec.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "3.15.7",
3
+ "version": "3.16.2",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -51,8 +51,7 @@
51
51
  "@google-cloud/vision": "^5.3.4",
52
52
  "@modelcontextprotocol/sdk": "^1.0.4",
53
53
  "@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
54
- "@prmichaelsen/mcp-auth": "^7.0.4",
55
- "@prmichaelsen/remember-core": "^0.45.0",
54
+ "@prmichaelsen/remember-core": "^0.49.16",
56
55
  "dotenv": "^16.4.5",
57
56
  "uuid": "^13.0.0",
58
57
  "weaviate-client": "^3.2.0"
@@ -24,12 +24,14 @@ export function e2eAuthContext(): AuthContext {
24
24
  return { accessToken: null, credentials: null };
25
25
  }
26
26
 
27
- /** AuthContext with ghost mode for cross-user tests */
27
+ /** AuthContext with ghost internal context for cross-user tests */
28
28
  export function e2eGhostAuthContext(ownerUserId: string, accessorUserId: string, trustLevel = 0.5): AuthContext {
29
29
  return {
30
30
  accessToken: null,
31
31
  credentials: null,
32
- ghostMode: {
32
+ internalContext: {
33
+ type: 'ghost',
34
+ ghost_type: 'user',
33
35
  owner_user_id: ownerUserId,
34
36
  accessor_user_id: accessorUserId,
35
37
  accessor_trust_level: trustLevel,