@prmichaelsen/remember-mcp 2.7.0 → 2.7.1

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,28 @@ 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.1] - 2026-02-17
9
+
10
+ ### Fixed
11
+
12
+ - **CRITICAL: Memory_public Auto-Schema**: Let Weaviate auto-generate schema instead of manual definition
13
+ - Removed manual schema creation for Memory_public collection
14
+ - Weaviate will auto-generate schema from first insert
15
+ - Ensures schema matches user memory collections EXACTLY
16
+ - Includes nested objects (context, location) that were auto-generated in user collections
17
+ - Fixes issue where nested objects were rejected due to schema expecting flattened properties
18
+ - Spread operator now works perfectly since schemas are identical
19
+
20
+ ### Root Cause
21
+
22
+ - User memory collections have auto-generated schemas with nested `context` and `location` objects
23
+ - Memory_public had manually defined schema with flattened properties
24
+ - When spreading `...originalMemory.properties`, nested objects didn't match flattened schema
25
+ - Weaviate rejected ALL properties due to nested object schema conflict
26
+ - Auto-schema approach ensures perfect compatibility
27
+
28
+ ---
29
+
8
30
  ## [2.7.0] - 2026-02-17
9
31
 
10
32
  ### Fixed
@@ -3687,283 +3687,11 @@ init_space_memory();
3687
3687
  init_logger();
3688
3688
  import weaviate3 from "weaviate-client";
3689
3689
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3690
- function getSpaceCollectionName(spaceId) {
3691
- return `Memory_${spaceId}`;
3692
- }
3693
3690
  function isValidSpaceId(spaceId) {
3694
3691
  return SUPPORTED_SPACES.includes(spaceId);
3695
3692
  }
3696
- async function createSpaceCollection(client2, spaceId) {
3697
- const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3698
- logger.info("Creating space collection", {
3699
- module: "weaviate-space-schema",
3700
- collectionName,
3701
- spaceId
3702
- });
3703
- await client2.collections.create({
3704
- name: collectionName,
3705
- // Vectorizer configuration
3706
- vectorizers: weaviate3.configure.vectorizer.text2VecOpenAI({
3707
- model: "text-embedding-3-small",
3708
- // Vectorize content for semantic search
3709
- sourceProperties: ["content", "observation"]
3710
- }),
3711
- properties: [
3712
- // Discriminator
3713
- {
3714
- name: "doc_type",
3715
- dataType: "text",
3716
- description: 'Document type: "space_memory"'
3717
- },
3718
- // Space identity
3719
- {
3720
- name: "spaces",
3721
- dataType: "text[]",
3722
- description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])'
3723
- },
3724
- {
3725
- name: "space_id",
3726
- dataType: "text",
3727
- description: "DEPRECATED: Use spaces array instead. Will be removed in v3.0.0."
3728
- },
3729
- {
3730
- name: "author_id",
3731
- dataType: "text",
3732
- description: "Original author user_id (for permissions)"
3733
- },
3734
- {
3735
- name: "ghost_id",
3736
- dataType: "text",
3737
- description: "Optional ghost profile ID for pseudonymous publishing"
3738
- },
3739
- {
3740
- name: "attribution",
3741
- dataType: "text",
3742
- description: 'Attribution type: "user" or "ghost"'
3743
- },
3744
- // Discovery metadata
3745
- {
3746
- name: "published_at",
3747
- dataType: "text",
3748
- description: "When published to space (ISO 8601)"
3749
- },
3750
- {
3751
- name: "discovery_count",
3752
- dataType: "number",
3753
- description: "How many times discovered"
3754
- },
3755
- // Memory fields (same as personal memories)
3756
- {
3757
- name: "content",
3758
- dataType: "text",
3759
- description: "Main memory content (vectorized)"
3760
- },
3761
- {
3762
- name: "title",
3763
- dataType: "text",
3764
- description: "Optional short title"
3765
- },
3766
- {
3767
- name: "summary",
3768
- dataType: "text",
3769
- description: "Optional brief summary"
3770
- },
3771
- {
3772
- name: "type",
3773
- dataType: "text",
3774
- description: "Content type (note, event, person, etc.)"
3775
- },
3776
- // Scoring fields
3777
- {
3778
- name: "weight",
3779
- dataType: "number",
3780
- description: "Significance/priority (0-1)"
3781
- },
3782
- {
3783
- name: "trust",
3784
- dataType: "number",
3785
- description: "Access control level (0-1)"
3786
- },
3787
- {
3788
- name: "confidence",
3789
- dataType: "number",
3790
- description: "System confidence in accuracy (0-1)"
3791
- },
3792
- // Location fields (flattened) - MUST match user memory schema exactly
3793
- {
3794
- name: "location_gps_lat",
3795
- dataType: "number",
3796
- description: "GPS latitude"
3797
- },
3798
- {
3799
- name: "location_gps_lng",
3800
- dataType: "number",
3801
- description: "GPS longitude"
3802
- },
3803
- {
3804
- name: "location_address",
3805
- dataType: "text",
3806
- description: "Formatted address"
3807
- },
3808
- {
3809
- name: "location_city",
3810
- dataType: "text",
3811
- description: "City name"
3812
- },
3813
- {
3814
- name: "location_country",
3815
- dataType: "text",
3816
- description: "Country name"
3817
- },
3818
- {
3819
- name: "location_source",
3820
- dataType: "text",
3821
- description: "Location source (gps, ip, manual, etc.)"
3822
- },
3823
- // Context fields (flattened) - MUST match user memory schema exactly
3824
- {
3825
- name: "context_conversation_id",
3826
- dataType: "text",
3827
- description: "Conversation ID"
3828
- },
3829
- {
3830
- name: "context_summary",
3831
- dataType: "text",
3832
- description: "Brief context summary"
3833
- },
3834
- {
3835
- name: "context_timestamp",
3836
- dataType: "date",
3837
- description: "Context timestamp"
3838
- },
3839
- // Locale fields - MUST match user memory schema exactly
3840
- {
3841
- name: "locale_language",
3842
- dataType: "text",
3843
- description: "Language code (e.g., en, es, fr)"
3844
- },
3845
- {
3846
- name: "locale_timezone",
3847
- dataType: "text",
3848
- description: "Timezone (e.g., America/Los_Angeles)"
3849
- },
3850
- // Relationships - MUST match user memory schema exactly
3851
- {
3852
- name: "relationships",
3853
- dataType: "text[]",
3854
- description: "Array of relationship IDs"
3855
- },
3856
- // Access tracking - MUST match user memory schema exactly
3857
- {
3858
- name: "access_count",
3859
- dataType: "number",
3860
- description: "Total times accessed"
3861
- },
3862
- {
3863
- name: "last_accessed_at",
3864
- dataType: "date",
3865
- description: "Most recent access timestamp"
3866
- },
3867
- // Metadata - MUST match user memory schema exactly
3868
- {
3869
- name: "tags",
3870
- dataType: "text[]",
3871
- description: "Tags for organization"
3872
- },
3873
- {
3874
- name: "references",
3875
- dataType: "text[]",
3876
- description: "Source URLs"
3877
- },
3878
- {
3879
- name: "template_id",
3880
- dataType: "text",
3881
- description: "Template ID if using template"
3882
- },
3883
- // Relationship-specific fields (for relationships in public space)
3884
- {
3885
- name: "memory_ids",
3886
- dataType: "text[]",
3887
- description: "Connected memory IDs (for relationships)"
3888
- },
3889
- {
3890
- name: "relationship_type",
3891
- dataType: "text",
3892
- description: "Relationship type (for relationships)"
3893
- },
3894
- {
3895
- name: "observation",
3896
- dataType: "text",
3897
- description: "Relationship observation (vectorized)"
3898
- },
3899
- {
3900
- name: "strength",
3901
- dataType: "number",
3902
- description: "Relationship strength (0-1)"
3903
- },
3904
- // Computed fields - MUST match user memory schema exactly
3905
- {
3906
- name: "base_weight",
3907
- dataType: "number",
3908
- description: "User-specified weight"
3909
- },
3910
- {
3911
- name: "computed_weight",
3912
- dataType: "number",
3913
- description: "Calculated effective weight"
3914
- },
3915
- // User ID field (for backwards compatibility with spread operator)
3916
- {
3917
- name: "user_id",
3918
- dataType: "text",
3919
- description: "User ID (copied from original memory, same as author_id)"
3920
- },
3921
- // Timestamps
3922
- {
3923
- name: "created_at",
3924
- dataType: "text",
3925
- description: "Original creation timestamp (ISO 8601)"
3926
- },
3927
- {
3928
- name: "updated_at",
3929
- dataType: "text",
3930
- description: "Last update timestamp (ISO 8601)"
3931
- },
3932
- // Versioning
3933
- {
3934
- name: "version",
3935
- dataType: "number",
3936
- description: "Version number (increments on update)"
3937
- },
3938
- // Comment/threading fields (for threaded discussions in shared spaces)
3939
- {
3940
- name: "parent_id",
3941
- dataType: "text",
3942
- description: "ID of parent memory or comment (for threading)"
3943
- },
3944
- {
3945
- name: "thread_root_id",
3946
- dataType: "text",
3947
- description: "Root memory ID for fetching entire thread"
3948
- },
3949
- {
3950
- name: "moderation_flags",
3951
- dataType: "text[]",
3952
- description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
3953
- }
3954
- ]
3955
- });
3956
- logger.info("Space collection created successfully", {
3957
- module: "weaviate-space-schema",
3958
- collectionName
3959
- });
3960
- }
3961
3693
  async function ensurePublicCollection(client2) {
3962
3694
  const collectionName = PUBLIC_COLLECTION_NAME;
3963
- const exists = await client2.collections.exists(collectionName);
3964
- if (!exists) {
3965
- await createSpaceCollection(client2, "public");
3966
- }
3967
3695
  return client2.collections.get(collectionName);
3968
3696
  }
3969
3697
 
package/dist/server.js CHANGED
@@ -3755,283 +3755,11 @@ init_space_memory();
3755
3755
  init_logger();
3756
3756
  import weaviate3 from "weaviate-client";
3757
3757
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3758
- function getSpaceCollectionName(spaceId) {
3759
- return `Memory_${spaceId}`;
3760
- }
3761
3758
  function isValidSpaceId(spaceId) {
3762
3759
  return SUPPORTED_SPACES.includes(spaceId);
3763
3760
  }
3764
- async function createSpaceCollection(client2, spaceId) {
3765
- const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3766
- logger.info("Creating space collection", {
3767
- module: "weaviate-space-schema",
3768
- collectionName,
3769
- spaceId
3770
- });
3771
- await client2.collections.create({
3772
- name: collectionName,
3773
- // Vectorizer configuration
3774
- vectorizers: weaviate3.configure.vectorizer.text2VecOpenAI({
3775
- model: "text-embedding-3-small",
3776
- // Vectorize content for semantic search
3777
- sourceProperties: ["content", "observation"]
3778
- }),
3779
- properties: [
3780
- // Discriminator
3781
- {
3782
- name: "doc_type",
3783
- dataType: "text",
3784
- description: 'Document type: "space_memory"'
3785
- },
3786
- // Space identity
3787
- {
3788
- name: "spaces",
3789
- dataType: "text[]",
3790
- description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])'
3791
- },
3792
- {
3793
- name: "space_id",
3794
- dataType: "text",
3795
- description: "DEPRECATED: Use spaces array instead. Will be removed in v3.0.0."
3796
- },
3797
- {
3798
- name: "author_id",
3799
- dataType: "text",
3800
- description: "Original author user_id (for permissions)"
3801
- },
3802
- {
3803
- name: "ghost_id",
3804
- dataType: "text",
3805
- description: "Optional ghost profile ID for pseudonymous publishing"
3806
- },
3807
- {
3808
- name: "attribution",
3809
- dataType: "text",
3810
- description: 'Attribution type: "user" or "ghost"'
3811
- },
3812
- // Discovery metadata
3813
- {
3814
- name: "published_at",
3815
- dataType: "text",
3816
- description: "When published to space (ISO 8601)"
3817
- },
3818
- {
3819
- name: "discovery_count",
3820
- dataType: "number",
3821
- description: "How many times discovered"
3822
- },
3823
- // Memory fields (same as personal memories)
3824
- {
3825
- name: "content",
3826
- dataType: "text",
3827
- description: "Main memory content (vectorized)"
3828
- },
3829
- {
3830
- name: "title",
3831
- dataType: "text",
3832
- description: "Optional short title"
3833
- },
3834
- {
3835
- name: "summary",
3836
- dataType: "text",
3837
- description: "Optional brief summary"
3838
- },
3839
- {
3840
- name: "type",
3841
- dataType: "text",
3842
- description: "Content type (note, event, person, etc.)"
3843
- },
3844
- // Scoring fields
3845
- {
3846
- name: "weight",
3847
- dataType: "number",
3848
- description: "Significance/priority (0-1)"
3849
- },
3850
- {
3851
- name: "trust",
3852
- dataType: "number",
3853
- description: "Access control level (0-1)"
3854
- },
3855
- {
3856
- name: "confidence",
3857
- dataType: "number",
3858
- description: "System confidence in accuracy (0-1)"
3859
- },
3860
- // Location fields (flattened) - MUST match user memory schema exactly
3861
- {
3862
- name: "location_gps_lat",
3863
- dataType: "number",
3864
- description: "GPS latitude"
3865
- },
3866
- {
3867
- name: "location_gps_lng",
3868
- dataType: "number",
3869
- description: "GPS longitude"
3870
- },
3871
- {
3872
- name: "location_address",
3873
- dataType: "text",
3874
- description: "Formatted address"
3875
- },
3876
- {
3877
- name: "location_city",
3878
- dataType: "text",
3879
- description: "City name"
3880
- },
3881
- {
3882
- name: "location_country",
3883
- dataType: "text",
3884
- description: "Country name"
3885
- },
3886
- {
3887
- name: "location_source",
3888
- dataType: "text",
3889
- description: "Location source (gps, ip, manual, etc.)"
3890
- },
3891
- // Context fields (flattened) - MUST match user memory schema exactly
3892
- {
3893
- name: "context_conversation_id",
3894
- dataType: "text",
3895
- description: "Conversation ID"
3896
- },
3897
- {
3898
- name: "context_summary",
3899
- dataType: "text",
3900
- description: "Brief context summary"
3901
- },
3902
- {
3903
- name: "context_timestamp",
3904
- dataType: "date",
3905
- description: "Context timestamp"
3906
- },
3907
- // Locale fields - MUST match user memory schema exactly
3908
- {
3909
- name: "locale_language",
3910
- dataType: "text",
3911
- description: "Language code (e.g., en, es, fr)"
3912
- },
3913
- {
3914
- name: "locale_timezone",
3915
- dataType: "text",
3916
- description: "Timezone (e.g., America/Los_Angeles)"
3917
- },
3918
- // Relationships - MUST match user memory schema exactly
3919
- {
3920
- name: "relationships",
3921
- dataType: "text[]",
3922
- description: "Array of relationship IDs"
3923
- },
3924
- // Access tracking - MUST match user memory schema exactly
3925
- {
3926
- name: "access_count",
3927
- dataType: "number",
3928
- description: "Total times accessed"
3929
- },
3930
- {
3931
- name: "last_accessed_at",
3932
- dataType: "date",
3933
- description: "Most recent access timestamp"
3934
- },
3935
- // Metadata - MUST match user memory schema exactly
3936
- {
3937
- name: "tags",
3938
- dataType: "text[]",
3939
- description: "Tags for organization"
3940
- },
3941
- {
3942
- name: "references",
3943
- dataType: "text[]",
3944
- description: "Source URLs"
3945
- },
3946
- {
3947
- name: "template_id",
3948
- dataType: "text",
3949
- description: "Template ID if using template"
3950
- },
3951
- // Relationship-specific fields (for relationships in public space)
3952
- {
3953
- name: "memory_ids",
3954
- dataType: "text[]",
3955
- description: "Connected memory IDs (for relationships)"
3956
- },
3957
- {
3958
- name: "relationship_type",
3959
- dataType: "text",
3960
- description: "Relationship type (for relationships)"
3961
- },
3962
- {
3963
- name: "observation",
3964
- dataType: "text",
3965
- description: "Relationship observation (vectorized)"
3966
- },
3967
- {
3968
- name: "strength",
3969
- dataType: "number",
3970
- description: "Relationship strength (0-1)"
3971
- },
3972
- // Computed fields - MUST match user memory schema exactly
3973
- {
3974
- name: "base_weight",
3975
- dataType: "number",
3976
- description: "User-specified weight"
3977
- },
3978
- {
3979
- name: "computed_weight",
3980
- dataType: "number",
3981
- description: "Calculated effective weight"
3982
- },
3983
- // User ID field (for backwards compatibility with spread operator)
3984
- {
3985
- name: "user_id",
3986
- dataType: "text",
3987
- description: "User ID (copied from original memory, same as author_id)"
3988
- },
3989
- // Timestamps
3990
- {
3991
- name: "created_at",
3992
- dataType: "text",
3993
- description: "Original creation timestamp (ISO 8601)"
3994
- },
3995
- {
3996
- name: "updated_at",
3997
- dataType: "text",
3998
- description: "Last update timestamp (ISO 8601)"
3999
- },
4000
- // Versioning
4001
- {
4002
- name: "version",
4003
- dataType: "number",
4004
- description: "Version number (increments on update)"
4005
- },
4006
- // Comment/threading fields (for threaded discussions in shared spaces)
4007
- {
4008
- name: "parent_id",
4009
- dataType: "text",
4010
- description: "ID of parent memory or comment (for threading)"
4011
- },
4012
- {
4013
- name: "thread_root_id",
4014
- dataType: "text",
4015
- description: "Root memory ID for fetching entire thread"
4016
- },
4017
- {
4018
- name: "moderation_flags",
4019
- dataType: "text[]",
4020
- description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
4021
- }
4022
- ]
4023
- });
4024
- logger.info("Space collection created successfully", {
4025
- module: "weaviate-space-schema",
4026
- collectionName
4027
- });
4028
- }
4029
3761
  async function ensurePublicCollection(client2) {
4030
3762
  const collectionName = PUBLIC_COLLECTION_NAME;
4031
- const exists = await client2.collections.exists(collectionName);
4032
- if (!exists) {
4033
- await createSpaceCollection(client2, "public");
4034
- }
4035
3763
  return client2.collections.get(collectionName);
4036
3764
  }
4037
3765
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -383,12 +383,16 @@ export async function ensurePublicCollection(
383
383
  ): Promise<Collection<any>> {
384
384
  const collectionName = PUBLIC_COLLECTION_NAME;
385
385
 
386
- // Check if collection exists
387
- const exists = await client.collections.exists(collectionName);
388
-
389
- if (!exists) {
390
- await createSpaceCollection(client, 'public');
391
- }
386
+ // DON'T manually create the collection!
387
+ // Let Weaviate auto-generate the schema from the first insert.
388
+ // This ensures the schema matches user memory collections exactly,
389
+ // including nested objects (context, location) that were auto-generated.
390
+ //
391
+ // When we spread {...originalMemory.properties}, the nested objects
392
+ // will be preserved and Weaviate will auto-create matching schema.
393
+ //
394
+ // NOTE: Collection will be created automatically on first insert.
395
+ // Weaviate's auto-schema feature handles this transparently.
392
396
 
393
397
  return client.collections.get(collectionName);
394
398
  }