mcp-vector-search 0.4.12__py3-none-any.whl → 0.4.14__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.
Potentially problematic release.
This version of mcp-vector-search might be problematic. Click here for more details.
- mcp_vector_search/__init__.py +2 -2
- mcp_vector_search/cli/commands/reset.py +393 -0
- mcp_vector_search/cli/didyoumean.py +374 -75
- mcp_vector_search/cli/main.py +158 -9
- mcp_vector_search/cli/suggestions.py +325 -0
- mcp_vector_search/core/database.py +213 -6
- mcp_vector_search/core/exceptions.py +6 -0
- mcp_vector_search/core/search.py +24 -2
- mcp_vector_search/mcp/server.py +36 -12
- {mcp_vector_search-0.4.12.dist-info → mcp_vector_search-0.4.14.dist-info}/METADATA +1 -1
- {mcp_vector_search-0.4.12.dist-info → mcp_vector_search-0.4.14.dist-info}/RECORD +14 -12
- mcp_vector_search-0.4.14.dist-info/entry_points.txt +2 -0
- mcp_vector_search-0.4.12.dist-info/entry_points.txt +0 -2
- {mcp_vector_search-0.4.12.dist-info → mcp_vector_search-0.4.14.dist-info}/WHEEL +0 -0
- {mcp_vector_search-0.4.12.dist-info → mcp_vector_search-0.4.14.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Database abstraction and ChromaDB implementation for MCP Vector Search."""
|
|
2
2
|
|
|
3
|
+
import shutil
|
|
3
4
|
from abc import ABC, abstractmethod
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Any, Protocol, runtime_checkable
|
|
@@ -12,6 +13,7 @@ from .exceptions import (
|
|
|
12
13
|
DatabaseInitializationError,
|
|
13
14
|
DatabaseNotInitializedError,
|
|
14
15
|
DocumentAdditionError,
|
|
16
|
+
IndexCorruptionError,
|
|
15
17
|
SearchError,
|
|
16
18
|
)
|
|
17
19
|
from .models import CodeChunk, IndexStats, SearchResult
|
|
@@ -95,6 +97,15 @@ class VectorDatabase(ABC):
|
|
|
95
97
|
"""Reset the database (delete all data)."""
|
|
96
98
|
...
|
|
97
99
|
|
|
100
|
+
@abstractmethod
|
|
101
|
+
async def health_check(self) -> bool:
|
|
102
|
+
"""Check database health and integrity.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
True if database is healthy, False otherwise
|
|
106
|
+
"""
|
|
107
|
+
...
|
|
108
|
+
|
|
98
109
|
async def __aenter__(self) -> "VectorDatabase":
|
|
99
110
|
"""Async context manager entry."""
|
|
100
111
|
await self.initialize()
|
|
@@ -128,12 +139,15 @@ class ChromaVectorDatabase(VectorDatabase):
|
|
|
128
139
|
self._collection = None
|
|
129
140
|
|
|
130
141
|
async def initialize(self) -> None:
|
|
131
|
-
"""Initialize ChromaDB client and collection."""
|
|
142
|
+
"""Initialize ChromaDB client and collection with corruption recovery."""
|
|
132
143
|
try:
|
|
133
144
|
import chromadb
|
|
134
145
|
|
|
135
146
|
# Ensure directory exists
|
|
136
147
|
self.persist_directory.mkdir(parents=True, exist_ok=True)
|
|
148
|
+
|
|
149
|
+
# Check for corruption before initializing
|
|
150
|
+
await self._detect_and_recover_corruption()
|
|
137
151
|
|
|
138
152
|
# Create client with new API
|
|
139
153
|
self._client = chromadb.PersistentClient(
|
|
@@ -156,10 +170,22 @@ class ChromaVectorDatabase(VectorDatabase):
|
|
|
156
170
|
logger.debug(f"ChromaDB initialized at {self.persist_directory}")
|
|
157
171
|
|
|
158
172
|
except Exception as e:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
# Check if this is a corruption error
|
|
174
|
+
error_msg = str(e).lower()
|
|
175
|
+
if any(indicator in error_msg for indicator in [
|
|
176
|
+
"pickle", "unpickling", "eof", "ran out of input",
|
|
177
|
+
"hnsw", "index", "deserialize", "corrupt"
|
|
178
|
+
]):
|
|
179
|
+
logger.warning(f"Detected index corruption: {e}")
|
|
180
|
+
# Try to recover
|
|
181
|
+
await self._recover_from_corruption()
|
|
182
|
+
# Retry initialization
|
|
183
|
+
await self.initialize()
|
|
184
|
+
else:
|
|
185
|
+
logger.error(f"Failed to initialize ChromaDB: {e}")
|
|
186
|
+
raise DatabaseInitializationError(
|
|
187
|
+
f"ChromaDB initialization failed: {e}"
|
|
188
|
+
) from e
|
|
163
189
|
|
|
164
190
|
async def remove_file_chunks(self, file_path: str) -> int:
|
|
165
191
|
"""Remove all chunks for a specific file.
|
|
@@ -438,6 +464,114 @@ class ChromaVectorDatabase(VectorDatabase):
|
|
|
438
464
|
|
|
439
465
|
return where
|
|
440
466
|
|
|
467
|
+
async def _detect_and_recover_corruption(self) -> None:
|
|
468
|
+
"""Detect and recover from index corruption proactively."""
|
|
469
|
+
# Check for common corruption indicators in ChromaDB files
|
|
470
|
+
chroma_db_path = self.persist_directory / "chroma.sqlite3"
|
|
471
|
+
|
|
472
|
+
# If database doesn't exist yet, nothing to check
|
|
473
|
+
if not chroma_db_path.exists():
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
# Check for HNSW index files that might be corrupted
|
|
477
|
+
collection_path = self.persist_directory / "chroma-collections.parquet"
|
|
478
|
+
index_path = self.persist_directory / "index"
|
|
479
|
+
|
|
480
|
+
if index_path.exists():
|
|
481
|
+
# Look for pickle files in the index
|
|
482
|
+
pickle_files = list(index_path.glob("**/*.pkl"))
|
|
483
|
+
pickle_files.extend(list(index_path.glob("**/*.pickle")))
|
|
484
|
+
|
|
485
|
+
for pickle_file in pickle_files:
|
|
486
|
+
try:
|
|
487
|
+
# Try to read the pickle file to detect corruption
|
|
488
|
+
import pickle
|
|
489
|
+
with open(pickle_file, 'rb') as f:
|
|
490
|
+
pickle.load(f)
|
|
491
|
+
except (EOFError, pickle.UnpicklingError, Exception) as e:
|
|
492
|
+
logger.warning(f"Corrupted index file detected: {pickle_file} - {e}")
|
|
493
|
+
await self._recover_from_corruption()
|
|
494
|
+
return
|
|
495
|
+
|
|
496
|
+
async def _recover_from_corruption(self) -> None:
|
|
497
|
+
"""Recover from index corruption by rebuilding the index."""
|
|
498
|
+
logger.info("Attempting to recover from index corruption...")
|
|
499
|
+
|
|
500
|
+
# Create backup directory
|
|
501
|
+
backup_dir = self.persist_directory.parent / f"{self.persist_directory.name}_backup"
|
|
502
|
+
backup_dir.mkdir(exist_ok=True)
|
|
503
|
+
|
|
504
|
+
# Backup current state (in case we need it)
|
|
505
|
+
import time
|
|
506
|
+
timestamp = int(time.time())
|
|
507
|
+
backup_path = backup_dir / f"backup_{timestamp}"
|
|
508
|
+
|
|
509
|
+
if self.persist_directory.exists():
|
|
510
|
+
try:
|
|
511
|
+
shutil.copytree(self.persist_directory, backup_path)
|
|
512
|
+
logger.info(f"Created backup at {backup_path}")
|
|
513
|
+
except Exception as e:
|
|
514
|
+
logger.warning(f"Could not create backup: {e}")
|
|
515
|
+
|
|
516
|
+
# Clear the corrupted index
|
|
517
|
+
if self.persist_directory.exists():
|
|
518
|
+
try:
|
|
519
|
+
shutil.rmtree(self.persist_directory)
|
|
520
|
+
logger.info(f"Cleared corrupted index at {self.persist_directory}")
|
|
521
|
+
except Exception as e:
|
|
522
|
+
logger.error(f"Failed to clear corrupted index: {e}")
|
|
523
|
+
raise IndexCorruptionError(
|
|
524
|
+
f"Could not clear corrupted index: {e}"
|
|
525
|
+
) from e
|
|
526
|
+
|
|
527
|
+
# Recreate the directory
|
|
528
|
+
self.persist_directory.mkdir(parents=True, exist_ok=True)
|
|
529
|
+
logger.info("Index directory recreated. Please re-index your codebase.")
|
|
530
|
+
|
|
531
|
+
async def health_check(self) -> bool:
|
|
532
|
+
"""Check database health and integrity.
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
True if database is healthy, False otherwise
|
|
536
|
+
"""
|
|
537
|
+
try:
|
|
538
|
+
# First check if client is initialized
|
|
539
|
+
if not self._client or not self._collection:
|
|
540
|
+
logger.warning("Database not initialized")
|
|
541
|
+
return False
|
|
542
|
+
|
|
543
|
+
# Try a simple operation to test the connection
|
|
544
|
+
try:
|
|
545
|
+
# Attempt to get count - this will fail if index is corrupted
|
|
546
|
+
count = self._collection.count()
|
|
547
|
+
logger.debug(f"Health check passed: {count} chunks in database")
|
|
548
|
+
|
|
549
|
+
# Try a minimal query to ensure search works
|
|
550
|
+
self._collection.query(
|
|
551
|
+
query_texts=["test"],
|
|
552
|
+
n_results=1,
|
|
553
|
+
include=["metadatas"]
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
return True
|
|
557
|
+
|
|
558
|
+
except Exception as e:
|
|
559
|
+
error_msg = str(e).lower()
|
|
560
|
+
if any(indicator in error_msg for indicator in [
|
|
561
|
+
"pickle", "unpickling", "eof", "ran out of input",
|
|
562
|
+
"hnsw", "index", "deserialize", "corrupt"
|
|
563
|
+
]):
|
|
564
|
+
logger.error(f"Index corruption detected during health check: {e}")
|
|
565
|
+
return False
|
|
566
|
+
else:
|
|
567
|
+
# Some other error
|
|
568
|
+
logger.warning(f"Health check failed: {e}")
|
|
569
|
+
return False
|
|
570
|
+
|
|
571
|
+
except Exception as e:
|
|
572
|
+
logger.error(f"Health check error: {e}")
|
|
573
|
+
return False
|
|
574
|
+
|
|
441
575
|
|
|
442
576
|
class PooledChromaVectorDatabase(VectorDatabase):
|
|
443
577
|
"""ChromaDB implementation with connection pooling for improved performance."""
|
|
@@ -729,7 +863,80 @@ class PooledChromaVectorDatabase(VectorDatabase):
|
|
|
729
863
|
|
|
730
864
|
async def health_check(self) -> bool:
|
|
731
865
|
"""Perform a health check on the database and connection pool."""
|
|
732
|
-
|
|
866
|
+
try:
|
|
867
|
+
# Check pool health
|
|
868
|
+
pool_healthy = await self._pool.health_check()
|
|
869
|
+
if not pool_healthy:
|
|
870
|
+
return False
|
|
871
|
+
|
|
872
|
+
# Try a simple query to verify database integrity
|
|
873
|
+
try:
|
|
874
|
+
async with self._pool.get_connection() as conn:
|
|
875
|
+
# Test basic operations
|
|
876
|
+
conn.collection.count()
|
|
877
|
+
conn.collection.query(
|
|
878
|
+
query_texts=["test"],
|
|
879
|
+
n_results=1,
|
|
880
|
+
include=["metadatas"]
|
|
881
|
+
)
|
|
882
|
+
return True
|
|
883
|
+
except Exception as e:
|
|
884
|
+
error_msg = str(e).lower()
|
|
885
|
+
if any(indicator in error_msg for indicator in [
|
|
886
|
+
"pickle", "unpickling", "eof", "ran out of input",
|
|
887
|
+
"hnsw", "index", "deserialize", "corrupt"
|
|
888
|
+
]):
|
|
889
|
+
logger.error(f"Index corruption detected: {e}")
|
|
890
|
+
# Attempt recovery
|
|
891
|
+
await self._recover_from_corruption()
|
|
892
|
+
return False
|
|
893
|
+
else:
|
|
894
|
+
logger.warning(f"Health check failed: {e}")
|
|
895
|
+
return False
|
|
896
|
+
except Exception as e:
|
|
897
|
+
logger.error(f"Health check error: {e}")
|
|
898
|
+
return False
|
|
899
|
+
|
|
900
|
+
async def _recover_from_corruption(self) -> None:
|
|
901
|
+
"""Recover from index corruption by rebuilding the index."""
|
|
902
|
+
logger.info("Attempting to recover from index corruption...")
|
|
903
|
+
|
|
904
|
+
# Close the pool first
|
|
905
|
+
await self._pool.close()
|
|
906
|
+
|
|
907
|
+
# Create backup directory
|
|
908
|
+
backup_dir = self.persist_directory.parent / f"{self.persist_directory.name}_backup"
|
|
909
|
+
backup_dir.mkdir(exist_ok=True)
|
|
910
|
+
|
|
911
|
+
# Backup current state
|
|
912
|
+
import time
|
|
913
|
+
timestamp = int(time.time())
|
|
914
|
+
backup_path = backup_dir / f"backup_{timestamp}"
|
|
915
|
+
|
|
916
|
+
if self.persist_directory.exists():
|
|
917
|
+
try:
|
|
918
|
+
shutil.copytree(self.persist_directory, backup_path)
|
|
919
|
+
logger.info(f"Created backup at {backup_path}")
|
|
920
|
+
except Exception as e:
|
|
921
|
+
logger.warning(f"Could not create backup: {e}")
|
|
922
|
+
|
|
923
|
+
# Clear the corrupted index
|
|
924
|
+
if self.persist_directory.exists():
|
|
925
|
+
try:
|
|
926
|
+
shutil.rmtree(self.persist_directory)
|
|
927
|
+
logger.info(f"Cleared corrupted index at {self.persist_directory}")
|
|
928
|
+
except Exception as e:
|
|
929
|
+
logger.error(f"Failed to clear corrupted index: {e}")
|
|
930
|
+
raise IndexCorruptionError(
|
|
931
|
+
f"Could not clear corrupted index: {e}"
|
|
932
|
+
) from e
|
|
933
|
+
|
|
934
|
+
# Recreate the directory
|
|
935
|
+
self.persist_directory.mkdir(parents=True, exist_ok=True)
|
|
936
|
+
|
|
937
|
+
# Reinitialize the pool
|
|
938
|
+
await self._pool.initialize()
|
|
939
|
+
logger.info("Index recovered. Please re-index your codebase.")
|
|
733
940
|
|
|
734
941
|
async def __aenter__(self):
|
|
735
942
|
"""Async context manager entry."""
|
mcp_vector_search/core/search.py
CHANGED
|
@@ -66,6 +66,16 @@ class SemanticSearchEngine:
|
|
|
66
66
|
if not query.strip():
|
|
67
67
|
return []
|
|
68
68
|
|
|
69
|
+
# Health check before search
|
|
70
|
+
try:
|
|
71
|
+
if hasattr(self.database, 'health_check'):
|
|
72
|
+
is_healthy = await self.database.health_check()
|
|
73
|
+
if not is_healthy:
|
|
74
|
+
logger.warning("Database health check failed - attempting recovery")
|
|
75
|
+
# Health check already attempts recovery, so we can proceed
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.warning(f"Health check failed: {e}")
|
|
78
|
+
|
|
69
79
|
# Auto-reindex check before search
|
|
70
80
|
if self.search_triggered_indexer:
|
|
71
81
|
try:
|
|
@@ -106,8 +116,20 @@ class SemanticSearchEngine:
|
|
|
106
116
|
return ranked_results
|
|
107
117
|
|
|
108
118
|
except Exception as e:
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
error_msg = str(e).lower()
|
|
120
|
+
# Check for corruption indicators
|
|
121
|
+
if any(indicator in error_msg for indicator in [
|
|
122
|
+
"pickle", "unpickling", "eof", "ran out of input",
|
|
123
|
+
"hnsw", "index", "deserialize", "corrupt"
|
|
124
|
+
]):
|
|
125
|
+
logger.error(f"Index corruption detected during search: {e}")
|
|
126
|
+
logger.info("The index appears to be corrupted. Please run 'mcp-vector-search reset' to clear the index and then 'mcp-vector-search index' to rebuild it.")
|
|
127
|
+
raise SearchError(
|
|
128
|
+
"Index corruption detected. Please run 'mcp-vector-search reset' followed by 'mcp-vector-search index' to rebuild."
|
|
129
|
+
) from e
|
|
130
|
+
else:
|
|
131
|
+
logger.error(f"Search failed for query '{query}': {e}")
|
|
132
|
+
raise SearchError(f"Search failed: {e}") from e
|
|
111
133
|
|
|
112
134
|
async def search_similar(
|
|
113
135
|
self,
|
mcp_vector_search/mcp/server.py
CHANGED
|
@@ -499,7 +499,6 @@ class MCPVectorSearchServer:
|
|
|
499
499
|
|
|
500
500
|
try:
|
|
501
501
|
from pathlib import Path
|
|
502
|
-
from ..cli.commands.search import run_similar_search
|
|
503
502
|
|
|
504
503
|
# Convert to Path object
|
|
505
504
|
file_path_obj = Path(file_path)
|
|
@@ -532,11 +531,24 @@ class MCPVectorSearchServer:
|
|
|
532
531
|
)]
|
|
533
532
|
)
|
|
534
533
|
|
|
535
|
-
|
|
534
|
+
response_lines = [f"Found {len(results)} similar code snippets for {file_path}\n"]
|
|
535
|
+
|
|
536
536
|
for i, result in enumerate(results, 1):
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
537
|
+
response_lines.append(f"## Result {i} (Score: {result.similarity_score:.3f})")
|
|
538
|
+
response_lines.append(f"**File:** {result.file_path}")
|
|
539
|
+
if result.function_name:
|
|
540
|
+
response_lines.append(f"**Function:** {result.function_name}")
|
|
541
|
+
if result.class_name:
|
|
542
|
+
response_lines.append(f"**Class:** {result.class_name}")
|
|
543
|
+
response_lines.append(f"**Lines:** {result.start_line}-{result.end_line}")
|
|
544
|
+
response_lines.append("**Code:**")
|
|
545
|
+
response_lines.append("```" + (result.language or ""))
|
|
546
|
+
# Show more of the content for similar search
|
|
547
|
+
content_preview = result.content[:500] if len(result.content) > 500 else result.content
|
|
548
|
+
response_lines.append(content_preview + ("..." if len(result.content) > 500 else ""))
|
|
549
|
+
response_lines.append("```\n")
|
|
550
|
+
|
|
551
|
+
result_text = "\n".join(response_lines)
|
|
540
552
|
|
|
541
553
|
return CallToolResult(
|
|
542
554
|
content=[TextContent(
|
|
@@ -586,15 +598,27 @@ class MCPVectorSearchServer:
|
|
|
586
598
|
)]
|
|
587
599
|
)
|
|
588
600
|
|
|
589
|
-
|
|
601
|
+
response_lines = [f"Found {len(results)} contextually relevant code snippets"]
|
|
590
602
|
if focus_areas:
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
603
|
+
response_lines[0] += f" (focus: {', '.join(focus_areas)})"
|
|
604
|
+
response_lines[0] += f" for: {description}\n"
|
|
605
|
+
|
|
594
606
|
for i, result in enumerate(results, 1):
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
607
|
+
response_lines.append(f"## Result {i} (Score: {result.similarity_score:.3f})")
|
|
608
|
+
response_lines.append(f"**File:** {result.file_path}")
|
|
609
|
+
if result.function_name:
|
|
610
|
+
response_lines.append(f"**Function:** {result.function_name}")
|
|
611
|
+
if result.class_name:
|
|
612
|
+
response_lines.append(f"**Class:** {result.class_name}")
|
|
613
|
+
response_lines.append(f"**Lines:** {result.start_line}-{result.end_line}")
|
|
614
|
+
response_lines.append("**Code:**")
|
|
615
|
+
response_lines.append("```" + (result.language or ""))
|
|
616
|
+
# Show more of the content for context search
|
|
617
|
+
content_preview = result.content[:500] if len(result.content) > 500 else result.content
|
|
618
|
+
response_lines.append(content_preview + ("..." if len(result.content) > 500 else ""))
|
|
619
|
+
response_lines.append("```\n")
|
|
620
|
+
|
|
621
|
+
result_text = "\n".join(response_lines)
|
|
598
622
|
|
|
599
623
|
return CallToolResult(
|
|
600
624
|
content=[TextContent(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-vector-search
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.14
|
|
4
4
|
Summary: CLI-first semantic code search with MCP integration
|
|
5
5
|
Project-URL: Homepage, https://github.com/bobmatnyc/mcp-vector-search
|
|
6
6
|
Project-URL: Documentation, https://mcp-vector-search.readthedocs.io
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
mcp_vector_search/__init__.py,sha256=
|
|
1
|
+
mcp_vector_search/__init__.py,sha256=ir_M_lclJGDDVJ6Gf_IYKqrhZLJU1I7Tq1zE7pTA7dM,300
|
|
2
2
|
mcp_vector_search/py.typed,sha256=lCKeV9Qcn9sGtbRsgg-LJO2ZwWRuknnnlmomq3bJFH0,43
|
|
3
3
|
mcp_vector_search/cli/__init__.py,sha256=TNB7CaOASz8u3yHWLbNmo8-GtHF0qwUjVKWAuNphKgo,40
|
|
4
|
-
mcp_vector_search/cli/didyoumean.py,sha256=
|
|
4
|
+
mcp_vector_search/cli/didyoumean.py,sha256=eq2uhP3E3qrPHmk2BrbFq8i8nT896uq24_IB8dzMHIk,16092
|
|
5
5
|
mcp_vector_search/cli/export.py,sha256=iluxuRT2KELdKlQeDAlVkteiel4GGrng153UAw9H0as,10804
|
|
6
6
|
mcp_vector_search/cli/history.py,sha256=osQVNiTIdGSRZQiJEjC_AYMmHxaqv7RSKSeuO325Ip0,9115
|
|
7
7
|
mcp_vector_search/cli/interactive.py,sha256=T7P4dAdvbglznzQYgiePv5YNyOx9FeE57Y3OKYnnbYE,12744
|
|
8
|
-
mcp_vector_search/cli/main.py,sha256=
|
|
8
|
+
mcp_vector_search/cli/main.py,sha256=I5WXHyB654YV0j2HODSv8Cy_zm_xfr91pFCSTb_0hLQ,15342
|
|
9
9
|
mcp_vector_search/cli/output.py,sha256=TGtWHrsfFg2tFf05aplZI2pDkoSnlKf_if78qXSRDtE,8077
|
|
10
|
+
mcp_vector_search/cli/suggestions.py,sha256=J7GB4r4PBqGY5QO20ZjfLLls1y1QYdvq0VxE-U3Cz70,12717
|
|
10
11
|
mcp_vector_search/cli/commands/__init__.py,sha256=vQls-YKZ54YEwmf7g1dL0T2SS9D4pdQljXzsUChG_V4,42
|
|
11
12
|
mcp_vector_search/cli/commands/auto_index.py,sha256=imVVbxWRlA128NPdK9BetNNl3ELrsdq-hqcsLqyAmoM,12712
|
|
12
13
|
mcp_vector_search/cli/commands/config.py,sha256=EHLqToCXrZs3gjIAg7pV8Bq8yVslUXWC4AnTcZQgSPQ,11337
|
|
@@ -14,6 +15,7 @@ mcp_vector_search/cli/commands/index.py,sha256=LsFCfqfXWd5s11wE_21mpsTitmsKsdGUh
|
|
|
14
15
|
mcp_vector_search/cli/commands/init.py,sha256=vKg4JlWaPipa9Nca-ruLs8ZZ5tXbczDQrPjHzp9zN1A,24816
|
|
15
16
|
mcp_vector_search/cli/commands/install.py,sha256=sE5mjv2pCDp2tvMj4UqfKLHpSt8Yedcb_CirWLoedDw,10375
|
|
16
17
|
mcp_vector_search/cli/commands/mcp.py,sha256=gpt9hfSmfpcr4rdis2DsenhNnGW5a0B8Xmb3RVEEtuY,17822
|
|
18
|
+
mcp_vector_search/cli/commands/reset.py,sha256=MwAbpqWYoXBHGzks0HDQclwN0qvUUZyPafOYrDOHQSo,14066
|
|
17
19
|
mcp_vector_search/cli/commands/search.py,sha256=UmMtRs15ZO5Bzc_DKWgBRoGwZgm9XXn6Lppsl1o-1I0,16785
|
|
18
20
|
mcp_vector_search/cli/commands/status.py,sha256=CqD3W4wI70o6c2XJiq0c7W0maQshWrsYQkeMyI6S13U,16600
|
|
19
21
|
mcp_vector_search/cli/commands/watch.py,sha256=2pyWRoo4fIppFnyQ4sW4IBLHmpb_IwnTjRnzHkVBPcQ,8927
|
|
@@ -23,20 +25,20 @@ mcp_vector_search/config/settings.py,sha256=v1bc2K2yTwDzQKiy_BQhTWCP7FinSWX99vQG
|
|
|
23
25
|
mcp_vector_search/core/__init__.py,sha256=bWKtKmmaFs7gG5XPCbrx77UYIVeO1FF8wIJxpj1dLNw,48
|
|
24
26
|
mcp_vector_search/core/auto_indexer.py,sha256=0S4lZXaUgqEytMSA2FxQsh5hN7V1mbSLYVzEf_dslYQ,10307
|
|
25
27
|
mcp_vector_search/core/connection_pool.py,sha256=Yo-gUQQbHawtuvh6OcJiAlbbvWQGQBd31QZOvs498fg,11224
|
|
26
|
-
mcp_vector_search/core/database.py,sha256=
|
|
28
|
+
mcp_vector_search/core/database.py,sha256=fo1hp0gs4BXquVuYm3O932f1dRF9N3NAg7HdiXzvDAQ,35178
|
|
27
29
|
mcp_vector_search/core/embeddings.py,sha256=wSMUNxZcuGPMxxQ1AbKqA1a3-0c6AiOqmuuI7OqTyaQ,10578
|
|
28
|
-
mcp_vector_search/core/exceptions.py,sha256=
|
|
30
|
+
mcp_vector_search/core/exceptions.py,sha256=3bCjT8wmrLz_0e_Tayr90049zNTKYFWZa19kl0saKz8,1597
|
|
29
31
|
mcp_vector_search/core/factory.py,sha256=GnsCBcRndBaUBWSXwtt8QKInAo-rGGBTSOKznUFETwA,10016
|
|
30
32
|
mcp_vector_search/core/git_hooks.py,sha256=xOfPpzgKoNTwM-vbhAihUucgudBQk45bCAVR5zJOFlQ,10878
|
|
31
33
|
mcp_vector_search/core/indexer.py,sha256=NroJxIoAQg1Egv_hZK76co13pbJrBxZ-IN6ZWDFu9W0,15645
|
|
32
34
|
mcp_vector_search/core/models.py,sha256=fnZxvUkd9Afxmdwtw2BJX7uik6rQTwuWBTTqTeqDi0A,6697
|
|
33
35
|
mcp_vector_search/core/project.py,sha256=RNeLBZZw6SO5mXqCwYfhStTGuVgeMq1US5UftG0SBYk,10069
|
|
34
36
|
mcp_vector_search/core/scheduler.py,sha256=PBSlu-ieDYCXOMGYY7QKv9UReFEDPHNmwnUv_xb4vxg,11761
|
|
35
|
-
mcp_vector_search/core/search.py,sha256=
|
|
37
|
+
mcp_vector_search/core/search.py,sha256=5xBl73xxQC0NGAHO0EyvKq39ZNVeW4MVpCrjl_U8UhA,29570
|
|
36
38
|
mcp_vector_search/core/watcher.py,sha256=-DFRCnuUfcqcTrkZPQqfJSvxKAxnpt-axgEj1V-B0O4,10862
|
|
37
39
|
mcp_vector_search/mcp/__init__.py,sha256=gfKR0QV7Jqvj5y0LMBe9gSghd5_rPsvm_rml0ryQtoY,158
|
|
38
40
|
mcp_vector_search/mcp/__main__.py,sha256=vhAUa4S8hoXqfJt4w0yX5z2h5GoPAar8iFqgIW-WdbY,575
|
|
39
|
-
mcp_vector_search/mcp/server.py,sha256=
|
|
41
|
+
mcp_vector_search/mcp/server.py,sha256=ZzLvqHnkIvWNkhqIMPXGpafgS38tS8XtmEmq_i7doHo,28547
|
|
40
42
|
mcp_vector_search/parsers/__init__.py,sha256=nk4clWDWQURMxzC1ev8O_vGlfraHlXqizTDXgFqIP5U,46
|
|
41
43
|
mcp_vector_search/parsers/base.py,sha256=-zBY9T0modfegowaNyf5_upkS3ImR4TgrRwoSLuAiDw,5421
|
|
42
44
|
mcp_vector_search/parsers/javascript.py,sha256=P7fT_tXCzUuXATTkTx_DyD4EuG0_KjIDlay09MhkKTE,9824
|
|
@@ -47,8 +49,8 @@ mcp_vector_search/utils/__init__.py,sha256=Eq6lY-oPMfCt-GpPUbg9QbmTHuQVmTaVDBMU2
|
|
|
47
49
|
mcp_vector_search/utils/gitignore.py,sha256=U1-1FERSYnDbxkH8JGG_azLxLasqkAh1urRUbZskmRU,8208
|
|
48
50
|
mcp_vector_search/utils/timing.py,sha256=THC7mfbTYnUpnnDcblgQacYMzbEkfFoIShx6plmhCgg,11285
|
|
49
51
|
mcp_vector_search/utils/version.py,sha256=d7fS-CLemxb8UzZ9j18zH0Y0Ud097ljKKYYOPulnGPE,1138
|
|
50
|
-
mcp_vector_search-0.4.
|
|
51
|
-
mcp_vector_search-0.4.
|
|
52
|
-
mcp_vector_search-0.4.
|
|
53
|
-
mcp_vector_search-0.4.
|
|
54
|
-
mcp_vector_search-0.4.
|
|
52
|
+
mcp_vector_search-0.4.14.dist-info/METADATA,sha256=EbalUrvvEgqQn5hGu1sD0WyDnL3EFQmZB2meZzmNRdA,15890
|
|
53
|
+
mcp_vector_search-0.4.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
54
|
+
mcp_vector_search-0.4.14.dist-info/entry_points.txt,sha256=y3Ygtc_JiBchNEIL-tPABo7EbzBExGAxwGdkkeP5D2I,86
|
|
55
|
+
mcp_vector_search-0.4.14.dist-info/licenses/LICENSE,sha256=FqZUgGJH_tZKZLQsMCpXaLawRyLmyFKRVfMwYyEcyTs,1072
|
|
56
|
+
mcp_vector_search-0.4.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|