feat(fts): 8e — sqlrite-mcp bm25_search tool#82
Merged
Conversation
Phase 8 sub-phase 8e per docs/phase-8-plan.md (Q9). Adds the
`bm25_search` MCP tool, mirroring `vector_search` (Phase 7h) for
keyword retrieval. Surfaces FTS prominently to LLM clients driving
SQLRite over MCP.
User-visible:
bm25_search(table, column, query, k?)
→ top-k rows by BM25 relevance, JSON-formatted
Wraps `SELECT * FROM <t> WHERE fts_match(<col>, 'q') ORDER BY
bm25_score(<col>, 'q') DESC LIMIT k` so the LLM doesn't need to
remember the WHERE-pre-filter, the DESC direction, or string
quoting. Picks up the Phase 8b optimizer hook automatically.
New:
- sqlrite-mcp/src/tools/bm25_search.rs — metadata + handle.
Pre-flight checks (table exists, column is TEXT, FTS index
attached) surface clean errors before any SQL runs. SQL
string-literal escaper handles embedded apostrophes per SQL
standard (doubled quote).
- sqlrite-mcp/src/tools/mod.rs — registers bm25_search in
tools/list (post vector_search, pre ask) and tools/call.
Tests (sqlrite-mcp 16 → 19 passing; +3 bm25-specific):
- protocol::bm25_search_returns_top_ranked_rows — 4-doc corpus,
the doc with tf=2 wins; the doc without 'rust' is filtered out.
- protocol::bm25_search_without_index_errors_clearly — actionable
error pointing at the missing CREATE INDEX step.
- protocol::bm25_search_rejects_non_text_column — clean error on
INTEGER columns.
- tools_list_returns_expected_set_in_default_mode updated to
include bm25_search.
- Internal: tools::bm25_search::tests::sql_string_literal_doubles_quotes.
Out of scope (last sub-phase):
- Docs sweep (fts.md, file-format.md, supported-sql.md, mcp.md, …) → 8f
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fifth sub-phase of Phase 8. Adds the
bm25_searchMCP tool — symmetric withvector_search(Phase 7h), surfaces FTS prominently to LLM clients driving SQLRite over MCP. Resolves Q9.Wraps
SELECT * FROM <t> WHERE fts_match(<col>, 'q') ORDER BY bm25_score(<col>, 'q') DESC LIMIT kso the LLM doesn't have to remember theWHEREpre-filter, theDESCdirection, or SQL string quoting. Picks up the Phase 8b optimizer hook automatically.What landed
sqlrite-mcp/src/tools/bm25_search.rs:table,column,query; optional:kclamped to 1..=100, default 10).sqlrite-mcp/src/tools/mod.rs:mod bm25_search;tools/listlists it aftervector_searchand beforeask.tools/calldispatches by name.Test plan
MCP test count went 16 → 19 (+3 bm25-specific):
bm25_search_returns_top_ranked_rows— 4-doc corpus, the doc with tf=2 wins; the doc withoutrustis filtered out (verifies the optimizer hook + WHERE pre-filter both work end-to-end through MCP).bm25_search_without_index_errors_clearly— actionable error pointing at the missingCREATE INDEX … USING ftsstep.bm25_search_rejects_non_text_column— clean error on INTEGER columns.tools_list_returns_expected_set_in_default_modeupdated to includebm25_search.tools::bm25_search::tests::sql_string_literal_doubles_quotes.cargo test -p sqlrite-mcp— 19 / 19 greencargo test --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs— engine 303 + 73 across other crates greencargo fmt --all -- --check— no diffcargo clippy --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs --all-targets— no new warnings on bm25_search codecargo doc --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs --no-deps— no doc warnings on bm25_searchOut of scope (last sub-phase)
docs/fts.md,docs/file-format.md,docs/supported-sql.md,docs/mcp.md(bm25_search entry)🤖 Generated with Claude Code