@prmichaelsen/remember-mcp 2.7.9 → 2.7.11

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,52 @@ 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
+ ## [2.7.10] - 2026-02-17
9
+
10
+ ### Added
11
+
12
+ - **Prevent Duplicate Publishing**
13
+ - Added validation to prevent re-publishing already published memories
14
+ - Checks for existing `space_memory_id` before allowing publish
15
+ - Returns clear error message with existing space memory ID
16
+ - Prevents data duplication and maintains data integrity
17
+
18
+ ### Security
19
+
20
+ - Users cannot accidentally publish the same memory multiple times
21
+ - Prevents duplicate entries in Memory_public collection
22
+ - Clear error messaging guides users to existing published memory
23
+
24
+ ### Technical Details
25
+
26
+ - Modified: `src/tools/confirm.ts` (lines 191-209)
27
+ - Added check for `originalMemory.properties.space_memory_id`
28
+ - Returns error with `space_memory_id` if already published
29
+ - Validation occurs before any database operations
30
+
31
+ ---
32
+
33
+ ## [2.7.9] - 2026-02-17
34
+
35
+ ### Added
36
+
37
+ - **Bidirectional Linking for Published Memories**
38
+ - Original memories now store `space_memory_id` after publishing
39
+ - Enables correlation between source memory and published space memory
40
+ - Added automatic update of original memory after successful publish
41
+ - Non-critical update - publish still succeeds if update fails
42
+ - Improves traceability and enables future features (unpublish, sync)
43
+
44
+ ### Technical Details
45
+
46
+ - Modified: `src/tools/confirm.ts` (lines 277-296)
47
+ - Added `userCollection.data.update()` call after publish
48
+ - Updates original memory with `space_memory_id` field
49
+ - Includes error handling with warning log (non-blocking)
50
+ - Maintains backward compatibility
51
+
52
+ ---
53
+
8
54
  ## [2.7.8] - 2026-02-17
9
55
 
10
56
  ### Fixed
@@ -4288,6 +4288,26 @@ async function executePublishMemory(request, userId) {
4288
4288
  2
4289
4289
  );
4290
4290
  }
4291
+ if (originalMemory.properties.space_memory_id) {
4292
+ const requestedSpaces = request.payload.spaces?.join(", ") || "unknown";
4293
+ logger.warn("Memory already published", {
4294
+ function: "executePublishMemory",
4295
+ memoryId: request.payload.memory_id,
4296
+ existingSpaceMemoryId: originalMemory.properties.space_memory_id,
4297
+ requestedSpaces: request.payload.spaces
4298
+ });
4299
+ return JSON.stringify(
4300
+ {
4301
+ success: false,
4302
+ error: "Already published",
4303
+ message: `This memory has already been published to this space. Space memory ID: ${originalMemory.properties.space_memory_id}`,
4304
+ space_memory_id: originalMemory.properties.space_memory_id,
4305
+ requested_spaces: request.payload.spaces
4306
+ },
4307
+ null,
4308
+ 2
4309
+ );
4310
+ }
4291
4311
  if (originalMemory.properties.user_id !== userId) {
4292
4312
  logger.warn("Permission denied - wrong owner", {
4293
4313
  function: "executePublishMemory",
@@ -4355,6 +4375,26 @@ async function executePublishMemory(request, userId) {
4355
4375
  spaceMemoryId: result,
4356
4376
  spaces: request.payload.spaces
4357
4377
  });
4378
+ try {
4379
+ await userCollection.data.update({
4380
+ id: request.payload.memory_id,
4381
+ properties: {
4382
+ space_memory_id: result
4383
+ }
4384
+ });
4385
+ logger.info("Updated original memory with space_memory_id", {
4386
+ function: "executePublishMemory",
4387
+ memoryId: request.payload.memory_id,
4388
+ spaceMemoryId: result
4389
+ });
4390
+ } catch (updateError) {
4391
+ logger.warn("Failed to update original memory with space_memory_id", {
4392
+ function: "executePublishMemory",
4393
+ memoryId: request.payload.memory_id,
4394
+ spaceMemoryId: result,
4395
+ error: updateError instanceof Error ? updateError.message : String(updateError)
4396
+ });
4397
+ }
4358
4398
  return JSON.stringify(
4359
4399
  {
4360
4400
  success: true,
package/dist/server.js CHANGED
@@ -4356,6 +4356,26 @@ async function executePublishMemory(request, userId) {
4356
4356
  2
4357
4357
  );
4358
4358
  }
4359
+ if (originalMemory.properties.space_memory_id) {
4360
+ const requestedSpaces = request.payload.spaces?.join(", ") || "unknown";
4361
+ logger.warn("Memory already published", {
4362
+ function: "executePublishMemory",
4363
+ memoryId: request.payload.memory_id,
4364
+ existingSpaceMemoryId: originalMemory.properties.space_memory_id,
4365
+ requestedSpaces: request.payload.spaces
4366
+ });
4367
+ return JSON.stringify(
4368
+ {
4369
+ success: false,
4370
+ error: "Already published",
4371
+ message: `This memory has already been published to this space. Space memory ID: ${originalMemory.properties.space_memory_id}`,
4372
+ space_memory_id: originalMemory.properties.space_memory_id,
4373
+ requested_spaces: request.payload.spaces
4374
+ },
4375
+ null,
4376
+ 2
4377
+ );
4378
+ }
4359
4379
  if (originalMemory.properties.user_id !== userId) {
4360
4380
  logger.warn("Permission denied - wrong owner", {
4361
4381
  function: "executePublishMemory",
@@ -4423,6 +4443,26 @@ async function executePublishMemory(request, userId) {
4423
4443
  spaceMemoryId: result,
4424
4444
  spaces: request.payload.spaces
4425
4445
  });
4446
+ try {
4447
+ await userCollection.data.update({
4448
+ id: request.payload.memory_id,
4449
+ properties: {
4450
+ space_memory_id: result
4451
+ }
4452
+ });
4453
+ logger.info("Updated original memory with space_memory_id", {
4454
+ function: "executePublishMemory",
4455
+ memoryId: request.payload.memory_id,
4456
+ spaceMemoryId: result
4457
+ });
4458
+ } catch (updateError) {
4459
+ logger.warn("Failed to update original memory with space_memory_id", {
4460
+ function: "executePublishMemory",
4461
+ memoryId: request.payload.memory_id,
4462
+ spaceMemoryId: result,
4463
+ error: updateError instanceof Error ? updateError.message : String(updateError)
4464
+ });
4465
+ }
4426
4466
  return JSON.stringify(
4427
4467
  {
4428
4468
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.7.9",
3
+ "version": "2.7.11",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -188,6 +188,28 @@ async function executePublishMemory(
188
188
  );
189
189
  }
190
190
 
191
+ // Check if memory has already been published
192
+ if (originalMemory.properties.space_memory_id) {
193
+ const requestedSpaces = request.payload.spaces?.join(', ') || 'unknown';
194
+ logger.warn('Memory already published', {
195
+ function: 'executePublishMemory',
196
+ memoryId: request.payload.memory_id,
197
+ existingSpaceMemoryId: originalMemory.properties.space_memory_id,
198
+ requestedSpaces: request.payload.spaces,
199
+ });
200
+ return JSON.stringify(
201
+ {
202
+ success: false,
203
+ error: 'Already published',
204
+ message: `This memory has already been published to this space. Space memory ID: ${originalMemory.properties.space_memory_id}`,
205
+ space_memory_id: originalMemory.properties.space_memory_id,
206
+ requested_spaces: request.payload.spaces,
207
+ },
208
+ null,
209
+ 2
210
+ );
211
+ }
212
+
191
213
  // Verify ownership again
192
214
  if (originalMemory.properties.user_id !== userId) {
193
215
  logger.warn('Permission denied - wrong owner', {
@@ -274,6 +296,30 @@ async function executePublishMemory(
274
296
  spaces: request.payload.spaces,
275
297
  });
276
298
 
299
+ // Update original memory with space_memory_id for bidirectional linking
300
+ try {
301
+ await userCollection.data.update({
302
+ id: request.payload.memory_id,
303
+ properties: {
304
+ space_memory_id: result,
305
+ },
306
+ });
307
+
308
+ logger.info('Updated original memory with space_memory_id', {
309
+ function: 'executePublishMemory',
310
+ memoryId: request.payload.memory_id,
311
+ spaceMemoryId: result,
312
+ });
313
+ } catch (updateError) {
314
+ logger.warn('Failed to update original memory with space_memory_id', {
315
+ function: 'executePublishMemory',
316
+ memoryId: request.payload.memory_id,
317
+ spaceMemoryId: result,
318
+ error: updateError instanceof Error ? updateError.message : String(updateError),
319
+ });
320
+ // Don't fail the publish if this update fails - it's not critical
321
+ }
322
+
277
323
  // Return minimal response with spaces array
278
324
  return JSON.stringify(
279
325
  {