@prmichaelsen/remember-mcp 3.0.0 → 3.13.0

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 (208) hide show
  1. package/AGENT.md +296 -250
  2. package/CHANGELOG.md +358 -0
  3. package/README.md +68 -45
  4. package/agent/commands/acp.clarification-create.md +382 -0
  5. package/agent/commands/acp.project-info.md +309 -0
  6. package/agent/commands/acp.project-remove.md +379 -0
  7. package/agent/commands/acp.project-update.md +296 -0
  8. package/agent/commands/acp.task-create.md +17 -9
  9. package/agent/commands/git.commit.md +13 -1
  10. package/agent/design/comment-memory-type.md +2 -2
  11. package/agent/design/local.collaborative-memory-sync.md +265 -0
  12. package/agent/design/local.content-flags.md +210 -0
  13. package/agent/design/local.ghost-persona-system.md +273 -0
  14. package/agent/design/local.group-acl-integration.md +338 -0
  15. package/agent/design/local.memory-acl-schema.md +352 -0
  16. package/agent/design/local.memory-collection-pattern-v2.md +348 -0
  17. package/agent/design/local.moderation-and-space-config.md +257 -0
  18. package/agent/design/local.v2-api-reference.md +621 -0
  19. package/agent/design/local.v2-migration-guide.md +191 -0
  20. package/agent/design/local.v2-usage-examples.md +265 -0
  21. package/agent/design/permissions-storage-architecture.md +11 -3
  22. package/agent/design/trust-escalation-prevention.md +9 -2
  23. package/agent/design/trust-system-implementation.md +12 -3
  24. package/agent/milestones/milestone-14-memory-collection-v2.md +182 -0
  25. package/agent/milestones/milestone-15-moderation-space-config.md +126 -0
  26. package/agent/progress.yaml +628 -49
  27. package/agent/scripts/acp.common.sh +2 -0
  28. package/agent/scripts/acp.install.sh +11 -1
  29. package/agent/scripts/acp.package-install-optimized.sh +454 -0
  30. package/agent/scripts/acp.package-install.sh +247 -300
  31. package/agent/scripts/acp.project-info.sh +218 -0
  32. package/agent/scripts/acp.project-remove.sh +302 -0
  33. package/agent/scripts/acp.project-update.sh +296 -0
  34. package/agent/scripts/acp.yaml-parser.sh +128 -10
  35. package/agent/tasks/milestone-14-memory-collection-v2/task-165-core-infrastructure-setup.md +171 -0
  36. package/agent/tasks/milestone-14-memory-collection-v2/task-166-update-remember-publish.md +191 -0
  37. package/agent/tasks/milestone-14-memory-collection-v2/task-167-update-remember-retract.md +186 -0
  38. package/agent/tasks/milestone-14-memory-collection-v2/task-168-implement-remember-revise.md +184 -0
  39. package/agent/tasks/milestone-14-memory-collection-v2/task-169-update-remember-search-space.md +179 -0
  40. package/agent/tasks/milestone-14-memory-collection-v2/task-170-update-remember-create-update.md +139 -0
  41. package/agent/tasks/milestone-14-memory-collection-v2/task-172-performance-testing-optimization.md +161 -0
  42. package/agent/tasks/milestone-14-memory-collection-v2/task-173-documentation-examples.md +258 -0
  43. package/agent/tasks/milestone-15-moderation-space-config/task-174-add-moderation-schema-fields.md +57 -0
  44. package/agent/tasks/milestone-15-moderation-space-config/task-175-create-space-config-service.md +64 -0
  45. package/agent/tasks/milestone-15-moderation-space-config/task-176-wire-moderation-publish-flow.md +45 -0
  46. package/agent/tasks/milestone-15-moderation-space-config/task-177-add-moderation-search-filters.md +70 -0
  47. package/agent/tasks/milestone-15-moderation-space-config/task-178-create-remember-moderate-tool.md +69 -0
  48. package/agent/tasks/milestone-15-moderation-space-config/task-179-documentation-integration-tests.md +58 -0
  49. package/agent/tasks/milestone-16-ghost-system/task-187-ghost-config-firestore.md +41 -0
  50. package/agent/tasks/milestone-16-ghost-system/task-188-trust-filter-integration.md +44 -0
  51. package/agent/tasks/milestone-16-ghost-system/task-189-ghost-memory-filtering.md +43 -0
  52. package/agent/tasks/milestone-16-ghost-system/task-190-ghost-config-tools.md +45 -0
  53. package/agent/tasks/milestone-16-ghost-system/task-191-escalation-firestore.md +38 -0
  54. package/agent/tasks/milestone-16-ghost-system/task-192-documentation-verification.md +39 -0
  55. package/agent/tasks/milestone-7-trust-permissions/task-180-access-result-permission-types.md +69 -0
  56. package/agent/tasks/milestone-7-trust-permissions/task-181-firestore-permissions-access-logs.md +56 -0
  57. package/agent/tasks/milestone-7-trust-permissions/task-182-trust-enforcement-service.md +68 -0
  58. package/agent/tasks/milestone-7-trust-permissions/task-183-access-control-service.md +70 -0
  59. package/agent/tasks/milestone-7-trust-permissions/task-184-permission-tools.md +79 -0
  60. package/agent/tasks/milestone-7-trust-permissions/task-185-wire-trust-into-search-query.md +55 -0
  61. package/agent/tasks/milestone-7-trust-permissions/task-186-documentation-verification.md +56 -0
  62. package/agent/tasks/task-76-fix-indexnullstate-schema-bug.md +197 -0
  63. package/dist/collections/composite-ids.d.ts +106 -0
  64. package/dist/collections/core-infrastructure.spec.d.ts +11 -0
  65. package/dist/collections/dot-notation.d.ts +106 -0
  66. package/dist/collections/tracking-arrays.d.ts +176 -0
  67. package/dist/constants/content-types.d.ts +1 -0
  68. package/dist/schema/v2-collections-comments.spec.d.ts +8 -0
  69. package/dist/schema/v2-collections.d.ts +210 -0
  70. package/dist/server-factory.d.ts +15 -0
  71. package/dist/server-factory.js +2798 -1029
  72. package/dist/server.js +2526 -1012
  73. package/dist/services/access-control.d.ts +103 -0
  74. package/dist/services/access-control.spec.d.ts +2 -0
  75. package/dist/services/credentials-provider.d.ts +24 -0
  76. package/dist/services/credentials-provider.spec.d.ts +2 -0
  77. package/dist/services/escalation.service.d.ts +22 -0
  78. package/dist/services/escalation.service.spec.d.ts +2 -0
  79. package/dist/services/ghost-config.service.d.ts +55 -0
  80. package/dist/services/ghost-config.service.spec.d.ts +2 -0
  81. package/dist/services/space-config.service.d.ts +23 -0
  82. package/dist/services/space-config.service.spec.d.ts +2 -0
  83. package/dist/services/trust-enforcement.d.ts +83 -0
  84. package/dist/services/trust-enforcement.spec.d.ts +2 -0
  85. package/dist/services/trust-validator.d.ts +43 -0
  86. package/dist/services/trust-validator.spec.d.ts +2 -0
  87. package/dist/tools/confirm-publish-moderation.spec.d.ts +8 -0
  88. package/dist/tools/confirm.d.ts +8 -1
  89. package/dist/tools/create-memory.d.ts +2 -1
  90. package/dist/tools/create-memory.spec.d.ts +10 -0
  91. package/dist/tools/create-relationship.d.ts +2 -1
  92. package/dist/tools/delete-memory.d.ts +2 -1
  93. package/dist/tools/delete-relationship.d.ts +2 -1
  94. package/dist/tools/deny.d.ts +2 -1
  95. package/dist/tools/find-similar.d.ts +2 -1
  96. package/dist/tools/get-preferences.d.ts +2 -1
  97. package/dist/tools/ghost-config.d.ts +27 -0
  98. package/dist/tools/ghost-config.spec.d.ts +2 -0
  99. package/dist/tools/moderate.d.ts +20 -0
  100. package/dist/tools/moderate.spec.d.ts +5 -0
  101. package/dist/tools/publish.d.ts +11 -3
  102. package/dist/tools/query-memory.d.ts +3 -1
  103. package/dist/tools/query-space.d.ts +4 -1
  104. package/dist/tools/retract.d.ts +29 -0
  105. package/dist/tools/revise.d.ts +45 -0
  106. package/dist/tools/revise.spec.d.ts +8 -0
  107. package/dist/tools/search-memory.d.ts +2 -1
  108. package/dist/tools/search-relationship.d.ts +2 -1
  109. package/dist/tools/search-space.d.ts +25 -5
  110. package/dist/tools/search-space.spec.d.ts +9 -0
  111. package/dist/tools/set-preference.d.ts +2 -1
  112. package/dist/tools/update-memory.d.ts +2 -1
  113. package/dist/tools/update-relationship.d.ts +2 -1
  114. package/dist/types/access-result.d.ts +48 -0
  115. package/dist/types/access-result.spec.d.ts +2 -0
  116. package/dist/types/auth.d.ts +46 -0
  117. package/dist/types/ghost-config.d.ts +36 -0
  118. package/dist/types/memory.d.ts +3 -1
  119. package/dist/types/preferences.d.ts +1 -1
  120. package/dist/utils/auth-helpers.d.ts +14 -0
  121. package/dist/utils/auth-helpers.spec.d.ts +2 -0
  122. package/dist/utils/test-data-generator.d.ts +124 -0
  123. package/dist/utils/test-data-generator.spec.d.ts +12 -0
  124. package/dist/v2-performance.e2e.d.ts +17 -0
  125. package/dist/v2-smoke.e2e.d.ts +14 -0
  126. package/dist/weaviate/client.d.ts +5 -8
  127. package/dist/weaviate/space-schema.d.ts +2 -2
  128. package/docs/performance/v2-benchmarks.md +80 -0
  129. package/jest.e2e.config.js +14 -3
  130. package/package.json +1 -1
  131. package/scripts/.collection-recreation-state.yaml +16 -0
  132. package/scripts/.gitkeep +5 -0
  133. package/scripts/README-collection-recreation.md +224 -0
  134. package/scripts/README.md +51 -0
  135. package/scripts/backup-collections.ts +543 -0
  136. package/scripts/delete-collection.ts +137 -0
  137. package/scripts/migrate-recreate-collections.ts +578 -0
  138. package/scripts/migrate-v1-to-v2.ts +1094 -0
  139. package/scripts/package-lock.json +1113 -0
  140. package/scripts/package.json +27 -0
  141. package/src/collections/composite-ids.ts +193 -0
  142. package/src/collections/core-infrastructure.spec.ts +353 -0
  143. package/src/collections/dot-notation.ts +212 -0
  144. package/src/collections/tracking-arrays.ts +298 -0
  145. package/src/constants/content-types.ts +20 -0
  146. package/src/schema/v2-collections-comments.spec.ts +141 -0
  147. package/src/schema/v2-collections.ts +433 -0
  148. package/src/server-factory.ts +89 -20
  149. package/src/server.ts +45 -17
  150. package/src/services/access-control.spec.ts +383 -0
  151. package/src/services/access-control.ts +291 -0
  152. package/src/services/credentials-provider.spec.ts +22 -0
  153. package/src/services/credentials-provider.ts +34 -0
  154. package/src/services/escalation.service.spec.ts +183 -0
  155. package/src/services/escalation.service.ts +150 -0
  156. package/src/services/ghost-config.service.spec.ts +339 -0
  157. package/src/services/ghost-config.service.ts +219 -0
  158. package/src/services/space-config.service.spec.ts +102 -0
  159. package/src/services/space-config.service.ts +79 -0
  160. package/src/services/trust-enforcement.spec.ts +309 -0
  161. package/src/services/trust-enforcement.ts +197 -0
  162. package/src/services/trust-validator.spec.ts +108 -0
  163. package/src/services/trust-validator.ts +105 -0
  164. package/src/tools/confirm-publish-moderation.spec.ts +240 -0
  165. package/src/tools/confirm.ts +869 -135
  166. package/src/tools/create-memory.spec.ts +126 -0
  167. package/src/tools/create-memory.ts +20 -27
  168. package/src/tools/create-relationship.ts +17 -8
  169. package/src/tools/delete-memory.ts +13 -6
  170. package/src/tools/delete-relationship.ts +15 -6
  171. package/src/tools/deny.ts +8 -1
  172. package/src/tools/find-similar.ts +21 -8
  173. package/src/tools/get-preferences.ts +10 -1
  174. package/src/tools/ghost-config.spec.ts +180 -0
  175. package/src/tools/ghost-config.ts +230 -0
  176. package/src/tools/moderate.spec.ts +277 -0
  177. package/src/tools/moderate.ts +219 -0
  178. package/src/tools/publish.ts +99 -41
  179. package/src/tools/query-memory.ts +28 -6
  180. package/src/tools/query-space.ts +39 -4
  181. package/src/tools/retract.ts +292 -0
  182. package/src/tools/revise.spec.ts +146 -0
  183. package/src/tools/revise.ts +283 -0
  184. package/src/tools/search-memory.ts +30 -7
  185. package/src/tools/search-relationship.ts +11 -2
  186. package/src/tools/search-space.spec.ts +341 -0
  187. package/src/tools/search-space.ts +323 -99
  188. package/src/tools/set-preference.ts +10 -1
  189. package/src/tools/update-memory.ts +16 -5
  190. package/src/tools/update-relationship.ts +10 -1
  191. package/src/types/access-result.spec.ts +193 -0
  192. package/src/types/access-result.ts +62 -0
  193. package/src/types/auth.ts +52 -0
  194. package/src/types/ghost-config.ts +46 -0
  195. package/src/types/memory.ts +9 -1
  196. package/src/types/preferences.ts +2 -2
  197. package/src/utils/auth-helpers.spec.ts +75 -0
  198. package/src/utils/auth-helpers.ts +25 -0
  199. package/src/utils/test-data-generator.spec.ts +317 -0
  200. package/src/utils/test-data-generator.ts +292 -0
  201. package/src/utils/weaviate-filters.ts +4 -4
  202. package/src/v2-performance.e2e.ts +173 -0
  203. package/src/v2-smoke.e2e.ts +401 -0
  204. package/src/weaviate/client.spec.ts +5 -5
  205. package/src/weaviate/client.ts +51 -36
  206. package/src/weaviate/schema.ts +11 -256
  207. package/src/weaviate/space-schema.spec.ts +24 -24
  208. package/src/weaviate/space-schema.ts +18 -6
@@ -0,0 +1,433 @@
1
+ /**
2
+ * Weaviate Schema Definitions for Memory Collection Pattern v2
3
+ *
4
+ * Defines schemas for the three collection types:
5
+ * 1. Memory_users_{userId} - User's private memories
6
+ * 2. Memory_spaces_public - Shared space memories
7
+ * 3. Memory_groups_{groupId} - Group memories
8
+ */
9
+
10
+ import weaviate, { WeaviateClient, configure } from 'weaviate-client';
11
+
12
+ /**
13
+ * Common properties shared across all memory collection types
14
+ *
15
+ * Note: 'id' is NOT included — it is reserved by Weaviate for the UUID primary key.
16
+ * Use the Weaviate UUID as the memory identifier. For published memories, store the
17
+ * composite ID ({userId}.{memoryId}) in 'original_memory_id' on the published copy.
18
+ */
19
+ const COMMON_MEMORY_PROPERTIES = [
20
+ // Core content
21
+ { name: 'content', dataType: configure.dataType.TEXT },
22
+ { name: 'content_type', dataType: configure.dataType.TEXT },
23
+ { name: 'title', dataType: configure.dataType.TEXT },
24
+ { name: 'summary', dataType: configure.dataType.TEXT },
25
+ { name: 'type', dataType: configure.dataType.TEXT }, // v1 compat (v2: content_type)
26
+
27
+ // Tracking arrays (v2 feature)
28
+ { name: 'space_ids', dataType: configure.dataType.TEXT_ARRAY },
29
+ { name: 'group_ids', dataType: configure.dataType.TEXT_ARRAY },
30
+
31
+ // Metadata
32
+ { name: 'created_at', dataType: configure.dataType.DATE },
33
+ { name: 'updated_at', dataType: configure.dataType.DATE },
34
+ { name: 'version', dataType: configure.dataType.INT },
35
+
36
+ // User context
37
+ { name: 'user_id', dataType: configure.dataType.TEXT },
38
+
39
+ // Document type (memory, relationship, comment)
40
+ { name: 'doc_type', dataType: configure.dataType.TEXT },
41
+
42
+ // Memory-specific fields
43
+ { name: 'tags', dataType: configure.dataType.TEXT_ARRAY },
44
+ { name: 'weight', dataType: configure.dataType.NUMBER },
45
+ { name: 'trust_score', dataType: configure.dataType.NUMBER },
46
+ { name: 'trust', dataType: configure.dataType.NUMBER }, // v1 compat (v2: trust_score)
47
+ { name: 'base_weight', dataType: configure.dataType.NUMBER },
48
+ { name: 'computed_weight', dataType: configure.dataType.NUMBER },
49
+ { name: 'confidence', dataType: configure.dataType.NUMBER },
50
+ { name: 'strength', dataType: configure.dataType.NUMBER },
51
+
52
+ // Location data (v2 names)
53
+ { name: 'location_name', dataType: configure.dataType.TEXT },
54
+ { name: 'location_lat', dataType: configure.dataType.NUMBER },
55
+ { name: 'location_lon', dataType: configure.dataType.NUMBER },
56
+ // Location data (v1 compat)
57
+ { name: 'location_gps_lat', dataType: configure.dataType.NUMBER },
58
+ { name: 'location_gps_lng', dataType: configure.dataType.NUMBER },
59
+ { name: 'location_address', dataType: configure.dataType.TEXT },
60
+ { name: 'location_city', dataType: configure.dataType.TEXT },
61
+ { name: 'location_country', dataType: configure.dataType.TEXT },
62
+ { name: 'location_source', dataType: configure.dataType.TEXT },
63
+
64
+ // Locale
65
+ { name: 'locale_language', dataType: configure.dataType.TEXT },
66
+ { name: 'locale_timezone', dataType: configure.dataType.TEXT },
67
+
68
+ // Context
69
+ { name: 'context_app', dataType: configure.dataType.TEXT },
70
+ { name: 'context_url', dataType: configure.dataType.TEXT },
71
+ { name: 'context_conversation_id', dataType: configure.dataType.TEXT },
72
+ { name: 'context_summary', dataType: configure.dataType.TEXT },
73
+ { name: 'context_timestamp', dataType: configure.dataType.DATE },
74
+
75
+ // Relationships (v2 names)
76
+ { name: 'relationship_ids', dataType: configure.dataType.TEXT_ARRAY },
77
+ { name: 'relationship_type', dataType: configure.dataType.TEXT },
78
+ { name: 'related_memory_ids', dataType: configure.dataType.TEXT_ARRAY },
79
+ { name: 'observation', dataType: configure.dataType.TEXT },
80
+ // Relationships (v1 compat)
81
+ { name: 'relationships', dataType: configure.dataType.TEXT_ARRAY },
82
+ { name: 'memory_ids', dataType: configure.dataType.TEXT_ARRAY },
83
+
84
+ // Access tracking
85
+ { name: 'access_count', dataType: configure.dataType.NUMBER },
86
+ { name: 'last_accessed_at', dataType: configure.dataType.DATE },
87
+
88
+ // References & templates
89
+ { name: 'references', dataType: configure.dataType.TEXT_ARRAY },
90
+ { name: 'template_id', dataType: configure.dataType.TEXT },
91
+
92
+ // Comments (Phase 1)
93
+ { name: 'parent_id', dataType: configure.dataType.TEXT },
94
+ { name: 'thread_root_id', dataType: configure.dataType.TEXT },
95
+ { name: 'moderation_flags', dataType: configure.dataType.TEXT_ARRAY },
96
+
97
+ // Soft delete
98
+ { name: 'deleted_at', dataType: configure.dataType.DATE },
99
+ { name: 'deleted_by', dataType: configure.dataType.TEXT },
100
+ { name: 'deletion_reason', dataType: configure.dataType.TEXT },
101
+ ];
102
+
103
+ /**
104
+ * Additional properties for published memories (spaces and groups)
105
+ */
106
+ const PUBLISHED_MEMORY_PROPERTIES = [
107
+ // Publication metadata
108
+ { name: 'published_at', dataType: configure.dataType.DATE },
109
+ { name: 'revised_at', dataType: configure.dataType.DATE },
110
+
111
+ // Attribution
112
+ { name: 'author_id', dataType: configure.dataType.TEXT },
113
+ { name: 'ghost_id', dataType: configure.dataType.TEXT },
114
+ { name: 'attribution', dataType: configure.dataType.TEXT },
115
+
116
+ // Discovery
117
+ { name: 'discovery_count', dataType: configure.dataType.INT },
118
+
119
+ // Revision tracking
120
+ { name: 'revision_count', dataType: configure.dataType.INT },
121
+ { name: 'original_memory_id', dataType: configure.dataType.TEXT },
122
+
123
+ // Moderation (nullable — null defaults to approved)
124
+ { name: 'moderation_status', dataType: configure.dataType.TEXT },
125
+ { name: 'moderated_by', dataType: configure.dataType.TEXT },
126
+ { name: 'moderated_at', dataType: configure.dataType.DATE },
127
+
128
+ // Memory-level ACL (nullable — null defaults to owner_only semantics)
129
+ { name: 'write_mode', dataType: configure.dataType.TEXT },
130
+ { name: 'owner_id', dataType: configure.dataType.TEXT },
131
+ { name: 'overwrite_allowed_ids', dataType: configure.dataType.TEXT_ARRAY },
132
+ { name: 'last_revised_by', dataType: configure.dataType.TEXT },
133
+
134
+ // Legacy compatibility (deprecated but kept for migration)
135
+ { name: 'spaces', dataType: configure.dataType.TEXT_ARRAY },
136
+ { name: 'space_id', dataType: configure.dataType.TEXT },
137
+ { name: 'space_memory_id', dataType: configure.dataType.TEXT },
138
+ ];
139
+
140
+ /**
141
+ * Create schema for a user's private memory collection
142
+ *
143
+ * @param userId - The user ID
144
+ * @returns Weaviate collection schema configuration
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const schema = createUserCollectionSchema('user123')
149
+ * await client.collections.create(schema)
150
+ * ```
151
+ */
152
+ export function createUserCollectionSchema(userId: string) {
153
+ const collectionName = `Memory_users_${userId}`;
154
+
155
+ return {
156
+ name: collectionName,
157
+ description: `Private memory collection for user: ${userId}`,
158
+
159
+ // Vector configuration
160
+ vectorizers: configure.vectorizer.text2VecOpenAI({
161
+ model: 'text-embedding-3-small',
162
+ dimensions: 1536,
163
+ vectorizeCollectionName: false,
164
+ }),
165
+
166
+ // Properties
167
+ properties: COMMON_MEMORY_PROPERTIES,
168
+
169
+ // Inverted index configuration
170
+ invertedIndex: configure.invertedIndex({
171
+ indexNullState: true,
172
+ indexPropertyLength: true,
173
+ indexTimestamps: true,
174
+ }),
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Create schema for the shared spaces collection
180
+ *
181
+ * @returns Weaviate collection schema configuration
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const schema = createSpaceCollectionSchema()
186
+ * await client.collections.create(schema)
187
+ * ```
188
+ */
189
+ export function createSpaceCollectionSchema() {
190
+ const collectionName = 'Memory_spaces_public';
191
+
192
+ return {
193
+ name: collectionName,
194
+ description: 'Shared memory collection for all public spaces',
195
+
196
+ // Vector configuration
197
+ vectorizers: configure.vectorizer.text2VecOpenAI({
198
+ model: 'text-embedding-3-small',
199
+ dimensions: 1536,
200
+ vectorizeCollectionName: false,
201
+ }),
202
+
203
+ // Properties (common + published)
204
+ properties: [
205
+ ...COMMON_MEMORY_PROPERTIES,
206
+ ...PUBLISHED_MEMORY_PROPERTIES,
207
+ ],
208
+
209
+ // Inverted index configuration
210
+ invertedIndex: configure.invertedIndex({
211
+ indexNullState: true,
212
+ indexPropertyLength: true,
213
+ indexTimestamps: true,
214
+ }),
215
+ };
216
+ }
217
+
218
+ /**
219
+ * Create schema for a group memory collection
220
+ *
221
+ * @param groupId - The group ID
222
+ * @returns Weaviate collection schema configuration
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const schema = createGroupCollectionSchema('group456')
227
+ * await client.collections.create(schema)
228
+ * ```
229
+ */
230
+ export function createGroupCollectionSchema(groupId: string) {
231
+ const collectionName = `Memory_groups_${groupId}`;
232
+
233
+ return {
234
+ name: collectionName,
235
+ description: `Group memory collection for group: ${groupId}`,
236
+
237
+ // Vector configuration
238
+ vectorizers: configure.vectorizer.text2VecOpenAI({
239
+ model: 'text-embedding-3-small',
240
+ dimensions: 1536,
241
+ vectorizeCollectionName: false,
242
+ }),
243
+
244
+ // Properties (common + published)
245
+ properties: [
246
+ ...COMMON_MEMORY_PROPERTIES,
247
+ ...PUBLISHED_MEMORY_PROPERTIES,
248
+ ],
249
+
250
+ // Inverted index configuration
251
+ invertedIndex: configure.invertedIndex({
252
+ indexNullState: true,
253
+ indexPropertyLength: true,
254
+ indexTimestamps: true,
255
+ }),
256
+ };
257
+ }
258
+
259
+ /**
260
+ * Ensure a user collection exists (create if needed)
261
+ *
262
+ * @param client - Weaviate client
263
+ * @param userId - The user ID
264
+ * @returns True if collection was created, false if it already existed
265
+ */
266
+ export async function ensureUserCollection(
267
+ client: WeaviateClient,
268
+ userId: string
269
+ ): Promise<boolean> {
270
+ const collectionName = `Memory_users_${userId}`;
271
+
272
+ try {
273
+ // Check if collection exists
274
+ const exists = await client.collections.exists(collectionName);
275
+
276
+ if (exists) {
277
+ return false;
278
+ }
279
+
280
+ // Create collection
281
+ const schema = createUserCollectionSchema(userId);
282
+ await client.collections.create(schema);
283
+
284
+ return true;
285
+ } catch (error) {
286
+ throw new Error(`Failed to ensure user collection for ${userId}: ${(error as Error).message}`);
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Ensure the spaces collection exists (create if needed)
292
+ *
293
+ * @param client - Weaviate client
294
+ * @returns True if collection was created, false if it already existed
295
+ */
296
+ export async function ensureSpaceCollection(client: WeaviateClient): Promise<boolean> {
297
+ const collectionName = 'Memory_spaces_public';
298
+
299
+ try {
300
+ // Check if collection exists
301
+ const exists = await client.collections.exists(collectionName);
302
+
303
+ if (exists) {
304
+ return false;
305
+ }
306
+
307
+ // Create collection
308
+ const schema = createSpaceCollectionSchema();
309
+ await client.collections.create(schema);
310
+
311
+ return true;
312
+ } catch (error) {
313
+ throw new Error(`Failed to ensure space collection: ${(error as Error).message}`);
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Ensure a group collection exists (create if needed)
319
+ *
320
+ * @param client - Weaviate client
321
+ * @param groupId - The group ID
322
+ * @returns True if collection was created, false if it already existed
323
+ */
324
+ export async function ensureGroupCollection(
325
+ client: WeaviateClient,
326
+ groupId: string
327
+ ): Promise<boolean> {
328
+ const collectionName = `Memory_groups_${groupId}`;
329
+
330
+ try {
331
+ // Check if collection exists
332
+ const exists = await client.collections.exists(collectionName);
333
+
334
+ if (exists) {
335
+ return false;
336
+ }
337
+
338
+ // Create collection
339
+ const schema = createGroupCollectionSchema(groupId);
340
+ await client.collections.create(schema);
341
+
342
+ return true;
343
+ } catch (error) {
344
+ throw new Error(`Failed to ensure group collection for ${groupId}: ${(error as Error).message}`);
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Get all property names for user collections
350
+ *
351
+ * @returns Array of property names
352
+ */
353
+ export function getUserCollectionProperties(): string[] {
354
+ return COMMON_MEMORY_PROPERTIES.map(prop => prop.name);
355
+ }
356
+
357
+ /**
358
+ * Get all property names for space/group collections
359
+ *
360
+ * @returns Array of property names
361
+ */
362
+ export function getPublishedCollectionProperties(): string[] {
363
+ return [
364
+ ...COMMON_MEMORY_PROPERTIES,
365
+ ...PUBLISHED_MEMORY_PROPERTIES,
366
+ ].map(prop => prop.name);
367
+ }
368
+
369
+ /**
370
+ * Validate that a collection name matches the expected v2 pattern
371
+ *
372
+ * @param collectionName - The collection name to validate
373
+ * @returns True if valid
374
+ * @throws Error if invalid
375
+ */
376
+ export function validateV2CollectionName(collectionName: string): boolean {
377
+ const userPattern = /^Memory_users_[a-zA-Z0-9_-]+$/;
378
+ const spacePattern = /^Memory_spaces_public$/;
379
+ const groupPattern = /^Memory_groups_[a-zA-Z0-9_-]+$/;
380
+
381
+ if (
382
+ userPattern.test(collectionName) ||
383
+ spacePattern.test(collectionName) ||
384
+ groupPattern.test(collectionName)
385
+ ) {
386
+ return true;
387
+ }
388
+
389
+ throw new Error(
390
+ `Invalid v2 collection name: ${collectionName}. ` +
391
+ `Must match: Memory_users_{userId}, Memory_spaces_public, or Memory_groups_{groupId}`
392
+ );
393
+ }
394
+
395
+ /**
396
+ * Get the collection type from a collection name
397
+ *
398
+ * @param collectionName - The collection name
399
+ * @returns 'users', 'spaces', or 'groups'
400
+ */
401
+ export function getCollectionType(collectionName: string): 'users' | 'spaces' | 'groups' {
402
+ if (collectionName.startsWith('Memory_users_')) {
403
+ return 'users';
404
+ }
405
+ if (collectionName === 'Memory_spaces_public') {
406
+ return 'spaces';
407
+ }
408
+ if (collectionName.startsWith('Memory_groups_')) {
409
+ return 'groups';
410
+ }
411
+
412
+ throw new Error(`Unknown collection type for: ${collectionName}`);
413
+ }
414
+
415
+ /**
416
+ * Extract the ID from a user or group collection name
417
+ *
418
+ * @param collectionName - The collection name
419
+ * @returns The user ID or group ID
420
+ */
421
+ export function extractIdFromCollectionName(collectionName: string): string | null {
422
+ if (collectionName.startsWith('Memory_users_')) {
423
+ return collectionName.replace('Memory_users_', '');
424
+ }
425
+ if (collectionName.startsWith('Memory_groups_')) {
426
+ return collectionName.replace('Memory_groups_', '');
427
+ }
428
+ if (collectionName === 'Memory_spaces_public') {
429
+ return null; // Spaces collection has no specific ID
430
+ }
431
+
432
+ throw new Error(`Cannot extract ID from: ${collectionName}`);
433
+ }
@@ -13,6 +13,8 @@ import {
13
13
  import { logger } from './utils/logger.js';
14
14
  import { initWeaviateClient } from './weaviate/client.js';
15
15
  import { initFirestore } from './firestore/init.js';
16
+ import type { AuthContext } from './types/auth.js';
17
+ import { credentialsProvider } from './services/credentials-provider.js';
16
18
 
17
19
  // Import memory tools
18
20
  import { createMemoryTool, handleCreateMemory } from './tools/create-memory.js';
@@ -34,14 +36,33 @@ import { getPreferencesTool, handleGetPreferences } from './tools/get-preference
34
36
 
35
37
  // Import space tools
36
38
  import { publishTool, handlePublish } from './tools/publish.js';
39
+ import { retractTool, handleRetract } from './tools/retract.js';
40
+ import { reviseTool, handleRevise } from './tools/revise.js';
37
41
  import { confirmTool, handleConfirm } from './tools/confirm.js';
38
42
  import { denyTool, handleDeny } from './tools/deny.js';
39
43
  import { searchSpaceTool, handleSearchSpace } from './tools/search-space.js';
40
44
  import { querySpaceTool, handleQuerySpace } from './tools/query-space.js';
45
+ import { moderateTool, handleModerate } from './tools/moderate.js';
46
+ import { ghostConfigTool, handleGhostConfig } from './tools/ghost-config.js';
41
47
 
42
48
  export interface ServerOptions {
43
49
  name?: string;
44
50
  version?: string;
51
+ /**
52
+ * Ghost mode configuration. When set, the server operates in ghost mode:
53
+ * - Search/query tools search the ghost owner's collection
54
+ * - Trust filtering is applied based on the accessor's trust level
55
+ * - Trust level is resolved server-side from GhostConfig (Firestore)
56
+ *
57
+ * agentbase.me sets this when creating a ghost conversation server.
58
+ * The LLM never has access to set or override these values.
59
+ */
60
+ ghostMode?: {
61
+ /** Ghost owner's user ID (whose memories to search) */
62
+ owner_user_id: string;
63
+ /** Accessor's user ID (who is chatting with the ghost) */
64
+ accessor_user_id: string;
65
+ };
45
66
  }
46
67
 
47
68
  // Global initialization flag to ensure databases are initialized once
@@ -151,16 +172,40 @@ export async function createServer(
151
172
  }
152
173
  );
153
174
 
175
+ // Resolve ghost mode trust level from Firestore if ghost mode is configured
176
+ let resolvedGhostMode: import('./types/auth.js').GhostModeContext | undefined;
177
+ if (options.ghostMode) {
178
+ const { getGhostConfig } = await import('./services/ghost-config.service.js');
179
+ const { resolveAccessorTrustLevel } = await import('./services/access-control.js');
180
+ const ghostConfig = await getGhostConfig(options.ghostMode.owner_user_id);
181
+ const trustLevel = resolveAccessorTrustLevel(ghostConfig, options.ghostMode.accessor_user_id);
182
+ resolvedGhostMode = {
183
+ owner_user_id: options.ghostMode.owner_user_id,
184
+ accessor_user_id: options.ghostMode.accessor_user_id,
185
+ accessor_trust_level: trustLevel,
186
+ };
187
+ logger.info('Ghost mode resolved', {
188
+ ownerUserId: resolvedGhostMode.owner_user_id,
189
+ accessorUserId: resolvedGhostMode.accessor_user_id,
190
+ trustLevel: resolvedGhostMode.accessor_trust_level,
191
+ });
192
+ }
193
+
154
194
  // Register handlers with userId scope
155
- registerHandlers(server, userId, accessToken);
156
-
195
+ registerHandlers(server, userId, accessToken, resolvedGhostMode);
196
+
157
197
  return server;
158
198
  }
159
199
 
160
200
  /**
161
201
  * Register MCP handlers scoped to userId
162
202
  */
163
- function registerHandlers(server: Server, userId: string, accessToken: string): void {
203
+ function registerHandlers(
204
+ server: Server,
205
+ userId: string,
206
+ accessToken: string,
207
+ ghostMode?: import('./types/auth.js').GhostModeContext
208
+ ): void {
164
209
  // List available tools
165
210
  server.setRequestHandler(ListToolsRequestSchema, async () => {
166
211
  return {
@@ -182,10 +227,14 @@ function registerHandlers(server: Server, userId: string, accessToken: string):
182
227
  getPreferencesTool,
183
228
  // Space tools
184
229
  publishTool,
230
+ retractTool,
231
+ reviseTool,
185
232
  confirmTool,
186
233
  denyTool,
187
234
  searchSpaceTool,
188
235
  querySpaceTool,
236
+ moderateTool,
237
+ ghostConfigTool,
189
238
  ],
190
239
  };
191
240
  });
@@ -195,75 +244,95 @@ function registerHandlers(server: Server, userId: string, accessToken: string):
195
244
  const { name, arguments: args } = request.params;
196
245
 
197
246
  try {
247
+ // Resolve credentials once per request
248
+ const credentials = await credentialsProvider.getCredentials(accessToken, userId);
249
+ const authContext: AuthContext = { accessToken, credentials, ghostMode };
250
+
198
251
  let result: string;
199
252
 
200
253
  switch (name) {
201
254
  case 'remember_create_memory':
202
- result = await handleCreateMemory(args as any, userId);
255
+ result = await handleCreateMemory(args as any, userId, authContext);
203
256
  break;
204
257
 
205
258
  case 'remember_search_memory':
206
- result = await handleSearchMemory(args as any, userId);
259
+ result = await handleSearchMemory(args as any, userId, authContext);
207
260
  break;
208
261
 
209
262
  case 'remember_delete_memory':
210
- result = await handleDeleteMemory(args as any, userId);
263
+ result = await handleDeleteMemory(args as any, userId, authContext);
211
264
  break;
212
265
 
213
266
  case 'remember_update_memory':
214
- result = await handleUpdateMemory(args as any, userId);
267
+ result = await handleUpdateMemory(args as any, userId, authContext);
215
268
  break;
216
269
 
217
270
  case 'remember_find_similar':
218
- result = await handleFindSimilar(args as any, userId);
271
+ result = await handleFindSimilar(args as any, userId, authContext);
219
272
  break;
220
273
 
221
274
  case 'remember_query_memory':
222
- result = await handleQueryMemory(args as any, userId);
275
+ result = await handleQueryMemory(args as any, userId, authContext);
223
276
  break;
224
277
 
225
278
  case 'remember_create_relationship':
226
- result = await handleCreateRelationship(args as any, userId);
279
+ result = await handleCreateRelationship(args as any, userId, authContext);
227
280
  break;
228
281
 
229
282
  case 'remember_update_relationship':
230
- result = await handleUpdateRelationship(args as any, userId);
283
+ result = await handleUpdateRelationship(args as any, userId, authContext);
231
284
  break;
232
285
 
233
286
  case 'remember_search_relationship':
234
- result = await handleSearchRelationship(args as any, userId);
287
+ result = await handleSearchRelationship(args as any, userId, authContext);
235
288
  break;
236
289
 
237
290
  case 'remember_delete_relationship':
238
- result = await handleDeleteRelationship(args as any, userId);
291
+ result = await handleDeleteRelationship(args as any, userId, authContext);
239
292
  break;
240
293
 
241
294
  case 'remember_set_preference':
242
- result = await handleSetPreference(args as any, userId);
295
+ result = await handleSetPreference(args as any, userId, authContext);
243
296
  break;
244
297
 
245
298
  case 'remember_get_preferences':
246
- result = await handleGetPreferences(args as any, userId);
299
+ result = await handleGetPreferences(args as any, userId, authContext);
247
300
  break;
248
301
 
249
302
  case 'remember_publish':
250
- result = await handlePublish(args as any, userId);
303
+ result = await handlePublish(args as any, userId, authContext);
304
+ break;
305
+
306
+ case 'remember_retract':
307
+ result = await handleRetract(args as any, userId, authContext);
308
+ break;
309
+
310
+ case 'remember_revise':
311
+ result = await handleRevise(args as any, userId, authContext);
251
312
  break;
252
313
 
253
314
  case 'remember_confirm':
254
- result = await handleConfirm(args as any, userId);
315
+ result = await handleConfirm(args as any, userId, authContext);
255
316
  break;
256
317
 
257
318
  case 'remember_deny':
258
- result = await handleDeny(args as any, userId);
319
+ result = await handleDeny(args as any, userId, authContext);
259
320
  break;
260
321
 
261
322
  case 'remember_search_space':
262
- result = await handleSearchSpace(args as any, userId);
323
+ result = await handleSearchSpace(args as any, userId, authContext);
263
324
  break;
264
325
 
265
326
  case 'remember_query_space':
266
- result = await handleQuerySpace(args as any, userId);
327
+ result = await handleQuerySpace(args as any, userId, authContext);
328
+ break;
329
+
330
+ case 'remember_moderate':
331
+ result = await handleModerate(args as any, userId, authContext);
332
+ break;
333
+
334
+ case 'remember_ghost_config':
335
+ result = await handleGhostConfig(args as any, userId, authContext);
267
336
  break;
268
337
 
269
338
  default: