@prmichaelsen/remember-mcp 2.0.4 → 2.1.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.
@@ -378,6 +378,22 @@ progress:
378
378
  overall: 50%
379
379
 
380
380
  recent_work:
381
+ - date: 2026-02-15
382
+ description: All Production Error Tasks COMPLETED (Tasks 23-25)
383
+ items:
384
+ - 🎉 Task 25 (Fix Update Memory Errors) COMPLETED!
385
+ - 🎉 Task 23 (Fix Relationship Creation Errors) COMPLETED!
386
+ - 🎉 Task 24 (Fix Weaviate Filter Path Error) COMPLETED!
387
+ - ✅ All 3 production error categories addressed
388
+ - ✅ Enhanced error logging across all affected tools
389
+ - ✅ Standardized error handling with handleToolError
390
+ - ✅ Added detailed context to all error messages
391
+ - ✅ Fixed critical Weaviate v3 filter API bug
392
+ - ✅ All 53 tests passing
393
+ - ✅ TypeScript compiles without errors
394
+ - ✅ Build successful
395
+ - 📊 Production errors should now have actionable diagnostics
396
+
381
397
  - date: 2026-02-15
382
398
  description: Task 24 COMPLETED - Fixed Weaviate Filter Path Error
383
399
  items:
@@ -0,0 +1,331 @@
1
+ # Task 26: Migrate PARM Schema to Remember Schema
2
+
3
+ **Milestone**: M8 - Testing & Quality
4
+ **Estimated Time**: 4 hours
5
+ **Dependencies**: None
6
+ **Status**: Not Started
7
+ **Priority**: Medium
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Migrate existing PARM (Personal Agent Relationship Manager) memories from the old schema to the new remember-mcp schema. This involves mapping old fields to new fields, handling missing fields, and ensuring data integrity.
14
+
15
+ ## Problem Statement
16
+
17
+ Existing memories in Weaviate were created with the PARM schema which has different field names and structure than the current remember-mcp schema:
18
+
19
+ ### Old PARM Schema (Observed)
20
+ ```yaml
21
+ author: string (UUID)
22
+ content: string (long text)
23
+ contentType: string (e.g., "note")
24
+ createdAt: datetime
25
+ description: string
26
+ filePath: string (firestore:// URL)
27
+ project: string (e.g., "parm-migration")
28
+ status: string (e.g., "migrated")
29
+ tags: string[] (e.g., ["love", "relationships", "poetry"])
30
+ title: string
31
+ updatedAt: datetime
32
+ ```
33
+
34
+ ### New Remember-MCP Schema (Current)
35
+ ```yaml
36
+ # Core Identity
37
+ user_id: string
38
+ doc_type: string ("memory" or "relationship")
39
+
40
+ # Content
41
+ content: string
42
+ title: string
43
+ summary: string
44
+ type: string (ContentType - 45 types)
45
+
46
+ # Scoring
47
+ weight: number (0-1)
48
+ trust: number (0-1)
49
+ confidence: number (0-1)
50
+
51
+ # Location
52
+ location_gps_lat: number
53
+ location_gps_lng: number
54
+ location_address: string
55
+ location_city: string
56
+ location_country: string
57
+
58
+ # Locale
59
+ locale_language: string
60
+ locale_timezone: string
61
+
62
+ # Context
63
+ context_conversation_id: string
64
+ context_summary: string
65
+ context_timestamp: date
66
+
67
+ # Relationships
68
+ relationships: string[] (relationship IDs)
69
+
70
+ # Access Tracking
71
+ access_count: number
72
+ last_accessed_at: date
73
+
74
+ # Metadata
75
+ tags: string[]
76
+ references: string[] (URLs)
77
+ created_at: date
78
+ updated_at: date
79
+ version: number
80
+
81
+ # Template
82
+ template_id: string
83
+ ```
84
+
85
+ ## Field Mapping
86
+
87
+ ### Direct Mappings
88
+ | PARM Field | Remember Field | Notes |
89
+ |------------|----------------|-------|
90
+ | `content` | `content` | Direct copy |
91
+ | `title` | `title` | Direct copy |
92
+ | `tags` | `tags` | Direct copy |
93
+ | `createdAt` | `created_at` | Rename |
94
+ | `updatedAt` | `updated_at` | Rename |
95
+ | `contentType` | `type` | Map to valid ContentType |
96
+
97
+ ### Derived Mappings
98
+ | PARM Field | Remember Field | Transformation |
99
+ |------------|----------------|----------------|
100
+ | `author` | `user_id` | Extract user ID from author UUID |
101
+ | `description` | `summary` | Use as summary |
102
+ | `title` | `summary` | If no description, use title |
103
+ | N/A | `doc_type` | Set to "memory" |
104
+ | N/A | `version` | Set to 1 |
105
+ | N/A | `weight` | Default to 0.5 |
106
+ | N/A | `trust` | Default to 0.5 |
107
+ | N/A | `confidence` | Default to 1.0 |
108
+
109
+ ### Fields to Drop
110
+ - `filePath` - Firestore reference, not needed in Weaviate
111
+ - `project` - Migration metadata, not needed
112
+ - `status` - Migration metadata, not needed
113
+
114
+ ### New Fields (Defaults)
115
+ - `relationships: []` - Empty array
116
+ - `references: []` - Empty array
117
+ - `access_count: 0` - Default 0
118
+ - `last_accessed_at: <created_at>` - Set to creation time
119
+ - `access_frequency: 0` - Default 0
120
+ - `base_weight: 0.5` - Same as weight
121
+ - `computed_weight: 0.5` - Same as weight
122
+ - `location: { gps: null, address: null, source: 'unavailable', confidence: 0, is_approximate: true }`
123
+ - `context: { timestamp: <created_at>, source: { type: 'migration', platform: 'parm' }, summary: 'Migrated from PARM' }`
124
+ - `template_id: null` - No template
125
+ - `structured_content: null` - No structured content
126
+
127
+ ## ContentType Mapping
128
+
129
+ Map old `contentType` values to new `type` values:
130
+
131
+ | Old contentType | New type | Reasoning |
132
+ |-----------------|----------|-----------|
133
+ | `note` | `note` | Direct match |
134
+ | `person` | `person` | Direct match |
135
+ | `event` | `event` | Direct match |
136
+ | `bookmark` | `bookmark` | Direct match |
137
+ | `recipe` | `recipe` | Direct match |
138
+ | `meeting` | `meeting` | Direct match |
139
+ | `project` | `project` | Direct match |
140
+ | (unknown) | `note` | Default fallback |
141
+
142
+ **Special Case**: If `tags` contains "poetry", consider setting `type: "note"` but keep the poetry tag.
143
+
144
+ ## Steps
145
+
146
+ ### 1. Analyze Existing Data
147
+ - [ ] Query Weaviate for all memories in user's collection
148
+ - [ ] Count total memories to migrate
149
+ - [ ] Identify unique `contentType` values
150
+ - [ ] Identify unique `author` values (should be one user)
151
+ - [ ] Check for any unexpected fields
152
+
153
+ ### 2. Create Migration Script
154
+ - [ ] Create `scripts/migrate-parm-to-remember.ts`
155
+ - [ ] Implement field mapping logic
156
+ - [ ] Implement contentType to type conversion
157
+ - [ ] Add validation for required fields
158
+ - [ ] Add dry-run mode (preview without writing)
159
+
160
+ ### 3. Implement Migration Logic
161
+ ```typescript
162
+ interface PARMMemory {
163
+ author: string;
164
+ content: string;
165
+ contentType: string;
166
+ createdAt: string;
167
+ description?: string;
168
+ filePath?: string;
169
+ project?: string;
170
+ status?: string;
171
+ tags: string[];
172
+ title: string;
173
+ updatedAt: string;
174
+ }
175
+
176
+ interface RememberMemory {
177
+ // All remember-mcp fields
178
+ }
179
+
180
+ function migratePARMToRemember(
181
+ parmMemory: PARMMemory,
182
+ userId: string
183
+ ): RememberMemory {
184
+ return {
185
+ // Core identity
186
+ user_id: userId,
187
+ doc_type: 'memory',
188
+
189
+ // Content
190
+ content: parmMemory.content,
191
+ title: parmMemory.title,
192
+ summary: parmMemory.description || parmMemory.title,
193
+ type: mapContentType(parmMemory.contentType),
194
+
195
+ // Scoring (defaults)
196
+ weight: 0.5,
197
+ trust: 0.5,
198
+ confidence: 1.0,
199
+
200
+ // Location (null)
201
+ location: {
202
+ gps: null,
203
+ address: null,
204
+ source: 'unavailable',
205
+ confidence: 0,
206
+ is_approximate: true,
207
+ },
208
+
209
+ // Context
210
+ context: {
211
+ timestamp: parmMemory.createdAt,
212
+ source: { type: 'migration', platform: 'parm' },
213
+ summary: 'Migrated from PARM',
214
+ },
215
+
216
+ // Relationships
217
+ relationships: [],
218
+
219
+ // Access tracking
220
+ access_count: 0,
221
+ last_accessed_at: parmMemory.createdAt,
222
+ access_frequency: 0,
223
+
224
+ // Metadata
225
+ tags: parmMemory.tags,
226
+ references: [],
227
+ created_at: parmMemory.createdAt,
228
+ updated_at: parmMemory.updatedAt,
229
+ version: 1,
230
+
231
+ // Template
232
+ template_id: null,
233
+ structured_content: null,
234
+
235
+ // Computed weight
236
+ base_weight: 0.5,
237
+ computed_weight: 0.5,
238
+ };
239
+ }
240
+
241
+ function mapContentType(oldType: string): string {
242
+ const mapping: Record<string, string> = {
243
+ 'note': 'note',
244
+ 'person': 'person',
245
+ 'event': 'event',
246
+ 'bookmark': 'bookmark',
247
+ 'recipe': 'recipe',
248
+ 'meeting': 'meeting',
249
+ 'project': 'project',
250
+ };
251
+
252
+ return mapping[oldType] || 'note';
253
+ }
254
+ ```
255
+
256
+ ### 4. Add Safety Checks
257
+ - [ ] Verify user_id matches expected user
258
+ - [ ] Validate all required fields are present
259
+ - [ ] Check for duplicate IDs
260
+ - [ ] Verify contentType mapping is valid
261
+ - [ ] Ensure no data loss (all old fields accounted for)
262
+
263
+ ### 5. Create Backup Strategy
264
+ - [ ] Export all existing memories to JSON file
265
+ - [ ] Store backup with timestamp
266
+ - [ ] Document rollback procedure
267
+
268
+ ### 6. Test Migration
269
+ - [ ] Test with 1 memory (dry-run)
270
+ - [ ] Test with 10 memories (dry-run)
271
+ - [ ] Verify migrated data structure
272
+ - [ ] Test search on migrated memories
273
+ - [ ] Verify tags are preserved
274
+
275
+ ### 7. Execute Migration
276
+ - [ ] Run full migration (dry-run first)
277
+ - [ ] Review migration report
278
+ - [ ] Execute actual migration
279
+ - [ ] Verify all memories migrated
280
+ - [ ] Test search functionality
281
+ - [ ] Verify no data loss
282
+
283
+ ### 8. Post-Migration Validation
284
+ - [ ] Count memories before and after
285
+ - [ ] Spot-check 10 random memories
286
+ - [ ] Search for poems by poetry tag
287
+ - [ ] Verify all contentTypes mapped correctly
288
+ - [ ] Check that old fields are gone
289
+ - [ ] Verify new fields have correct defaults
290
+
291
+ ## Verification
292
+
293
+ - [ ] All PARM memories successfully migrated
294
+ - [ ] No data loss (content, title, tags preserved)
295
+ - [ ] All memories have valid remember-mcp schema
296
+ - [ ] Search works correctly on migrated memories
297
+ - [ ] Poems findable via poetry tag
298
+ - [ ] No old PARM fields remain
299
+ - [ ] Backup created and verified
300
+ - [ ] Migration report generated
301
+
302
+ ## Files to Create
303
+
304
+ - `scripts/migrate-parm-to-remember.ts` - Migration script
305
+ - `scripts/backup-memories.ts` - Backup utility
306
+ - `scripts/validate-migration.ts` - Validation script
307
+ - `agent/design/parm-migration-report.md` - Migration report template
308
+
309
+ ## Expected Outcome
310
+
311
+ - All existing PARM memories converted to remember-mcp schema
312
+ - No data loss
313
+ - Improved searchability with proper schema
314
+ - Poems findable via tags
315
+ - Clean, consistent data structure
316
+ - Documented migration process for future reference
317
+
318
+ ## Rollback Plan
319
+
320
+ If migration fails:
321
+ 1. Stop migration immediately
322
+ 2. Restore from backup JSON file
323
+ 3. Re-import using Weaviate batch import
324
+ 4. Verify restoration
325
+ 5. Debug migration script
326
+ 6. Retry with fixes
327
+
328
+ ---
329
+
330
+ **Next Task**: Task 27 - Add Poetry Content Type
331
+ **Blockers**: Need user confirmation before executing migration
@@ -30,7 +30,7 @@ export declare const CONTENT_TYPE_CATEGORIES: {
30
30
  readonly communication: readonly ["email", "conversation", "meeting", "person"];
31
31
  readonly content: readonly ["article", "webpage", "social", "presentation", "spreadsheet", "pdf"];
32
32
  readonly media: readonly ["image", "video", "audio", "transcript"];
33
- readonly creative: readonly ["screenplay", "recipe", "idea", "quote"];
33
+ readonly creative: readonly ["song", "screenplay", "recipe", "idea", "quote"];
34
34
  readonly personal: readonly ["journal", "memory", "event"];
35
35
  readonly organizational: readonly ["bookmark", "form", "location"];
36
36
  readonly business: readonly ["invoice", "contract"];
@@ -839,6 +839,7 @@ var CONTENT_TYPES = [
839
839
  "spreadsheet",
840
840
  "pdf",
841
841
  // Creative
842
+ "song",
842
843
  "screenplay",
843
844
  "recipe",
844
845
  "idea",
@@ -1024,6 +1025,13 @@ var CONTENT_TYPE_METADATA = {
1024
1025
  common_fields: ["pages", "file_size"]
1025
1026
  },
1026
1027
  // Creative
1028
+ song: {
1029
+ name: "song",
1030
+ category: "creative",
1031
+ description: "Music tracks and songs",
1032
+ examples: ["Songs", "Music tracks", "Albums", "Playlists"],
1033
+ common_fields: ["artist", "album", "genre", "duration", "release_date", "url"]
1034
+ },
1027
1035
  screenplay: {
1028
1036
  name: "screenplay",
1029
1037
  category: "creative",
package/dist/server.js CHANGED
@@ -881,6 +881,7 @@ var CONTENT_TYPES = [
881
881
  "spreadsheet",
882
882
  "pdf",
883
883
  // Creative
884
+ "song",
884
885
  "screenplay",
885
886
  "recipe",
886
887
  "idea",
@@ -1066,6 +1067,13 @@ var CONTENT_TYPE_METADATA = {
1066
1067
  common_fields: ["pages", "file_size"]
1067
1068
  },
1068
1069
  // Creative
1070
+ song: {
1071
+ name: "song",
1072
+ category: "creative",
1073
+ description: "Music tracks and songs",
1074
+ examples: ["Songs", "Music tracks", "Albums", "Playlists"],
1075
+ common_fields: ["artist", "album", "genre", "duration", "release_date", "url"]
1076
+ },
1069
1077
  screenplay: {
1070
1078
  name: "screenplay",
1071
1079
  category: "creative",
@@ -5,7 +5,7 @@
5
5
  * Content types for memories
6
6
  * Based on agent/design/content-types-expansion.md
7
7
  */
8
- export type ContentType = 'code' | 'note' | 'documentation' | 'reference' | 'todo' | 'checklist' | 'project' | 'goal' | 'habit' | 'email' | 'conversation' | 'meeting' | 'person' | 'article' | 'webpage' | 'social' | 'image' | 'video' | 'audio' | 'transcript' | 'presentation' | 'spreadsheet' | 'pdf' | 'screenplay' | 'recipe' | 'idea' | 'quote' | 'journal' | 'memory' | 'event' | 'bookmark' | 'form' | 'location' | 'invoice' | 'contract' | 'system' | 'action' | 'audit' | 'history';
8
+ export type ContentType = 'code' | 'note' | 'documentation' | 'reference' | 'todo' | 'checklist' | 'project' | 'goal' | 'habit' | 'email' | 'conversation' | 'meeting' | 'person' | 'article' | 'webpage' | 'social' | 'image' | 'video' | 'audio' | 'song' | 'transcript' | 'presentation' | 'spreadsheet' | 'pdf' | 'screenplay' | 'recipe' | 'idea' | 'quote' | 'journal' | 'memory' | 'event' | 'bookmark' | 'form' | 'location' | 'invoice' | 'contract' | 'system' | 'action' | 'audit' | 'history';
9
9
  /**
10
10
  * GPS coordinates
11
11
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -37,6 +37,7 @@ export const CONTENT_TYPES: readonly ContentType[] = [
37
37
  'spreadsheet',
38
38
  'pdf',
39
39
  // Creative
40
+ 'song',
40
41
  'screenplay',
41
42
  'recipe',
42
43
  'idea',
@@ -241,6 +242,13 @@ export const CONTENT_TYPE_METADATA: Record<ContentType, ContentTypeMetadata> = {
241
242
  },
242
243
 
243
244
  // Creative
245
+ song: {
246
+ name: 'song',
247
+ category: 'creative',
248
+ description: 'Music tracks and songs',
249
+ examples: ['Songs', 'Music tracks', 'Albums', 'Playlists'],
250
+ common_fields: ['artist', 'album', 'genre', 'duration', 'release_date', 'url'],
251
+ },
244
252
  screenplay: {
245
253
  name: 'screenplay',
246
254
  category: 'creative',
@@ -371,7 +379,7 @@ export const CONTENT_TYPE_CATEGORIES = {
371
379
  communication: ['email', 'conversation', 'meeting', 'person'],
372
380
  content: ['article', 'webpage', 'social', 'presentation', 'spreadsheet', 'pdf'],
373
381
  media: ['image', 'video', 'audio', 'transcript'],
374
- creative: ['screenplay', 'recipe', 'idea', 'quote'],
382
+ creative: ['song', 'screenplay', 'recipe', 'idea', 'quote'],
375
383
  personal: ['journal', 'memory', 'event'],
376
384
  organizational: ['bookmark', 'form', 'location'],
377
385
  business: ['invoice', 'contract'],
@@ -30,6 +30,7 @@ export type ContentType =
30
30
  | 'image'
31
31
  | 'video'
32
32
  | 'audio'
33
+ | 'song'
33
34
  | 'transcript'
34
35
  | 'presentation'
35
36
  | 'spreadsheet'