Skip to content

RHOKP-1758: add MCP transport for OKP RAG enrichment - #2719

Draft
mwcz wants to merge 8 commits into
lightspeed-core:mainfrom
mwcz:RHOKP-1758-okp-mcp-rag-provider
Draft

mwcz wants to merge 8 commits into
lightspeed-core:mainfrom
mwcz:RHOKP-1758-okp-mcp-rag-provider

Conversation

@mwcz

@mwcz mwcz commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

RHOKP RAG context used to enrich LCORE responses currently comes from direct calls to the Solr API hosted in RHOKP.

This PR adds conditional support for fetching that same context via RHOKP's upcoming MCP server. The support is conditional in the following sense: when LCORE is configured to fetch context from RHOKP, it will attempt MCP, and fall back to Solr if MCP is not available. In this way, LCORE has support for RHOKP RAG regardless of the version of RHOKP currently deployed. The conditional support also allows existing LCORE configuration to work with RHOKP before and after the release of the MCP server.

The plan discussed with the LCORE team is that the Solr provider (in lightspeed-providers) will be deprecated and eventually removed. The migration to Pydantic AI will not include Solr, so the migration timeline is, in a way, the same as the timeline for Solr provider removal.

Transport selection

  • Launch: always wire the Solr vector_io provider.
  • Query: prefer the MCP transport whenever okp_mcp_available() is True, falling back to Solr when MCP is unavailable or hard-fails for the request. This provides compatibility with RHOKP RAG
  • Fail-forward: the probe result is TTL-cached (not sticky), so an upgraded RHOKP is adopted without restarting LCORE.

Product/version filtering is now query-time only via the request okp filter; the launch-time product/product_version config is dropped. OkpMcpConfiguration and RH_SERVER_OKP_MCP_DEFAULT_URL are removed; the OpenAPI schema is regenerated.

Testing

  • uv run make format, black, pylint (10.00/10), pyright src (0 errors): clean.
  • uv run make test-unit: 3600 passed, 1 skipped.
  • make verify still fails on check-types-tests (mypy-on-tests): 41 pre-existing errors across 13 files not touched here (identical at the branch base).

The RHOKP team can provide a container image of RHOKP with RAG and MCP built in (but with a small sample of the full corpus to save on build & transfer time), and we will also work on updating the internal instance of RHOKP to include MCP as well, for even easier testing.

🤖 Assisted by Claude Code

mwcz and others added 4 commits September 15, 2026 14:25
…ring

Adds an interchangeable MCP transport for OKP RAG retrieval alongside the
existing OGX/Solr vector_io path, forked at build_rag_context by
okp_rag_mcp_enabled().

- OkpMcpConfiguration (rag.okp.mcp): enabled flag, url, tool_name, max_chunks,
  timeout, authorization_headers, plus structured product/product_version
  filters that mirror the Solr transport's chunk_filter_query filtering.
- OkpMcpRetriever + call_okp_search: single direct MCP search-tool call over
  streamable HTTP (pydantic-ai MCPToolset), mapping results to the
  backend-neutral RAGChunk/ReferencedDocument contract shared with the Solr
  path; product/product_version passed as structured tool args when set.
- Regenerated OpenAPI schema for the new config fields.
- Unit tests for the client, provider, config model, configuration fork,
  vector_search fork, and enrichment.

The server-side product/version filtering support (mimcp search tool) is a
separate change in the RHOKP repository.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce OkpFilter/OkpProductFilter, a backend-neutral query-time RAG
filter (product selections, each scoping its own exact-match versions),
decoupled from Solr fq and the OGX {type,key,value} grammar so the public
interface survives the OGX->pydantic-ai migration.

- models.common.query: OkpProductFilter + OkpFilter (nested array shape).
- QueryRequest / OpenAI responses request: new optional `okp` field.
- OkpMcpRetriever.fetch: accept `okp`, fan out one MCP search per
  (product, version) pair, then merge/dedup/sort/cap results.

WIP: `okp` is not yet threaded through vector_search.build_rag_context ->
_fetch_okp_rag_mcp/_fetch_okp_rag, so the field is accepted but not yet
consumed. Endpoint wiring, Solr-side translation, tests, and rag_guide
docs still pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Thread the request-level `okp` filter from all three inference entry
points (query, streaming_query, responses) through build_rag_context to
whichever OKP transport is active, completing the query-time filtering
started in the previous commit.

- vector_search: build_rag_context/_fetch_okp_rag_mcp/_fetch_okp_rag now
  accept `okp`; _okp_filter_to_structured translates it to an OGX
  eq/in/and/or filter for the legacy Solr path (AND-combined with any
  structured solr filter), so `okp` is not a no-op on the default
  transport.
- MCP transport: OkpMcpRetriever.fetch fans out one search per
  (product, version), then merges/dedups/score-sorts/caps; a query-time
  filter overrides the launch-time config defaults.
- Regenerate OpenAPI schema (OkpFilter/OkpProductFilter components) and
  document `okp` in rag_guide.md as the backend-neutral, preferred filter.
- Unit tests: model validation, Solr translation, param merge, provider
  fan-out/override/merge/partial-failure, and transport forwarding.

Verified: ruff, black, pydocstyle, pylint, pyright, and mypy clean on
changed sources; affected unit suites pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ansport probe

Replace the launch-time MCP config flag with automatic per-request transport
selection. The OKP config reverts to its pre-MCP shape (rag.okp.{rhokp_url,
offline, ...}) with no mcp block; the MCP endpoint is always derived as
rhokp_url/mcp. Old configs keep working unchanged.

Transport selection:
- Launch: always wire the Solr vector_io provider (no synthesis-time coupling
  to RHOKP; enrich_okp_mcp and the synthesis fork are removed).
- Query: prefer the MCP transport whenever okp_mcp_available() is True, falling
  back to Solr when MCP is unavailable or hard-fails for the request.
- Fail-forward: the probe result is TTL-cached (not sticky) so an upgraded
  RHOKP is adopted without restarting LCORE.

Product/version filtering is query-time only via the request `okp` filter; the
launch-time product/product_version config is dropped. OkpMcpConfiguration and
RH_SERVER_OKP_MCP_DEFAULT_URL are removed; OpenAPI schema regenerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The RHOKP MCP `search` tool now accepts a structured, Solr-fq-analogous
product filter and builds the query-side filter itself, so the OKP MCP
retriever no longer fans out one call per (product, version) combo.

- _client.call_okp_search: replace scalar product/product_version with an
  optional structured `products` arg, forwarded verbatim and omitted when
  None/empty.
- _provider: drop _resolve_search_combos; add _okp_products_arg to translate
  the transport-neutral OkpFilter into the structured products list, and issue
  a single search call, raising OkpMcpUnavailableError on any failure so the
  caller falls back to the Solr transport.
- Rewrite unit tests for the single-call structured-filter contract.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread docs/devel_doc/openapi.json Outdated
"description": "Exact product identifier (exact match, no wildcards).",
"examples": [
"openshift_container_platform",
"rhel"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rhel is not correct.

mwcz and others added 3 commits September 17, 2026 14:57
The OKP product identifier is red_hat_enterprise_linux, not rhel. Correct
the OkpProductFilter/OkpFilter examples and the tests exercising the slug,
and regenerate the affected openapi.json examples from the model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mwcz mwcz changed the title RHOKP-1758: derive OKP MCP endpoint from rhokp_url with query-time transport probe RHOKP-1758: add MCP transport for OKP RAG enrichment Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant