# Vector Search MCP - Documentation A comprehensive Model Context Protocol (MCP) server for vector similarity search operations with pluggable backend support. ## ๐Ÿ“‹ Table of Contents - [Overview](#overview) - [Architecture](#architecture) - [API Documentation](#api-documentation) - [Type Safety](#type-safety) - [Testing](#testing) - [Development](#development) - [Examples](#examples) ## ๐Ÿ” Overview This package provides a production-ready MCP server that enables semantic search capabilities through a unified interface. It supports multiple vector database backends while maintaining type safety and comprehensive test coverage. ### Key Features - **๐Ÿ”Œ Pluggable Backends**: Abstract engine interface for easy backend integration - **๐Ÿ›ก๏ธ Type Safety**: Full generic typing with Rust-like associated types pattern - **โšก Performance**: Caching and async/await throughout - **๐Ÿงช Well Tested**: 62+ tests with 100% critical path coverage - **๐Ÿ“š Comprehensive Docs**: Detailed docstrings and examples ### Supported Backends - **Qdrant** โœ… Fully implemented with async client - **Cosmos DB** ๐Ÿšง Planned (interface ready) ## ๐Ÿ—๏ธ Architecture ### Core Components ```mermaid graph TB A[MCP Server] --> B[BaseEngine Abstract Class] B --> C[QdrantEngine] B --> D[CosmosEngine - Future] C --> E[Qdrant AsyncClient] F[Factory with Overloads] --> B G[Generic Type System] --> B ``` ### Design Patterns #### 1. **Abstract Factory with Overloaded Types** ```python # Type checker knows exact return type for literals engine = get_engine(Backend.QDRANT) # Returns: QdrantEngine # Generic typing for variables backend: Backend = some_variable engine = get_engine(backend) # Returns: BaseEngine ``` #### 2. **Generic Interface (Rust-like Associated Types)** ```python class BaseEngine(ABC, Generic[ResponseType, ConditionType]): # ResponseType: Backend-specific raw response (e.g., list[ScoredPoint]) # ConditionType: Backend-specific filter type (e.g., models.Filter) class QdrantEngine(BaseEngine[list[models.ScoredPoint], models.Filter]): # Concrete implementation with Qdrant types ``` #### 3. **Template Method Pattern** ```python async def semantic_search(self, ...): """Public interface orchestrates the workflow""" conditions = self.transform_conditions(...) # Abstract response = await self.run_similarity_query(...) # Abstract return self.transform_response(response) # Abstract ``` ## ๐Ÿ“– API Documentation ### Main Entry Points #### `run(transport: Transport = "sse")` Starts the MCP server with specified transport protocol. **Parameters:** - `transport`: Either `"sse"` (Server-Sent Events) or `"stdio"` **Example:** ```python from vector_search_mcp import run run("sse") # Start server ``` #### `get_engine(backend: Backend) -> BaseEngine` Factory function creating cached engine instances. **Parameters:** - `backend`: Backend enum value (Backend.QDRANT, Backend.COSMOS) **Returns:** - Typed engine instance (QdrantEngine for QDRANT) **Example:** ```python from vector_search_mcp.engine import get_engine, Backend engine = get_engine(Backend.QDRANT) results = await engine.semantic_search( embedding=[0.1, 0.2, 0.3], collection="documents", limit=10 ) ``` ### Core Classes #### `BaseEngine[ResponseType, ConditionType]` Abstract base class defining the engine interface. **Generic Parameters:** - `ResponseType`: Backend's native response format - `ConditionType`: Backend's native filter format **Key Methods:** - `semantic_search()`: Main public interface - `transform_conditions()`: Convert generic to backend conditions - `transform_response()`: Convert backend to generic results - `run_similarity_query()`: Execute backend-specific search #### `QdrantEngine(BaseEngine[list[ScoredPoint], Filter])` Concrete Qdrant implementation. **Features:** - Async Qdrant client with connection pooling - Automatic payload filtering (excludes null payloads) - Support for Match, MatchAny, MatchExclude conditions - Named vector support ### Data Models #### `SearchRow` Standardized search result format. ```python SearchRow( chunk_id="doc_123", # Document identifier score=0.95, # Similarity score (0.0-1.0) payload={"text": "...", ...} # Metadata dictionary ) ``` #### Condition Types **`Match`** - Exact field matching ```python Match(key="category", value="technology") ``` **`MatchAny`** - Match any of provided values ```python MatchAny(key="tags", any=["python", "rust", "go"]) ``` **`MatchExclude`** - Exclude specified values ```python MatchExclude(key="status", exclude=["draft", "deleted"]) ``` ## ๐Ÿ›ก๏ธ Type Safety ### Generic Type System The package uses a sophisticated generic type system that provides compile-time type safety while maintaining flexibility: ```python # Engine implementations specify their exact types class QdrantEngine(BaseEngine[list[models.ScoredPoint], models.Filter]): def transform_response(self, response: list[models.ScoredPoint]) -> list[SearchRow]: # Type checker validates response parameter type async def run_similarity_query(...) -> list[models.ScoredPoint]: # Type checker validates return type matches generic parameter ``` ### Factory Type Overloads ```python @overload def get_engine(backend: Literal[Backend.QDRANT]) -> QdrantEngine: ... @overload def get_engine(backend: Backend) -> BaseEngine: ... # Usage provides different type information: engine1 = get_engine(Backend.QDRANT) # Type: QdrantEngine engine2 = get_engine(some_variable) # Type: BaseEngine ``` ## ๐Ÿงช Testing ### Test Coverage - **62 Tests Total** across 4 test modules - **100% Critical Path Coverage** for search workflows - **Integration Testing** with full mock environments - **Type Safety Validation** with runtime checks ### Test Structure ``` tests/test_engine/ โ”œโ”€โ”€ test_base_engine.py # Abstract interface tests (12 tests) โ”œโ”€โ”€ test_qdrant_engine.py # Qdrant implementation (20 tests) โ”œโ”€โ”€ test_factory.py # Factory and typing tests (17 tests) โ”œโ”€โ”€ test_integration.py # End-to-end workflows (13 tests) โ”œโ”€โ”€ conftest.py # Shared fixtures and mocks โ””โ”€โ”€ README.md # Testing documentation ``` ### Running Tests ```bash # Run all engine tests uv run pytest tests/test_engine/ -v # Run with coverage uv run pytest tests/test_engine/ --cov=src/vector_search_mcp/engine --cov-report=html # Run specific test categories uv run pytest tests/test_engine/test_integration.py -v ``` ### Key Testing Features - **Cache Management**: Auto-clearing fixtures prevent test interference - **Mock Isolation**: Comprehensive mocking prevents real network calls - **Async Testing**: Full async/await support with proper event loops - **Type Validation**: Runtime checks for generic type correctness ## ๐Ÿ› ๏ธ Development ### Prerequisites ```bash # Install with uv uv install # Or with pip pip install -e . ``` ### Code Quality The package maintains high code quality standards: ```bash # Linting and formatting uv run ruff check # Check for issues uv run ruff check --fix # Auto-fix issues uv run ruff format # Format code # Type checking uv run mypy src/ # Run tests uv run pytest ``` ### Adding New Backends 1. **Define Types**: Determine ResponseType and ConditionType for your backend 2. **Implement Engine**: Create class extending `BaseEngine[ResponseType, ConditionType]` 3. **Add to Factory**: Update `Backend` enum and `get_engine()` function 4. **Write Tests**: Follow existing test patterns 5. **Update Documentation**: Add examples and API docs Example template: ```python class MyEngine(BaseEngine[MyResponseType, MyConditionType]): def transform_conditions(self, conditions: list[Condition] | None) -> MyConditionType | None: # Convert generic conditions to backend format def transform_response(self, response: MyResponseType) -> list[SearchRow]: # Convert backend response to SearchRow objects async def run_similarity_query(...) -> MyResponseType: # Execute backend-specific search ``` ## ๐Ÿ’ก Examples ### Basic Usage ```python from vector_search_mcp.engine import get_engine, Backend from vector_search_mcp.models import Match, MatchAny # Create engine engine = get_engine(Backend.QDRANT) # Simple search results = await engine.semantic_search( embedding=[0.1, 0.2, 0.3, 0.4, 0.5], collection="documents", limit=10 ) for result in results: print(f"Score: {result.score:.3f} - {result.payload['text'][:50]}...") ``` ### Advanced Filtering ```python # Complex conditions conditions = [ Match(key="category", value="technology"), MatchAny(key="language", any=["python", "rust", "go"]), MatchExclude(key="status", exclude=["draft", "archived"]) ] results = await engine.semantic_search( embedding=query_vector, collection="tech_docs", limit=20, conditions=conditions, threshold=0.75 # Minimum similarity score ) ``` ### Custom Backend Implementation ```python from vector_search_mcp.engine.base_engine import BaseEngine from vector_search_mcp.models import SearchRow, Condition class CustomEngine(BaseEngine[dict, str]): """Example custom backend implementation.""" def transform_conditions(self, conditions: list[Condition] | None) -> str | None: if not conditions: return None # Convert to custom query string format return " AND ".join([f"{c.key}:{c.value}" for c in conditions]) def transform_response(self, response: dict) -> list[SearchRow]: # Convert custom response to SearchRow objects return [ SearchRow( chunk_id=str(item['id']), score=item['similarity'], payload=item['metadata'] ) for item in response.get('results', []) ] async def run_similarity_query(self, embedding, collection, limit=10, conditions=None, threshold=None) -> dict: # Custom backend API call return await self.custom_client.search( vector=embedding, index=collection, limit=limit, filter=conditions, min_score=threshold ) ``` ### MCP Server Integration ```python # Start the MCP server from vector_search_mcp import run # With Server-Sent Events (web-based clients) run("sse") # With stdio (terminal/CLI clients) run("stdio") ``` --- ## ๐Ÿ“š Additional Resources - **Source Code**: Fully documented with comprehensive docstrings - **Test Suite**: Located in `tests/test_engine/` with detailed README - **Type Definitions**: All public APIs have complete type annotations - **Examples**: See `examples/` directory (if available) for more use cases This documentation covers the current state of the Vector Search MCP package. The architecture is designed for extensibility, type safety, and production use.