mcp-sqlite-memory-bank 1.4.3__py3-none-any.whl → 1.5.1__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 +20 -3
- mcp_sqlite_memory_bank/__main__.py +59 -0
- mcp_sqlite_memory_bank/database.py +60 -12
- mcp_sqlite_memory_bank/resources.py +256 -0
- mcp_sqlite_memory_bank/semantic.py +14 -4
- mcp_sqlite_memory_bank/server.py +336 -491
- mcp_sqlite_memory_bank/tools/__init__.py +79 -0
- mcp_sqlite_memory_bank/tools/analytics.py +419 -0
- mcp_sqlite_memory_bank/tools/basic.py +112 -0
- mcp_sqlite_memory_bank/tools/discovery.py +1176 -0
- mcp_sqlite_memory_bank/tools/search.py +380 -0
- mcp_sqlite_memory_bank/utils.py +189 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.1.dist-info}/METADATA +1 -1
- mcp_sqlite_memory_bank-1.5.1.dist-info/RECORD +21 -0
- mcp_sqlite_memory_bank-1.4.3.dist-info/RECORD +0 -15
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.1.dist-info}/WHEEL +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.1.dist-info}/entry_points.txt +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.1.dist-info}/licenses/LICENSE +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.1.dist-info}/top_level.txt +0 -0
mcp_sqlite_memory_bank/server.py
CHANGED
@@ -50,6 +50,7 @@ from typing import Dict, Optional, List, cast, Any
|
|
50
50
|
from fastmcp import FastMCP
|
51
51
|
|
52
52
|
from .database import get_database
|
53
|
+
from .semantic import is_semantic_search_available
|
53
54
|
from .types import (
|
54
55
|
ToolResponse,
|
55
56
|
CreateTableResponse,
|
@@ -68,6 +69,9 @@ from .utils import catch_errors
|
|
68
69
|
from .resources import setup_mcp_resources
|
69
70
|
from .prompts import setup_mcp_prompts
|
70
71
|
|
72
|
+
# Import modular tool implementations (for aliases only)
|
73
|
+
from .tools import basic, search, analytics
|
74
|
+
|
71
75
|
# Initialize FastMCP app with explicit name
|
72
76
|
mcp: FastMCP = FastMCP("SQLite Memory Bank for Copilot/AI Agents")
|
73
77
|
|
@@ -86,6 +90,9 @@ setup_mcp_resources(mcp, DB_PATH)
|
|
86
90
|
# Set up MCP Prompts for enhanced workflow support
|
87
91
|
setup_mcp_prompts(mcp, DB_PATH)
|
88
92
|
|
93
|
+
# All tools are registered via @mcp.tool decorators below
|
94
|
+
# No explicit registration needed - decorators handle this automatically
|
95
|
+
|
89
96
|
|
90
97
|
# --- Schema Management Tools for SQLite Memory Bank ---
|
91
98
|
|
@@ -392,12 +399,32 @@ def list_all_columns() -> ToolResponse:
|
|
392
399
|
return cast(ListAllColumnsResponse, get_database(DB_PATH).list_all_columns())
|
393
400
|
|
394
401
|
|
395
|
-
#
|
402
|
+
# Import the implementation functions from tools modules
|
403
|
+
from .tools.search import (
|
404
|
+
search_content as search_content_impl,
|
405
|
+
explore_tables as explore_tables_impl,
|
406
|
+
add_embeddings as add_embeddings_impl,
|
407
|
+
auto_semantic_search as auto_semantic_search_impl,
|
408
|
+
auto_smart_search as auto_smart_search_impl,
|
409
|
+
embedding_stats as embedding_stats_impl,
|
410
|
+
)
|
411
|
+
|
412
|
+
# Import the implementation functions from discovery module
|
413
|
+
from .tools.discovery import (
|
414
|
+
intelligent_discovery as intelligent_discovery_impl,
|
415
|
+
discovery_templates as discovery_templates_impl,
|
416
|
+
discover_relationships as discover_relationships_impl,
|
417
|
+
)
|
396
418
|
|
419
|
+
# --- MCP Tool Definitions (Required in main server.py for FastMCP) ---
|
397
420
|
|
398
421
|
@mcp.tool
|
399
422
|
@catch_errors
|
400
|
-
def search_content(
|
423
|
+
def search_content(
|
424
|
+
query: str,
|
425
|
+
tables: Optional[List[str]] = None,
|
426
|
+
limit: int = 50,
|
427
|
+
) -> ToolResponse:
|
401
428
|
"""
|
402
429
|
Perform full-text search across table content using natural language queries.
|
403
430
|
|
@@ -424,12 +451,15 @@ def search_content(query: str, tables: Optional[List[str]] = None, limit: int =
|
|
424
451
|
- Supports phrase search with quotes: "exact phrase"
|
425
452
|
- Supports boolean operators: AND, OR, NOT
|
426
453
|
"""
|
427
|
-
return
|
454
|
+
return search_content_impl(query, tables, limit)
|
428
455
|
|
429
456
|
|
430
457
|
@mcp.tool
|
431
|
-
@catch_errors
|
432
|
-
def explore_tables(
|
458
|
+
@catch_errors
|
459
|
+
def explore_tables(
|
460
|
+
pattern: Optional[str] = None,
|
461
|
+
include_row_counts: bool = True,
|
462
|
+
) -> ToolResponse:
|
433
463
|
"""
|
434
464
|
Explore and discover table structures and content for better searchability.
|
435
465
|
|
@@ -458,22 +488,22 @@ def explore_tables(pattern: Optional[str] = None, include_row_counts: bool = Tru
|
|
458
488
|
- Helps understand what data is available for searching
|
459
489
|
- Useful for exploratory data analysis
|
460
490
|
"""
|
461
|
-
return
|
462
|
-
|
463
|
-
|
464
|
-
# --- Semantic Search and AI-Enhanced Discovery Tools ---
|
491
|
+
return explore_tables_impl(pattern, include_row_counts)
|
465
492
|
|
466
493
|
|
467
494
|
@mcp.tool
|
468
495
|
@catch_errors
|
469
496
|
def add_embeddings(
|
470
|
-
table_name: str,
|
497
|
+
table_name: str,
|
498
|
+
text_columns: List[str],
|
499
|
+
embedding_column: str = "embedding",
|
500
|
+
model_name: str = "all-MiniLM-L6-v2",
|
471
501
|
) -> ToolResponse:
|
472
502
|
"""
|
473
503
|
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
474
|
-
|
504
|
+
|
475
505
|
Generate and store vector embeddings for semantic search on table content.
|
476
|
-
|
506
|
+
|
477
507
|
**RECOMMENDATION**: Use auto_smart_search() or auto_semantic_search() for automatic setup.
|
478
508
|
This tool is for advanced users who need manual control over embedding generation.
|
479
509
|
|
@@ -501,14 +531,12 @@ def add_embeddings(
|
|
501
531
|
- Uses efficient batch processing for large datasets
|
502
532
|
- Supports various sentence-transformer models for different use cases
|
503
533
|
"""
|
504
|
-
return
|
505
|
-
ToolResponse, get_database(DB_PATH).generate_embeddings(table_name, text_columns, embedding_column, model_name)
|
506
|
-
)
|
534
|
+
return add_embeddings_impl(table_name, text_columns, embedding_column, model_name)
|
507
535
|
|
508
536
|
|
509
537
|
@mcp.tool
|
510
538
|
@catch_errors
|
511
|
-
def
|
539
|
+
def auto_semantic_search(
|
512
540
|
query: str,
|
513
541
|
tables: Optional[List[str]] = None,
|
514
542
|
similarity_threshold: float = 0.5,
|
@@ -516,102 +544,48 @@ def semantic_search(
|
|
516
544
|
model_name: str = "all-MiniLM-L6-v2",
|
517
545
|
) -> ToolResponse:
|
518
546
|
"""
|
519
|
-
|
520
|
-
|
521
|
-
Find content using natural language semantic similarity rather than exact keyword matching.
|
522
|
-
|
523
|
-
**RECOMMENDATION**: Use auto_smart_search() for automatic setup and hybrid search capabilities.
|
524
|
-
This tool requires manual embedding setup via add_embeddings() first.
|
547
|
+
🚀 **ZERO-SETUP SEMANTIC SEARCH** - Just search, embeddings are handled automatically!
|
525
548
|
|
526
|
-
|
527
|
-
they
|
549
|
+
Find content using natural language semantic similarity. If embeddings don't exist,
|
550
|
+
they will be automatically generated for text columns. This is the easiest way to
|
551
|
+
do semantic search - no manual setup required!
|
528
552
|
|
529
553
|
Args:
|
530
554
|
query (str): Natural language search query
|
531
|
-
tables (Optional[List[str]]): Specific tables to search (default: all tables
|
555
|
+
tables (Optional[List[str]]): Specific tables to search (default: all tables)
|
532
556
|
similarity_threshold (float): Minimum similarity score (0.0-1.0, default: 0.5)
|
533
557
|
limit (int): Maximum number of results to return (default: 10)
|
534
|
-
model_name (str): Model to use for
|
558
|
+
model_name (str): Model to use for embeddings (default: "all-MiniLM-L6-v2")
|
535
559
|
|
536
560
|
Returns:
|
537
|
-
ToolResponse: On success: {"success": True, "results": List[...], "
|
561
|
+
ToolResponse: On success: {"success": True, "results": List[...], "auto_embedded_tables": List[str]}
|
538
562
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
539
563
|
|
540
564
|
Examples:
|
541
|
-
>>>
|
565
|
+
>>> auto_semantic_search("API design patterns")
|
542
566
|
{"success": True, "results": [
|
543
|
-
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
544
|
-
|
545
|
-
]}
|
567
|
+
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
568
|
+
], "auto_embedded_tables": ["technical_decisions"]}
|
546
569
|
|
547
|
-
>>>
|
570
|
+
>>> auto_semantic_search("machine learning concepts")
|
548
571
|
# Finds content about "ML", "AI", "neural networks", etc.
|
572
|
+
# Automatically creates embeddings if they don't exist!
|
549
573
|
|
550
574
|
FastMCP Tool Info:
|
575
|
+
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
576
|
+
- Auto-detects text columns and creates embeddings as needed
|
551
577
|
- Works across multiple tables simultaneously
|
552
578
|
- Finds conceptually similar content regardless of exact wording
|
553
579
|
- Returns relevance scores for ranking results
|
554
580
|
- Supports fuzzy matching and concept discovery
|
555
|
-
-
|
556
|
-
"""
|
557
|
-
return cast(
|
558
|
-
ToolResponse,
|
559
|
-
get_database(DB_PATH).semantic_search(
|
560
|
-
query, tables, "embedding", None, similarity_threshold, limit, model_name
|
561
|
-
),
|
562
|
-
)
|
563
|
-
|
564
|
-
|
565
|
-
@mcp.tool
|
566
|
-
@catch_errors
|
567
|
-
def find_related(
|
568
|
-
table_name: str,
|
569
|
-
row_id: int,
|
570
|
-
similarity_threshold: float = 0.5,
|
571
|
-
limit: int = 5,
|
572
|
-
model_name: str = "all-MiniLM-L6-v2",
|
573
|
-
) -> ToolResponse:
|
574
|
-
"""
|
575
|
-
Find content related to a specific row by semantic similarity.
|
576
|
-
|
577
|
-
Discover connections and related information that might not be obvious
|
578
|
-
from direct references or tags.
|
579
|
-
|
580
|
-
Args:
|
581
|
-
table_name (str): Table containing the reference row
|
582
|
-
row_id (int): ID of the row to find related content for
|
583
|
-
similarity_threshold (float): Minimum similarity score (default: 0.5)
|
584
|
-
limit (int): Maximum number of related items to return (default: 5)
|
585
|
-
model_name (str): Model for similarity comparison (default: "all-MiniLM-L6-v2")
|
586
|
-
|
587
|
-
Returns:
|
588
|
-
ToolResponse: On success: {"success": True, "results": List[...], "target_row": Dict}
|
589
|
-
On error: {"success": False, "error": str, "category": str, "details": dict}
|
590
|
-
|
591
|
-
Examples:
|
592
|
-
>>> find_related("technical_decisions", 5)
|
593
|
-
{"success": True, "results": [
|
594
|
-
{"id": 12, "similarity_score": 0.84, "decision_name": "Related Architecture Choice", ...},
|
595
|
-
{"id": 3, "similarity_score": 0.71, "decision_name": "Similar Technology Decision", ...}
|
596
|
-
], "target_row": {"id": 5, "decision_name": "API Framework Selection", ...}}
|
597
|
-
|
598
|
-
FastMCP Tool Info:
|
599
|
-
- Helps discover hidden relationships between data
|
600
|
-
- Useful for finding similar decisions, related problems, or connected concepts
|
601
|
-
- Can reveal patterns and themes across your knowledge base
|
602
|
-
- Enables serendipitous discovery of relevant information
|
581
|
+
- Perfect for agents - just search and it works!
|
603
582
|
"""
|
604
|
-
return
|
605
|
-
ToolResponse,
|
606
|
-
get_database(DB_PATH).find_related_content(
|
607
|
-
table_name, row_id, "embedding", similarity_threshold, limit, model_name
|
608
|
-
),
|
609
|
-
)
|
583
|
+
return auto_semantic_search_impl(query, tables, similarity_threshold, limit, model_name)
|
610
584
|
|
611
585
|
|
612
586
|
@mcp.tool
|
613
587
|
@catch_errors
|
614
|
-
def
|
588
|
+
def auto_smart_search(
|
615
589
|
query: str,
|
616
590
|
tables: Optional[List[str]] = None,
|
617
591
|
semantic_weight: float = 0.7,
|
@@ -620,15 +594,11 @@ def smart_search(
|
|
620
594
|
model_name: str = "all-MiniLM-L6-v2",
|
621
595
|
) -> ToolResponse:
|
622
596
|
"""
|
623
|
-
|
624
|
-
|
625
|
-
Intelligent hybrid search combining semantic understanding with keyword matching.
|
626
|
-
|
627
|
-
**RECOMMENDATION**: Use auto_smart_search() for the same functionality with automatic setup.
|
628
|
-
This tool requires manual embedding setup via add_embeddings() first.
|
597
|
+
🚀 **ZERO-SETUP HYBRID SEARCH** - Best of both worlds with automatic embedding!
|
629
598
|
|
630
|
-
|
631
|
-
|
599
|
+
Intelligent hybrid search combining semantic understanding with keyword matching.
|
600
|
+
Automatically generates embeddings for text columns when needed. This is the
|
601
|
+
ultimate search tool - no manual setup required!
|
632
602
|
|
633
603
|
Args:
|
634
604
|
query (str): Search query (natural language or keywords)
|
@@ -639,37 +609,63 @@ def smart_search(
|
|
639
609
|
model_name (str): Semantic model to use (default: "all-MiniLM-L6-v2")
|
640
610
|
|
641
611
|
Returns:
|
642
|
-
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "
|
612
|
+
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "auto_hybrid"}
|
643
613
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
644
614
|
|
645
615
|
Examples:
|
646
|
-
>>>
|
616
|
+
>>> auto_smart_search("user authentication security")
|
647
617
|
{"success": True, "results": [
|
648
|
-
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
649
|
-
|
650
|
-
], "search_type": "hybrid"}
|
618
|
+
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
619
|
+
], "search_type": "auto_hybrid", "auto_embedded_tables": ["user_data"]}
|
651
620
|
|
652
621
|
FastMCP Tool Info:
|
622
|
+
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
653
623
|
- Automatically balances semantic and keyword search
|
624
|
+
- Auto-detects text columns and creates embeddings as needed
|
654
625
|
- Provides separate scores for transparency
|
655
626
|
- Falls back gracefully if semantic search unavailable
|
656
627
|
- Optimal for both exploratory and precise searches
|
657
628
|
- Perfect for agents - ultimate search tool that just works!
|
658
629
|
"""
|
659
|
-
return
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
630
|
+
return auto_smart_search_impl(query, tables, semantic_weight, text_weight, limit, model_name)
|
631
|
+
|
632
|
+
|
633
|
+
@mcp.tool
|
634
|
+
@catch_errors
|
635
|
+
def embedding_stats(
|
636
|
+
table_name: str,
|
637
|
+
embedding_column: str = "embedding",
|
638
|
+
) -> ToolResponse:
|
639
|
+
"""
|
640
|
+
Get statistics about semantic search readiness for a table.
|
641
|
+
|
642
|
+
Check which content has embeddings and can be searched semantically.
|
665
643
|
|
644
|
+
Args:
|
645
|
+
table_name (str): Table to analyze
|
646
|
+
embedding_column (str): Embedding column to check (default: "embedding")
|
666
647
|
|
667
|
-
|
648
|
+
Returns:
|
649
|
+
ToolResponse: On success: {"success": True, "coverage_percent": float, "total_rows": int}
|
650
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
651
|
+
|
652
|
+
Examples:
|
653
|
+
>>> embedding_stats("technical_decisions")
|
654
|
+
{"success": True, "total_rows": 25, "embedded_rows": 25, "coverage_percent": 100.0,
|
655
|
+
"embedding_dimensions": 384}
|
656
|
+
|
657
|
+
FastMCP Tool Info:
|
658
|
+
- Shows how much content is ready for semantic search
|
659
|
+
- Helps identify tables that need embedding generation
|
660
|
+
- Provides embedding dimension info for debugging
|
661
|
+
- Useful for monitoring semantic search capabilities
|
662
|
+
"""
|
663
|
+
return embedding_stats_impl(table_name, embedding_column)
|
668
664
|
|
669
665
|
|
670
666
|
@mcp.tool
|
671
667
|
@catch_errors
|
672
|
-
def
|
668
|
+
def semantic_search(
|
673
669
|
query: str,
|
674
670
|
tables: Optional[List[str]] = None,
|
675
671
|
similarity_threshold: float = 0.5,
|
@@ -677,117 +673,50 @@ def auto_semantic_search(
|
|
677
673
|
model_name: str = "all-MiniLM-L6-v2",
|
678
674
|
) -> ToolResponse:
|
679
675
|
"""
|
680
|
-
|
676
|
+
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
681
677
|
|
682
|
-
Find content using natural language semantic similarity
|
683
|
-
|
684
|
-
|
678
|
+
Find content using natural language semantic similarity rather than exact keyword matching.
|
679
|
+
|
680
|
+
**RECOMMENDATION**: Use auto_smart_search() for the same functionality with automatic setup.
|
681
|
+
This tool requires manual embedding setup via add_embeddings() first.
|
682
|
+
|
683
|
+
This enables intelligent knowledge discovery - find related concepts even when
|
684
|
+
they use different terminology or phrasing.
|
685
685
|
|
686
686
|
Args:
|
687
687
|
query (str): Natural language search query
|
688
|
-
tables (Optional[List[str]]): Specific tables to search (default: all tables)
|
688
|
+
tables (Optional[List[str]]): Specific tables to search (default: all tables with embeddings)
|
689
689
|
similarity_threshold (float): Minimum similarity score (0.0-1.0, default: 0.5)
|
690
690
|
limit (int): Maximum number of results to return (default: 10)
|
691
|
-
model_name (str): Model to use for
|
691
|
+
model_name (str): Model to use for query embedding (default: "all-MiniLM-L6-v2")
|
692
692
|
|
693
693
|
Returns:
|
694
|
-
ToolResponse: On success: {"success": True, "results": List[...], "
|
694
|
+
ToolResponse: On success: {"success": True, "results": List[...], "total_results": int}
|
695
695
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
696
696
|
|
697
697
|
Examples:
|
698
|
-
>>>
|
698
|
+
>>> semantic_search("API design patterns")
|
699
699
|
{"success": True, "results": [
|
700
|
-
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
701
|
-
|
700
|
+
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...},
|
701
|
+
{"table_name": "project_structure", "similarity_score": 0.72, "component": "API Gateway", ...}
|
702
|
+
]}
|
702
703
|
|
703
|
-
>>>
|
704
|
+
>>> semantic_search("machine learning", tables=["technical_decisions"], similarity_threshold=0.7)
|
704
705
|
# Finds content about "ML", "AI", "neural networks", etc.
|
705
|
-
# Automatically creates embeddings if they don't exist!
|
706
706
|
|
707
707
|
FastMCP Tool Info:
|
708
|
-
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
709
|
-
- Auto-detects text columns and creates embeddings as needed
|
710
708
|
- Works across multiple tables simultaneously
|
711
709
|
- Finds conceptually similar content regardless of exact wording
|
712
710
|
- Returns relevance scores for ranking results
|
713
711
|
- Supports fuzzy matching and concept discovery
|
714
|
-
-
|
712
|
+
- Much more powerful than keyword-based search for knowledge discovery
|
715
713
|
"""
|
716
|
-
|
717
|
-
db = get_database(DB_PATH)
|
718
|
-
auto_embedded_tables: List[str] = []
|
719
|
-
|
720
|
-
# Get tables to search
|
721
|
-
search_tables: List[str]
|
722
|
-
if tables:
|
723
|
-
search_tables = tables
|
724
|
-
else:
|
725
|
-
tables_result = db.list_tables()
|
726
|
-
if not tables_result.get("success"):
|
727
|
-
return cast(ToolResponse, tables_result)
|
728
|
-
all_tables = tables_result.get("tables", [])
|
729
|
-
if isinstance(all_tables, list):
|
730
|
-
search_tables = all_tables
|
731
|
-
else:
|
732
|
-
search_tables = []
|
733
|
-
|
734
|
-
# Auto-embed text columns in tables that don't have embeddings
|
735
|
-
for table_name in search_tables:
|
736
|
-
try:
|
737
|
-
# Check if table has embeddings
|
738
|
-
stats_result = db.get_embedding_stats(table_name, "embedding")
|
739
|
-
coverage_percent = stats_result.get("coverage_percent", 0)
|
740
|
-
if stats_result.get("success") and isinstance(coverage_percent, (int, float)) and coverage_percent > 0:
|
741
|
-
continue # Table already has embeddings
|
742
|
-
|
743
|
-
# Get table schema to find text columns
|
744
|
-
schema_result = db.describe_table(table_name)
|
745
|
-
if not schema_result.get("success"):
|
746
|
-
continue
|
747
|
-
|
748
|
-
# Find text columns
|
749
|
-
text_columns = []
|
750
|
-
columns = schema_result.get("columns", [])
|
751
|
-
if isinstance(columns, list):
|
752
|
-
for col in columns:
|
753
|
-
if isinstance(col, dict) and "TEXT" in col.get("type", "").upper():
|
754
|
-
text_columns.append(col["name"])
|
755
|
-
|
756
|
-
# Auto-embed text columns
|
757
|
-
if text_columns:
|
758
|
-
embed_result = db.generate_embeddings(table_name, text_columns, "embedding", model_name)
|
759
|
-
if embed_result.get("success"):
|
760
|
-
auto_embedded_tables.append(table_name)
|
761
|
-
|
762
|
-
except Exception:
|
763
|
-
# If auto-embedding fails, continue without it
|
764
|
-
continue
|
765
|
-
|
766
|
-
# Perform semantic search
|
767
|
-
search_result = db.semantic_search(
|
768
|
-
query, search_tables, "embedding", None, similarity_threshold, limit, model_name
|
769
|
-
)
|
770
|
-
|
771
|
-
# Add auto-embedding info to result
|
772
|
-
if isinstance(search_result, dict):
|
773
|
-
search_result["auto_embedded_tables"] = auto_embedded_tables
|
774
|
-
if auto_embedded_tables:
|
775
|
-
search_result["auto_embedding_note"] = f"Automatically generated embeddings for {len(auto_embedded_tables)} table(s)"
|
776
|
-
|
777
|
-
return cast(ToolResponse, search_result)
|
778
|
-
|
779
|
-
except Exception as e:
|
780
|
-
return cast(ToolResponse, {
|
781
|
-
"success": False,
|
782
|
-
"error": f"Auto semantic search failed: {str(e)}",
|
783
|
-
"category": "SEMANTIC_SEARCH_ERROR",
|
784
|
-
"details": {"query": query, "tables": tables}
|
785
|
-
})
|
714
|
+
return _semantic_search_impl(query, tables, similarity_threshold, limit, model_name)
|
786
715
|
|
787
716
|
|
788
717
|
@mcp.tool
|
789
718
|
@catch_errors
|
790
|
-
def
|
719
|
+
def smart_search(
|
791
720
|
query: str,
|
792
721
|
tables: Optional[List[str]] = None,
|
793
722
|
semantic_weight: float = 0.7,
|
@@ -796,11 +725,15 @@ def auto_smart_search(
|
|
796
725
|
model_name: str = "all-MiniLM-L6-v2",
|
797
726
|
) -> ToolResponse:
|
798
727
|
"""
|
799
|
-
|
728
|
+
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
800
729
|
|
801
730
|
Intelligent hybrid search combining semantic understanding with keyword matching.
|
802
|
-
|
803
|
-
|
731
|
+
|
732
|
+
**RECOMMENDATION**: Use auto_smart_search() for the same functionality with automatic setup.
|
733
|
+
This tool requires manual embedding setup via add_embeddings() first.
|
734
|
+
|
735
|
+
Provides the best of both worlds - semantic similarity for concept discovery
|
736
|
+
plus exact text matching for precise searches.
|
804
737
|
|
805
738
|
Args:
|
806
739
|
query (str): Search query (natural language or keywords)
|
@@ -811,242 +744,207 @@ def auto_smart_search(
|
|
811
744
|
model_name (str): Semantic model to use (default: "all-MiniLM-L6-v2")
|
812
745
|
|
813
746
|
Returns:
|
814
|
-
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "
|
747
|
+
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "hybrid"}
|
815
748
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
816
749
|
|
817
750
|
Examples:
|
818
|
-
>>>
|
751
|
+
>>> smart_search("user authentication security")
|
819
752
|
{"success": True, "results": [
|
820
|
-
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
821
|
-
|
753
|
+
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...},
|
754
|
+
{"combined_score": 0.76, "semantic_score": 0.71, "text_score": 0.85, ...}
|
755
|
+
], "search_type": "hybrid"}
|
822
756
|
|
823
757
|
FastMCP Tool Info:
|
824
|
-
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
825
758
|
- Automatically balances semantic and keyword search
|
826
|
-
- Auto-detects text columns and creates embeddings as needed
|
827
759
|
- Provides separate scores for transparency
|
828
760
|
- Falls back gracefully if semantic search unavailable
|
829
761
|
- Optimal for both exploratory and precise searches
|
830
762
|
- Perfect for agents - ultimate search tool that just works!
|
831
763
|
"""
|
832
|
-
|
833
|
-
db = get_database(DB_PATH)
|
834
|
-
auto_embedded_tables: List[str] = []
|
835
|
-
|
836
|
-
# Get tables to search
|
837
|
-
search_tables: List[str]
|
838
|
-
if tables:
|
839
|
-
search_tables = tables
|
840
|
-
else:
|
841
|
-
tables_result = db.list_tables()
|
842
|
-
if not tables_result.get("success"):
|
843
|
-
return cast(ToolResponse, tables_result)
|
844
|
-
all_tables = tables_result.get("tables", [])
|
845
|
-
if isinstance(all_tables, list):
|
846
|
-
search_tables = all_tables
|
847
|
-
else:
|
848
|
-
search_tables = []
|
849
|
-
|
850
|
-
# Auto-embed text columns in tables that don't have embeddings
|
851
|
-
for table_name in search_tables:
|
852
|
-
try:
|
853
|
-
# Check if table has embeddings
|
854
|
-
stats_result = db.get_embedding_stats(table_name, "embedding")
|
855
|
-
coverage_percent = stats_result.get("coverage_percent", 0)
|
856
|
-
if stats_result.get("success") and isinstance(coverage_percent, (int, float)) and coverage_percent > 0:
|
857
|
-
continue # Table already has embeddings
|
858
|
-
|
859
|
-
# Get table schema to find text columns
|
860
|
-
schema_result = db.describe_table(table_name)
|
861
|
-
if not schema_result.get("success"):
|
862
|
-
continue
|
863
|
-
|
864
|
-
# Find text columns
|
865
|
-
text_columns = []
|
866
|
-
columns = schema_result.get("columns", [])
|
867
|
-
if isinstance(columns, list):
|
868
|
-
for col in columns:
|
869
|
-
if isinstance(col, dict) and "TEXT" in col.get("type", "").upper():
|
870
|
-
text_columns.append(col["name"])
|
871
|
-
|
872
|
-
# Auto-embed text columns
|
873
|
-
if text_columns:
|
874
|
-
embed_result = db.generate_embeddings(table_name, text_columns, "embedding", model_name)
|
875
|
-
if embed_result.get("success"):
|
876
|
-
auto_embedded_tables.append(table_name)
|
877
|
-
|
878
|
-
except Exception:
|
879
|
-
# If auto-embedding fails, continue without it
|
880
|
-
continue
|
881
|
-
|
882
|
-
# Now perform hybrid search
|
883
|
-
db = get_database(DB_PATH)
|
884
|
-
hybrid_result = db.hybrid_search(
|
885
|
-
query, tables, None, "embedding", semantic_weight, text_weight, limit, model_name
|
886
|
-
)
|
887
|
-
|
888
|
-
# Add auto-embedding info to result
|
889
|
-
if isinstance(hybrid_result, dict) and hybrid_result.get("success"):
|
890
|
-
# Convert to mutable dict to add extra fields
|
891
|
-
final_result = dict(hybrid_result)
|
892
|
-
final_result["search_type"] = "auto_hybrid"
|
893
|
-
final_result["auto_embedded_tables"] = auto_embedded_tables
|
894
|
-
if auto_embedded_tables:
|
895
|
-
final_result["auto_embedding_note"] = f"Automatically generated embeddings for {len(auto_embedded_tables)} table(s)"
|
896
|
-
return cast(ToolResponse, final_result)
|
897
|
-
else:
|
898
|
-
return cast(ToolResponse, hybrid_result)
|
899
|
-
|
900
|
-
except Exception as e:
|
901
|
-
return cast(ToolResponse, {
|
902
|
-
"success": False,
|
903
|
-
"error": f"Auto smart search failed: {str(e)}",
|
904
|
-
"category": "HYBRID_SEARCH_ERROR",
|
905
|
-
"details": {"query": query, "tables": tables}
|
906
|
-
})
|
764
|
+
return _smart_search_impl(query, tables, semantic_weight, text_weight, limit, model_name)
|
907
765
|
|
908
766
|
|
909
767
|
@mcp.tool
|
910
|
-
@catch_errors
|
911
|
-
def
|
768
|
+
@catch_errors
|
769
|
+
def find_related(
|
770
|
+
table_name: str,
|
771
|
+
row_id: int,
|
772
|
+
similarity_threshold: float = 0.5,
|
773
|
+
limit: int = 5,
|
774
|
+
model_name: str = "all-MiniLM-L6-v2",
|
775
|
+
) -> ToolResponse:
|
912
776
|
"""
|
913
|
-
|
777
|
+
Find content related to a specific row by semantic similarity.
|
914
778
|
|
915
|
-
|
779
|
+
Discover connections and related information that might not be obvious
|
780
|
+
from direct references or tags.
|
916
781
|
|
917
782
|
Args:
|
918
|
-
table_name (str): Table
|
919
|
-
|
783
|
+
table_name (str): Table containing the reference row
|
784
|
+
row_id (int): ID of the row to find related content for
|
785
|
+
similarity_threshold (float): Minimum similarity score (default: 0.5)
|
786
|
+
limit (int): Maximum number of related items to return (default: 5)
|
787
|
+
model_name (str): Model for similarity comparison (default: "all-MiniLM-L6-v2")
|
920
788
|
|
921
789
|
Returns:
|
922
|
-
ToolResponse: On success: {"success": True, "
|
790
|
+
ToolResponse: On success: {"success": True, "results": List[...], "target_row": Dict}
|
923
791
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
924
792
|
|
925
793
|
Examples:
|
926
|
-
>>>
|
927
|
-
{"success": True, "
|
928
|
-
|
794
|
+
>>> find_related("technical_decisions", 5)
|
795
|
+
{"success": True, "results": [
|
796
|
+
{"id": 12, "similarity_score": 0.84, "decision_name": "Related Architecture Choice", ...},
|
797
|
+
{"id": 3, "similarity_score": 0.71, "decision_name": "Similar Technology Decision", ...}
|
798
|
+
], "target_row": {"id": 5, "decision_name": "API Framework Selection", ...}}
|
929
799
|
|
930
800
|
FastMCP Tool Info:
|
931
|
-
-
|
932
|
-
-
|
933
|
-
-
|
934
|
-
-
|
801
|
+
- Helps discover hidden relationships between data
|
802
|
+
- Useful for finding similar decisions, related problems, or connected concepts
|
803
|
+
- Can reveal patterns and themes across your knowledge base
|
804
|
+
- Enables serendipitous discovery of relevant information
|
935
805
|
"""
|
936
|
-
return
|
806
|
+
return _find_related_impl(table_name, row_id, similarity_threshold, limit, model_name)
|
937
807
|
|
938
808
|
|
939
|
-
# ---
|
809
|
+
# --- Advanced Discovery Tools for SQLite Memory Bank ---
|
810
|
+
|
811
|
+
@mcp.tool
|
812
|
+
@catch_errors
|
813
|
+
def intelligent_discovery(
|
814
|
+
discovery_goal: str = "understand_content",
|
815
|
+
focus_area: Optional[str] = None,
|
816
|
+
depth: str = "moderate",
|
817
|
+
agent_id: Optional[str] = None,
|
818
|
+
) -> ToolResponse:
|
819
|
+
"""
|
820
|
+
🧠 **INTELLIGENT DISCOVERY** - AI-guided exploration of your memory bank!
|
821
|
+
|
822
|
+
Orchestrates multiple discovery tools based on your exploration goals.
|
823
|
+
Provides step-by-step guidance and actionable insights tailored to your needs.
|
824
|
+
|
825
|
+
Args:
|
826
|
+
discovery_goal (str): What you want to achieve
|
827
|
+
- "understand_content": Learn what data is available and how it's organized
|
828
|
+
- "find_patterns": Discover themes, relationships, and content patterns
|
829
|
+
- "explore_structure": Understand database schema and organization
|
830
|
+
- "assess_quality": Evaluate content quality and completeness
|
831
|
+
- "prepare_search": Get ready for effective content searching
|
832
|
+
focus_area (Optional[str]): Specific table or topic to focus on (default: all)
|
833
|
+
depth (str): How thorough the discovery should be
|
834
|
+
- "quick": Fast overview with key insights
|
835
|
+
- "moderate": Balanced analysis with actionable recommendations
|
836
|
+
- "comprehensive": Deep dive with detailed analysis
|
837
|
+
agent_id (Optional[str]): Agent identifier for learning discovery patterns
|
838
|
+
|
839
|
+
Returns:
|
840
|
+
ToolResponse: On success: {"success": True, "discovery": Dict, "next_steps": List}
|
841
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
842
|
+
|
843
|
+
Examples:
|
844
|
+
>>> intelligent_discovery("understand_content")
|
845
|
+
{"success": True, "discovery": {
|
846
|
+
"overview": {"total_tables": 5, "total_rows": 234},
|
847
|
+
"content_summary": {...},
|
848
|
+
"recommendations": [...]
|
849
|
+
}, "next_steps": ["Use auto_smart_search() for specific queries"]}
|
850
|
+
|
851
|
+
FastMCP Tool Info:
|
852
|
+
- **COMPLETELY AUTOMATED**: No manual tool chaining required
|
853
|
+
- **GOAL-ORIENTED**: Tailored discovery based on your specific objectives
|
854
|
+
- **ACTIONABLE INSIGHTS**: Always includes concrete next steps
|
855
|
+
- **LEARNING**: Improves recommendations based on usage patterns
|
856
|
+
- **PERFECT FOR AGENTS**: Single tool that orchestrates complex discovery workflows
|
857
|
+
"""
|
858
|
+
return intelligent_discovery_impl(discovery_goal, focus_area, depth, agent_id)
|
940
859
|
|
941
860
|
|
942
861
|
@mcp.tool
|
943
862
|
@catch_errors
|
944
|
-
def
|
863
|
+
def discovery_templates(
|
864
|
+
template_type: str = "first_time_exploration",
|
865
|
+
customize_for: Optional[str] = None
|
866
|
+
) -> ToolResponse:
|
945
867
|
"""
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
868
|
+
📋 **DISCOVERY TEMPLATES** - Pre-built exploration workflows for common scenarios!
|
869
|
+
|
870
|
+
Provides step-by-step discovery templates optimized for specific agent use cases.
|
871
|
+
Each template includes the exact sequence of tools to call and what to look for.
|
872
|
+
|
873
|
+
Args:
|
874
|
+
template_type (str): Type of discovery template to provide
|
875
|
+
- "first_time_exploration": Complete workflow for new agents
|
876
|
+
- "content_audit": Systematic content quality review
|
877
|
+
- "search_optimization": Prepare memory bank for optimal searching
|
878
|
+
- "relationship_mapping": Discover connections between data
|
879
|
+
- "problem_solving": Find information to solve specific problems
|
880
|
+
- "knowledge_extraction": Extract insights from stored knowledge
|
881
|
+
customize_for (Optional[str]): Customize template for specific domain/topic
|
882
|
+
|
950
883
|
Returns:
|
951
|
-
ToolResponse: {"success": True, "
|
884
|
+
ToolResponse: {"success": True, "template": Dict, "workflow": List}
|
885
|
+
|
886
|
+
Examples:
|
887
|
+
>>> discovery_templates("first_time_exploration")
|
888
|
+
{"success": True, "template": {
|
889
|
+
"name": "First Time Exploration",
|
890
|
+
"description": "Complete discovery workflow for new agents",
|
891
|
+
"workflow": [
|
892
|
+
{"step": 1, "tool": "intelligent_discovery", "params": {...}},
|
893
|
+
{"step": 2, "tool": "explore_tables", "params": {...}}
|
894
|
+
]
|
895
|
+
}}
|
896
|
+
|
897
|
+
FastMCP Tool Info:
|
898
|
+
- **PROVEN WORKFLOWS**: Battle-tested discovery sequences
|
899
|
+
- **STEP-BY-STEP GUIDANCE**: Exact tools and parameters to use
|
900
|
+
- **CUSTOMIZABLE**: Adapt templates to your specific needs
|
901
|
+
- **LEARNING-OPTIMIZED**: Based on successful discovery patterns
|
952
902
|
"""
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
],
|
958
|
-
"data_operations": [
|
959
|
-
"create_row", "read_rows", "update_rows",
|
960
|
-
"delete_rows", "run_select_query"
|
961
|
-
],
|
962
|
-
"search_discovery": [
|
963
|
-
"search_content", "explore_tables"
|
964
|
-
],
|
965
|
-
"semantic_search": [
|
966
|
-
"add_embeddings", "semantic_search", "find_related",
|
967
|
-
"smart_search", "embedding_stats"
|
968
|
-
],
|
969
|
-
"workflow_shortcuts": [
|
970
|
-
"quick_note", "remember_decision", "store_context"
|
971
|
-
],
|
972
|
-
"analytics_insights": [
|
973
|
-
"memory_usage_stats", "content_analytics"
|
974
|
-
]
|
975
|
-
}
|
976
|
-
|
977
|
-
return cast(ToolResponse, {
|
978
|
-
"success": True,
|
979
|
-
"categories": categories,
|
980
|
-
"total_tools": sum(len(tools) for tools in categories.values()),
|
981
|
-
"description": "Organized view of all available memory bank capabilities"
|
982
|
-
})
|
983
|
-
|
984
|
-
|
985
|
-
@mcp.tool
|
903
|
+
return discovery_templates_impl(template_type, customize_for)
|
904
|
+
|
905
|
+
|
906
|
+
@mcp.tool
|
986
907
|
@catch_errors
|
987
|
-
def
|
908
|
+
def discover_relationships(
|
909
|
+
table_name: Optional[str] = None,
|
910
|
+
relationship_types: List[str] = ["foreign_keys", "semantic_similarity", "temporal_patterns"],
|
911
|
+
similarity_threshold: float = 0.6
|
912
|
+
) -> ToolResponse:
|
988
913
|
"""
|
989
|
-
|
990
|
-
|
914
|
+
🔗 **RELATIONSHIP DISCOVERY** - Find hidden connections in your data!
|
915
|
+
|
916
|
+
Automatically discovers relationships between tables and content areas using
|
917
|
+
both structural analysis and semantic similarity to reveal data connections.
|
918
|
+
|
991
919
|
Args:
|
992
|
-
|
993
|
-
|
994
|
-
|
920
|
+
table_name (Optional[str]): Focus on relationships for specific table (default: all)
|
921
|
+
relationship_types (List[str]): Types of relationships to discover
|
922
|
+
- "foreign_keys": Structural relationships via foreign keys
|
923
|
+
- "semantic_similarity": Content-based relationships via semantic analysis
|
924
|
+
- "temporal_patterns": Time-based relationships and patterns
|
925
|
+
- "naming_patterns": Relationships based on naming conventions
|
926
|
+
similarity_threshold (float): Minimum similarity for semantic relationships (0.0-1.0)
|
927
|
+
|
995
928
|
Returns:
|
996
|
-
ToolResponse: {"success": True, "
|
929
|
+
ToolResponse: {"success": True, "relationships": Dict, "insights": List}
|
930
|
+
|
931
|
+
Examples:
|
932
|
+
>>> discover_relationships("users")
|
933
|
+
{"success": True, "relationships": {
|
934
|
+
"users": {
|
935
|
+
"foreign_key_refs": ["posts.user_id", "comments.user_id"],
|
936
|
+
"semantic_similar": [{"table": "profiles", "similarity": 0.8}],
|
937
|
+
"temporal_related": ["user_sessions"]
|
938
|
+
}
|
939
|
+
}}
|
940
|
+
|
941
|
+
FastMCP Tool Info:
|
942
|
+
- **AUTOMATIC DETECTION**: Finds relationships you might not notice manually
|
943
|
+
- **MULTIPLE METHODS**: Combines structural, semantic, and temporal analysis
|
944
|
+
- **ACTIONABLE INSIGHTS**: Suggests how to leverage discovered relationships
|
945
|
+
- **PERFECT FOR EXPLORATION**: Reveals hidden data organization patterns
|
997
946
|
"""
|
998
|
-
|
999
|
-
"schema_management": [
|
1000
|
-
{"name": "create_table", "description": "Create new tables with custom schemas", "usage": "create_table('table_name', [{'name': 'col', 'type': 'TEXT'}])"},
|
1001
|
-
{"name": "list_tables", "description": "List all available tables", "usage": "list_tables()"},
|
1002
|
-
{"name": "describe_table", "description": "Get detailed schema for a table", "usage": "describe_table('table_name')"},
|
1003
|
-
{"name": "drop_table", "description": "Delete a table permanently", "usage": "drop_table('table_name')"},
|
1004
|
-
{"name": "rename_table", "description": "Rename an existing table", "usage": "rename_table('old_name', 'new_name')"},
|
1005
|
-
{"name": "list_all_columns", "description": "Get all columns across all tables", "usage": "list_all_columns()"},
|
1006
|
-
],
|
1007
|
-
"data_operations": [
|
1008
|
-
{"name": "create_row", "description": "Insert new data into any table", "usage": "create_row('table', {'col': 'value'})"},
|
1009
|
-
{"name": "read_rows", "description": "Query data with optional filtering", "usage": "read_rows('table', {'filter_col': 'value'})"},
|
1010
|
-
{"name": "update_rows", "description": "Modify existing data", "usage": "update_rows('table', {'new_data': 'value'}, {'where_col': 'value'})"},
|
1011
|
-
{"name": "delete_rows", "description": "Remove data from tables", "usage": "delete_rows('table', {'filter_col': 'value'})"},
|
1012
|
-
{"name": "run_select_query", "description": "Execute safe SELECT queries", "usage": "run_select_query('table', ['col1', 'col2'], {'filter': 'value'})"},
|
1013
|
-
],
|
1014
|
-
"search_discovery": [
|
1015
|
-
{"name": "search_content", "description": "Full-text search across all content", "usage": "search_content('search query', ['table1', 'table2'])"},
|
1016
|
-
{"name": "explore_tables", "description": "Discover table structures and sample data", "usage": "explore_tables('pattern*')"},
|
1017
|
-
],
|
1018
|
-
"semantic_search": [
|
1019
|
-
{"name": "add_embeddings", "description": "Enable semantic search on tables", "usage": "add_embeddings('table', ['text_col1', 'text_col2'])"},
|
1020
|
-
{"name": "semantic_search", "description": "Natural language content discovery", "usage": "semantic_search('find ML algorithms')"},
|
1021
|
-
{"name": "find_related", "description": "Discover similar content", "usage": "find_related('table', row_id, 0.5)"},
|
1022
|
-
{"name": "smart_search", "description": "Hybrid keyword + semantic search", "usage": "smart_search('search query')"},
|
1023
|
-
{"name": "embedding_stats", "description": "Check semantic search readiness", "usage": "embedding_stats('table')"},
|
1024
|
-
],
|
1025
|
-
"workflow_shortcuts": [
|
1026
|
-
{"name": "quick_note", "description": "Rapidly store notes and observations", "usage": "quick_note('content', 'category')"},
|
1027
|
-
{"name": "remember_decision", "description": "Store technical decisions with context", "usage": "remember_decision('decision', 'approach', 'rationale')"},
|
1028
|
-
{"name": "store_context", "description": "Save session context and progress", "usage": "store_context('topic', 'current_state', 'next_steps')"},
|
1029
|
-
],
|
1030
|
-
"analytics_insights": [
|
1031
|
-
{"name": "memory_usage_stats", "description": "Analyze memory bank usage patterns", "usage": "memory_usage_stats()"},
|
1032
|
-
{"name": "content_analytics", "description": "Get insights on stored content", "usage": "content_analytics('table_name')"},
|
1033
|
-
],
|
1034
|
-
}
|
1035
|
-
|
1036
|
-
if category not in tool_details:
|
1037
|
-
return cast(ToolResponse, {
|
1038
|
-
"success": False,
|
1039
|
-
"error": f"Unknown category '{category}'. Available: {list(tool_details.keys())}",
|
1040
|
-
"category": "VALIDATION",
|
1041
|
-
"details": {"available_categories": list(tool_details.keys())},
|
1042
|
-
})
|
1043
|
-
|
1044
|
-
return cast(ToolResponse, {
|
1045
|
-
"success": True,
|
1046
|
-
"category": category,
|
1047
|
-
"tools": tool_details[category],
|
1048
|
-
"tool_count": len(tool_details[category]),
|
1049
|
-
})
|
947
|
+
return discover_relationships_impl(table_name, relationship_types, similarity_threshold)
|
1050
948
|
|
1051
949
|
|
1052
950
|
# Export the FastMCP app for use in other modules and server runners
|
@@ -1073,108 +971,19 @@ Available tools:
|
|
1073
971
|
- run_select_query: Run a safe SELECT query (no arbitrary SQL)
|
1074
972
|
- search_content: Perform full-text search across table content
|
1075
973
|
- explore_tables: Discover table structures and content for better searchability
|
974
|
+
- auto_semantic_search: Zero-setup semantic search with automatic embeddings
|
975
|
+
- auto_smart_search: Zero-setup hybrid search combining semantic and keyword search
|
976
|
+
- add_embeddings: Manual embedding generation for advanced users
|
977
|
+
- embedding_stats: Check semantic search readiness
|
1076
978
|
"""
|
1077
979
|
|
1078
980
|
|
1079
|
-
# Legacy implementation functions for backwards compatibility with tests
|
1080
|
-
def _create_row_impl(table_name: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
1081
|
-
"""Legacy implementation function for tests."""
|
1082
|
-
try:
|
1083
|
-
# Handle test-specific table creation for legacy compatibility
|
1084
|
-
if not re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", table_name):
|
1085
|
-
return {"success": False, "error": f"Invalid table name: {table_name}"}
|
1086
|
-
|
1087
|
-
# Auto-create test tables for compatibility
|
1088
|
-
current_db = get_database(DB_PATH)
|
1089
|
-
if table_name == "nodes":
|
1090
|
-
try:
|
1091
|
-
current_db.create_table(
|
1092
|
-
"nodes",
|
1093
|
-
[
|
1094
|
-
{"name": "id", "type": "INTEGER PRIMARY KEY AUTOINCREMENT"},
|
1095
|
-
{"name": "label", "type": "TEXT NOT NULL"},
|
1096
|
-
],
|
1097
|
-
)
|
1098
|
-
except Exception:
|
1099
|
-
pass # Table might already exist
|
1100
|
-
elif table_name == "edges":
|
1101
|
-
try:
|
1102
|
-
current_db.create_table(
|
1103
|
-
"edges",
|
1104
|
-
[
|
1105
|
-
{"name": "id", "type": "INTEGER PRIMARY KEY AUTOINCREMENT"},
|
1106
|
-
{"name": "source", "type": "INTEGER NOT NULL"},
|
1107
|
-
{"name": "target", "type": "INTEGER NOT NULL"},
|
1108
|
-
{"name": "type", "type": "TEXT NOT NULL"},
|
1109
|
-
],
|
1110
|
-
)
|
1111
|
-
except Exception:
|
1112
|
-
pass # Table might already exist
|
1113
|
-
|
1114
|
-
result = current_db.insert_row(table_name, data)
|
1115
|
-
# Ensure we return Dict[str, Any] for legacy compatibility
|
1116
|
-
return dict(result) if isinstance(result, dict) else {"success": False, "error": "Unknown error"}
|
1117
|
-
|
1118
|
-
except Exception as e:
|
1119
|
-
logging.error(f"_create_row_impl error: {e}")
|
1120
|
-
return {"success": False, "error": str(e)}
|
1121
|
-
|
1122
|
-
|
1123
|
-
def _read_rows_impl(table_name: str, where: Optional[Dict[str, Any]] = None, limit: int = 100) -> Dict[str, Any]:
|
1124
|
-
"""Legacy implementation function for tests."""
|
1125
|
-
try:
|
1126
|
-
result = get_database(DB_PATH).read_rows(table_name, where, limit)
|
1127
|
-
# Ensure we return Dict[str, Any] for legacy compatibility
|
1128
|
-
return dict(result) if isinstance(result, dict) else {"success": False, "error": "Unknown error"}
|
1129
|
-
except Exception as e:
|
1130
|
-
logging.error(f"_read_rows_impl error: {e}")
|
1131
|
-
return {"success": False, "error": str(e)}
|
1132
|
-
|
1133
|
-
|
1134
|
-
def _update_rows_impl(table_name: str, data: Dict[str, Any], where: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
1135
|
-
"""Legacy implementation function for tests."""
|
1136
|
-
try:
|
1137
|
-
# Auto-create test tables for compatibility
|
1138
|
-
if table_name == "edges":
|
1139
|
-
try:
|
1140
|
-
current_db = get_database(DB_PATH)
|
1141
|
-
current_db.create_table(
|
1142
|
-
"edges",
|
1143
|
-
[
|
1144
|
-
{"name": "id", "type": "INTEGER PRIMARY KEY AUTOINCREMENT"},
|
1145
|
-
{"name": "source", "type": "INTEGER NOT NULL"},
|
1146
|
-
{"name": "target", "type": "INTEGER NOT NULL"},
|
1147
|
-
{"name": "type", "type": "TEXT NOT NULL"},
|
1148
|
-
],
|
1149
|
-
)
|
1150
|
-
except Exception:
|
1151
|
-
pass # Table might already exist
|
1152
|
-
|
1153
|
-
result = get_database(DB_PATH).update_rows(table_name, data, where)
|
1154
|
-
# Ensure we return Dict[str, Any] for legacy compatibility
|
1155
|
-
return dict(result) if isinstance(result, dict) else {"success": False, "error": "Unknown error"}
|
1156
|
-
except Exception as e:
|
1157
|
-
logging.error(f"_update_rows_impl error: {e}")
|
1158
|
-
return {"success": False, "error": str(e)}
|
1159
|
-
|
1160
|
-
|
1161
|
-
def _delete_rows_impl(table_name: str, where: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
1162
|
-
"""Legacy implementation function for tests."""
|
1163
|
-
try:
|
1164
|
-
result = get_database(DB_PATH).delete_rows(table_name, where)
|
1165
|
-
# Ensure we return Dict[str, Any] for legacy compatibility
|
1166
|
-
return dict(result) if isinstance(result, dict) else {"success": False, "error": "Unknown error"}
|
1167
|
-
except Exception as e:
|
1168
|
-
logging.error(f"_delete_rows_impl error: {e}")
|
1169
|
-
return {"success": False, "error": str(e)}
|
1170
|
-
|
1171
|
-
|
1172
981
|
# Public API - these functions are available for direct Python use and as MCP tools
|
1173
982
|
__all__ = [
|
1174
983
|
"app",
|
1175
984
|
"mcp",
|
1176
985
|
"create_table",
|
1177
|
-
"drop_table",
|
986
|
+
"drop_table",
|
1178
987
|
"rename_table",
|
1179
988
|
"list_tables",
|
1180
989
|
"describe_table",
|
@@ -1186,10 +995,13 @@ __all__ = [
|
|
1186
995
|
"run_select_query",
|
1187
996
|
"search_content",
|
1188
997
|
"explore_tables",
|
1189
|
-
"
|
1190
|
-
"
|
1191
|
-
"
|
1192
|
-
"
|
998
|
+
"add_embeddings",
|
999
|
+
"auto_semantic_search",
|
1000
|
+
"auto_smart_search",
|
1001
|
+
"embedding_stats",
|
1002
|
+
"intelligent_discovery",
|
1003
|
+
"discovery_templates",
|
1004
|
+
"discover_relationships",
|
1193
1005
|
]
|
1194
1006
|
|
1195
1007
|
|
@@ -1239,4 +1051,37 @@ if __name__ == "__main__":
|
|
1239
1051
|
logging.info(f"Starting SQLite Memory Bank with database at {DB_PATH}")
|
1240
1052
|
|
1241
1053
|
# Run the FastMCP app in stdio mode for MCP clients
|
1242
|
-
app.run()
|
1054
|
+
app.run(transport="stdio")
|
1055
|
+
|
1056
|
+
|
1057
|
+
# Compatibility aliases for tests that expect _impl functions
|
1058
|
+
# Import modules already imported above for tool implementations
|
1059
|
+
|
1060
|
+
# Basic CRUD operation aliases
|
1061
|
+
_create_row_impl = basic.create_row
|
1062
|
+
_read_rows_impl = basic.read_rows
|
1063
|
+
_update_rows_impl = basic.update_rows
|
1064
|
+
_delete_rows_impl = basic.delete_rows
|
1065
|
+
_list_tables_impl = basic.list_tables
|
1066
|
+
_describe_table_impl = basic.describe_table
|
1067
|
+
_drop_table_impl = basic.drop_table
|
1068
|
+
_create_table_impl = basic.create_table
|
1069
|
+
|
1070
|
+
# Search operation aliases
|
1071
|
+
_search_content_impl = search.search_content
|
1072
|
+
_explore_tables_impl = search.explore_tables
|
1073
|
+
_add_embeddings_impl = search.add_embeddings
|
1074
|
+
_semantic_search_impl = search.semantic_search
|
1075
|
+
_smart_search_impl = search.smart_search
|
1076
|
+
_find_related_impl = search.find_related
|
1077
|
+
_auto_semantic_search_impl = search.auto_semantic_search
|
1078
|
+
_auto_smart_search_impl = search.auto_smart_search
|
1079
|
+
|
1080
|
+
# Analytics operation aliases
|
1081
|
+
_analyze_memory_patterns_impl = analytics.analyze_memory_patterns
|
1082
|
+
_get_content_health_score_impl = analytics.get_content_health_score
|
1083
|
+
|
1084
|
+
# Discovery operation aliases
|
1085
|
+
_intelligent_discovery_impl = intelligent_discovery_impl
|
1086
|
+
_discovery_templates_impl = discovery_templates_impl
|
1087
|
+
_discover_relationships_impl = discover_relationships_impl
|