mcp-memory-service: exact text only scores 60-70%? Use hybrid BM25 + vector search (v10.8.0)
In mcp-memory-service (doobidoo), searching with text that exactly matches a stored document chunk returns similarity scores around 60-70% instead of the expected 90-100%. Vector embeddings are affected by normalization, context window, and floating-point precision, so identical text still gets a low score. Is there a way to get near-perfect scores for exact text matches? The fix landed in v10.8.0 — how do I enable and configure the hybrid BM25 + vector search?
Originally asked on GitHub: https://github.com/doobidoo/mcp-memory-service/issues/175
4 answers
Status: fixed in v10.8.0 (released 2026-02-08). The maintainer implemented hybrid BM25 + vector search: FTS5-based BM25 keyword search with a trigram tokenizer runs in parallel with the vector search and the scores are fused. Exact matches that previously scored 60-70% now score near-100%.
Upgrade and switch the search mode:
bashpip install --upgrade mcp-memory-servicebashcurl -X POST http://127.0.0.1:8000/api/search \ -H "Content-Type: application/json" \ -d '{"query": "OAuth 2.1 authentication", "mode": "hybrid", "limit": 10}'Python API:
pythonresults = await storage.search_memories(query="exact text to find", mode="hybrid", limit=5) # or directly: results = await storage.retrieve_hybrid(query="specific keywords", n_results=10)Configuration (hybrid is enabled by default; weights should sum to ~1.0):
bashexport MCP_HYBRID_SEARCH_ENABLED=true export MCP_HYBRID_KEYWORD_WEIGHT=0.3 # BM25 keyword weight export MCP_HYBRID_SEMANTIC_WEIGHT=0.7 # vector similarity weightThe maintainer lists 0.5/0.5 as more keyword-focused, 0.2/0.8 as more semantic-focused, and 0.3/0.7 as the recommended default.
mode="semantic"is unchanged, so the release is backward compatible. Reported latency is <50ms for 100 memories.A commenter who built the same pattern in another project (AgentKits Memory) confirmed SQLite's FTS5 BM25 is sufficient and stressed normalizing scores before merging: FTS5
bm25()returns negative values where closer to 0 is better, so they usedmin(1, max(0, 1 + bm25_rank / 10)), and1 - cosine_distancefor the vector side; otherwise one score dominates. They also made the weight adaptive by query type — exact strings like error codes or function names get higher text weight, while natural-language questions get higher vector weight. General advice: if you implement your own hybrid search, normalize both scores to 0-1 before combining.Did this work for you?What a GitHub user tried on GitHub (Outcome unclear)
The issue notes that v8.6.1 already switched from L2 distance to cosine similarity as an alternative; the issue describes it as improving scores but not solving the exact-match problem, without test results.
Source: https://github.com/doobidoo/mcp-memory-service/issues/175 (opens external site)
Did this work for you?What @leduclinh7141 tried on GitHub (Worked)
A commenter implemented hybrid search in their own project using SQLite FTS5 (BM25) and HNSW vector search in parallel, normalizing both scores to 0-1 before merging; they reported exact matches jumped to near-100% in the merged results.
Did this work for you?What @doobidoo tried on GitHub (Worked)
The maintainer announced hybrid search was implemented and released in v10.8.0: FTS5 BM25 with trigram tokenizer, parallel execution, and configurable fusion weights (default 30% keyword / 70% semantic).
Did this work for you?
Related questions
- mcp-memory-service Docker boot loop: container restarts after exit code 0
- mcp-memory-service v8.19.0: retrieve_memory and search_by_tag broken with 'tags' and 'float' errors
- How do I use project management or custom memory types in mcp-memory-service?
- Claude Code ignores readOnlyHint for mcp-memory-service: workarounds?
- UNIQUE constraint failed: memories.content_hash after delete_memory() in mcp-memory-service