MCP Server for enVector encrypted vector search with FastMCP and enVector SDK Adapter, supporting FHE-based similarity search with optional Rune-Vault integration for secure decryption
The server implements 12 tools with reasonable coverage of vector database operations. Most tools have descriptions and input schemas with type information, placing it solidly in the C-to-low-B range. However, there are significant gaps: (1) several parameter descriptions are overly terse or generic (e.g., 'list of vectors to insert'), (2) output schemas are not documented in the visible code, (3) error handling guidance is minimal, and (4) some tool names could be clearer (e.g., 'remind' is opaque). The naming follows verb_noun convention reasonably well, but descriptions lack actionable context for LLM selection. Tool annotations (readOnlyHint/destructiveHint) are present and well-applied, which is a strong point.
Create an index in enVector.
Delete vectors from an enVector index by ID.
Delete an entire index from enVector.
Generate embeddings for text using the configured embedding model.
Encrypt a query vector for use in encrypted similarity search.
Get information about a specific index from the enVector SDK.
Get the list of indexes from the enVector SDK.
Tool names 'score' and 'remind' are opaque and do not clearly convey their actions. 'score' suggests a scoring operation on query results; 'remind' suggests memory retrieval or notifications. LLMs will struggle to distinguish when to use these over 'search' or 'encrypt_query'. A name like 'decrypt_search_results' or 'get_decrypted_similarities' would be clearer.
Parameter descriptions are often terse and lack context. E.g., 'insert' parameter 'vectors' is described as 'list of vectors to insert, or list of texts to embed and insert' but does not specify dimensionality, format (dense floats vs. sparse), or examples. 'metadata' is described as 'optional list of metadata associated with vectors' without explaining its structure (flat list, list of dicts, per-vector or global?).
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 62 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 32 | - | v1 |
Insert vectors or metadata using enVector SDK. Allowing to insert metadata as text only as supporting embedding the metadata as vectors.
Preprocess documents from text or file paths using LangChain text splitters.
Retrieve results from Vault-decrypted ciphertexts for encrypted similarity search.
Query against the encrypted index and return the result ciphertext for Vault decryption.
Search vectors in an enVector index using encrypted or plaintext similarity search.
Output schemas are not documented in the visible code. The server returns {'ok': bool, 'results': Any, 'error': str}, but the structure of 'results' for each tool is not specified. LLMs cannot plan downstream tool calls without knowing what fields to expect (e.g., does 'search' return [{'id': ..., 'score': ...}] or {'matches': [...]}, and does it include vector IDs for the 'remind' call?).
The 'score' and 'remind' tool pair appears to implement encrypted similarity search with a split between client-side encryption ('score' for query encryption) and server-side decryption (via Vault). However, the tool descriptions do not explain this workflow or when to use 'score' vs 'search'. An LLM will not understand that 'score' must precede 'remind', or that 'search' is the plaintext alternative.
Parameter 'index_params' in 'create_index' accepts a free-form object without schema constraints. The description hints at structure ('{'index_type': 'IVF_FLAT', 'nlist': <int>, 'default_nprobe': <int>}'), but does not enforce valid keys or provide an enum for 'index_type'. LLMs will hallucinate invalid keys like 'nlist_min' or 'metric=cosine'.
The 'preprocess_document' tool accepts three mutually exclusive inputs: 'texts' (array), 'path' (string), and 'language' (optional enum). The description does not clarify which are required, which are mutually exclusive, or what happens if multiple are provided. LLMs may pass both 'texts' and 'path', causing ambiguous behavior.
No error recovery guidance. The tool return format includes an 'error' field for failures, but does not categorize errors as retryable, user-fixable, or fatal. If 'search' fails with 'index not found', the LLM does not know whether to retry, call 'create_index', or ask the user.
The 'delete' and 'delete_index' tools are marked as DESTRUCTIVE but lack a confirmation pattern. An agent could accidentally delete all vectors in an index without a dry-run or explicit confirmation step. Consider adding a 'confirm' parameter or a separate 'preview_deletion' tool.
The 'search' and 'encrypt_query' tools accept 'query' as type ['array', 'string'], allowing flexible input. However, the description does not explain how string queries are processed (auto-embedded?) or what embedding model is used. If the embedding model is not specified in the server config, the LLM cannot reason about embedding consistency between 'embed_text' and 'search'.