mem-brain-mcp 1.0.2__tar.gz → 1.0.3__tar.gz

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.
Files changed (21) hide show
  1. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/PKG-INFO +1 -1
  2. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/pyproject.toml +1 -1
  3. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/src/mem_brain_mcp/__init__.py +1 -1
  4. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/src/mem_brain_mcp/server.py +57 -15
  5. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/.dockerignore +0 -0
  6. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/.env +0 -0
  7. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/.gitignore +0 -0
  8. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/README.md +0 -0
  9. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/TROUBLESHOOTING.md +0 -0
  10. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/USAGE.md +0 -0
  11. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/DEPLOYMENT.md +0 -0
  12. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/alb-target-group.json +0 -0
  13. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/deploy.sh +0 -0
  14. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/ecs-service-config.json +0 -0
  15. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/ecs-task-definition.json +0 -0
  16. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/aws/security-groups.md +0 -0
  17. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/docker/Dockerfile +0 -0
  18. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/src/mem_brain_mcp/__main__.py +0 -0
  19. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/src/mem_brain_mcp/client.py +0 -0
  20. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/src/mem_brain_mcp/config.py +0 -0
  21. {mem_brain_mcp-1.0.2 → mem_brain_mcp-1.0.3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mem-brain-mcp
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: MCP Server for Mem-Brain API - Exposes memory operations as MCP tools
5
5
  Keywords: ai,claude,cursor,llm,mcp,memory,model-context-protocol
6
6
  Classifier: Development Status :: 4 - Beta
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mem-brain-mcp"
3
- version = "1.0.2"
3
+ version = "1.0.3"
4
4
  description = "MCP Server for Mem-Brain API - Exposes memory operations as MCP tools"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10,<3.14"
@@ -1,4 +1,4 @@
1
1
  """Mem-Brain MCP Server - Exposes Mem-Brain API as MCP tools."""
2
2
 
3
- __version__ = "1.0.2"
3
+ __version__ = "1.0.3"
4
4
 
@@ -1,5 +1,6 @@
1
1
  """MCP Server for Mem-Brain API using FastMCP."""
2
2
 
3
+ import json
3
4
  import logging
4
5
  from typing import Any, Dict, List, Optional, Union
5
6
  import httpx
@@ -407,11 +408,13 @@ async def add_memory(
407
408
  - Example: "User prefers Python over JavaScript"
408
409
  - Example: "User prefers dark mode interfaces"
409
410
 
410
- tags (list[str], optional): List of tags to categorize the memory.
411
- - Can be None (default) or a list of strings
411
+ tags (list[str] or str, optional): Tags to categorize the memory.
412
+ - Can be None (default), a list of strings, a comma-separated string, or a JSON array string
413
+ - If omitted, the system will auto-generate tags based on content
412
414
  - Example: ["coding", "preferences"]
413
- - Example: ["personal", "pets", "animals"]
414
- - If you pass a single string, it will be converted to a list
415
+ - Example: "coding,preferences" (comma-separated)
416
+ - Example: '["coding", "preferences"]' (JSON string)
417
+ - Note: The system auto-generates relevant tags, so providing tags is optional
415
418
 
416
419
  category (str, optional): Category name for the memory.
417
420
  - Can be None (default) or a non-empty string
@@ -480,7 +483,7 @@ async def add_memory(
480
483
  logger.info(f"add_memory called - content length: {len(content_str)}, tags: {tags}, category: {category}")
481
484
  logger.debug(f"add_memory full content: {content_str[:100]}...")
482
485
 
483
- # Normalize tags: convert empty list to None, ensure it's a list if provided
486
+ # Normalize tags: handle various input formats and convert to list of strings
484
487
  normalized_tags = None
485
488
  if tags is not None:
486
489
  if isinstance(tags, list):
@@ -495,13 +498,31 @@ async def add_memory(
495
498
  )
496
499
  normalized_tags = tags if tags else None # Empty list becomes None
497
500
  elif isinstance(tags, str):
498
- # Handle case where tags might be passed as a single string
499
- normalized_tags = [tags]
501
+ tags_str = tags.strip()
502
+ if not tags_str:
503
+ normalized_tags = None
504
+ else:
505
+ # Try to parse as JSON array first (e.g., '["tag1", "tag2"]')
506
+ try:
507
+ parsed = json.loads(tags_str)
508
+ if isinstance(parsed, list):
509
+ normalized_tags = [str(item).strip() for item in parsed if str(item).strip()]
510
+ else:
511
+ # If JSON but not a list, treat as single tag
512
+ normalized_tags = [tags_str]
513
+ except (json.JSONDecodeError, ValueError):
514
+ # Not JSON, try comma-separated string
515
+ if ',' in tags_str:
516
+ normalized_tags = [tag.strip() for tag in tags_str.split(',') if tag.strip()]
517
+ else:
518
+ # Single tag string
519
+ normalized_tags = [tags_str]
500
520
  else:
501
521
  raise ToolError(
502
- f"The 'tags' parameter must be a list of strings or None, but got {type(tags).__name__}.\n"
522
+ f"The 'tags' parameter must be a list of strings, a comma-separated string, or None, but got {type(tags).__name__}.\n"
503
523
  f"Received: {repr(tags)}\n"
504
524
  "Example: add_memory(content=\"...\", tags=[\"coding\", \"preferences\"])\n"
525
+ "Example: add_memory(content=\"...\", tags=\"coding,preferences\")\n"
505
526
  "Example: add_memory(content=\"...\", tags=None) # or omit tags parameter"
506
527
  )
507
528
 
@@ -738,10 +759,13 @@ async def update_memory(
738
759
  - If provided, must not be empty or whitespace-only
739
760
  - Example: "User no longer likes TypeScript, prefers Python"
740
761
 
741
- tags (list[str], optional): New tags for the memory.
742
- - Can be None (to keep existing tags) or a list of strings
762
+ tags (list[str] or str, optional): New tags for the memory.
763
+ - Can be None (to keep existing tags), a list of strings, a comma-separated string, or a JSON array string
764
+ - If provided, replaces existing tags
743
765
  - Example: ["coding", "python"]
744
- - Example: ["preferences", "updated"]
766
+ - Example: "coding,python" (comma-separated)
767
+ - Example: '["coding", "python"]' (JSON string)
768
+ - Note: The system can auto-generate tags if you omit this parameter
745
769
 
746
770
  Returns:
747
771
  str: A formatted string with the updated memory details.
@@ -819,7 +843,7 @@ async def update_memory(
819
843
  else:
820
844
  content_str = None
821
845
 
822
- # Validate tags if provided
846
+ # Validate tags if provided - handle various input formats
823
847
  normalized_tags = None
824
848
  if tags is not None:
825
849
  if isinstance(tags, list):
@@ -834,13 +858,31 @@ async def update_memory(
834
858
  )
835
859
  normalized_tags = tags if tags else None # Empty list becomes None
836
860
  elif isinstance(tags, str):
837
- # Handle case where tags might be passed as a single string
838
- normalized_tags = [tags]
861
+ tags_str = tags.strip()
862
+ if not tags_str:
863
+ normalized_tags = None
864
+ else:
865
+ # Try to parse as JSON array first (e.g., '["tag1", "tag2"]')
866
+ try:
867
+ parsed = json.loads(tags_str)
868
+ if isinstance(parsed, list):
869
+ normalized_tags = [str(item).strip() for item in parsed if str(item).strip()]
870
+ else:
871
+ # If JSON but not a list, treat as single tag
872
+ normalized_tags = [tags_str]
873
+ except (json.JSONDecodeError, ValueError):
874
+ # Not JSON, try comma-separated string
875
+ if ',' in tags_str:
876
+ normalized_tags = [tag.strip() for tag in tags_str.split(',') if tag.strip()]
877
+ else:
878
+ # Single tag string
879
+ normalized_tags = [tags_str]
839
880
  else:
840
881
  raise ToolError(
841
- f"The 'tags' parameter must be a list of strings or None, but got {type(tags).__name__}.\n"
882
+ f"The 'tags' parameter must be a list of strings, a comma-separated string, or None, but got {type(tags).__name__}.\n"
842
883
  f"Received: {repr(tags)}\n"
843
884
  "Example: update_memory(memory_id=\"...\", tags=[\"coding\", \"preferences\"])\n"
885
+ "Example: update_memory(memory_id=\"...\", tags=\"coding,preferences\")\n"
844
886
  "Example: update_memory(memory_id=\"...\", tags=None) # or omit tags parameter"
845
887
  )
846
888
 
File without changes
File without changes
File without changes
File without changes
File without changes