# AGENTS.md - Guide for Coding Agents This document provides essential information for coding agents working on the Searchbox MCP (Model Context Protocol) project. It serves as a quick reference to understand the codebase architecture, testing setup, and development workflows. ## ๐Ÿ—๏ธ Project Overview **Searchbox** is an MCP server that provides vector search capabilities using Qdrant as the backend. It allows AI assistants to perform semantic search operations on document collections through a standardized MCP interface. ### Key Components: - **MCP Server**: FastMCP-based server exposing semantic search tools - **Vector Engine**: Pluggable backend system (currently supports Qdrant) - **Client Interface**: High-level API for vector operations - **Models**: Pydantic data structures for search operations ## ๐Ÿ“ Project Structure ``` qdrant-mcp/ โ”œโ”€โ”€ src/searchbox/ # Main package (renamed from vector_search_mcp) โ”‚ โ”œโ”€โ”€ __init__.py # Package initialization โ”‚ โ”œโ”€โ”€ client.py # High-level client interface โ”‚ โ”œโ”€โ”€ config.py # Configuration management โ”‚ โ”œโ”€โ”€ models.py # Pydantic models and data structures โ”‚ โ”œโ”€โ”€ engine/ # Vector database backends โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py # Engine factory and Backend enum โ”‚ โ”‚ โ”œโ”€โ”€ base_engine.py # Abstract base engine with generics โ”‚ โ”‚ โ””โ”€โ”€ qdrant_engine.py # Qdrant implementation โ”‚ โ””โ”€โ”€ mcp_server/ # MCP protocol implementation โ”‚ โ”œโ”€โ”€ __init__.py # Server entry point โ”‚ โ””โ”€โ”€ server.py # FastMCP server setup โ”œโ”€โ”€ tests/ # Test suite (97.22% coverage) โ”‚ โ”œโ”€โ”€ test_client/ # Client API tests โ”‚ โ”œโ”€โ”€ test_engine/ # Engine implementation tests โ”‚ โ””โ”€โ”€ test_mcp/ # MCP server integration tests โ”œโ”€โ”€ pyproject.toml # Project configuration โ””โ”€โ”€ README.md # Project documentation ``` ## ๐Ÿ”ง Development Environment ### Prerequisites - Python 3.13+ - UV package manager - Qdrant (for integration tests) ### Setup Commands ```bash # Install dependencies uv sync --all-extras --dev # Run tests with coverage uv run pytest --cov --cov-report=term-missing # Run linting uv run ruff check # Start MCP server uv run searchbox-mcp ``` ### Package Management - **Main deps**: `qdrant-client`, `vault-settings` - **Optional**: `fastmcp` (MCP functionality) - **Dev deps**: `pytest`, `pytest-cov`, `pytest-asyncio`, `ruff`, `fastembed` ## ๐Ÿงช Testing Framework ### Test Structure (91 tests, 97.22% coverage) ``` tests/ โ”œโ”€โ”€ test_client/ # 14 tests - Client API functionality โ”œโ”€โ”€ test_engine/ # 68 tests - Engine implementations & factory โ””โ”€โ”€ test_mcp/ # 9 tests - MCP server integration ``` ### Key Test Commands ```bash # Run all tests uv run pytest # Run with coverage uv run pytest --cov --cov-report=html # Run specific test module uv run pytest tests/test_client/ # Run integration tests (starts real MCP server) uv run pytest tests/test_mcp/ ``` ### Test Patterns - **Unit tests**: Mock external dependencies (Qdrant client, settings) - **Integration tests**: Use real MCP server with in-memory Qdrant - **Fixtures**: Located in `conftest.py` files for each test package - **Async testing**: Uses `pytest-asyncio` with `asyncio_mode = "auto"` ## ๐Ÿ›๏ธ Architecture Patterns ### 1. Generic Engine System ```python # Base engine uses generics for type safety class BaseEngine[ResponseType, ConditionType, ChunkType](ABC): # Abstract methods that subclasses must implement @abstractmethod def transform_conditions(self, conditions: list[Condition] | None) -> ConditionType | None: ... # Template method pattern for semantic search async def semantic_search(self, embedding, collection, limit, conditions, threshold): # Orchestrates: transform -> query -> transform ``` ### 2. Factory Pattern with Caching ```python @cache # functools.cache for singleton behavior def get_engine(backend: Backend): if backend == Backend.QDRANT: return QdrantEngine() elif backend == Backend.COSMOS: raise NotImplementedError("Cosmos engine not implemented yet") ``` ### 3. Client Facade Pattern ```python @final class Client: """High-level interface abstracting engine complexity""" def __init__(self, backend: Backend, collection: str): self.engine = get_engine(backend) # Factory usage self.collection = collection ``` ## ๐Ÿ“Š Data Models ### Core Models (in `models.py`) ```python # Search conditions class Match(BaseModel): # Exact match filter class MatchAny(BaseModel): # Any-of match filter class MatchExclude(BaseModel): # Exclusion filter # Document data class ChunkData(BaseModel): # Document content + metadata class Chunk(BaseModel): # Vector + ChunkData class SearchRow(BaseModel): # Search result format ``` ### Backend-Specific Models - **Qdrant**: Uses `qdrant_client.models` (PointStruct, Filter, etc.) - **Generic**: Abstractions in `base_engine.py` ## ๐Ÿ”Œ MCP Integration ### Server Setup (`mcp_server/server.py`) ```python from fastmcp import FastMCP from ..engine import Backend, get_engine mcp = FastMCP("Vector Search MCP") engine = get_engine(Backend.QDRANT) # Auto-register semantic_search as MCP tool _ = mcp.tool(engine.semantic_search) ``` ### Entry Point (`mcp_server/__init__.py`) ```python def run(transport: Transport = "sse"): """Start MCP server with specified transport""" mcp.run(transport=transport) ``` ## ๐ŸŽฏ Common Development Tasks ### Adding a New Vector Backend 1. **Create engine**: Inherit from `BaseEngine[ResponseType, ConditionType, ChunkType]` 2. **Implement abstracts**: `transform_conditions`, `transform_response`, `run_similarity_query`, etc. 3. **Update factory**: Add new backend to `Backend` enum and `get_engine()` 4. **Add tests**: Create test file following existing patterns 5. **Update docs**: Add configuration examples ### Modifying Search Functionality - **Models**: Extend condition types in `models.py` - **Base Engine**: Update abstract methods if needed - **Implementations**: Update concrete engines (`qdrant_engine.py`) - **Tests**: Add test cases for new functionality ### Extending MCP Tools - **Server**: Add new tools in `mcp_server/server.py` - **Client**: Extend `Client` class with new methods - **Integration**: Add MCP integration tests ## ๐Ÿ› Debugging & Troubleshooting ### Common Issues 1. **Import errors**: Check if module was renamed from `vector_search_mcp` to `searchbox` 2. **Test failures**: Ensure MCP server uses correct script name `searchbox-mcp` 3. **Coverage gaps**: Focus on branch coverage, not just line coverage 4. **Async issues**: Use `pytest.mark.asyncio` for async tests ### Debugging Tools ```bash # Verbose test output uv run pytest -v --tb=long # Coverage with missing lines uv run pytest --cov --cov-report=term-missing # Run single test uv run pytest tests/path/to/test.py::TestClass::test_method -v ``` ### MCP Server Testing - Integration tests start real server on `http://localhost:8000/sse` - Server startup takes ~5 seconds (configured in test fixtures) - Uses in-memory Qdrant with pre-seeded test data ## ๐Ÿ“‹ Code Quality Standards ### Linting Configuration (Ruff) ```toml [tool.ruff.lint] extend-select = ["I", "D", "ERA", "UP", "FURB", "TRY", "PERF"] ignore = ["D203", "D213"] ``` - **I**: Import sorting - **D**: Docstring conventions (Google style) - **ERA**: Remove commented code - **UP**: Python upgrade syntax - **FURB**: Refurb suggestions - **TRY**: Exception handling - **PERF**: Performance ### Coverage Standards - **Target**: >95% coverage (currently 97.22%) - **Branch coverage**: Enabled via `tool.coverage.run.branch = true` - **Exclusions**: Abstract methods, defensive code patterns - **HTML reports**: Generated in `htmlcov/` directory ### Documentation Requirements - **Docstrings**: All public classes/methods (Google style) - **Type hints**: Full typing for all functions - **Examples**: Include usage examples in docstrings - **Generics**: Document type parameters clearly ## ๐Ÿš€ Deployment & Distribution ### Package Configuration - **Name**: `searchbox` (internal), distributed as `vector-search-mcp` - **Entry point**: `searchbox-mcp` command - **Build system**: `uv_build` - **Python requirement**: `>=3.13` ### Dependencies - **Core**: Minimal (qdrant-client, vault-settings) - **MCP**: Optional extras (`[mcp]`) - **Dev**: Comprehensive testing and linting tools ## ๐Ÿ”— Key Files to Understand ### Must-read files for new contributors: 1. **`src/searchbox/engine/base_engine.py`** - Core abstractions and patterns 2. **`src/searchbox/client.py`** - Main user-facing API 3. **`src/searchbox/models.py`** - Data structures and types 4. **`tests/conftest.py` files** - Test configuration and fixtures 5. **`pyproject.toml`** - Project configuration and dependencies ### Reference implementations: - **`src/searchbox/engine/qdrant_engine.py`** - Complete backend implementation - **`tests/test_client/test_client.py`** - Comprehensive testing patterns - **`src/searchbox/mcp_server/server.py`** - MCP integration example This guide should provide sufficient context for any coding agent to quickly understand the project structure, make meaningful contributions, and maintain the high code quality standards established in this codebase.