@prmichaelsen/remember-mcp 2.7.7 → 2.7.9

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,60 @@ 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.8] - 2026-02-17
9
+
10
+ ### Fixed
11
+
12
+ - **CRITICAL: Fixed Shared Space Discovery Bug**
13
+ - Search and query tools now correctly filter by `doc_type: 'memory'` instead of `'space_memory'`
14
+ - The `space_memory` concept was removed from the architecture
15
+ - Search tools were filtering for `doc_type: 'space_memory'` but published memories had `doc_type: 'memory'`
16
+ - Now all users can discover memories published to shared spaces like The Void
17
+ - Root cause: Lines 159 in `search-space.ts` and 147 in `query-space.ts` filtered for wrong doc_type
18
+ - Fix: Changed filters from `'space_memory'` to `'memory'` to match actual data
19
+
20
+ ### Technical Details
21
+
22
+ - Modified: `src/tools/search-space.ts` (line 159)
23
+ - Modified: `src/tools/query-space.ts` (line 147)
24
+ - Changed filter from `.equal('space_memory')` to `.equal('memory')`
25
+ - Published memories keep `doc_type: 'memory'` (as intended)
26
+
27
+ ### Impact
28
+
29
+ - **Fixes**: Shared space discovery now works correctly
30
+ - **Unblocks**: Core shared spaces functionality (The Void)
31
+ - **Note**: No data migration needed - existing published memories are correct
32
+
33
+ ---
34
+
35
+ ## [2.7.7] - 2026-02-17
36
+
37
+ ### Fixed
38
+
39
+ - **CRITICAL: Fixed Memory_public vectorizer missing**
40
+ - `ensurePublicCollection()` now properly creates collection with vectorizer
41
+ - Previously relied on auto-schema which doesn't include vectorizers
42
+ - Now calls `createSpaceCollection(client, 'public')` to create with full schema
43
+ - Fixes "vectorizer not configured" errors when searching The Void
44
+
45
+ ### Root Cause
46
+
47
+ - Commit bcde314 changed to auto-schema approach for schema compatibility
48
+ - Auto-schema creates collections without vectorizers (vectorizer: "none")
49
+ - This broke semantic search in Memory_public (The Void)
50
+ - Manual creation with vectorizer config is required
51
+
52
+ ### Technical Details
53
+
54
+ - Modified: `src/weaviate/space-schema.ts` (lines 382-398)
55
+ - Changed `ensurePublicCollection()` to check if collection exists
56
+ - If not exists, calls `createSpaceCollection(client, 'public')`
57
+ - Creates collection with vectorizer: `text2VecOpenAI`, model: `text-embedding-3-small`
58
+ - Vectorizes: `content`, `title`, `summary`, `observation`
59
+
60
+ ---
61
+
8
62
  ## [2.7.6] - 2026-02-17
9
63
 
10
64
  ### Changed
@@ -2,11 +2,11 @@
2
2
 
3
3
  project:
4
4
  name: remember-mcp
5
- version: 2.6.3
5
+ version: 2.7.8
6
6
  started: 2026-02-11
7
7
  status: in_progress
8
8
  current_milestone: M12
9
- last_updated: 2026-02-16
9
+ last_updated: 2026-02-17
10
10
 
11
11
  milestones:
12
12
  - id: M1
@@ -523,6 +523,19 @@ progress:
523
523
  overall: 50%
524
524
 
525
525
  recent_work:
526
+ - date: 2026-02-17
527
+ description: CRITICAL BUG FIX - Shared Space Discovery Now Works (v2.7.8)
528
+ items:
529
+ - 🐛 CRITICAL: Fixed shared space discovery bug
530
+ - ✅ Search/query tools now filter by doc_type: 'memory' (was 'space_memory')
531
+ - ✅ space_memory concept was removed from architecture
532
+ - ✅ All users can now discover memories in The Void
533
+ - ✅ Root cause: search-space.ts and query-space.ts filtered for wrong doc_type
534
+ - ✅ Changed filters from 'space_memory' to 'memory'
535
+ - ✅ Build successful, all 81 tests passing
536
+ - ✅ No data migration needed - existing memories are correct
537
+ - 📋 Released v2.7.8 with critical bug fix
538
+
526
539
  - date: 2026-02-17
527
540
  description: Fixed Build Error & Completed Task 66 - Comment Field Initialization
528
541
  items:
@@ -544,20 +557,25 @@ recent_work:
544
557
  - 📋 Ready for M12 completion: Tasks 58-59 remaining
545
558
 
546
559
  - date: 2026-02-17
547
- description: ACP Initialization Complete - Project Context Loaded
560
+ description: ACP Initialization Complete - Ready for M12 Completion
548
561
  items:
549
562
  - ✅ ACP initialization workflow executed via @acp.init command
550
563
  - ⚠️ ACP updates available (v1.4.3 with improved script color output)
551
- - ✅ All agent documentation reviewed (23 design docs, 11 milestones, 66 tasks, 5 patterns)
564
+ - ✅ All agent documentation reviewed (30 design docs, 12 milestones, 67 tasks, 7 patterns)
552
565
  - ✅ Project status verified: M1-M4, M10-M11 complete (100%), M12 in progress (60%)
553
- - ✅ Version 2.6.7 confirmed (latest release)
554
- - ✅ 53 unit tests passing (1 skipped integration test)
555
- - ⚠️ TypeScript compilation error: Missing 'poetry' in content-types.ts
566
+ - ✅ Version 2.7.7 confirmed (latest release)
567
+ - ✅ 81 unit tests passing (1 skipped integration test)
568
+ - Test coverage: 33.12% overall
569
+ - ✅ TypeScript compiles without errors
570
+ - ✅ Build successful (dual export: server + factory)
556
571
  - ✅ All 17 MCP tools implemented and working
557
572
  - ✅ M12 Comment System: 3/5 tasks complete (schema, search, query updates)
573
+ - ✅ Task 66 completed: Comment fields initialized in create/update tools
558
574
  - 📋 Remaining M12 tasks: Task 58 (unit tests), Task 59 (documentation)
559
- - 📋 Build blocked by TypeScript error in content-types.ts
560
- - 📋 Need to fix 'poetry' content type metadata
575
+ - 📋 Ready to complete M12 milestone
576
+ - 📋 Multi-tenant architecture with per-user isolation operational
577
+ - 📋 Vector search with Weaviate + metadata with Firestore working
578
+ - 📋 Shared spaces with multi-space support functional
561
579
 
562
580
  - date: 2026-02-16
563
581
  description: Comment System, Structured Logging, and Safety Guidelines (v2.6.0-v2.6.2)
@@ -3688,11 +3688,284 @@ init_space_memory();
3688
3688
  init_logger();
3689
3689
  import weaviate3 from "weaviate-client";
3690
3690
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3691
+ function getSpaceCollectionName(spaceId) {
3692
+ return `Memory_${spaceId}`;
3693
+ }
3691
3694
  function isValidSpaceId(spaceId) {
3692
3695
  return SUPPORTED_SPACES.includes(spaceId);
3693
3696
  }
3697
+ async function createSpaceCollection(client2, spaceId) {
3698
+ const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3699
+ logger.info("Creating space collection", {
3700
+ module: "weaviate-space-schema",
3701
+ collectionName,
3702
+ spaceId
3703
+ });
3704
+ await client2.collections.create({
3705
+ name: collectionName,
3706
+ // Vectorizer configuration
3707
+ vectorizers: weaviate3.configure.vectorizer.text2VecOpenAI({
3708
+ model: "text-embedding-3-small",
3709
+ // Vectorize content, title, summary, and observation for semantic search
3710
+ // Note: title and summary are optional fields
3711
+ sourceProperties: ["content", "title", "summary", "observation"]
3712
+ }),
3713
+ properties: [
3714
+ // Discriminator
3715
+ {
3716
+ name: "doc_type",
3717
+ dataType: "text",
3718
+ description: 'Document type: "space_memory"'
3719
+ },
3720
+ // Space identity
3721
+ {
3722
+ name: "spaces",
3723
+ dataType: "text[]",
3724
+ description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])'
3725
+ },
3726
+ {
3727
+ name: "space_id",
3728
+ dataType: "text",
3729
+ description: "DEPRECATED: Use spaces array instead. Will be removed in v3.0.0."
3730
+ },
3731
+ {
3732
+ name: "author_id",
3733
+ dataType: "text",
3734
+ description: "Original author user_id (for permissions)"
3735
+ },
3736
+ {
3737
+ name: "ghost_id",
3738
+ dataType: "text",
3739
+ description: "Optional ghost profile ID for pseudonymous publishing"
3740
+ },
3741
+ {
3742
+ name: "attribution",
3743
+ dataType: "text",
3744
+ description: 'Attribution type: "user" or "ghost"'
3745
+ },
3746
+ // Discovery metadata
3747
+ {
3748
+ name: "published_at",
3749
+ dataType: "text",
3750
+ description: "When published to space (ISO 8601)"
3751
+ },
3752
+ {
3753
+ name: "discovery_count",
3754
+ dataType: "number",
3755
+ description: "How many times discovered"
3756
+ },
3757
+ // Memory fields (same as personal memories)
3758
+ {
3759
+ name: "content",
3760
+ dataType: "text",
3761
+ description: "Main memory content (vectorized)"
3762
+ },
3763
+ {
3764
+ name: "title",
3765
+ dataType: "text",
3766
+ description: "Optional short title"
3767
+ },
3768
+ {
3769
+ name: "summary",
3770
+ dataType: "text",
3771
+ description: "Optional brief summary"
3772
+ },
3773
+ {
3774
+ name: "type",
3775
+ dataType: "text",
3776
+ description: "Content type (note, event, person, etc.)"
3777
+ },
3778
+ // Scoring fields
3779
+ {
3780
+ name: "weight",
3781
+ dataType: "number",
3782
+ description: "Significance/priority (0-1)"
3783
+ },
3784
+ {
3785
+ name: "trust",
3786
+ dataType: "number",
3787
+ description: "Access control level (0-1)"
3788
+ },
3789
+ {
3790
+ name: "confidence",
3791
+ dataType: "number",
3792
+ description: "System confidence in accuracy (0-1)"
3793
+ },
3794
+ // Location fields (flattened) - MUST match user memory schema exactly
3795
+ {
3796
+ name: "location_gps_lat",
3797
+ dataType: "number",
3798
+ description: "GPS latitude"
3799
+ },
3800
+ {
3801
+ name: "location_gps_lng",
3802
+ dataType: "number",
3803
+ description: "GPS longitude"
3804
+ },
3805
+ {
3806
+ name: "location_address",
3807
+ dataType: "text",
3808
+ description: "Formatted address"
3809
+ },
3810
+ {
3811
+ name: "location_city",
3812
+ dataType: "text",
3813
+ description: "City name"
3814
+ },
3815
+ {
3816
+ name: "location_country",
3817
+ dataType: "text",
3818
+ description: "Country name"
3819
+ },
3820
+ {
3821
+ name: "location_source",
3822
+ dataType: "text",
3823
+ description: "Location source (gps, ip, manual, etc.)"
3824
+ },
3825
+ // Context fields (flattened) - MUST match user memory schema exactly
3826
+ {
3827
+ name: "context_conversation_id",
3828
+ dataType: "text",
3829
+ description: "Conversation ID"
3830
+ },
3831
+ {
3832
+ name: "context_summary",
3833
+ dataType: "text",
3834
+ description: "Brief context summary"
3835
+ },
3836
+ {
3837
+ name: "context_timestamp",
3838
+ dataType: "date",
3839
+ description: "Context timestamp"
3840
+ },
3841
+ // Locale fields - MUST match user memory schema exactly
3842
+ {
3843
+ name: "locale_language",
3844
+ dataType: "text",
3845
+ description: "Language code (e.g., en, es, fr)"
3846
+ },
3847
+ {
3848
+ name: "locale_timezone",
3849
+ dataType: "text",
3850
+ description: "Timezone (e.g., America/Los_Angeles)"
3851
+ },
3852
+ // Relationships - MUST match user memory schema exactly
3853
+ {
3854
+ name: "relationships",
3855
+ dataType: "text[]",
3856
+ description: "Array of relationship IDs"
3857
+ },
3858
+ // Access tracking - MUST match user memory schema exactly
3859
+ {
3860
+ name: "access_count",
3861
+ dataType: "number",
3862
+ description: "Total times accessed"
3863
+ },
3864
+ {
3865
+ name: "last_accessed_at",
3866
+ dataType: "date",
3867
+ description: "Most recent access timestamp"
3868
+ },
3869
+ // Metadata - MUST match user memory schema exactly
3870
+ {
3871
+ name: "tags",
3872
+ dataType: "text[]",
3873
+ description: "Tags for organization"
3874
+ },
3875
+ {
3876
+ name: "references",
3877
+ dataType: "text[]",
3878
+ description: "Source URLs"
3879
+ },
3880
+ {
3881
+ name: "template_id",
3882
+ dataType: "text",
3883
+ description: "Template ID if using template"
3884
+ },
3885
+ // Relationship-specific fields (for relationships in public space)
3886
+ {
3887
+ name: "memory_ids",
3888
+ dataType: "text[]",
3889
+ description: "Connected memory IDs (for relationships)"
3890
+ },
3891
+ {
3892
+ name: "relationship_type",
3893
+ dataType: "text",
3894
+ description: "Relationship type (for relationships)"
3895
+ },
3896
+ {
3897
+ name: "observation",
3898
+ dataType: "text",
3899
+ description: "Relationship observation (vectorized)"
3900
+ },
3901
+ {
3902
+ name: "strength",
3903
+ dataType: "number",
3904
+ description: "Relationship strength (0-1)"
3905
+ },
3906
+ // Computed fields - MUST match user memory schema exactly
3907
+ {
3908
+ name: "base_weight",
3909
+ dataType: "number",
3910
+ description: "User-specified weight"
3911
+ },
3912
+ {
3913
+ name: "computed_weight",
3914
+ dataType: "number",
3915
+ description: "Calculated effective weight"
3916
+ },
3917
+ // User ID field (for backwards compatibility with spread operator)
3918
+ {
3919
+ name: "user_id",
3920
+ dataType: "text",
3921
+ description: "User ID (copied from original memory, same as author_id)"
3922
+ },
3923
+ // Timestamps
3924
+ {
3925
+ name: "created_at",
3926
+ dataType: "text",
3927
+ description: "Original creation timestamp (ISO 8601)"
3928
+ },
3929
+ {
3930
+ name: "updated_at",
3931
+ dataType: "text",
3932
+ description: "Last update timestamp (ISO 8601)"
3933
+ },
3934
+ // Versioning
3935
+ {
3936
+ name: "version",
3937
+ dataType: "number",
3938
+ description: "Version number (increments on update)"
3939
+ },
3940
+ // Comment/threading fields (for threaded discussions in shared spaces)
3941
+ {
3942
+ name: "parent_id",
3943
+ dataType: "text",
3944
+ description: "ID of parent memory or comment (for threading)"
3945
+ },
3946
+ {
3947
+ name: "thread_root_id",
3948
+ dataType: "text",
3949
+ description: "Root memory ID for fetching entire thread"
3950
+ },
3951
+ {
3952
+ name: "moderation_flags",
3953
+ dataType: "text[]",
3954
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
3955
+ }
3956
+ ]
3957
+ });
3958
+ logger.info("Space collection created successfully", {
3959
+ module: "weaviate-space-schema",
3960
+ collectionName
3961
+ });
3962
+ }
3694
3963
  async function ensurePublicCollection(client2) {
3695
3964
  const collectionName = PUBLIC_COLLECTION_NAME;
3965
+ const exists = await client2.collections.exists(collectionName);
3966
+ if (!exists) {
3967
+ await createSpaceCollection(client2, "public");
3968
+ }
3696
3969
  return client2.collections.get(collectionName);
3697
3970
  }
3698
3971
 
@@ -4057,7 +4330,7 @@ async function executePublishMemory(request, userId) {
4057
4330
  attribution: "user",
4058
4331
  // Merge additional tags with original tags
4059
4332
  tags: [...originalTags, ...additionalTags]
4060
- // Keep doc_type as 'memory' (don't change to 'space_memory')
4333
+ // Keep doc_type as 'memory' (space_memory concept was removed)
4061
4334
  // Keep original created_at, updated_at, version (don't overwrite)
4062
4335
  };
4063
4336
  logger.info("Inserting memory into Memory_public", {
@@ -4269,7 +4542,7 @@ async function handleSearchSpace(args, userId) {
4269
4542
  const publicCollection = await ensurePublicCollection(weaviateClient);
4270
4543
  const filterList = [];
4271
4544
  filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4272
- filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4545
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("memory"));
4273
4546
  if (args.content_type) {
4274
4547
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4275
4548
  }
@@ -4425,7 +4698,7 @@ async function handleQuerySpace(args, userId) {
4425
4698
  const publicCollection = await ensurePublicCollection(weaviateClient);
4426
4699
  const filterList = [];
4427
4700
  filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4428
- filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4701
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("memory"));
4429
4702
  if (args.content_type) {
4430
4703
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4431
4704
  }
package/dist/server.js CHANGED
@@ -3756,11 +3756,284 @@ init_space_memory();
3756
3756
  init_logger();
3757
3757
  import weaviate3 from "weaviate-client";
3758
3758
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3759
+ function getSpaceCollectionName(spaceId) {
3760
+ return `Memory_${spaceId}`;
3761
+ }
3759
3762
  function isValidSpaceId(spaceId) {
3760
3763
  return SUPPORTED_SPACES.includes(spaceId);
3761
3764
  }
3765
+ async function createSpaceCollection(client2, spaceId) {
3766
+ const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3767
+ logger.info("Creating space collection", {
3768
+ module: "weaviate-space-schema",
3769
+ collectionName,
3770
+ spaceId
3771
+ });
3772
+ await client2.collections.create({
3773
+ name: collectionName,
3774
+ // Vectorizer configuration
3775
+ vectorizers: weaviate3.configure.vectorizer.text2VecOpenAI({
3776
+ model: "text-embedding-3-small",
3777
+ // Vectorize content, title, summary, and observation for semantic search
3778
+ // Note: title and summary are optional fields
3779
+ sourceProperties: ["content", "title", "summary", "observation"]
3780
+ }),
3781
+ properties: [
3782
+ // Discriminator
3783
+ {
3784
+ name: "doc_type",
3785
+ dataType: "text",
3786
+ description: 'Document type: "space_memory"'
3787
+ },
3788
+ // Space identity
3789
+ {
3790
+ name: "spaces",
3791
+ dataType: "text[]",
3792
+ description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])'
3793
+ },
3794
+ {
3795
+ name: "space_id",
3796
+ dataType: "text",
3797
+ description: "DEPRECATED: Use spaces array instead. Will be removed in v3.0.0."
3798
+ },
3799
+ {
3800
+ name: "author_id",
3801
+ dataType: "text",
3802
+ description: "Original author user_id (for permissions)"
3803
+ },
3804
+ {
3805
+ name: "ghost_id",
3806
+ dataType: "text",
3807
+ description: "Optional ghost profile ID for pseudonymous publishing"
3808
+ },
3809
+ {
3810
+ name: "attribution",
3811
+ dataType: "text",
3812
+ description: 'Attribution type: "user" or "ghost"'
3813
+ },
3814
+ // Discovery metadata
3815
+ {
3816
+ name: "published_at",
3817
+ dataType: "text",
3818
+ description: "When published to space (ISO 8601)"
3819
+ },
3820
+ {
3821
+ name: "discovery_count",
3822
+ dataType: "number",
3823
+ description: "How many times discovered"
3824
+ },
3825
+ // Memory fields (same as personal memories)
3826
+ {
3827
+ name: "content",
3828
+ dataType: "text",
3829
+ description: "Main memory content (vectorized)"
3830
+ },
3831
+ {
3832
+ name: "title",
3833
+ dataType: "text",
3834
+ description: "Optional short title"
3835
+ },
3836
+ {
3837
+ name: "summary",
3838
+ dataType: "text",
3839
+ description: "Optional brief summary"
3840
+ },
3841
+ {
3842
+ name: "type",
3843
+ dataType: "text",
3844
+ description: "Content type (note, event, person, etc.)"
3845
+ },
3846
+ // Scoring fields
3847
+ {
3848
+ name: "weight",
3849
+ dataType: "number",
3850
+ description: "Significance/priority (0-1)"
3851
+ },
3852
+ {
3853
+ name: "trust",
3854
+ dataType: "number",
3855
+ description: "Access control level (0-1)"
3856
+ },
3857
+ {
3858
+ name: "confidence",
3859
+ dataType: "number",
3860
+ description: "System confidence in accuracy (0-1)"
3861
+ },
3862
+ // Location fields (flattened) - MUST match user memory schema exactly
3863
+ {
3864
+ name: "location_gps_lat",
3865
+ dataType: "number",
3866
+ description: "GPS latitude"
3867
+ },
3868
+ {
3869
+ name: "location_gps_lng",
3870
+ dataType: "number",
3871
+ description: "GPS longitude"
3872
+ },
3873
+ {
3874
+ name: "location_address",
3875
+ dataType: "text",
3876
+ description: "Formatted address"
3877
+ },
3878
+ {
3879
+ name: "location_city",
3880
+ dataType: "text",
3881
+ description: "City name"
3882
+ },
3883
+ {
3884
+ name: "location_country",
3885
+ dataType: "text",
3886
+ description: "Country name"
3887
+ },
3888
+ {
3889
+ name: "location_source",
3890
+ dataType: "text",
3891
+ description: "Location source (gps, ip, manual, etc.)"
3892
+ },
3893
+ // Context fields (flattened) - MUST match user memory schema exactly
3894
+ {
3895
+ name: "context_conversation_id",
3896
+ dataType: "text",
3897
+ description: "Conversation ID"
3898
+ },
3899
+ {
3900
+ name: "context_summary",
3901
+ dataType: "text",
3902
+ description: "Brief context summary"
3903
+ },
3904
+ {
3905
+ name: "context_timestamp",
3906
+ dataType: "date",
3907
+ description: "Context timestamp"
3908
+ },
3909
+ // Locale fields - MUST match user memory schema exactly
3910
+ {
3911
+ name: "locale_language",
3912
+ dataType: "text",
3913
+ description: "Language code (e.g., en, es, fr)"
3914
+ },
3915
+ {
3916
+ name: "locale_timezone",
3917
+ dataType: "text",
3918
+ description: "Timezone (e.g., America/Los_Angeles)"
3919
+ },
3920
+ // Relationships - MUST match user memory schema exactly
3921
+ {
3922
+ name: "relationships",
3923
+ dataType: "text[]",
3924
+ description: "Array of relationship IDs"
3925
+ },
3926
+ // Access tracking - MUST match user memory schema exactly
3927
+ {
3928
+ name: "access_count",
3929
+ dataType: "number",
3930
+ description: "Total times accessed"
3931
+ },
3932
+ {
3933
+ name: "last_accessed_at",
3934
+ dataType: "date",
3935
+ description: "Most recent access timestamp"
3936
+ },
3937
+ // Metadata - MUST match user memory schema exactly
3938
+ {
3939
+ name: "tags",
3940
+ dataType: "text[]",
3941
+ description: "Tags for organization"
3942
+ },
3943
+ {
3944
+ name: "references",
3945
+ dataType: "text[]",
3946
+ description: "Source URLs"
3947
+ },
3948
+ {
3949
+ name: "template_id",
3950
+ dataType: "text",
3951
+ description: "Template ID if using template"
3952
+ },
3953
+ // Relationship-specific fields (for relationships in public space)
3954
+ {
3955
+ name: "memory_ids",
3956
+ dataType: "text[]",
3957
+ description: "Connected memory IDs (for relationships)"
3958
+ },
3959
+ {
3960
+ name: "relationship_type",
3961
+ dataType: "text",
3962
+ description: "Relationship type (for relationships)"
3963
+ },
3964
+ {
3965
+ name: "observation",
3966
+ dataType: "text",
3967
+ description: "Relationship observation (vectorized)"
3968
+ },
3969
+ {
3970
+ name: "strength",
3971
+ dataType: "number",
3972
+ description: "Relationship strength (0-1)"
3973
+ },
3974
+ // Computed fields - MUST match user memory schema exactly
3975
+ {
3976
+ name: "base_weight",
3977
+ dataType: "number",
3978
+ description: "User-specified weight"
3979
+ },
3980
+ {
3981
+ name: "computed_weight",
3982
+ dataType: "number",
3983
+ description: "Calculated effective weight"
3984
+ },
3985
+ // User ID field (for backwards compatibility with spread operator)
3986
+ {
3987
+ name: "user_id",
3988
+ dataType: "text",
3989
+ description: "User ID (copied from original memory, same as author_id)"
3990
+ },
3991
+ // Timestamps
3992
+ {
3993
+ name: "created_at",
3994
+ dataType: "text",
3995
+ description: "Original creation timestamp (ISO 8601)"
3996
+ },
3997
+ {
3998
+ name: "updated_at",
3999
+ dataType: "text",
4000
+ description: "Last update timestamp (ISO 8601)"
4001
+ },
4002
+ // Versioning
4003
+ {
4004
+ name: "version",
4005
+ dataType: "number",
4006
+ description: "Version number (increments on update)"
4007
+ },
4008
+ // Comment/threading fields (for threaded discussions in shared spaces)
4009
+ {
4010
+ name: "parent_id",
4011
+ dataType: "text",
4012
+ description: "ID of parent memory or comment (for threading)"
4013
+ },
4014
+ {
4015
+ name: "thread_root_id",
4016
+ dataType: "text",
4017
+ description: "Root memory ID for fetching entire thread"
4018
+ },
4019
+ {
4020
+ name: "moderation_flags",
4021
+ dataType: "text[]",
4022
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
4023
+ }
4024
+ ]
4025
+ });
4026
+ logger.info("Space collection created successfully", {
4027
+ module: "weaviate-space-schema",
4028
+ collectionName
4029
+ });
4030
+ }
3762
4031
  async function ensurePublicCollection(client2) {
3763
4032
  const collectionName = PUBLIC_COLLECTION_NAME;
4033
+ const exists = await client2.collections.exists(collectionName);
4034
+ if (!exists) {
4035
+ await createSpaceCollection(client2, "public");
4036
+ }
3764
4037
  return client2.collections.get(collectionName);
3765
4038
  }
3766
4039
 
@@ -4125,7 +4398,7 @@ async function executePublishMemory(request, userId) {
4125
4398
  attribution: "user",
4126
4399
  // Merge additional tags with original tags
4127
4400
  tags: [...originalTags, ...additionalTags]
4128
- // Keep doc_type as 'memory' (don't change to 'space_memory')
4401
+ // Keep doc_type as 'memory' (space_memory concept was removed)
4129
4402
  // Keep original created_at, updated_at, version (don't overwrite)
4130
4403
  };
4131
4404
  logger.info("Inserting memory into Memory_public", {
@@ -4337,7 +4610,7 @@ async function handleSearchSpace(args, userId) {
4337
4610
  const publicCollection = await ensurePublicCollection(weaviateClient);
4338
4611
  const filterList = [];
4339
4612
  filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4340
- filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4613
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("memory"));
4341
4614
  if (args.content_type) {
4342
4615
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4343
4616
  }
@@ -4493,7 +4766,7 @@ async function handleQuerySpace(args, userId) {
4493
4766
  const publicCollection = await ensurePublicCollection(weaviateClient);
4494
4767
  const filterList = [];
4495
4768
  filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4496
- filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4769
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("memory"));
4497
4770
  if (args.content_type) {
4498
4771
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4499
4772
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -243,7 +243,7 @@ async function executePublishMemory(
243
243
  attribution: 'user' as const,
244
244
  // Merge additional tags with original tags
245
245
  tags: [...originalTags, ...additionalTags],
246
- // Keep doc_type as 'memory' (don't change to 'space_memory')
246
+ // Keep doc_type as 'memory' (space_memory concept was removed)
247
247
  // Keep original created_at, updated_at, version (don't overwrite)
248
248
  };
249
249
 
@@ -143,8 +143,8 @@ export async function handleQuerySpace(
143
143
  // Filter by spaces array (memory must be in at least one requested space)
144
144
  filterList.push(publicCollection.filter.byProperty('spaces').containsAny(args.spaces));
145
145
 
146
- // Filter by doc_type (space_memory)
147
- filterList.push(publicCollection.filter.byProperty('doc_type').equal('space_memory'));
146
+ // Filter by doc_type (memory) - space_memory concept was removed
147
+ filterList.push(publicCollection.filter.byProperty('doc_type').equal('memory'));
148
148
 
149
149
  // Apply content type filter
150
150
  if (args.content_type) {
@@ -155,8 +155,8 @@ export async function handleSearchSpace(
155
155
  // Filter by spaces array (memory must be in at least one requested space)
156
156
  filterList.push(publicCollection.filter.byProperty('spaces').containsAny(args.spaces));
157
157
 
158
- // Filter by doc_type (space_memory)
159
- filterList.push(publicCollection.filter.byProperty('doc_type').equal('space_memory'));
158
+ // Filter by doc_type (memory) - space_memory concept was removed
159
+ filterList.push(publicCollection.filter.byProperty('doc_type').equal('memory'));
160
160
 
161
161
  // Apply content type filter
162
162
  if (args.content_type) {
@@ -384,16 +384,14 @@ export async function ensurePublicCollection(
384
384
  ): Promise<Collection<any>> {
385
385
  const collectionName = PUBLIC_COLLECTION_NAME;
386
386
 
387
- // DON'T manually create the collection!
388
- // Let Weaviate auto-generate the schema from the first insert.
389
- // This ensures the schema matches user memory collections exactly,
390
- // including nested objects (context, location) that were auto-generated.
391
- //
392
- // When we spread {...originalMemory.properties}, the nested objects
393
- // will be preserved and Weaviate will auto-create matching schema.
394
- //
395
- // NOTE: Collection will be created automatically on first insert.
396
- // Weaviate's auto-schema feature handles this transparently.
387
+ // Check if collection exists
388
+ const exists = await client.collections.exists(collectionName);
389
+
390
+ if (!exists) {
391
+ // Create with proper vectorizer configuration
392
+ // Use 'public' as spaceId to trigger PUBLIC_COLLECTION_NAME
393
+ await createSpaceCollection(client, 'public');
394
+ }
397
395
 
398
396
  return client.collections.get(collectionName);
399
397
  }