mcp-sqlite-memory-bank 1.5.0__py3-none-any.whl → 1.6.0__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.
- mcp_sqlite_memory_bank/__init__.py +2 -2
- mcp_sqlite_memory_bank/__main__.py +68 -0
- mcp_sqlite_memory_bank/database.py +234 -68
- mcp_sqlite_memory_bank/prompts.py +76 -52
- mcp_sqlite_memory_bank/resources.py +250 -150
- mcp_sqlite_memory_bank/semantic.py +50 -17
- mcp_sqlite_memory_bank/server.py +351 -23
- mcp_sqlite_memory_bank/tools/__init__.py +33 -25
- mcp_sqlite_memory_bank/tools/analytics.py +225 -139
- mcp_sqlite_memory_bank/tools/basic.py +417 -7
- mcp_sqlite_memory_bank/tools/discovery.py +1428 -0
- mcp_sqlite_memory_bank/tools/search.py +159 -72
- mcp_sqlite_memory_bank/types.py +6 -1
- mcp_sqlite_memory_bank/utils.py +165 -107
- {mcp_sqlite_memory_bank-1.5.0.dist-info → mcp_sqlite_memory_bank-1.6.0.dist-info}/METADATA +54 -6
- mcp_sqlite_memory_bank-1.6.0.dist-info/RECORD +21 -0
- mcp_sqlite_memory_bank-1.5.0.dist-info/RECORD +0 -19
- {mcp_sqlite_memory_bank-1.5.0.dist-info → mcp_sqlite_memory_bank-1.6.0.dist-info}/WHEEL +0 -0
- {mcp_sqlite_memory_bank-1.5.0.dist-info → mcp_sqlite_memory_bank-1.6.0.dist-info}/entry_points.txt +0 -0
- {mcp_sqlite_memory_bank-1.5.0.dist-info → mcp_sqlite_memory_bank-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_sqlite_memory_bank-1.5.0.dist-info → mcp_sqlite_memory_bank-1.6.0.dist-info}/top_level.txt +0 -0
mcp_sqlite_memory_bank/server.py
CHANGED
@@ -124,7 +124,9 @@ def create_table(table_name: str, columns: List[Dict[str, str]]) -> ToolResponse
|
|
124
124
|
- Creates table if it doesn't exist (idempotent)
|
125
125
|
- Raises appropriate errors for invalid input
|
126
126
|
"""
|
127
|
-
return cast(
|
127
|
+
return cast(
|
128
|
+
CreateTableResponse, get_database(DB_PATH).create_table(table_name, columns)
|
129
|
+
)
|
128
130
|
|
129
131
|
|
130
132
|
@mcp.tool
|
@@ -236,7 +238,9 @@ def rename_table(old_name: str, new_name: str) -> ToolResponse:
|
|
236
238
|
- Validates both old and new table names
|
237
239
|
- Confirms old table exists and new name doesn't conflict
|
238
240
|
"""
|
239
|
-
return cast(
|
241
|
+
return cast(
|
242
|
+
RenameTableResponse, get_database(DB_PATH).rename_table(old_name, new_name)
|
243
|
+
)
|
240
244
|
|
241
245
|
|
242
246
|
@mcp.tool
|
@@ -265,6 +269,42 @@ def create_row(table_name: str, data: Dict[str, Any]) -> ToolResponse:
|
|
265
269
|
return cast(CreateRowResponse, get_database(DB_PATH).insert_row(table_name, data))
|
266
270
|
|
267
271
|
|
272
|
+
@mcp.tool
|
273
|
+
@catch_errors
|
274
|
+
def upsert_memory(
|
275
|
+
table_name: str, data: Dict[str, Any], match_columns: List[str]
|
276
|
+
) -> ToolResponse:
|
277
|
+
"""
|
278
|
+
🔄 **SMART MEMORY UPSERT** - Prevent duplicates and maintain data consistency!
|
279
|
+
|
280
|
+
Update existing records or create new ones based on matching columns.
|
281
|
+
This is the preferred method for memory management as it prevents duplicates.
|
282
|
+
|
283
|
+
Args:
|
284
|
+
table_name (str): Table to upsert into
|
285
|
+
data (Dict[str, Any]): Data to upsert (column-value pairs)
|
286
|
+
match_columns (List[str]): Columns to use for finding existing records
|
287
|
+
|
288
|
+
Returns:
|
289
|
+
ToolResponse: On success: {"success": True, "action": "updated"|"created", "id": rowid}
|
290
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
291
|
+
|
292
|
+
Examples:
|
293
|
+
>>> upsert_memory('technical_decisions',
|
294
|
+
... {'decision_name': 'API Design', 'chosen_approach': 'REST'},
|
295
|
+
... ['decision_name'])
|
296
|
+
{"success": True, "action": "updated", "id": 15, "rows_affected": 1}
|
297
|
+
|
298
|
+
FastMCP Tool Info:
|
299
|
+
- **PREVENTS DUPLICATES**: Automatically updates existing records instead of creating duplicates
|
300
|
+
- **SMART MATCHING**: Uses specified columns to find existing records
|
301
|
+
- **EFFICIENT MEMORY MANAGEMENT**: Ideal for agent memory patterns
|
302
|
+
- **CLEAR FEEDBACK**: Returns whether record was created or updated
|
303
|
+
- **PERFECT FOR AGENTS**: Handles the common "update or create" pattern automatically
|
304
|
+
"""
|
305
|
+
return basic.upsert_memory(table_name, data, match_columns)
|
306
|
+
|
307
|
+
|
268
308
|
@mcp.tool
|
269
309
|
@catch_errors
|
270
310
|
def read_rows(table_name: str, where: Optional[Dict[str, Any]] = None) -> ToolResponse:
|
@@ -293,7 +333,9 @@ def read_rows(table_name: str, where: Optional[Dict[str, Any]] = None) -> ToolRe
|
|
293
333
|
|
294
334
|
@mcp.tool
|
295
335
|
@catch_errors
|
296
|
-
def update_rows(
|
336
|
+
def update_rows(
|
337
|
+
table_name: str, data: Dict[str, Any], where: Optional[Dict[str, Any]] = None
|
338
|
+
) -> ToolResponse:
|
297
339
|
"""
|
298
340
|
Update rows in any table in the SQLite Memory Bank for Copilot/AI agents, matching the WHERE clause.
|
299
341
|
|
@@ -316,12 +358,16 @@ def update_rows(table_name: str, data: Dict[str, Any], where: Optional[Dict[str,
|
|
316
358
|
- Parameterizes all queries for safety
|
317
359
|
- Where clause is optional (omitting it updates all rows!)
|
318
360
|
"""
|
319
|
-
return cast(
|
361
|
+
return cast(
|
362
|
+
UpdateRowsResponse, get_database(DB_PATH).update_rows(table_name, data, where)
|
363
|
+
)
|
320
364
|
|
321
365
|
|
322
366
|
@mcp.tool
|
323
367
|
@catch_errors
|
324
|
-
def delete_rows(
|
368
|
+
def delete_rows(
|
369
|
+
table_name: str, where: Optional[Dict[str, Any]] = None
|
370
|
+
) -> ToolResponse:
|
325
371
|
"""
|
326
372
|
Delete rows from any table in the SQLite Memory Bank for Copilot/AI agents, matching the WHERE clause.
|
327
373
|
|
@@ -343,13 +389,18 @@ def delete_rows(table_name: str, where: Optional[Dict[str, Any]] = None) -> Tool
|
|
343
389
|
- Parameterizes all queries for safety
|
344
390
|
- Where clause is optional (omitting it deletes all rows!)
|
345
391
|
"""
|
346
|
-
return cast(
|
392
|
+
return cast(
|
393
|
+
DeleteRowsResponse, get_database(DB_PATH).delete_rows(table_name, where)
|
394
|
+
)
|
347
395
|
|
348
396
|
|
349
397
|
@mcp.tool
|
350
398
|
@catch_errors
|
351
399
|
def run_select_query(
|
352
|
-
table_name: str,
|
400
|
+
table_name: str,
|
401
|
+
columns: Optional[List[str]] = None,
|
402
|
+
where: Optional[Dict[str, Any]] = None,
|
403
|
+
limit: int = 100,
|
353
404
|
) -> ToolResponse:
|
354
405
|
"""
|
355
406
|
Run a safe SELECT query on a table in the SQLite memory bank.
|
@@ -374,7 +425,10 @@ def run_select_query(
|
|
374
425
|
- Only SELECT queries are allowed (no arbitrary SQL)
|
375
426
|
- Default limit of 100 rows prevents memory issues
|
376
427
|
"""
|
377
|
-
return cast(
|
428
|
+
return cast(
|
429
|
+
SelectQueryResponse,
|
430
|
+
get_database(DB_PATH).select_query(table_name, columns, where, limit),
|
431
|
+
)
|
378
432
|
|
379
433
|
|
380
434
|
@mcp.tool
|
@@ -402,15 +456,23 @@ def list_all_columns() -> ToolResponse:
|
|
402
456
|
# Import the implementation functions from tools modules
|
403
457
|
from .tools.search import (
|
404
458
|
search_content as search_content_impl,
|
405
|
-
explore_tables as explore_tables_impl,
|
459
|
+
explore_tables as explore_tables_impl,
|
406
460
|
add_embeddings as add_embeddings_impl,
|
407
461
|
auto_semantic_search as auto_semantic_search_impl,
|
408
462
|
auto_smart_search as auto_smart_search_impl,
|
409
463
|
embedding_stats as embedding_stats_impl,
|
410
464
|
)
|
411
465
|
|
466
|
+
# Import the implementation functions from discovery module
|
467
|
+
from .tools.discovery import (
|
468
|
+
intelligent_discovery as intelligent_discovery_impl,
|
469
|
+
discovery_templates as discovery_templates_impl,
|
470
|
+
discover_relationships as discover_relationships_impl,
|
471
|
+
)
|
472
|
+
|
412
473
|
# --- MCP Tool Definitions (Required in main server.py for FastMCP) ---
|
413
474
|
|
475
|
+
|
414
476
|
@mcp.tool
|
415
477
|
@catch_errors
|
416
478
|
def search_content(
|
@@ -448,7 +510,7 @@ def search_content(
|
|
448
510
|
|
449
511
|
|
450
512
|
@mcp.tool
|
451
|
-
@catch_errors
|
513
|
+
@catch_errors
|
452
514
|
def explore_tables(
|
453
515
|
pattern: Optional[str] = None,
|
454
516
|
include_row_counts: bool = True,
|
@@ -573,7 +635,9 @@ def auto_semantic_search(
|
|
573
635
|
- Supports fuzzy matching and concept discovery
|
574
636
|
- Perfect for agents - just search and it works!
|
575
637
|
"""
|
576
|
-
return auto_semantic_search_impl(
|
638
|
+
return auto_semantic_search_impl(
|
639
|
+
query, tables, similarity_threshold, limit, model_name
|
640
|
+
)
|
577
641
|
|
578
642
|
|
579
643
|
@mcp.tool
|
@@ -620,7 +684,9 @@ def auto_smart_search(
|
|
620
684
|
- Optimal for both exploratory and precise searches
|
621
685
|
- Perfect for agents - ultimate search tool that just works!
|
622
686
|
"""
|
623
|
-
return auto_smart_search_impl(
|
687
|
+
return auto_smart_search_impl(
|
688
|
+
query, tables, semantic_weight, text_weight, limit, model_name
|
689
|
+
)
|
624
690
|
|
625
691
|
|
626
692
|
@mcp.tool
|
@@ -649,7 +715,7 @@ def embedding_stats(
|
|
649
715
|
|
650
716
|
FastMCP Tool Info:
|
651
717
|
- Shows how much content is ready for semantic search
|
652
|
-
- Helps identify tables that need embedding generation
|
718
|
+
- Helps identify tables that need embedding generation
|
653
719
|
- Provides embedding dimension info for debugging
|
654
720
|
- Useful for monitoring semantic search capabilities
|
655
721
|
"""
|
@@ -754,7 +820,9 @@ def smart_search(
|
|
754
820
|
- Optimal for both exploratory and precise searches
|
755
821
|
- Perfect for agents - ultimate search tool that just works!
|
756
822
|
"""
|
757
|
-
return _smart_search_impl(
|
823
|
+
return _smart_search_impl(
|
824
|
+
query, tables, semantic_weight, text_weight, limit, model_name
|
825
|
+
)
|
758
826
|
|
759
827
|
|
760
828
|
@mcp.tool
|
@@ -796,7 +864,156 @@ def find_related(
|
|
796
864
|
- Can reveal patterns and themes across your knowledge base
|
797
865
|
- Enables serendipitous discovery of relevant information
|
798
866
|
"""
|
799
|
-
return _find_related_impl(
|
867
|
+
return _find_related_impl(
|
868
|
+
table_name, row_id, similarity_threshold, limit, model_name
|
869
|
+
)
|
870
|
+
|
871
|
+
|
872
|
+
# --- Advanced Discovery Tools for SQLite Memory Bank ---
|
873
|
+
|
874
|
+
|
875
|
+
@mcp.tool
|
876
|
+
@catch_errors
|
877
|
+
def intelligent_discovery(
|
878
|
+
discovery_goal: str = "understand_content",
|
879
|
+
focus_area: Optional[str] = None,
|
880
|
+
depth: str = "moderate",
|
881
|
+
agent_id: Optional[str] = None,
|
882
|
+
) -> ToolResponse:
|
883
|
+
"""
|
884
|
+
🧠 **INTELLIGENT DISCOVERY** - AI-guided exploration of your memory bank!
|
885
|
+
|
886
|
+
Orchestrates multiple discovery tools based on your exploration goals.
|
887
|
+
Provides step-by-step guidance and actionable insights tailored to your needs.
|
888
|
+
|
889
|
+
Args:
|
890
|
+
discovery_goal (str): What you want to achieve
|
891
|
+
- "understand_content": Learn what data is available and how it's organized
|
892
|
+
- "find_patterns": Discover themes, relationships, and content patterns
|
893
|
+
- "explore_structure": Understand database schema and organization
|
894
|
+
- "assess_quality": Evaluate content quality and completeness
|
895
|
+
- "prepare_search": Get ready for effective content searching
|
896
|
+
focus_area (Optional[str]): Specific table or topic to focus on (default: all)
|
897
|
+
depth (str): How thorough the discovery should be
|
898
|
+
- "quick": Fast overview with key insights
|
899
|
+
- "moderate": Balanced analysis with actionable recommendations
|
900
|
+
- "comprehensive": Deep dive with detailed analysis
|
901
|
+
agent_id (Optional[str]): Agent identifier for learning discovery patterns
|
902
|
+
|
903
|
+
Returns:
|
904
|
+
ToolResponse: On success: {"success": True, "discovery": Dict, "next_steps": List}
|
905
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
906
|
+
|
907
|
+
Examples:
|
908
|
+
>>> intelligent_discovery("understand_content")
|
909
|
+
{"success": True, "discovery": {
|
910
|
+
"overview": {"total_tables": 5, "total_rows": 234},
|
911
|
+
"content_summary": {...},
|
912
|
+
"recommendations": [...]
|
913
|
+
}, "next_steps": ["Use auto_smart_search() for specific queries"]}
|
914
|
+
|
915
|
+
FastMCP Tool Info:
|
916
|
+
- **COMPLETELY AUTOMATED**: No manual tool chaining required
|
917
|
+
- **GOAL-ORIENTED**: Tailored discovery based on your specific objectives
|
918
|
+
- **ACTIONABLE INSIGHTS**: Always includes concrete next steps
|
919
|
+
- **LEARNING**: Improves recommendations based on usage patterns
|
920
|
+
- **PERFECT FOR AGENTS**: Single tool that orchestrates complex discovery workflows
|
921
|
+
"""
|
922
|
+
return intelligent_discovery_impl(discovery_goal, focus_area, depth, agent_id)
|
923
|
+
|
924
|
+
|
925
|
+
@mcp.tool
|
926
|
+
@catch_errors
|
927
|
+
def discovery_templates(
|
928
|
+
template_type: str = "first_time_exploration", customize_for: Optional[str] = None
|
929
|
+
) -> ToolResponse:
|
930
|
+
"""
|
931
|
+
📋 **DISCOVERY TEMPLATES** - Pre-built exploration workflows for common scenarios!
|
932
|
+
|
933
|
+
Provides step-by-step discovery templates optimized for specific agent use cases.
|
934
|
+
Each template includes the exact sequence of tools to call and what to look for.
|
935
|
+
|
936
|
+
Args:
|
937
|
+
template_type (str): Type of discovery template to provide
|
938
|
+
- "first_time_exploration": Complete workflow for new agents
|
939
|
+
- "content_audit": Systematic content quality review
|
940
|
+
- "search_optimization": Prepare memory bank for optimal searching
|
941
|
+
- "relationship_mapping": Discover connections between data
|
942
|
+
- "problem_solving": Find information to solve specific problems
|
943
|
+
- "knowledge_extraction": Extract insights from stored knowledge
|
944
|
+
customize_for (Optional[str]): Customize template for specific domain/topic
|
945
|
+
|
946
|
+
Returns:
|
947
|
+
ToolResponse: {"success": True, "template": Dict, "workflow": List}
|
948
|
+
|
949
|
+
Examples:
|
950
|
+
>>> discovery_templates("first_time_exploration")
|
951
|
+
{"success": True, "template": {
|
952
|
+
"name": "First Time Exploration",
|
953
|
+
"description": "Complete discovery workflow for new agents",
|
954
|
+
"workflow": [
|
955
|
+
{"step": 1, "tool": "intelligent_discovery", "params": {...}},
|
956
|
+
{"step": 2, "tool": "explore_tables", "params": {...}}
|
957
|
+
]
|
958
|
+
}}
|
959
|
+
|
960
|
+
FastMCP Tool Info:
|
961
|
+
- **PROVEN WORKFLOWS**: Battle-tested discovery sequences
|
962
|
+
- **STEP-BY-STEP GUIDANCE**: Exact tools and parameters to use
|
963
|
+
- **CUSTOMIZABLE**: Adapt templates to your specific needs
|
964
|
+
- **LEARNING-OPTIMIZED**: Based on successful discovery patterns
|
965
|
+
"""
|
966
|
+
return discovery_templates_impl(template_type, customize_for)
|
967
|
+
|
968
|
+
|
969
|
+
@mcp.tool
|
970
|
+
@catch_errors
|
971
|
+
def discover_relationships(
|
972
|
+
table_name: Optional[str] = None,
|
973
|
+
relationship_types: List[str] = [
|
974
|
+
"foreign_keys",
|
975
|
+
"semantic_similarity",
|
976
|
+
"temporal_patterns",
|
977
|
+
],
|
978
|
+
similarity_threshold: float = 0.6,
|
979
|
+
) -> ToolResponse:
|
980
|
+
"""
|
981
|
+
🔗 **RELATIONSHIP DISCOVERY** - Find hidden connections in your data!
|
982
|
+
|
983
|
+
Automatically discovers relationships between tables and content areas using
|
984
|
+
both structural analysis and semantic similarity to reveal data connections.
|
985
|
+
|
986
|
+
Args:
|
987
|
+
table_name (Optional[str]): Focus on relationships for specific table (default: all)
|
988
|
+
relationship_types (List[str]): Types of relationships to discover
|
989
|
+
- "foreign_keys": Structural relationships via foreign keys
|
990
|
+
- "semantic_similarity": Content-based relationships via semantic analysis
|
991
|
+
- "temporal_patterns": Time-based relationships and patterns
|
992
|
+
- "naming_patterns": Relationships based on naming conventions
|
993
|
+
similarity_threshold (float): Minimum similarity for semantic relationships (0.0-1.0)
|
994
|
+
|
995
|
+
Returns:
|
996
|
+
ToolResponse: {"success": True, "relationships": Dict, "insights": List}
|
997
|
+
|
998
|
+
Examples:
|
999
|
+
>>> discover_relationships("users")
|
1000
|
+
{"success": True, "relationships": {
|
1001
|
+
"users": {
|
1002
|
+
"foreign_key_refs": ["posts.user_id", "comments.user_id"],
|
1003
|
+
"semantic_similar": [{"table": "profiles", "similarity": 0.8}],
|
1004
|
+
"temporal_related": ["user_sessions"]
|
1005
|
+
}
|
1006
|
+
}}
|
1007
|
+
|
1008
|
+
FastMCP Tool Info:
|
1009
|
+
- **AUTOMATIC DETECTION**: Finds relationships you might not notice manually
|
1010
|
+
- **MULTIPLE METHODS**: Combines structural, semantic, and temporal analysis
|
1011
|
+
- **ACTIONABLE INSIGHTS**: Suggests how to leverage discovered relationships
|
1012
|
+
- **PERFECT FOR EXPLORATION**: Reveals hidden data organization patterns
|
1013
|
+
"""
|
1014
|
+
return discover_relationships_impl(
|
1015
|
+
table_name, relationship_types, similarity_threshold
|
1016
|
+
)
|
800
1017
|
|
801
1018
|
|
802
1019
|
# Export the FastMCP app for use in other modules and server runners
|
@@ -835,12 +1052,13 @@ __all__ = [
|
|
835
1052
|
"app",
|
836
1053
|
"mcp",
|
837
1054
|
"create_table",
|
838
|
-
"drop_table",
|
1055
|
+
"drop_table",
|
839
1056
|
"rename_table",
|
840
1057
|
"list_tables",
|
841
1058
|
"describe_table",
|
842
1059
|
"list_all_columns",
|
843
1060
|
"create_row",
|
1061
|
+
"upsert_memory",
|
844
1062
|
"read_rows",
|
845
1063
|
"update_rows",
|
846
1064
|
"delete_rows",
|
@@ -851,13 +1069,19 @@ __all__ = [
|
|
851
1069
|
"auto_semantic_search",
|
852
1070
|
"auto_smart_search",
|
853
1071
|
"embedding_stats",
|
1072
|
+
"intelligent_discovery",
|
1073
|
+
"discovery_templates",
|
1074
|
+
"discover_relationships",
|
854
1075
|
]
|
855
1076
|
|
856
1077
|
|
857
1078
|
def mcp_server():
|
858
1079
|
"""Entry point for MCP stdio server (for uvx and package installations)."""
|
859
1080
|
# Configure logging for MCP server
|
860
|
-
logging.basicConfig(
|
1081
|
+
logging.basicConfig(
|
1082
|
+
level=logging.INFO,
|
1083
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
1084
|
+
)
|
861
1085
|
|
862
1086
|
# Log startup information
|
863
1087
|
logging.info(f"Starting SQLite Memory Bank MCP server with database at {DB_PATH}")
|
@@ -871,11 +1095,15 @@ def main():
|
|
871
1095
|
import uvicorn
|
872
1096
|
import argparse
|
873
1097
|
|
874
|
-
parser = argparse.ArgumentParser(
|
1098
|
+
parser = argparse.ArgumentParser(
|
1099
|
+
description="Run MCP SQLite Memory Bank Server in HTTP mode"
|
1100
|
+
)
|
875
1101
|
parser.add_argument("--host", default="127.0.0.1", help="Host to bind to")
|
876
1102
|
parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
|
877
1103
|
parser.add_argument("--db-path", help="Path to SQLite database file")
|
878
|
-
parser.add_argument(
|
1104
|
+
parser.add_argument(
|
1105
|
+
"--reload", action="store_true", help="Enable auto-reload for development"
|
1106
|
+
)
|
879
1107
|
|
880
1108
|
args = parser.parse_args()
|
881
1109
|
|
@@ -885,22 +1113,32 @@ def main():
|
|
885
1113
|
DB_PATH = args.db_path
|
886
1114
|
os.environ["DB_PATH"] = args.db_path
|
887
1115
|
|
888
|
-
print(
|
1116
|
+
print(
|
1117
|
+
f"Starting MCP SQLite Memory Bank server in HTTP mode on {args.host}:{args.port}"
|
1118
|
+
)
|
889
1119
|
print(f"Database path: {DB_PATH}")
|
890
1120
|
print("Available at: http://localhost:8000/docs")
|
891
1121
|
|
892
|
-
uvicorn.run(
|
1122
|
+
uvicorn.run(
|
1123
|
+
"mcp_sqlite_memory_bank.server:app",
|
1124
|
+
host=args.host,
|
1125
|
+
port=args.port,
|
1126
|
+
reload=args.reload,
|
1127
|
+
)
|
893
1128
|
|
894
1129
|
|
895
1130
|
if __name__ == "__main__":
|
896
1131
|
# Configure logging
|
897
|
-
logging.basicConfig(
|
1132
|
+
logging.basicConfig(
|
1133
|
+
level=logging.INFO,
|
1134
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
1135
|
+
)
|
898
1136
|
|
899
1137
|
# Log startup information
|
900
1138
|
logging.info(f"Starting SQLite Memory Bank with database at {DB_PATH}")
|
901
1139
|
|
902
1140
|
# Run the FastMCP app in stdio mode for MCP clients
|
903
|
-
app.run()
|
1141
|
+
app.run(transport="stdio")
|
904
1142
|
|
905
1143
|
|
906
1144
|
# Compatibility aliases for tests that expect _impl functions
|
@@ -929,3 +1167,93 @@ _auto_smart_search_impl = search.auto_smart_search
|
|
929
1167
|
# Analytics operation aliases
|
930
1168
|
_analyze_memory_patterns_impl = analytics.analyze_memory_patterns
|
931
1169
|
_get_content_health_score_impl = analytics.get_content_health_score
|
1170
|
+
|
1171
|
+
# Discovery operation aliases
|
1172
|
+
_intelligent_discovery_impl = intelligent_discovery_impl
|
1173
|
+
_discovery_templates_impl = discovery_templates_impl
|
1174
|
+
_discover_relationships_impl = discover_relationships_impl
|
1175
|
+
|
1176
|
+
|
1177
|
+
@mcp.tool
|
1178
|
+
@catch_errors
|
1179
|
+
def batch_create_memories(
|
1180
|
+
table_name: str,
|
1181
|
+
data_list: List[Dict[str, Any]],
|
1182
|
+
match_columns: Optional[List[str]] = None,
|
1183
|
+
use_upsert: bool = True,
|
1184
|
+
) -> ToolResponse:
|
1185
|
+
"""
|
1186
|
+
🚀 **BATCH MEMORY CREATION** - Efficiently add multiple memories at once!
|
1187
|
+
|
1188
|
+
Create multiple memory records in a single operation with optional duplicate prevention.
|
1189
|
+
Much faster than creating records one by one.
|
1190
|
+
|
1191
|
+
Args:
|
1192
|
+
table_name (str): Table to insert records into
|
1193
|
+
data_list (List[Dict[str, Any]]): List of memory records to create
|
1194
|
+
match_columns (Optional[List[str]]): Columns to use for duplicate detection (if use_upsert=True)
|
1195
|
+
use_upsert (bool): Whether to use upsert logic to prevent duplicates (default: True)
|
1196
|
+
|
1197
|
+
Returns:
|
1198
|
+
ToolResponse: On success: {"success": True, "created": int, "updated": int, "failed": int}
|
1199
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
1200
|
+
|
1201
|
+
Examples:
|
1202
|
+
>>> batch_create_memories('technical_decisions', [
|
1203
|
+
... {'decision_name': 'API Design', 'chosen_approach': 'REST'},
|
1204
|
+
... {'decision_name': 'Database Choice', 'chosen_approach': 'SQLite'},
|
1205
|
+
... {'decision_name': 'Frontend Framework', 'chosen_approach': 'React'}
|
1206
|
+
... ], match_columns=['decision_name'])
|
1207
|
+
{"success": True, "created": 2, "updated": 1, "failed": 0, "total_processed": 3}
|
1208
|
+
|
1209
|
+
FastMCP Tool Info:
|
1210
|
+
- **EFFICIENT**: Process multiple records in one operation
|
1211
|
+
- **SMART DEDUPLICATION**: Optional upsert logic prevents duplicates
|
1212
|
+
- **DETAILED FEEDBACK**: Returns counts for created, updated, and failed records
|
1213
|
+
- **PARTIAL SUCCESS**: Continues processing even if some records fail
|
1214
|
+
- **PERFECT FOR BULK IMPORTS**: Ideal for importing knowledge bases or datasets
|
1215
|
+
"""
|
1216
|
+
return basic.batch_create_memories(table_name, data_list, match_columns, use_upsert)
|
1217
|
+
|
1218
|
+
|
1219
|
+
@mcp.tool
|
1220
|
+
@catch_errors
|
1221
|
+
def batch_delete_memories(
|
1222
|
+
table_name: str, where_conditions: List[Dict[str, Any]], match_all: bool = False
|
1223
|
+
) -> ToolResponse:
|
1224
|
+
"""
|
1225
|
+
🗑️ **BATCH MEMORY DELETION** - Efficiently delete multiple memories at once!
|
1226
|
+
|
1227
|
+
Delete multiple memory records in a single operation with flexible matching conditions.
|
1228
|
+
Much faster than deleting records one by one.
|
1229
|
+
|
1230
|
+
Args:
|
1231
|
+
table_name (str): Table to delete records from
|
1232
|
+
where_conditions (List[Dict[str, Any]]): List of WHERE conditions for deletion
|
1233
|
+
match_all (bool): If True, delete records matching ALL conditions; if False, delete records matching ANY condition (default: False)
|
1234
|
+
|
1235
|
+
Returns:
|
1236
|
+
ToolResponse: On success: {"success": True, "deleted": int, "failed": int}
|
1237
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
1238
|
+
|
1239
|
+
Examples:
|
1240
|
+
>>> batch_delete_memories('technical_decisions', [
|
1241
|
+
... {'decision_name': 'Old Decision 1'},
|
1242
|
+
... {'decision_name': 'Old Decision 2'},
|
1243
|
+
... {'id': 42}
|
1244
|
+
... ])
|
1245
|
+
{"success": True, "deleted": 3, "failed": 0, "total_conditions": 3}
|
1246
|
+
|
1247
|
+
>>> batch_delete_memories('notes', [
|
1248
|
+
... {'category': 'temp', 'created_date': '2024-01-01'}
|
1249
|
+
... ], match_all=True)
|
1250
|
+
{"success": True, "deleted": 15, "failed": 0} # Deletes notes that are BOTH temp AND from that date
|
1251
|
+
|
1252
|
+
FastMCP Tool Info:
|
1253
|
+
- **EFFICIENT**: Process multiple deletions in one operation
|
1254
|
+
- **FLEXIBLE MATCHING**: Support both OR logic (any condition) and AND logic (all conditions)
|
1255
|
+
- **DETAILED FEEDBACK**: Returns counts and per-condition results
|
1256
|
+
- **PARTIAL SUCCESS**: Continues processing even if some deletions fail
|
1257
|
+
- **SAFE**: Uses parameterized queries to prevent SQL injection
|
1258
|
+
"""
|
1259
|
+
return basic.batch_delete_memories(table_name, where_conditions, match_all)
|
@@ -3,7 +3,8 @@ Tools module for SQLite Memory Bank MCP server.
|
|
3
3
|
|
4
4
|
This module organizes the various MCP tools into logical categories:
|
5
5
|
- analytics: Content analysis and health assessment tools
|
6
|
-
- search: Intelligent search and discovery tools
|
6
|
+
- search: Intelligent search and discovery tools
|
7
|
+
- discovery: Advanced exploration and relationship discovery tools
|
7
8
|
- basic: Core CRUD operations and table management
|
8
9
|
"""
|
9
10
|
|
@@ -23,6 +24,11 @@ from .search import (
|
|
23
24
|
auto_semantic_search,
|
24
25
|
auto_smart_search,
|
25
26
|
)
|
27
|
+
from .discovery import (
|
28
|
+
intelligent_discovery,
|
29
|
+
discovery_templates,
|
30
|
+
discover_relationships,
|
31
|
+
)
|
26
32
|
from .basic import (
|
27
33
|
create_table,
|
28
34
|
list_tables,
|
@@ -39,30 +45,32 @@ from .basic import (
|
|
39
45
|
|
40
46
|
__all__ = [
|
41
47
|
# Analytics tools
|
42
|
-
|
43
|
-
|
44
|
-
|
48
|
+
"analyze_memory_patterns",
|
49
|
+
"get_content_health_score",
|
45
50
|
# Search tools
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
"search_content",
|
52
|
+
"explore_tables",
|
53
|
+
"add_embeddings",
|
54
|
+
"semantic_search",
|
55
|
+
"find_related",
|
56
|
+
"smart_search",
|
57
|
+
"embedding_stats",
|
58
|
+
"auto_semantic_search",
|
59
|
+
"auto_smart_search",
|
60
|
+
# Discovery tools
|
61
|
+
"intelligent_discovery",
|
62
|
+
"discovery_templates",
|
63
|
+
"discover_relationships",
|
56
64
|
# Basic tools
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
"create_table",
|
66
|
+
"list_tables",
|
67
|
+
"describe_table",
|
68
|
+
"drop_table",
|
69
|
+
"rename_table",
|
70
|
+
"create_row",
|
71
|
+
"read_rows",
|
72
|
+
"update_rows",
|
73
|
+
"delete_rows",
|
74
|
+
"run_select_query",
|
75
|
+
"list_all_columns",
|
68
76
|
]
|