@prmichaelsen/remember-mcp 2.6.2 → 2.6.4

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.
@@ -565,6 +565,34 @@ function sanitizeUserId(userId) {
565
565
  function getMemoryCollectionName(userId) {
566
566
  return `Memory_${sanitizeUserId(userId)}`;
567
567
  }
568
+ var ALL_MEMORY_PROPERTIES = [
569
+ "user_id",
570
+ "doc_type",
571
+ "type",
572
+ "title",
573
+ "content",
574
+ "tags",
575
+ "weight",
576
+ "base_weight",
577
+ "trust_level",
578
+ "context",
579
+ "location",
580
+ "relationships",
581
+ "created_at",
582
+ "updated_at",
583
+ "version",
584
+ "attribution",
585
+ "source_url",
586
+ "author",
587
+ "parent_id",
588
+ "thread_root_id",
589
+ "moderation_flags"
590
+ ];
591
+ async function fetchMemoryWithAllProperties(collection, memoryId) {
592
+ return await collection.query.fetchObjectById(memoryId, {
593
+ returnProperties: ALL_MEMORY_PROPERTIES
594
+ });
595
+ }
568
596
 
569
597
  // src/firestore/init.ts
570
598
  init_config();
@@ -1542,6 +1570,11 @@ var searchMemoryTool = {
1542
1570
  - "Show me notes from last week" \u2192 returns notes + any relationships created that week
1543
1571
 
1544
1572
  **AGENT GUIDANCE**:
1573
+ - \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
1574
+ * \u2705 CORRECT: User says "search for hiking" \u2192 { query: "hiking" }
1575
+ * \u274C WRONG: User says "search for hiking" \u2192 { query: "hiking", filters: { types: ["note"] } }
1576
+ * \u2705 CORRECT: User says "search for note memories about hiking" \u2192 { query: "hiking", filters: { types: ["note"] } }
1577
+ * Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.
1545
1578
  - If search results are too narrow or miss relevant content, try remember_query_memory instead - it uses pure semantic search which is better for broader, concept-based queries. You can inform the user: "I didn't find what you're looking for with keyword search. Let me try a broader semantic search using the query tool."
1546
1579
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
1547
1580
  * Create a new memory with the information they're looking for
@@ -2112,6 +2145,11 @@ var queryMemoryTool = {
2112
2145
  - "What are my project goals?"
2113
2146
 
2114
2147
  **AGENT GUIDANCE**:
2148
+ - \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
2149
+ * \u2705 CORRECT: User says "what do I know about hiking?" \u2192 { query: "hiking" }
2150
+ * \u274C WRONG: User says "what do I know about hiking?" \u2192 { query: "hiking", filters: { types: ["note"] } }
2151
+ * \u2705 CORRECT: User says "what notes do I have about hiking?" \u2192 { query: "hiking", filters: { types: ["note"] } }
2152
+ * Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.
2115
2153
  - If query results are too broad or include irrelevant content, try remember_search_memory instead - it uses hybrid search with keyword matching which is better for precise, specific searches. You can inform the user: "The results were too broad. Let me try a more precise keyword search using the search tool."
2116
2154
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
2117
2155
  * Create a new memory with the information they're looking for
@@ -3833,11 +3871,15 @@ async function handlePublish(args, userId) {
3833
3871
  memoryId: args.memory_id
3834
3872
  });
3835
3873
  const userCollection = weaviateClient.collections.get(collectionName);
3836
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
3874
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
3837
3875
  logger.debug("Memory fetch result", {
3838
3876
  tool: "remember_publish",
3839
3877
  found: !!memory,
3840
- memoryId: args.memory_id
3878
+ memoryId: args.memory_id,
3879
+ hasProperties: !!memory?.properties,
3880
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
3881
+ hasTitle: !!memory?.properties?.title,
3882
+ hasContent: !!memory?.properties?.content
3841
3883
  });
3842
3884
  if (!memory) {
3843
3885
  logger.info("Memory not found", {
@@ -4024,13 +4066,18 @@ async function executePublishMemory(request, userId) {
4024
4066
  collectionName: getMemoryCollectionName(userId),
4025
4067
  memoryId: request.payload.memory_id
4026
4068
  });
4027
- const originalMemory = await userCollection.query.fetchObjectById(
4069
+ const originalMemory = await fetchMemoryWithAllProperties(
4070
+ userCollection,
4028
4071
  request.payload.memory_id
4029
4072
  );
4030
4073
  logger.debug("Original memory fetch result", {
4031
4074
  function: "executePublishMemory",
4032
4075
  found: !!originalMemory,
4033
- memoryId: request.payload.memory_id
4076
+ memoryId: request.payload.memory_id,
4077
+ hasProperties: !!originalMemory?.properties,
4078
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
4079
+ hasTitle: !!originalMemory?.properties?.title,
4080
+ hasContent: !!originalMemory?.properties?.content
4034
4081
  });
4035
4082
  if (!originalMemory) {
4036
4083
  logger.info("Original memory not found", {
@@ -4186,7 +4233,14 @@ import { Filters as Filters3 } from "weaviate-client";
4186
4233
  init_space_memory();
4187
4234
  var searchSpaceTool = {
4188
4235
  name: "remember_search_space",
4189
- description: "Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.",
4236
+ description: `Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.
4237
+
4238
+ \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
4239
+ - \u2705 CORRECT: User says "search The Void for hiking" \u2192 { spaces: ["the_void"], query: "hiking" }
4240
+ - \u274C WRONG: User says "search The Void for hiking" \u2192 { spaces: ["the_void"], query: "hiking", content_type: "note" }
4241
+ - \u2705 CORRECT: User says "search The Void for note memories about hiking" \u2192 { spaces: ["the_void"], query: "hiking", content_type: "note" }
4242
+
4243
+ Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
4190
4244
  inputSchema: {
4191
4245
  type: "object",
4192
4246
  properties: {
@@ -4345,7 +4399,14 @@ import { Filters as Filters4 } from "weaviate-client";
4345
4399
  init_space_memory();
4346
4400
  var querySpaceTool = {
4347
4401
  name: "remember_query_space",
4348
- description: "Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.",
4402
+ description: `Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.
4403
+
4404
+ \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
4405
+ - \u2705 CORRECT: User says "what's in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking" }
4406
+ - \u274C WRONG: User says "what's in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking", content_type: "note" }
4407
+ - \u2705 CORRECT: User says "what notes are in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking", content_type: "note" }
4408
+
4409
+ Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
4349
4410
  inputSchema: {
4350
4411
  type: "object",
4351
4412
  properties: {
package/dist/server.js CHANGED
@@ -611,6 +611,34 @@ function sanitizeUserId(userId) {
611
611
  function getMemoryCollectionName(userId) {
612
612
  return `Memory_${sanitizeUserId(userId)}`;
613
613
  }
614
+ var ALL_MEMORY_PROPERTIES = [
615
+ "user_id",
616
+ "doc_type",
617
+ "type",
618
+ "title",
619
+ "content",
620
+ "tags",
621
+ "weight",
622
+ "base_weight",
623
+ "trust_level",
624
+ "context",
625
+ "location",
626
+ "relationships",
627
+ "created_at",
628
+ "updated_at",
629
+ "version",
630
+ "attribution",
631
+ "source_url",
632
+ "author",
633
+ "parent_id",
634
+ "thread_root_id",
635
+ "moderation_flags"
636
+ ];
637
+ async function fetchMemoryWithAllProperties(collection, memoryId) {
638
+ return await collection.query.fetchObjectById(memoryId, {
639
+ returnProperties: ALL_MEMORY_PROPERTIES
640
+ });
641
+ }
614
642
 
615
643
  // src/firestore/init.ts
616
644
  init_config();
@@ -1610,6 +1638,11 @@ var searchMemoryTool = {
1610
1638
  - "Show me notes from last week" \u2192 returns notes + any relationships created that week
1611
1639
 
1612
1640
  **AGENT GUIDANCE**:
1641
+ - \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
1642
+ * \u2705 CORRECT: User says "search for hiking" \u2192 { query: "hiking" }
1643
+ * \u274C WRONG: User says "search for hiking" \u2192 { query: "hiking", filters: { types: ["note"] } }
1644
+ * \u2705 CORRECT: User says "search for note memories about hiking" \u2192 { query: "hiking", filters: { types: ["note"] } }
1645
+ * Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.
1613
1646
  - If search results are too narrow or miss relevant content, try remember_query_memory instead - it uses pure semantic search which is better for broader, concept-based queries. You can inform the user: "I didn't find what you're looking for with keyword search. Let me try a broader semantic search using the query tool."
1614
1647
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
1615
1648
  * Create a new memory with the information they're looking for
@@ -2180,6 +2213,11 @@ var queryMemoryTool = {
2180
2213
  - "What are my project goals?"
2181
2214
 
2182
2215
  **AGENT GUIDANCE**:
2216
+ - \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
2217
+ * \u2705 CORRECT: User says "what do I know about hiking?" \u2192 { query: "hiking" }
2218
+ * \u274C WRONG: User says "what do I know about hiking?" \u2192 { query: "hiking", filters: { types: ["note"] } }
2219
+ * \u2705 CORRECT: User says "what notes do I have about hiking?" \u2192 { query: "hiking", filters: { types: ["note"] } }
2220
+ * Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.
2183
2221
  - If query results are too broad or include irrelevant content, try remember_search_memory instead - it uses hybrid search with keyword matching which is better for precise, specific searches. You can inform the user: "The results were too broad. Let me try a more precise keyword search using the search tool."
2184
2222
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
2185
2223
  * Create a new memory with the information they're looking for
@@ -3901,11 +3939,15 @@ async function handlePublish(args, userId) {
3901
3939
  memoryId: args.memory_id
3902
3940
  });
3903
3941
  const userCollection = weaviateClient.collections.get(collectionName);
3904
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
3942
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
3905
3943
  logger.debug("Memory fetch result", {
3906
3944
  tool: "remember_publish",
3907
3945
  found: !!memory,
3908
- memoryId: args.memory_id
3946
+ memoryId: args.memory_id,
3947
+ hasProperties: !!memory?.properties,
3948
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
3949
+ hasTitle: !!memory?.properties?.title,
3950
+ hasContent: !!memory?.properties?.content
3909
3951
  });
3910
3952
  if (!memory) {
3911
3953
  logger.info("Memory not found", {
@@ -4092,13 +4134,18 @@ async function executePublishMemory(request, userId) {
4092
4134
  collectionName: getMemoryCollectionName(userId),
4093
4135
  memoryId: request.payload.memory_id
4094
4136
  });
4095
- const originalMemory = await userCollection.query.fetchObjectById(
4137
+ const originalMemory = await fetchMemoryWithAllProperties(
4138
+ userCollection,
4096
4139
  request.payload.memory_id
4097
4140
  );
4098
4141
  logger.debug("Original memory fetch result", {
4099
4142
  function: "executePublishMemory",
4100
4143
  found: !!originalMemory,
4101
- memoryId: request.payload.memory_id
4144
+ memoryId: request.payload.memory_id,
4145
+ hasProperties: !!originalMemory?.properties,
4146
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
4147
+ hasTitle: !!originalMemory?.properties?.title,
4148
+ hasContent: !!originalMemory?.properties?.content
4102
4149
  });
4103
4150
  if (!originalMemory) {
4104
4151
  logger.info("Original memory not found", {
@@ -4254,7 +4301,14 @@ import { Filters as Filters3 } from "weaviate-client";
4254
4301
  init_space_memory();
4255
4302
  var searchSpaceTool = {
4256
4303
  name: "remember_search_space",
4257
- description: "Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.",
4304
+ description: `Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.
4305
+
4306
+ \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
4307
+ - \u2705 CORRECT: User says "search The Void for hiking" \u2192 { spaces: ["the_void"], query: "hiking" }
4308
+ - \u274C WRONG: User says "search The Void for hiking" \u2192 { spaces: ["the_void"], query: "hiking", content_type: "note" }
4309
+ - \u2705 CORRECT: User says "search The Void for note memories about hiking" \u2192 { spaces: ["the_void"], query: "hiking", content_type: "note" }
4310
+
4311
+ Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
4258
4312
  inputSchema: {
4259
4313
  type: "object",
4260
4314
  properties: {
@@ -4413,7 +4467,14 @@ import { Filters as Filters4 } from "weaviate-client";
4413
4467
  init_space_memory();
4414
4468
  var querySpaceTool = {
4415
4469
  name: "remember_query_space",
4416
- description: "Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.",
4470
+ description: `Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.
4471
+
4472
+ \u26A0\uFE0F **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
4473
+ - \u2705 CORRECT: User says "what's in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking" }
4474
+ - \u274C WRONG: User says "what's in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking", content_type: "note" }
4475
+ - \u2705 CORRECT: User says "what notes are in The Void about hiking?" \u2192 { spaces: ["the_void"], question: "hiking", content_type: "note" }
4476
+
4477
+ Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
4417
4478
  inputSchema: {
4418
4479
  type: "object",
4419
4480
  properties: {
@@ -33,6 +33,22 @@ export declare function getTemplateCollectionName(userId: string): string;
33
33
  * Get collection name for user's audit logs
34
34
  */
35
35
  export declare function getAuditCollectionName(userId: string): string;
36
+ /**
37
+ * List of all memory properties to fetch
38
+ * Centralized to ensure consistency across all tools
39
+ */
40
+ export declare const ALL_MEMORY_PROPERTIES: readonly ["user_id", "doc_type", "type", "title", "content", "tags", "weight", "base_weight", "trust_level", "context", "location", "relationships", "created_at", "updated_at", "version", "attribution", "source_url", "author", "parent_id", "thread_root_id", "moderation_flags"];
41
+ /**
42
+ * Fetch a memory object by ID with all properties
43
+ *
44
+ * This utility ensures all memory properties are fetched consistently
45
+ * across all tools, preventing bugs where properties are missing.
46
+ *
47
+ * @param collection - Weaviate collection
48
+ * @param memoryId - Memory ID to fetch
49
+ * @returns Memory object with all properties
50
+ */
51
+ export declare function fetchMemoryWithAllProperties(collection: any, memoryId: string): Promise<any>;
36
52
  /**
37
53
  * Check if collection exists
38
54
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.6.2",
3
+ "version": "2.6.4",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
9
  import { confirmationTokenService, type ConfirmationRequest } from '../services/confirmation-token.service.js';
10
- import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
10
+ import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
11
11
  import { ensurePublicCollection } from '../weaviate/space-schema.js';
12
12
  import { handleToolError } from '../utils/error-handler.js';
13
13
  import { logger } from '../utils/logger.js';
@@ -151,7 +151,8 @@ async function executePublishMemory(
151
151
  memoryId: request.payload.memory_id,
152
152
  });
153
153
 
154
- const originalMemory = await userCollection.query.fetchObjectById(
154
+ const originalMemory = await fetchMemoryWithAllProperties(
155
+ userCollection,
155
156
  request.payload.memory_id
156
157
  );
157
158
 
@@ -159,6 +160,10 @@ async function executePublishMemory(
159
160
  function: 'executePublishMemory',
160
161
  found: !!originalMemory,
161
162
  memoryId: request.payload.memory_id,
163
+ hasProperties: !!originalMemory?.properties,
164
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
165
+ hasTitle: !!originalMemory?.properties?.title,
166
+ hasContent: !!originalMemory?.properties?.content,
162
167
  });
163
168
 
164
169
  if (!originalMemory) {
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
9
  import { confirmationTokenService } from '../services/confirmation-token.service.js';
10
- import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
10
+ import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
11
11
  import { isValidSpaceId } from '../weaviate/space-schema.js';
12
12
  import { handleToolError } from '../utils/error-handler.js';
13
13
  import { SUPPORTED_SPACES } from '../types/space-memory.js';
@@ -122,12 +122,16 @@ export async function handlePublish(
122
122
 
123
123
  const userCollection = weaviateClient.collections.get(collectionName);
124
124
 
125
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
125
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
126
126
 
127
127
  logger.debug('Memory fetch result', {
128
128
  tool: 'remember_publish',
129
129
  found: !!memory,
130
130
  memoryId: args.memory_id,
131
+ hasProperties: !!memory?.properties,
132
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
133
+ hasTitle: !!memory?.properties?.title,
134
+ hasContent: !!memory?.properties?.content,
131
135
  });
132
136
 
133
137
  if (!memory) {
@@ -35,6 +35,11 @@ export const queryMemoryTool = {
35
35
  - "What are my project goals?"
36
36
 
37
37
  **AGENT GUIDANCE**:
38
+ - ⚠️ **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
39
+ * ✅ CORRECT: User says "what do I know about hiking?" → { query: "hiking" }
40
+ * ❌ WRONG: User says "what do I know about hiking?" → { query: "hiking", filters: { types: ["note"] } }
41
+ * ✅ CORRECT: User says "what notes do I have about hiking?" → { query: "hiking", filters: { types: ["note"] } }
42
+ * Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.
38
43
  - If query results are too broad or include irrelevant content, try remember_search_memory instead - it uses hybrid search with keyword matching which is better for precise, specific searches. You can inform the user: "The results were too broad. Let me try a more precise keyword search using the search tool."
39
44
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
40
45
  * Create a new memory with the information they're looking for
@@ -17,7 +17,14 @@ import { handleToolError } from '../utils/error-handler.js';
17
17
  */
18
18
  export const querySpaceTool: Tool = {
19
19
  name: 'remember_query_space',
20
- description: 'Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.',
20
+ description: `Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.
21
+
22
+ ⚠️ **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
23
+ - ✅ CORRECT: User says "what's in The Void about hiking?" → { spaces: ["the_void"], question: "hiking" }
24
+ - ❌ WRONG: User says "what's in The Void about hiking?" → { spaces: ["the_void"], question: "hiking", content_type: "note" }
25
+ - ✅ CORRECT: User says "what notes are in The Void about hiking?" → { spaces: ["the_void"], question: "hiking", content_type: "note" }
26
+
27
+ Let the query algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
21
28
  inputSchema: {
22
29
  type: 'object',
23
30
  properties: {
@@ -34,6 +34,11 @@ export const searchMemoryTool = {
34
34
  - "Show me notes from last week" → returns notes + any relationships created that week
35
35
 
36
36
  **AGENT GUIDANCE**:
37
+ - ⚠️ **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add filters.types unless the user explicitly requests filtering by content type.
38
+ * ✅ CORRECT: User says "search for hiking" → { query: "hiking" }
39
+ * ❌ WRONG: User says "search for hiking" → { query: "hiking", filters: { types: ["note"] } }
40
+ * ✅ CORRECT: User says "search for note memories about hiking" → { query: "hiking", filters: { types: ["note"] } }
41
+ * Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.
37
42
  - If search results are too narrow or miss relevant content, try remember_query_memory instead - it uses pure semantic search which is better for broader, concept-based queries. You can inform the user: "I didn't find what you're looking for with keyword search. Let me try a broader semantic search using the query tool."
38
43
  - **CRITICAL**: If no results are returned, DO NOT make up or fabricate memories. Only report what was actually found. Tell the user honestly that no matching memories were found and suggest they:
39
44
  * Create a new memory with the information they're looking for
@@ -18,7 +18,14 @@ import type { SearchFilters } from '../types/memory.js';
18
18
  */
19
19
  export const searchSpaceTool: Tool = {
20
20
  name: 'remember_search_space',
21
- description: 'Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.',
21
+ description: `Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.
22
+
23
+ ⚠️ **CRITICAL - CONTENT TYPE FILTERING**: Do NOT add content_type filter unless the user explicitly requests filtering by type.
24
+ - ✅ CORRECT: User says "search The Void for hiking" → { spaces: ["the_void"], query: "hiking" }
25
+ - ❌ WRONG: User says "search The Void for hiking" → { spaces: ["the_void"], query: "hiking", content_type: "note" }
26
+ - ✅ CORRECT: User says "search The Void for note memories about hiking" → { spaces: ["the_void"], query: "hiking", content_type: "note" }
27
+
28
+ Let the search algorithm find ALL relevant memories regardless of type unless explicitly requested.`,
22
29
  inputSchema: {
23
30
  type: 'object',
24
31
  properties: {
@@ -139,6 +139,53 @@ export function getAuditCollectionName(userId: string): string {
139
139
  return `Audit_${sanitizeUserId(userId)}`;
140
140
  }
141
141
 
142
+ /**
143
+ * List of all memory properties to fetch
144
+ * Centralized to ensure consistency across all tools
145
+ */
146
+ export const ALL_MEMORY_PROPERTIES = [
147
+ 'user_id',
148
+ 'doc_type',
149
+ 'type',
150
+ 'title',
151
+ 'content',
152
+ 'tags',
153
+ 'weight',
154
+ 'base_weight',
155
+ 'trust_level',
156
+ 'context',
157
+ 'location',
158
+ 'relationships',
159
+ 'created_at',
160
+ 'updated_at',
161
+ 'version',
162
+ 'attribution',
163
+ 'source_url',
164
+ 'author',
165
+ 'parent_id',
166
+ 'thread_root_id',
167
+ 'moderation_flags',
168
+ ] as const;
169
+
170
+ /**
171
+ * Fetch a memory object by ID with all properties
172
+ *
173
+ * This utility ensures all memory properties are fetched consistently
174
+ * across all tools, preventing bugs where properties are missing.
175
+ *
176
+ * @param collection - Weaviate collection
177
+ * @param memoryId - Memory ID to fetch
178
+ * @returns Memory object with all properties
179
+ */
180
+ export async function fetchMemoryWithAllProperties(
181
+ collection: any,
182
+ memoryId: string
183
+ ) {
184
+ return await collection.query.fetchObjectById(memoryId, {
185
+ returnProperties: ALL_MEMORY_PROPERTIES,
186
+ });
187
+ }
188
+
142
189
  /**
143
190
  * Check if collection exists
144
191
  */