Skip to content

docs(mcp): document multi-index server contract (RAAE-1608) - #633

Merged
vishal-bala merged 1 commit into
feature/raae-1603-mcp-multi-indexfrom
feature/raae-1608-docs
Jul 2, 2026
Merged

docs(mcp): document multi-index server contract (RAAE-1608)#633
vishal-bala merged 1 commit into
feature/raae-1603-mcp-multi-indexfrom
feature/raae-1608-docs

Conversation

@vishal-bala

@vishal-bala vishal-bala commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Motivation

The RedisVL MCP docs were written for the original single-index model and still stated that "one server process binds to exactly one existing Redis index." With multi-index support now implemented across RAAE-1604RAAE-1607, the user-facing documentation (RAAE-1608) needs to describe the new compatibility story without confusing existing single-index users.

The guiding principle in the rewrite is that single-index remains the simplest deployment and works exactly as before — callers never name an index — while multi-index is presented as a formal, additive capability layered on top via discovery (list-indexes) and explicit routing (the index argument). No documentation still claims a server must bind to exactly one index.

Implemented changes

The concept doc (concepts/mcp.md) now frames the server as binding one or several logical indexes, each addressed by an id, and adds an "Index Selection and Discovery" section covering the optional index argument, the omitted-index and unknown-id rules, the response echo, and discovery-first guidance. The "Single Index Binding" section becomes "Single and Multiple Index Bindings," the read-only section explains the two-level write policy (global --read-only vs per-index read_only, folded into effective write availability), and the tool surface gains a list-indexes subsection documenting its minimal payload — filterable fields only, vector/embed-source fields omitted, explicit-only limits, and redis_name never exposed.

The how-to guide (how_to_guides/mcp.md) adds a two-binding config example (a writable vector index alongside a read-only fulltext index), an Index Selection subsection, a list-indexes tool contract with a response example, and threads the optional index argument through the search-records and upsert-records argument lists and request/response examples. A discovery-first multi-index flow is shown at the top of the search examples, and the CLI/env-var notes are updated for per-index read-only and the multi-index search description.

Minor additional changes:

  • README MCP section and feature-table entry reworded from "an existing Redis index" to "one or more existing Redis indexes," with list-indexes and the discovery-first flow noted. (The README edit was explicitly authorized for this ticket, overriding the repo's default no-README-edits rule.)

Verification

  • sphinx-build (the docs dependency group) completes cleanly (exit 0). The only warnings are pre-existing and unrelated (upstream redis-py docstrings and index.md heading levels); no warnings reference the MCP pages, and no broken cross-reference/anchor warnings were introduced.

Stacking

This PR targets feature/raae-1607-upsert-routing and is the top of the stack. Review/merge bottom-up: #629#630#631#632 → this PR.

🤖 Generated with Claude Code


Note

Low Risk
Markdown-only changes with no runtime, API, or security behavior modified.

Overview
Documentation-only update aligning RedisVL MCP user-facing docs with multi-index support: one server can bind one or several logical indexes while single-index deployments stay backward compatible (omit index).

README rewords MCP copy from a single index to one or more, and notes list-indexes, discovery-first routing, and per-index tools.

docs/concepts/mcp.md reframes the model (per-index config, all-or-nothing startup), adds Index Selection and Discovery (index argument rules, response echo), expands read-only to global vs per-index read_only and effective upsert_available, and documents the list-indexes payload (minimal fields, no redis_name).

docs/user_guide/how_to_guides/mcp.md adds a two-binding YAML example, list-indexes contract and examples, threads optional index through search/upsert docs, a discovery-first flow, and updates CLI/env notes for multi-index search tool descriptions.

Reviewed by Cursor Bugbot for commit de2eb4f. Bugbot is set up for automated code reviews on this repo. Configure here.

@jit-ci

jit-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

@vishal-bala
vishal-bala force-pushed the feature/raae-1607-upsert-routing branch from e92fb9a to 2f878a9 Compare June 30, 2026 20:30
@vishal-bala
vishal-bala force-pushed the feature/raae-1608-docs branch from abd5dda to eacbf8e Compare July 1, 2026 06:53
@vishal-bala
vishal-bala force-pushed the feature/raae-1607-upsert-routing branch from 2f878a9 to 98aded7 Compare July 1, 2026 09:22
@vishal-bala
vishal-bala force-pushed the feature/raae-1608-docs branch from eacbf8e to ab2bfee Compare July 1, 2026 09:22
Base automatically changed from feature/raae-1607-upsert-routing to feature/raae-1603-mcp-multi-index July 2, 2026 11:41
@vishal-bala
vishal-bala marked this pull request as ready for review July 2, 2026 11:42
@vishal-bala
vishal-bala requested a review from nkanu17 July 2, 2026 11:42
Update the MCP concept doc, how-to guide, and README MCP section to reflect
formal multi-index support. Replace single-index-only language ("one server
binds to exactly one index") with the compatibility story: a single configured
index remains the simplest deployment and behaves unchanged, while multiple
indexes are formally supported behind discovery and explicit routing.

Document the list-indexes discovery tool and recommend clients call it first on
a multi-index server, then pass the chosen logical id as the index argument to
search-records and upsert-records. Explain that both tools echo the resolved
index, that an omitted index is valid only on single-index servers, and that
unknown ids fail with invalid_request.

Explain the two-level write policy: global --read-only disables writes across
every binding, while per-index read_only disables a single binding; upsert is
exposed only when at least one binding is writable, and writes to a read-only
binding are rejected with invalid_request. Clarify that list-indexes shares the
filterable fields discovered from each index, omits the vector and embed-source
fields, surfaces only explicitly configured runtime limits, and never exposes
redis_name.

- Add a two-binding config example (writable vector index + read-only fulltext
  index) and a list-indexes response example.
- Add index-parameterized search-records and upsert-records request/response
  examples and a discovery-first multi-index flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vishal-bala
vishal-bala force-pushed the feature/raae-1608-docs branch from ab2bfee to de2eb4f Compare July 2, 2026 11:45

@nkanu17 nkanu17 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@vishal-bala
vishal-bala merged commit a55b751 into feature/raae-1603-mcp-multi-index Jul 2, 2026
100 of 101 checks passed
@vishal-bala
vishal-bala deleted the feature/raae-1608-docs branch July 2, 2026 13:37
vishal-bala added a commit that referenced this pull request Jul 3, 2026
## Overview

Rolls up the **RedisVL MCP multi-index server** epic
([RAAE-1603](https://redislabs.atlassian.net/browse/RAAE-1603)) into
`main`. A single MCP server can now expose **one or more** configured
Redis index bindings — with discovery (`list-indexes`), explicit
per-call routing (an optional `index` argument on
`search-records`/`upsert-records`), and per-index write policy — while
existing **single-index configs and callers behave exactly as before**.

## This is a roll-up — every change was already reviewed and merged

This PR introduces **no new code**. It is the aggregate of a stacked
series of per-ticket PRs, each reviewed and squash-merged into the
`feature/raae-1603-mcp-multi-index` collector branch:

- [#629](#629) — RAAE-1604:
config + runtime refactor (immutable `BindingRuntime`, per-binding
startup/teardown, `resolve_binding` routing, single global concurrency
semaphore)
- [#630](#630) — RAAE-1605:
`list-indexes` discovery tool
- [#631](#631) — RAAE-1606:
`search-records` index routing
- [#632](#632) — RAAE-1607:
`upsert-records` index routing + per-index write policy
- [#633](#633) — RAAE-1608:
concept/how-to/README docs

Each stacked PR was reviewed (human + Cursor Bugbot) and its threads
resolved before merge; this branch is the sum of those merges plus a
sync with `main`.

## Synced with `main`

The branch is up to date with `main`, including the recently merged MCP
security work — **Host/Origin header validation
([#643](#643 and the
**nltk drop
([#645](#645 — pulled
in via merge, so this PR's diff contains **only** the epic's own changes
(main's commits are in the merge base).

## Security review

A security review of the epic diff was run (auth scope enforcement,
read-only/write policy, index routing, info leakage, injection,
config/vectorizer resolution). **No findings** — tokenless HTTP is
rejected upstream by the SDK auth middleware, scopes and read-only
policy are enforced at both registration and per-call, routing is
confined to configured bindings, and `redis_name` is never exposed by
`list-indexes`.

## Verification

- Full MCP unit + integration suite: **283 passed / 1 skipped** on
`redis:8.2` (now runs without nltk).
- `mypy` clean; `black`/`isort` clean.
- Backward compatibility covered by dedicated tests (single-binding
defaults, omitted-`index` behavior, unchanged response contract aside
from the additive `index` echo).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

[RAAE-1603]:
https://redislabs.atlassian.net/browse/RAAE-1603?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes MCP server startup, routing, and write boundaries across
bindings; single-index behavior is preserved but multi-index
misconfiguration or routing errors could affect production assistants.
> 
> **Overview**
> **Multi-index MCP server** — One process can expose several logical
index bindings from YAML `indexes`, each with its own schema inspection,
search config, vectorizer, and runtime limits. Startup is
all-or-nothing: any binding failure prevents the server from starting.
> 
> **Routing and discovery** — New **`list-indexes`** tool enumerates
logical ids, filterable fields, `upsert_available`, and optional limits
(without exposing `redis_name`). **`search-records`** and
**`upsert-records`** accept an optional **`index`** argument; responses
echo the resolved id. With a single binding, omitting `index` still
works; with multiple bindings, omitting or using an unknown id returns
`invalid_request`.
> 
> **Write policy** — Global `--read-only` / `REDISVL_MCP_READ_ONLY` plus
per-binding **`read_only: true`** combine into
**`effective_read_only`**. `upsert-records` is registered only if at
least one binding is writable; writes to a read-only binding fail with
**`forbidden`** before Redis is touched.
> 
> **Implementation** — Config drops the “exactly one index” rule and
adds **`description`** / **`read_only`** on bindings. Server state moves
to per-binding **`BindingRuntime`** and **`resolve_binding()`**; removed
single-index helpers like `get_index()`. Search tool descriptions omit
per-schema hints when multiple indexes are configured and point clients
to `list-indexes`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
553e55f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ahsd-coder pushed a commit to ahsd-coder/LLM-Smart-Cache that referenced this pull request Jul 7, 2026
## Overview

Rolls up the **RedisVL MCP multi-index server** epic
([RAAE-1603](https://redislabs.atlassian.net/browse/RAAE-1603)) into
`main`. A single MCP server can now expose **one or more** configured
Redis index bindings — with discovery (`list-indexes`), explicit
per-call routing (an optional `index` argument on
`search-records`/`upsert-records`), and per-index write policy — while
existing **single-index configs and callers behave exactly as before**.

## This is a roll-up — every change was already reviewed and merged

This PR introduces **no new code**. It is the aggregate of a stacked
series of per-ticket PRs, each reviewed and squash-merged into the
`feature/raae-1603-mcp-multi-index` collector branch:

- [#629](redis/redis-vl-python#629) — RAAE-1604:
config + runtime refactor (immutable `BindingRuntime`, per-binding
startup/teardown, `resolve_binding` routing, single global concurrency
semaphore)
- [#630](redis/redis-vl-python#630) — RAAE-1605:
`list-indexes` discovery tool
- [#631](redis/redis-vl-python#631) — RAAE-1606:
`search-records` index routing
- [#632](redis/redis-vl-python#632) — RAAE-1607:
`upsert-records` index routing + per-index write policy
- [#633](redis/redis-vl-python#633) — RAAE-1608:
concept/how-to/README docs

Each stacked PR was reviewed (human + Cursor Bugbot) and its threads
resolved before merge; this branch is the sum of those merges plus a
sync with `main`.

## Synced with `main`

The branch is up to date with `main`, including the recently merged MCP
security work — **Host/Origin header validation
([#643](redis/redis-vl-python#643 and the
**nltk drop
([#645](redis/redis-vl-python#645 — pulled
in via merge, so this PR's diff contains **only** the epic's own changes
(main's commits are in the merge base).

## Security review

A security review of the epic diff was run (auth scope enforcement,
read-only/write policy, index routing, info leakage, injection,
config/vectorizer resolution). **No findings** — tokenless HTTP is
rejected upstream by the SDK auth middleware, scopes and read-only
policy are enforced at both registration and per-call, routing is
confined to configured bindings, and `redis_name` is never exposed by
`list-indexes`.

## Verification

- Full MCP unit + integration suite: **283 passed / 1 skipped** on
`redis:8.2` (now runs without nltk).
- `mypy` clean; `black`/`isort` clean.
- Backward compatibility covered by dedicated tests (single-binding
defaults, omitted-`index` behavior, unchanged response contract aside
from the additive `index` echo).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

[RAAE-1603]:
https://redislabs.atlassian.net/browse/RAAE-1603?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes MCP server startup, routing, and write boundaries across
bindings; single-index behavior is preserved but multi-index
misconfiguration or routing errors could affect production assistants.
> 
> **Overview**
> **Multi-index MCP server** — One process can expose several logical
index bindings from YAML `indexes`, each with its own schema inspection,
search config, vectorizer, and runtime limits. Startup is
all-or-nothing: any binding failure prevents the server from starting.
> 
> **Routing and discovery** — New **`list-indexes`** tool enumerates
logical ids, filterable fields, `upsert_available`, and optional limits
(without exposing `redis_name`). **`search-records`** and
**`upsert-records`** accept an optional **`index`** argument; responses
echo the resolved id. With a single binding, omitting `index` still
works; with multiple bindings, omitting or using an unknown id returns
`invalid_request`.
> 
> **Write policy** — Global `--read-only` / `REDISVL_MCP_READ_ONLY` plus
per-binding **`read_only: true`** combine into
**`effective_read_only`**. `upsert-records` is registered only if at
least one binding is writable; writes to a read-only binding fail with
**`forbidden`** before Redis is touched.
> 
> **Implementation** — Config drops the “exactly one index” rule and
adds **`description`** / **`read_only`** on bindings. Server state moves
to per-binding **`BindingRuntime`** and **`resolve_binding()`**; removed
single-index helpers like `get_index()`. Search tool descriptions omit
per-schema hints when multiple indexes are configured and point clients
to `list-indexes`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
553e55f4e93b306b643e3b8aca157e7a40a1497b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants