mcp-sqlite-memory-bank 1.4.3__py3-none-any.whl → 1.5.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 +20 -3
- 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 +193 -504
- mcp_sqlite_memory_bank/tools/__init__.py +68 -0
- mcp_sqlite_memory_bank/tools/analytics.py +419 -0
- mcp_sqlite_memory_bank/tools/basic.py +112 -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.0.dist-info}/METADATA +1 -1
- mcp_sqlite_memory_bank-1.5.0.dist-info/RECORD +19 -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.0.dist-info}/WHEEL +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.0.dist-info}/entry_points.txt +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_sqlite_memory_bank-1.4.3.dist-info → mcp_sqlite_memory_bank-1.5.0.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,25 @@ 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
|
+
)
|
396
411
|
|
412
|
+
# --- MCP Tool Definitions (Required in main server.py for FastMCP) ---
|
397
413
|
|
398
414
|
@mcp.tool
|
399
415
|
@catch_errors
|
400
|
-
def search_content(
|
416
|
+
def search_content(
|
417
|
+
query: str,
|
418
|
+
tables: Optional[List[str]] = None,
|
419
|
+
limit: int = 50,
|
420
|
+
) -> ToolResponse:
|
401
421
|
"""
|
402
422
|
Perform full-text search across table content using natural language queries.
|
403
423
|
|
@@ -424,12 +444,15 @@ def search_content(query: str, tables: Optional[List[str]] = None, limit: int =
|
|
424
444
|
- Supports phrase search with quotes: "exact phrase"
|
425
445
|
- Supports boolean operators: AND, OR, NOT
|
426
446
|
"""
|
427
|
-
return
|
447
|
+
return search_content_impl(query, tables, limit)
|
428
448
|
|
429
449
|
|
430
450
|
@mcp.tool
|
431
|
-
@catch_errors
|
432
|
-
def explore_tables(
|
451
|
+
@catch_errors
|
452
|
+
def explore_tables(
|
453
|
+
pattern: Optional[str] = None,
|
454
|
+
include_row_counts: bool = True,
|
455
|
+
) -> ToolResponse:
|
433
456
|
"""
|
434
457
|
Explore and discover table structures and content for better searchability.
|
435
458
|
|
@@ -458,22 +481,22 @@ def explore_tables(pattern: Optional[str] = None, include_row_counts: bool = Tru
|
|
458
481
|
- Helps understand what data is available for searching
|
459
482
|
- Useful for exploratory data analysis
|
460
483
|
"""
|
461
|
-
return
|
462
|
-
|
463
|
-
|
464
|
-
# --- Semantic Search and AI-Enhanced Discovery Tools ---
|
484
|
+
return explore_tables_impl(pattern, include_row_counts)
|
465
485
|
|
466
486
|
|
467
487
|
@mcp.tool
|
468
488
|
@catch_errors
|
469
489
|
def add_embeddings(
|
470
|
-
table_name: str,
|
490
|
+
table_name: str,
|
491
|
+
text_columns: List[str],
|
492
|
+
embedding_column: str = "embedding",
|
493
|
+
model_name: str = "all-MiniLM-L6-v2",
|
471
494
|
) -> ToolResponse:
|
472
495
|
"""
|
473
496
|
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
474
|
-
|
497
|
+
|
475
498
|
Generate and store vector embeddings for semantic search on table content.
|
476
|
-
|
499
|
+
|
477
500
|
**RECOMMENDATION**: Use auto_smart_search() or auto_semantic_search() for automatic setup.
|
478
501
|
This tool is for advanced users who need manual control over embedding generation.
|
479
502
|
|
@@ -501,14 +524,12 @@ def add_embeddings(
|
|
501
524
|
- Uses efficient batch processing for large datasets
|
502
525
|
- Supports various sentence-transformer models for different use cases
|
503
526
|
"""
|
504
|
-
return
|
505
|
-
ToolResponse, get_database(DB_PATH).generate_embeddings(table_name, text_columns, embedding_column, model_name)
|
506
|
-
)
|
527
|
+
return add_embeddings_impl(table_name, text_columns, embedding_column, model_name)
|
507
528
|
|
508
529
|
|
509
530
|
@mcp.tool
|
510
531
|
@catch_errors
|
511
|
-
def
|
532
|
+
def auto_semantic_search(
|
512
533
|
query: str,
|
513
534
|
tables: Optional[List[str]] = None,
|
514
535
|
similarity_threshold: float = 0.5,
|
@@ -516,102 +537,48 @@ def semantic_search(
|
|
516
537
|
model_name: str = "all-MiniLM-L6-v2",
|
517
538
|
) -> ToolResponse:
|
518
539
|
"""
|
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.
|
540
|
+
🚀 **ZERO-SETUP SEMANTIC SEARCH** - Just search, embeddings are handled automatically!
|
525
541
|
|
526
|
-
|
527
|
-
they
|
542
|
+
Find content using natural language semantic similarity. If embeddings don't exist,
|
543
|
+
they will be automatically generated for text columns. This is the easiest way to
|
544
|
+
do semantic search - no manual setup required!
|
528
545
|
|
529
546
|
Args:
|
530
547
|
query (str): Natural language search query
|
531
|
-
tables (Optional[List[str]]): Specific tables to search (default: all tables
|
548
|
+
tables (Optional[List[str]]): Specific tables to search (default: all tables)
|
532
549
|
similarity_threshold (float): Minimum similarity score (0.0-1.0, default: 0.5)
|
533
550
|
limit (int): Maximum number of results to return (default: 10)
|
534
|
-
model_name (str): Model to use for
|
551
|
+
model_name (str): Model to use for embeddings (default: "all-MiniLM-L6-v2")
|
535
552
|
|
536
553
|
Returns:
|
537
|
-
ToolResponse: On success: {"success": True, "results": List[...], "
|
554
|
+
ToolResponse: On success: {"success": True, "results": List[...], "auto_embedded_tables": List[str]}
|
538
555
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
539
556
|
|
540
557
|
Examples:
|
541
|
-
>>>
|
558
|
+
>>> auto_semantic_search("API design patterns")
|
542
559
|
{"success": True, "results": [
|
543
|
-
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
544
|
-
|
545
|
-
]}
|
560
|
+
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
561
|
+
], "auto_embedded_tables": ["technical_decisions"]}
|
546
562
|
|
547
|
-
>>>
|
563
|
+
>>> auto_semantic_search("machine learning concepts")
|
548
564
|
# Finds content about "ML", "AI", "neural networks", etc.
|
565
|
+
# Automatically creates embeddings if they don't exist!
|
549
566
|
|
550
567
|
FastMCP Tool Info:
|
568
|
+
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
569
|
+
- Auto-detects text columns and creates embeddings as needed
|
551
570
|
- Works across multiple tables simultaneously
|
552
571
|
- Finds conceptually similar content regardless of exact wording
|
553
572
|
- Returns relevance scores for ranking results
|
554
573
|
- 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
|
574
|
+
- Perfect for agents - just search and it works!
|
603
575
|
"""
|
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
|
-
)
|
576
|
+
return auto_semantic_search_impl(query, tables, similarity_threshold, limit, model_name)
|
610
577
|
|
611
578
|
|
612
579
|
@mcp.tool
|
613
580
|
@catch_errors
|
614
|
-
def
|
581
|
+
def auto_smart_search(
|
615
582
|
query: str,
|
616
583
|
tables: Optional[List[str]] = None,
|
617
584
|
semantic_weight: float = 0.7,
|
@@ -620,15 +587,11 @@ def smart_search(
|
|
620
587
|
model_name: str = "all-MiniLM-L6-v2",
|
621
588
|
) -> ToolResponse:
|
622
589
|
"""
|
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.
|
590
|
+
🚀 **ZERO-SETUP HYBRID SEARCH** - Best of both worlds with automatic embedding!
|
629
591
|
|
630
|
-
|
631
|
-
|
592
|
+
Intelligent hybrid search combining semantic understanding with keyword matching.
|
593
|
+
Automatically generates embeddings for text columns when needed. This is the
|
594
|
+
ultimate search tool - no manual setup required!
|
632
595
|
|
633
596
|
Args:
|
634
597
|
query (str): Search query (natural language or keywords)
|
@@ -639,37 +602,63 @@ def smart_search(
|
|
639
602
|
model_name (str): Semantic model to use (default: "all-MiniLM-L6-v2")
|
640
603
|
|
641
604
|
Returns:
|
642
|
-
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "
|
605
|
+
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "auto_hybrid"}
|
643
606
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
644
607
|
|
645
608
|
Examples:
|
646
|
-
>>>
|
609
|
+
>>> auto_smart_search("user authentication security")
|
647
610
|
{"success": True, "results": [
|
648
|
-
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
649
|
-
|
650
|
-
], "search_type": "hybrid"}
|
611
|
+
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
612
|
+
], "search_type": "auto_hybrid", "auto_embedded_tables": ["user_data"]}
|
651
613
|
|
652
614
|
FastMCP Tool Info:
|
615
|
+
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
653
616
|
- Automatically balances semantic and keyword search
|
617
|
+
- Auto-detects text columns and creates embeddings as needed
|
654
618
|
- Provides separate scores for transparency
|
655
619
|
- Falls back gracefully if semantic search unavailable
|
656
620
|
- Optimal for both exploratory and precise searches
|
657
621
|
- Perfect for agents - ultimate search tool that just works!
|
658
622
|
"""
|
659
|
-
return
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
623
|
+
return auto_smart_search_impl(query, tables, semantic_weight, text_weight, limit, model_name)
|
624
|
+
|
625
|
+
|
626
|
+
@mcp.tool
|
627
|
+
@catch_errors
|
628
|
+
def embedding_stats(
|
629
|
+
table_name: str,
|
630
|
+
embedding_column: str = "embedding",
|
631
|
+
) -> ToolResponse:
|
632
|
+
"""
|
633
|
+
Get statistics about semantic search readiness for a table.
|
634
|
+
|
635
|
+
Check which content has embeddings and can be searched semantically.
|
636
|
+
|
637
|
+
Args:
|
638
|
+
table_name (str): Table to analyze
|
639
|
+
embedding_column (str): Embedding column to check (default: "embedding")
|
640
|
+
|
641
|
+
Returns:
|
642
|
+
ToolResponse: On success: {"success": True, "coverage_percent": float, "total_rows": int}
|
643
|
+
On error: {"success": False, "error": str, "category": str, "details": dict}
|
665
644
|
|
645
|
+
Examples:
|
646
|
+
>>> embedding_stats("technical_decisions")
|
647
|
+
{"success": True, "total_rows": 25, "embedded_rows": 25, "coverage_percent": 100.0,
|
648
|
+
"embedding_dimensions": 384}
|
666
649
|
|
667
|
-
|
650
|
+
FastMCP Tool Info:
|
651
|
+
- Shows how much content is ready for semantic search
|
652
|
+
- Helps identify tables that need embedding generation
|
653
|
+
- Provides embedding dimension info for debugging
|
654
|
+
- Useful for monitoring semantic search capabilities
|
655
|
+
"""
|
656
|
+
return embedding_stats_impl(table_name, embedding_column)
|
668
657
|
|
669
658
|
|
670
659
|
@mcp.tool
|
671
660
|
@catch_errors
|
672
|
-
def
|
661
|
+
def semantic_search(
|
673
662
|
query: str,
|
674
663
|
tables: Optional[List[str]] = None,
|
675
664
|
similarity_threshold: float = 0.5,
|
@@ -677,117 +666,50 @@ def auto_semantic_search(
|
|
677
666
|
model_name: str = "all-MiniLM-L6-v2",
|
678
667
|
) -> ToolResponse:
|
679
668
|
"""
|
680
|
-
|
669
|
+
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
681
670
|
|
682
|
-
Find content using natural language semantic similarity
|
683
|
-
|
684
|
-
|
671
|
+
Find content using natural language semantic similarity rather than exact keyword matching.
|
672
|
+
|
673
|
+
**RECOMMENDATION**: Use auto_smart_search() for the same functionality with automatic setup.
|
674
|
+
This tool requires manual embedding setup via add_embeddings() first.
|
675
|
+
|
676
|
+
This enables intelligent knowledge discovery - find related concepts even when
|
677
|
+
they use different terminology or phrasing.
|
685
678
|
|
686
679
|
Args:
|
687
680
|
query (str): Natural language search query
|
688
|
-
tables (Optional[List[str]]): Specific tables to search (default: all tables)
|
681
|
+
tables (Optional[List[str]]): Specific tables to search (default: all tables with embeddings)
|
689
682
|
similarity_threshold (float): Minimum similarity score (0.0-1.0, default: 0.5)
|
690
683
|
limit (int): Maximum number of results to return (default: 10)
|
691
|
-
model_name (str): Model to use for
|
684
|
+
model_name (str): Model to use for query embedding (default: "all-MiniLM-L6-v2")
|
692
685
|
|
693
686
|
Returns:
|
694
|
-
ToolResponse: On success: {"success": True, "results": List[...], "
|
687
|
+
ToolResponse: On success: {"success": True, "results": List[...], "total_results": int}
|
695
688
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
696
689
|
|
697
690
|
Examples:
|
698
|
-
>>>
|
691
|
+
>>> semantic_search("API design patterns")
|
699
692
|
{"success": True, "results": [
|
700
|
-
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...}
|
701
|
-
|
693
|
+
{"table_name": "technical_decisions", "similarity_score": 0.87, "decision_name": "REST API Structure", ...},
|
694
|
+
{"table_name": "project_structure", "similarity_score": 0.72, "component": "API Gateway", ...}
|
695
|
+
]}
|
702
696
|
|
703
|
-
>>>
|
697
|
+
>>> semantic_search("machine learning", tables=["technical_decisions"], similarity_threshold=0.7)
|
704
698
|
# Finds content about "ML", "AI", "neural networks", etc.
|
705
|
-
# Automatically creates embeddings if they don't exist!
|
706
699
|
|
707
700
|
FastMCP Tool Info:
|
708
|
-
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
709
|
-
- Auto-detects text columns and creates embeddings as needed
|
710
701
|
- Works across multiple tables simultaneously
|
711
702
|
- Finds conceptually similar content regardless of exact wording
|
712
703
|
- Returns relevance scores for ranking results
|
713
704
|
- Supports fuzzy matching and concept discovery
|
714
|
-
-
|
705
|
+
- Much more powerful than keyword-based search for knowledge discovery
|
715
706
|
"""
|
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
|
-
})
|
707
|
+
return _semantic_search_impl(query, tables, similarity_threshold, limit, model_name)
|
786
708
|
|
787
709
|
|
788
710
|
@mcp.tool
|
789
711
|
@catch_errors
|
790
|
-
def
|
712
|
+
def smart_search(
|
791
713
|
query: str,
|
792
714
|
tables: Optional[List[str]] = None,
|
793
715
|
semantic_weight: float = 0.7,
|
@@ -796,11 +718,15 @@ def auto_smart_search(
|
|
796
718
|
model_name: str = "all-MiniLM-L6-v2",
|
797
719
|
) -> ToolResponse:
|
798
720
|
"""
|
799
|
-
|
721
|
+
⚠️ **ADVANCED TOOL** - Most agents should use auto_smart_search() instead!
|
800
722
|
|
801
723
|
Intelligent hybrid search combining semantic understanding with keyword matching.
|
802
|
-
|
803
|
-
|
724
|
+
|
725
|
+
**RECOMMENDATION**: Use auto_smart_search() for the same functionality with automatic setup.
|
726
|
+
This tool requires manual embedding setup via add_embeddings() first.
|
727
|
+
|
728
|
+
Provides the best of both worlds - semantic similarity for concept discovery
|
729
|
+
plus exact text matching for precise searches.
|
804
730
|
|
805
731
|
Args:
|
806
732
|
query (str): Search query (natural language or keywords)
|
@@ -811,242 +737,66 @@ def auto_smart_search(
|
|
811
737
|
model_name (str): Semantic model to use (default: "all-MiniLM-L6-v2")
|
812
738
|
|
813
739
|
Returns:
|
814
|
-
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "
|
740
|
+
ToolResponse: On success: {"success": True, "results": List[...], "search_type": "hybrid"}
|
815
741
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
816
742
|
|
817
743
|
Examples:
|
818
|
-
>>>
|
744
|
+
>>> smart_search("user authentication security")
|
819
745
|
{"success": True, "results": [
|
820
|
-
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...}
|
821
|
-
|
746
|
+
{"combined_score": 0.89, "semantic_score": 0.92, "text_score": 0.82, ...},
|
747
|
+
{"combined_score": 0.76, "semantic_score": 0.71, "text_score": 0.85, ...}
|
748
|
+
], "search_type": "hybrid"}
|
822
749
|
|
823
750
|
FastMCP Tool Info:
|
824
|
-
- **COMPLETELY AUTOMATIC**: No manual embedding setup required
|
825
751
|
- Automatically balances semantic and keyword search
|
826
|
-
- Auto-detects text columns and creates embeddings as needed
|
827
752
|
- Provides separate scores for transparency
|
828
753
|
- Falls back gracefully if semantic search unavailable
|
829
754
|
- Optimal for both exploratory and precise searches
|
830
755
|
- Perfect for agents - ultimate search tool that just works!
|
831
756
|
"""
|
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
|
-
})
|
757
|
+
return _smart_search_impl(query, tables, semantic_weight, text_weight, limit, model_name)
|
907
758
|
|
908
759
|
|
909
760
|
@mcp.tool
|
910
|
-
@catch_errors
|
911
|
-
def
|
761
|
+
@catch_errors
|
762
|
+
def find_related(
|
763
|
+
table_name: str,
|
764
|
+
row_id: int,
|
765
|
+
similarity_threshold: float = 0.5,
|
766
|
+
limit: int = 5,
|
767
|
+
model_name: str = "all-MiniLM-L6-v2",
|
768
|
+
) -> ToolResponse:
|
912
769
|
"""
|
913
|
-
|
770
|
+
Find content related to a specific row by semantic similarity.
|
914
771
|
|
915
|
-
|
772
|
+
Discover connections and related information that might not be obvious
|
773
|
+
from direct references or tags.
|
916
774
|
|
917
775
|
Args:
|
918
|
-
table_name (str): Table
|
919
|
-
|
776
|
+
table_name (str): Table containing the reference row
|
777
|
+
row_id (int): ID of the row to find related content for
|
778
|
+
similarity_threshold (float): Minimum similarity score (default: 0.5)
|
779
|
+
limit (int): Maximum number of related items to return (default: 5)
|
780
|
+
model_name (str): Model for similarity comparison (default: "all-MiniLM-L6-v2")
|
920
781
|
|
921
782
|
Returns:
|
922
|
-
ToolResponse: On success: {"success": True, "
|
783
|
+
ToolResponse: On success: {"success": True, "results": List[...], "target_row": Dict}
|
923
784
|
On error: {"success": False, "error": str, "category": str, "details": dict}
|
924
785
|
|
925
786
|
Examples:
|
926
|
-
>>>
|
927
|
-
{"success": True, "
|
928
|
-
|
787
|
+
>>> find_related("technical_decisions", 5)
|
788
|
+
{"success": True, "results": [
|
789
|
+
{"id": 12, "similarity_score": 0.84, "decision_name": "Related Architecture Choice", ...},
|
790
|
+
{"id": 3, "similarity_score": 0.71, "decision_name": "Similar Technology Decision", ...}
|
791
|
+
], "target_row": {"id": 5, "decision_name": "API Framework Selection", ...}}
|
929
792
|
|
930
793
|
FastMCP Tool Info:
|
931
|
-
-
|
932
|
-
-
|
933
|
-
-
|
934
|
-
-
|
935
|
-
"""
|
936
|
-
return cast(ToolResponse, get_database(DB_PATH).get_embedding_stats(table_name, embedding_column))
|
937
|
-
|
938
|
-
|
939
|
-
# --- Enhanced Tool Discovery and Categorization ---
|
940
|
-
|
941
|
-
|
942
|
-
@mcp.tool
|
943
|
-
@catch_errors
|
944
|
-
def list_tool_categories() -> ToolResponse:
|
945
|
-
"""
|
946
|
-
List all available tool categories for better organization and discovery.
|
947
|
-
|
948
|
-
Returns organized view of available functionality for LLMs and agents.
|
949
|
-
|
950
|
-
Returns:
|
951
|
-
ToolResponse: {"success": True, "categories": {category: [tool_names]}}
|
952
|
-
"""
|
953
|
-
categories = {
|
954
|
-
"schema_management": [
|
955
|
-
"create_table", "list_tables", "describe_table",
|
956
|
-
"drop_table", "rename_table", "list_all_columns"
|
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
|
986
|
-
@catch_errors
|
987
|
-
def get_tools_by_category(category: str) -> ToolResponse:
|
988
|
-
"""
|
989
|
-
Get detailed information about tools in a specific category.
|
990
|
-
|
991
|
-
Args:
|
992
|
-
category (str): Category name (schema_management, data_operations,
|
993
|
-
search_discovery, semantic_search, workflow_shortcuts, analytics_insights)
|
994
|
-
|
995
|
-
Returns:
|
996
|
-
ToolResponse: {"success": True, "tools": [{"name": str, "description": str, "usage": str}]}
|
794
|
+
- Helps discover hidden relationships between data
|
795
|
+
- Useful for finding similar decisions, related problems, or connected concepts
|
796
|
+
- Can reveal patterns and themes across your knowledge base
|
797
|
+
- Enables serendipitous discovery of relevant information
|
997
798
|
"""
|
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
|
-
})
|
799
|
+
return _find_related_impl(table_name, row_id, similarity_threshold, limit, model_name)
|
1050
800
|
|
1051
801
|
|
1052
802
|
# Export the FastMCP app for use in other modules and server runners
|
@@ -1073,108 +823,19 @@ Available tools:
|
|
1073
823
|
- run_select_query: Run a safe SELECT query (no arbitrary SQL)
|
1074
824
|
- search_content: Perform full-text search across table content
|
1075
825
|
- explore_tables: Discover table structures and content for better searchability
|
826
|
+
- auto_semantic_search: Zero-setup semantic search with automatic embeddings
|
827
|
+
- auto_smart_search: Zero-setup hybrid search combining semantic and keyword search
|
828
|
+
- add_embeddings: Manual embedding generation for advanced users
|
829
|
+
- embedding_stats: Check semantic search readiness
|
1076
830
|
"""
|
1077
831
|
|
1078
832
|
|
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
833
|
# Public API - these functions are available for direct Python use and as MCP tools
|
1173
834
|
__all__ = [
|
1174
835
|
"app",
|
1175
836
|
"mcp",
|
1176
837
|
"create_table",
|
1177
|
-
"drop_table",
|
838
|
+
"drop_table",
|
1178
839
|
"rename_table",
|
1179
840
|
"list_tables",
|
1180
841
|
"describe_table",
|
@@ -1186,10 +847,10 @@ __all__ = [
|
|
1186
847
|
"run_select_query",
|
1187
848
|
"search_content",
|
1188
849
|
"explore_tables",
|
1189
|
-
"
|
1190
|
-
"
|
1191
|
-
"
|
1192
|
-
"
|
850
|
+
"add_embeddings",
|
851
|
+
"auto_semantic_search",
|
852
|
+
"auto_smart_search",
|
853
|
+
"embedding_stats",
|
1193
854
|
]
|
1194
855
|
|
1195
856
|
|
@@ -1240,3 +901,31 @@ if __name__ == "__main__":
|
|
1240
901
|
|
1241
902
|
# Run the FastMCP app in stdio mode for MCP clients
|
1242
903
|
app.run()
|
904
|
+
|
905
|
+
|
906
|
+
# Compatibility aliases for tests that expect _impl functions
|
907
|
+
# Import modules already imported above for tool implementations
|
908
|
+
|
909
|
+
# Basic CRUD operation aliases
|
910
|
+
_create_row_impl = basic.create_row
|
911
|
+
_read_rows_impl = basic.read_rows
|
912
|
+
_update_rows_impl = basic.update_rows
|
913
|
+
_delete_rows_impl = basic.delete_rows
|
914
|
+
_list_tables_impl = basic.list_tables
|
915
|
+
_describe_table_impl = basic.describe_table
|
916
|
+
_drop_table_impl = basic.drop_table
|
917
|
+
_create_table_impl = basic.create_table
|
918
|
+
|
919
|
+
# Search operation aliases
|
920
|
+
_search_content_impl = search.search_content
|
921
|
+
_explore_tables_impl = search.explore_tables
|
922
|
+
_add_embeddings_impl = search.add_embeddings
|
923
|
+
_semantic_search_impl = search.semantic_search
|
924
|
+
_smart_search_impl = search.smart_search
|
925
|
+
_find_related_impl = search.find_related
|
926
|
+
_auto_semantic_search_impl = search.auto_semantic_search
|
927
|
+
_auto_smart_search_impl = search.auto_smart_search
|
928
|
+
|
929
|
+
# Analytics operation aliases
|
930
|
+
_analyze_memory_patterns_impl = analytics.analyze_memory_patterns
|
931
|
+
_get_content_health_score_impl = analytics.get_content_health_score
|