feat(MCP): Introduce a configurable MCP server for RedisVL indexes#575
feat(MCP): Introduce a configurable MCP server for RedisVL indexes#575vishal-bala merged 20 commits intomainfrom
Conversation
…feat/RAAE-1395-redisvl-mcp
#532) This PR implements the base framework for a RedisVL MCP server. In this iteration, the goal is to introduce the scaffolding for the MCP server to the extent that the server is runnable but does not have any meaningful functionality. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces a new MCP server layer that manages Redis connections, schema inspection/override logic, and request concurrency/timeouts; issues here could impact startup/shutdown reliability and Redis resource cleanup. Dependency changes also add a sizable optional stack (`fastmcp`), increasing integration surface area. > > **Overview** > Adds a new optional `redisvl.mcp` package that provides a runnable MCP server scaffold (`RedisVLMCPServer`) with explicit startup/shutdown lifecycle, guarded request execution (timeouts + max concurrency), and vectorizer initialization/cleanup. > > Introduces YAML-based MCP configuration loading (`load_mcp_config`) with environment-variable substitution, strict validation (single index binding, runtime limits, field mappings), and schema inspection + safe override merging to patch incomplete `FT.INFO` output while preventing type/path identity changes. > > Adds `MCPSettings` (env-backed via `pydantic-settings`), deterministic error mapping (`map_exception`), integration/unit tests for startup/teardown and guarded shutdown behavior, and a new `mcp` optional dependency group (plus import-sanity skips for `redisvl.mcp`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d29d307. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
> Builds on top of #532 This PR implements a tool for searching records in a configured index for the RedisVL MCP. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new MCP search tool and extends server startup/config validation, including runtime probing for native hybrid search; issues could affect MCP server startup or query behavior across Redis/redis-py versions. > > **Overview** > Adds an MCP `search-records` tool that executes vector, fulltext, or hybrid searches against the configured index, with pagination, field projection, and normalized result formatting (stable `id`/`score`/`score_type`). > > Extends MCP YAML config with a required `search` section (`type` + validated `params`) and validates hybrid configs against runtime capabilities by probing redis/redis-py for native hybrid support during server startup. > > Introduces a structured filter DSL (`and`/`or`/`not`, field ops like `eq`/`gte`/`in`/`exists`) mapped to RedisVL `FilterExpression`s with a new `INVALID_FILTER` error code; adds comprehensive unit/integration coverage and minor typing fixes in `redisvl.query.filter`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 078b779. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
🛡️ Jit Security Scan Results✅ No security findings were detected in this PR
Security scan by Jit
|
> Builds on top of #539 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces a new MCP write path that validates, embeds, and loads user-supplied records into Redis, which could impact data integrity and performance if misused despite added validation and limits. > > **Overview** > Adds a new MCP tool, `upsert-records`, that accepts a batch of records, validates request shape and schema conformance, optionally generates missing vector embeddings via the configured vectorizer (with async/sync and batch fallbacks), and upserts them into the configured index while returning the resulting keys. > > Tool registration is wired into `RedisVLMCPServer` (disabled when `read_only`), exposed via `redisvl.mcp.tools.__all__`, and covered by new unit + integration tests including vector serialization for HASH storage, request/runtime limit enforcement, non-mutation of inputs, and error mapping that flags `partial_write_possible` on backend failures. > > Separately, `mcp/filters.py` is adjusted to use `typing.Union`/`List`/`Dict` annotations (dropping newer `|` syntax) without changing filter behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8aef518. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
> Builds on top of #540 ## Summary - The repo did not have an end-to-end MCP entrypoint, which made the MCP design in `spec/MCP.md` incomplete in practice and left users without a supported way to run RedisVL as an MCP server. - That gap creates friction for local agent integrations: the server contract, config, filters, and tools existed as design and implementation work, but there was no polished CLI path and no clear packaging/runtime story for using it. - This change completes the MCP implementation by adding the `rvl mcp` command, wiring in lazy optional-dependency handling, and rounding out the MCP server/config/tooling surface with tests and documentation updates. - It also adds task-oriented help text for the new subcommand and keeps the base CLI usable without MCP extras installed. ## Testing - `uv run python -m pytest tests/unit/test_cli_mcp.py -q` - `uv run python -m pytest tests/unit/test_mcp -q` - `uv run rvl` - `uv run rvl mcp --help` - Manual smoke check: started `uv run rvl mcp --config /tmp/redisvl_mcp_smoke/config.yaml` against a live Redis container - `uvx --from 'redisvl[mcp]' rvl mcp --config ...` currently resolves the published package, which does not yet include the new extra/CLI path, so that install-path check is not green until a release is cut <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new MCP CLI entrypoint and introduces an `upsert-records` tool that can write data into Redis indexes (including embedding generation/serialization), which could impact data integrity and runtime behavior if misconfigured. > > **Overview** > Adds a new `rvl mcp` subcommand that lazily loads optional MCP dependencies, enforces Python >=3.10, and runs the MCP server over stdio with improved help/usage and error handling. > > Extends the MCP server to conditionally register a new `upsert-records` tool when not in *read-only* mode, and exports it via `redisvl.mcp.tools`. The upsert tool validates request shape and schema, optionally generates missing embeddings via the configured vectorizer (with async/sync fallbacks), serializes HASH vector fields to buffers, and annotates backend failures as potentially partial writes. > > Includes comprehensive unit/integration tests covering CLI behavior, read-only tool registration, embedding/serialization behavior, and request validation; plus minor typing tweaks in `mcp/filters.py` to avoid newer annotation syntax. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9433eec. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Summary - Add a RedisVL MCP server, CLI entrypoint, configuration models, error handling, filter parsing, and `search-records` / `upsert-records` tools - Document how to run and configure MCP, including a new concepts page, a how-to guide, README updates, installation notes, and aligned spec examples - Cover the pain point of reimplementing Redis retrieval logic in each MCP client by exposing an existing Redis index through a stable, configuration-owned tool surface - Add unit and integration coverage for startup, config validation, search, upsert, filters, settings, and CLI behavior <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Mostly documentation/spec updates plus a small CLI lifecycle tweak around MCP server startup/shutdown; low risk but could affect `rvl mcp` process shutdown behavior. > > **Overview** > Adds first-class documentation for RedisVL’s MCP server, including a new `concepts/mcp` page and a detailed how-to guide for configuring and running `rvl mcp` (with `redisvl[mcp]` and Python 3.10+), plus cross-links from the README, install docs, and guide indexes. > > Updates MCP spec/example docs to reflect config-owned search behavior (no request `search_type`), read-only controlled via CLI/env rather than YAML, and `upsert-records` embedding behavior using `runtime.default_embed_text_field`. Also adjusts `redisvl/cli/mcp.py` to more robustly manage async server startup/run/shutdown when `run_async` isn’t available. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a99611a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7efc41f8d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
dd7e5fe to
396fdde
Compare
|
|
||
| RedisVL MCP works with a focused model: | ||
|
|
||
| - One server process binds to exactly one existing Redis index. |
There was a problem hiding this comment.
One MCP deployed per index?
There was a problem hiding this comment.
That's the scope for this first release, with the framework ready to be extended to support multiple indexes in the MCP! That's the next prioritized feature. The additional complexity with multiple indexes is that we have to give the agent a way to see and choose an index for each of its queries.
| operand = value["value"] | ||
| if field.type == "tag": | ||
| return _parse_tag_expression(field_name, normalized_op, operand) | ||
| if field.type == "text": |
There was a problem hiding this comment.
I think it would be valuable to have some generic filter builder helper at some point to make this kind of thing useful in the SDK for those users as well as internals like MCP filter build outs
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6e2fe5b. Configure here.
|
🚀 PR was released in |

This PR is an aggregation of changes reviewed in the following PRs:
search-recordstool to RedisVL MCP #539upsert-recordstool to RedisVL MCP #540Note
Medium Risk
Adds a new MCP server surface area that performs schema inspection, embedding, and optional write operations against Redis, increasing operational and correctness risk despite extensive validation and tests. Optional dependency gating and Python-version checks reduce impact on core installs but the new server path could affect Redis access patterns and resource lifecycle.
Overview
Adds an optional RedisVL MCP server that binds to one existing Redis Search index and exposes a stable tool contract for
search-recordsand (unless read-only)upsert-records, driven entirely by a YAML config.Introduces new MCP configuration/settings loading with env var substitution, schema inspection plus
schema_overrides, reserved-field and capability validation (including native vs fallback hybrid search), plus guarded concurrency/timeouts and deterministic error mapping. Updates thervlCLI and docs/README/installation to supportredisvl[mcp](Python 3.10+) and adds comprehensive unit/integration tests; also tweaks filter type hints and ignores.codex/.Reviewed by Cursor Bugbot for commit 6e2fe5b. Bugbot is set up for automated code reviews on this repo. Configure here.