memorygraphMCP 0.11.7__py3-none-any.whl

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 (65) hide show
  1. memorygraph/__init__.py +50 -0
  2. memorygraph/__main__.py +12 -0
  3. memorygraph/advanced_tools.py +509 -0
  4. memorygraph/analytics/__init__.py +46 -0
  5. memorygraph/analytics/advanced_queries.py +727 -0
  6. memorygraph/backends/__init__.py +21 -0
  7. memorygraph/backends/base.py +179 -0
  8. memorygraph/backends/cloud.py +75 -0
  9. memorygraph/backends/cloud_backend.py +858 -0
  10. memorygraph/backends/factory.py +577 -0
  11. memorygraph/backends/falkordb_backend.py +749 -0
  12. memorygraph/backends/falkordblite_backend.py +746 -0
  13. memorygraph/backends/ladybugdb_backend.py +242 -0
  14. memorygraph/backends/memgraph_backend.py +327 -0
  15. memorygraph/backends/neo4j_backend.py +298 -0
  16. memorygraph/backends/sqlite_fallback.py +463 -0
  17. memorygraph/backends/turso.py +448 -0
  18. memorygraph/cli.py +743 -0
  19. memorygraph/cloud_database.py +297 -0
  20. memorygraph/config.py +295 -0
  21. memorygraph/database.py +933 -0
  22. memorygraph/graph_analytics.py +631 -0
  23. memorygraph/integration/__init__.py +69 -0
  24. memorygraph/integration/context_capture.py +426 -0
  25. memorygraph/integration/project_analysis.py +583 -0
  26. memorygraph/integration/workflow_tracking.py +492 -0
  27. memorygraph/intelligence/__init__.py +59 -0
  28. memorygraph/intelligence/context_retrieval.py +447 -0
  29. memorygraph/intelligence/entity_extraction.py +386 -0
  30. memorygraph/intelligence/pattern_recognition.py +420 -0
  31. memorygraph/intelligence/temporal.py +374 -0
  32. memorygraph/migration/__init__.py +27 -0
  33. memorygraph/migration/manager.py +579 -0
  34. memorygraph/migration/models.py +142 -0
  35. memorygraph/migration/scripts/__init__.py +17 -0
  36. memorygraph/migration/scripts/bitemporal_migration.py +595 -0
  37. memorygraph/migration/scripts/multitenancy_migration.py +452 -0
  38. memorygraph/migration_tools_module.py +146 -0
  39. memorygraph/models.py +684 -0
  40. memorygraph/proactive/__init__.py +46 -0
  41. memorygraph/proactive/outcome_learning.py +444 -0
  42. memorygraph/proactive/predictive.py +410 -0
  43. memorygraph/proactive/session_briefing.py +399 -0
  44. memorygraph/relationships.py +668 -0
  45. memorygraph/server.py +883 -0
  46. memorygraph/sqlite_database.py +1876 -0
  47. memorygraph/tools/__init__.py +59 -0
  48. memorygraph/tools/activity_tools.py +262 -0
  49. memorygraph/tools/memory_tools.py +315 -0
  50. memorygraph/tools/migration_tools.py +181 -0
  51. memorygraph/tools/relationship_tools.py +147 -0
  52. memorygraph/tools/search_tools.py +406 -0
  53. memorygraph/tools/temporal_tools.py +339 -0
  54. memorygraph/utils/__init__.py +10 -0
  55. memorygraph/utils/context_extractor.py +429 -0
  56. memorygraph/utils/error_handling.py +151 -0
  57. memorygraph/utils/export_import.py +425 -0
  58. memorygraph/utils/graph_algorithms.py +200 -0
  59. memorygraph/utils/pagination.py +149 -0
  60. memorygraph/utils/project_detection.py +133 -0
  61. memorygraphmcp-0.11.7.dist-info/METADATA +970 -0
  62. memorygraphmcp-0.11.7.dist-info/RECORD +65 -0
  63. memorygraphmcp-0.11.7.dist-info/WHEEL +4 -0
  64. memorygraphmcp-0.11.7.dist-info/entry_points.txt +2 -0
  65. memorygraphmcp-0.11.7.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,181 @@
1
+ """
2
+ MCP tools for database migration.
3
+
4
+ Provides migration tools for moving memories between different backend types.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any, Optional
9
+
10
+ from ..migration.manager import MigrationManager, MigrationError
11
+ from ..migration.models import BackendConfig, MigrationOptions, BackendType
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ async def handle_migrate_database(
17
+ target_backend: str,
18
+ target_config: Optional[Dict[str, Any]] = None,
19
+ dry_run: bool = False,
20
+ skip_duplicates: bool = True,
21
+ verify: bool = True
22
+ ) -> Dict[str, Any]:
23
+ """
24
+ Migrate memories from current backend to target backend.
25
+
26
+ This tool enables AI assistants to help users migrate their memory database
27
+ to a different backend (e.g., SQLite → FalkorDB for production).
28
+
29
+ Args:
30
+ target_backend: Target backend type (sqlite, neo4j, memgraph, falkordb, falkordblite)
31
+ target_config: Target backend configuration (path, URI, credentials)
32
+ dry_run: Validate without making changes
33
+ skip_duplicates: Skip memories that already exist in target
34
+ verify: Verify data integrity after migration
35
+
36
+ Returns:
37
+ Migration result with statistics and status
38
+
39
+ Example:
40
+ # Migrate from SQLite to FalkorDB
41
+ result = await migrate_database(
42
+ target_backend="falkordb",
43
+ target_config={
44
+ "uri": "redis://prod.example.com:6379",
45
+ "username": "admin",
46
+ "password": "secret"
47
+ },
48
+ dry_run=True # Test first
49
+ )
50
+ """
51
+ try:
52
+ # Source is current environment
53
+ source_config = BackendConfig.from_env()
54
+
55
+ # Parse target backend type
56
+ try:
57
+ target_backend_type = BackendType(target_backend.lower())
58
+ except ValueError:
59
+ return {
60
+ "success": False,
61
+ "error": f"Invalid target backend: {target_backend}. Must be one of: sqlite, neo4j, memgraph, falkordb, falkordblite",
62
+ "error_type": "ValueError"
63
+ }
64
+
65
+ # Build target config
66
+ target_config_obj = BackendConfig(
67
+ backend_type=target_backend_type,
68
+ path=target_config.get("path") if target_config else None,
69
+ uri=target_config.get("uri") if target_config else None,
70
+ username=target_config.get("username") if target_config else None,
71
+ password=target_config.get("password") if target_config else None,
72
+ database=target_config.get("database") if target_config else None
73
+ )
74
+
75
+ # Validate target config
76
+ validation_errors = target_config_obj.validate()
77
+ if validation_errors:
78
+ return {
79
+ "success": False,
80
+ "error": f"Invalid target configuration: {', '.join(validation_errors)}",
81
+ "error_type": "ValidationError"
82
+ }
83
+
84
+ # Build options
85
+ options = MigrationOptions(
86
+ dry_run=dry_run,
87
+ verbose=True,
88
+ skip_duplicates=skip_duplicates,
89
+ verify=verify,
90
+ rollback_on_failure=True
91
+ )
92
+
93
+ # Perform migration
94
+ logger.info(f"Starting migration: {source_config.backend_type.value} → {target_backend_type.value}")
95
+ manager = MigrationManager()
96
+ result = await manager.migrate(source_config, target_config_obj, options)
97
+
98
+ # Format response
99
+ response = {
100
+ "success": result.success,
101
+ "dry_run": result.dry_run,
102
+ "source_backend": source_config.backend_type.value,
103
+ "target_backend": target_backend,
104
+ "imported_memories": result.imported_memories,
105
+ "imported_relationships": result.imported_relationships,
106
+ "skipped_memories": result.skipped_memories,
107
+ "duration_seconds": round(result.duration_seconds, 2),
108
+ "errors": result.errors
109
+ }
110
+
111
+ # Add verification results if available
112
+ if result.verification_result:
113
+ response["verification"] = {
114
+ "valid": result.verification_result.valid,
115
+ "source_count": result.verification_result.source_count,
116
+ "target_count": result.verification_result.target_count,
117
+ "sample_checks": result.verification_result.sample_checks,
118
+ "sample_passed": result.verification_result.sample_passed,
119
+ "errors": result.verification_result.errors
120
+ }
121
+
122
+ # Add stats if available
123
+ if result.source_stats:
124
+ response["source_stats"] = result.source_stats
125
+ if result.target_stats:
126
+ response["target_stats"] = result.target_stats
127
+
128
+ return response
129
+
130
+ except MigrationError as e:
131
+ logger.error(f"Migration failed: {e}")
132
+ return {
133
+ "success": False,
134
+ "error": str(e),
135
+ "error_type": "MigrationError"
136
+ }
137
+ except Exception as e:
138
+ logger.error(f"Unexpected error during migration: {e}", exc_info=True)
139
+ return {
140
+ "success": False,
141
+ "error": str(e),
142
+ "error_type": type(e).__name__
143
+ }
144
+
145
+
146
+ async def handle_validate_migration(
147
+ target_backend: str,
148
+ target_config: Optional[Dict[str, Any]] = None
149
+ ) -> Dict[str, Any]:
150
+ """
151
+ Validate that migration to target backend would succeed.
152
+
153
+ This is a dry-run that checks:
154
+ - Source backend is accessible
155
+ - Target backend is accessible
156
+ - Backends are compatible
157
+ - Estimates migration size and duration
158
+
159
+ Args:
160
+ target_backend: Target backend type
161
+ target_config: Target backend configuration
162
+
163
+ Returns:
164
+ Validation result with checks and estimates
165
+
166
+ Example:
167
+ # Validate migration before running
168
+ result = await validate_migration(
169
+ target_backend="falkordb",
170
+ target_config={
171
+ "uri": "redis://prod.example.com:6379"
172
+ }
173
+ )
174
+ """
175
+ # Call migrate_database with dry_run=True
176
+ return await handle_migrate_database(
177
+ target_backend=target_backend,
178
+ target_config=target_config,
179
+ dry_run=True,
180
+ verify=False # No need to verify in dry-run
181
+ )
@@ -0,0 +1,147 @@
1
+ """
2
+ Relationship tool handlers for the MCP server.
3
+
4
+ This module contains handlers for relationship operations:
5
+ - create_relationship: Create relationships between memories
6
+ - get_related_memories: Find memories related to a specific memory
7
+ """
8
+
9
+ import json
10
+ import logging
11
+ from typing import Any, Dict
12
+
13
+ from mcp.types import CallToolResult, TextContent
14
+
15
+ from ..database import MemoryDatabase
16
+ from ..models import RelationshipType, RelationshipProperties
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ async def handle_create_relationship(
22
+ memory_db: MemoryDatabase,
23
+ arguments: Dict[str, Any]
24
+ ) -> CallToolResult:
25
+ """Handle create_relationship tool call.
26
+
27
+ Args:
28
+ memory_db: Database instance for memory operations
29
+ arguments: Tool arguments from MCP call containing:
30
+ - from_memory_id: ID of source memory
31
+ - to_memory_id: ID of target memory
32
+ - relationship_type: Type of relationship (SOLVES, CAUSES, etc.)
33
+ - strength: Optional relationship strength (0.0-1.0, default: 0.5)
34
+ - confidence: Optional confidence score (0.0-1.0, default: 0.8)
35
+ - context: Optional natural language description
36
+
37
+ Returns:
38
+ CallToolResult with relationship ID on success or error message on failure
39
+ """
40
+ try:
41
+ # Get user-provided context (natural language)
42
+ user_context = arguments.get("context")
43
+
44
+ # Auto-extract structure if context provided
45
+ structured_context = None
46
+ if user_context:
47
+ from ..utils.context_extractor import extract_context_structure
48
+ structure = extract_context_structure(user_context)
49
+ structured_context = json.dumps(structure) # Serialize to JSON string
50
+
51
+ properties = RelationshipProperties(
52
+ strength=arguments.get("strength", 0.5),
53
+ confidence=arguments.get("confidence", 0.8),
54
+ context=structured_context # Store JSON string
55
+ )
56
+
57
+ relationship_id = await memory_db.create_relationship(
58
+ from_memory_id=arguments["from_memory_id"],
59
+ to_memory_id=arguments["to_memory_id"],
60
+ relationship_type=RelationshipType(arguments["relationship_type"]),
61
+ properties=properties
62
+ )
63
+
64
+ return CallToolResult(
65
+ content=[TextContent(
66
+ type="text",
67
+ text=f"Relationship created successfully: {relationship_id}"
68
+ )]
69
+ )
70
+
71
+ except Exception as e:
72
+ logger.error(f"Failed to create relationship: {e}")
73
+ return CallToolResult(
74
+ content=[TextContent(
75
+ type="text",
76
+ text=f"Failed to create relationship: {e}"
77
+ )],
78
+ isError=True
79
+ )
80
+
81
+
82
+ async def handle_get_related_memories(
83
+ memory_db: MemoryDatabase,
84
+ arguments: Dict[str, Any]
85
+ ) -> CallToolResult:
86
+ """Handle get_related_memories tool call.
87
+
88
+ Args:
89
+ memory_db: Database instance for memory operations
90
+ arguments: Tool arguments from MCP call containing:
91
+ - memory_id: ID of memory to find relations for
92
+ - relationship_types: Optional list of relationship types to filter
93
+ - max_depth: Optional maximum traversal depth (default: 2)
94
+
95
+ Returns:
96
+ CallToolResult with list of related memories or error message
97
+ """
98
+ try:
99
+ memory_id = arguments["memory_id"]
100
+ relationship_types = None
101
+
102
+ if "relationship_types" in arguments:
103
+ relationship_types = [RelationshipType(t) for t in arguments["relationship_types"]]
104
+
105
+ max_depth = arguments.get("max_depth", 2)
106
+
107
+ related_memories = await memory_db.get_related_memories(
108
+ memory_id=memory_id,
109
+ relationship_types=relationship_types,
110
+ max_depth=max_depth
111
+ )
112
+
113
+ if not related_memories:
114
+ return CallToolResult(
115
+ content=[TextContent(
116
+ type="text",
117
+ text=f"No related memories found for: {memory_id}"
118
+ )]
119
+ )
120
+
121
+ # Format results
122
+ results_text = f"Found {len(related_memories)} related memories:\n\n"
123
+ for i, (memory, relationship) in enumerate(related_memories, 1):
124
+ results_text += f"**{i}. {memory.title}** (ID: {memory.id})\n"
125
+ results_text += f"Relationship: {relationship.type.value} (strength: {relationship.properties.strength})\n"
126
+ results_text += f"Type: {memory.type.value} | Importance: {memory.importance}\n\n"
127
+
128
+ return CallToolResult(
129
+ content=[TextContent(type="text", text=results_text)]
130
+ )
131
+ except KeyError as e:
132
+ return CallToolResult(
133
+ content=[TextContent(
134
+ type="text",
135
+ text=f"Missing required field: {e}"
136
+ )],
137
+ isError=True
138
+ )
139
+ except Exception as e:
140
+ logger.error(f"Failed to get related memories: {e}")
141
+ return CallToolResult(
142
+ content=[TextContent(
143
+ type="text",
144
+ text=f"Failed to get related memories: {e}"
145
+ )],
146
+ isError=True
147
+ )