adityamparikh opened a new issue, #209:
URL: https://github.com/apache/solr-mcp/issues/209

   ## Motivation
   
   The `search` tool 
(`src/main/java/org/apache/solr/mcp/server/search/SearchService.java`) 
currently exposes seven parameters:
   
   | Parameter | Solr equivalent |
   |---|---|
   | `collection` | path |
   | `query` | `q` |
   | `filterQueries` | `fq` |
   | `facetFields` | `facet.field` (with `facet.mincount=1`, `facet.sort=count` 
hard-coded) |
   | `sortClauses` | `sort` |
   | `start` | `start` |
   | `rows` | `rows` |
   
   That covers the basic "find documents" loop, but an LLM client hits walls 
quickly:
   
   - **Every document comes back whole.** There is no `fl`, so a 20-row result 
over a wide schema burns thousands of tokens on fields the model never asked 
for. Field selection is the single biggest lever on cost and context window for 
MCP clients.
   - **No relevance signal per document.** `maxScore` is on the response, but 
the per-document `score` pseudo-field can only be requested via `fl`.
   - **No snippets.** Without highlighting the model has to read full bodies to 
find *why* a document matched.
   - **Faceting is field-only.** No range facets (dates, prices), no facet 
queries, and `mincount`/`limit` cannot be tuned. PR #162 declares "field facets 
only" in the server instructions precisely because this is the current surface.
   - **Deep pagination is `start`-only.** Solr recommends `cursorMark` for 
anything past the first few pages; large `start` offsets are expensive on the 
server.
   
   ## Proposal
   
   Add optional parameters to the existing `search` tool. All are `required = 
false`, so this is backward compatible. Nothing here adds a new tool.
   
   ### Tier 1: high value, low risk
   
   | Parameter | Type | Solr | Notes |
   |---|---|---|---|
   | `fields` | `List<String>` | `fl` | Field list to return. Allow `score` so 
clients can request per-doc relevance. Cuts response token cost dramatically. |
   | `highlightFields` | `List<String>` | `hl=true`, `hl.fl` | Adds a 
`highlighting` map (`docId -> field -> [snippets]`) to `SearchResponse`. 
Optionally `highlightSnippets` / `highlightFragsize`. |
   | `facetMinCount` | `Integer` | `facet.mincount` | Currently hard-coded to 
1. |
   | `facetLimit` | `Integer` | `facet.limit` | Solr default is 100; models 
often want top 5–10. |
   | `defaultOperator` | `AND`/`OR` enum | `q.op` | Lets the client tighten 
recall without rewriting the query. |
   
   ### Tier 2: worthwhile, needs a small design
   
   | Parameter | Type | Solr | Notes |
   |---|---|---|---|
   | `facetQueries` | `List<String>` | `facet.query` | Arbitrary bucket counts 
(`price:[* TO 10]`). Response gains a `facetQueries` map. |
   | `rangeFacets` | `List<RangeFacet>` | `facet.range` + `start`/`end`/`gap` | 
Typed record `(field, start, end, gap)` following the `SortClause` pattern from 
PR #164. Needs a `SolrNativeHints` entry. |
   | `cursorMark` | `String` | `cursorMark` | Response returns 
`nextCursorMark`. Requires a sort that ends on the unique key; the tool should 
validate that and give a remediation hint (see PR #166 style). |
   | `timeAllowed` | `Integer` | `timeAllowed` | Bounded query time for agent 
loops; response should surface `partialResults`. |
   
   ### Deliberately out of scope for this issue
   
   - **Separate `defType` / `qf` / `mm` / `pf` / `bq` parameters.** PR #161 
chose to document local params in `q` (`{!edismax qf='name author' mm=2}`) 
instead of adding parameters. Revisiting that is a separate discussion: 
explicit parameters would let the server escape values (cf. closed #122 on 
local-param injection) but widen the surface. Not proposed here.
   - **`debugQuery`, KNN / vector search, grouping, MoreLikeThis, spellcheck.** 
#162 explicitly declares debugQuery and KNN out of the tool surface; #64 tracks 
semantic/hybrid search separately.
   - **JSON Facet API (`json.facet`).** Powerful but effectively an untyped 
DSL; better as its own follow-up once Tier 1/2 lands.
   
   ## Implementation notes
   
   - `SearchResponse` will gain `highlighting` (and later `facetQueries`, 
`rangeFacets`, `nextCursorMark`). It is registered in `SolrNativeHints`, so any 
new nested record needs a hint too or the native image will fail at runtime.
   - Update the `search` tool description and the 
`spring.ai.mcp.server.instructions` text from #162 ("field facets only") in the 
same PR as the facet changes, so the declared boundaries stay truthful.
   - Tests: unit test per parameter in `SearchServiceTest`, plus Testcontainers 
coverage for highlighting, range facets and `cursorMark` since those depend on 
real Solr behaviour (mocks would be tautological).
   - Suggest landing Tier 1 as one PR and each Tier 2 parameter as its own 
small PR.
   
   ## Acceptance criteria
   
   - [ ] `fields` limits returned document fields and `score` works as a 
pseudo-field
   - [ ] `highlightFields` returns snippets in the response
   - [ ] `facetMinCount` / `facetLimit` / `defaultOperator` are honoured
   - [ ] Existing calls with only the current seven parameters behave exactly 
as before
   - [ ] Tool description and server instructions updated to match the new 
surface
   - [ ] `./gradlew build` and `./gradlew nativeTest -Pnative` pass
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to