feat(MCP): Implement the base framework for a RedisVL MCP server#532
feat(MCP): Implement the base framework for a RedisVL MCP server#532vishal-bala wants to merge 6 commits intofeat/RAAE-1395-redisvl-mcpfrom
Conversation
🛡️ Jit Security Scan Results✅ No security findings were detected in this PR
Security scan by Jit
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf0f0895a2
ℹ️ 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".
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.
| def vector_field_dims(self) -> Optional[int]: | ||
| """Return the configured vector dimension when the field exposes one.""" | ||
| attrs = self.vector_field.attrs | ||
| return getattr(attrs, "dims", None) |
There was a problem hiding this comment.
Repeated schema reconstruction on every property access
Low Severity
The vector_field and vector_field_dims properties each call to_index_schema(), which fully reconstructs and re-validates an IndexSchema via model_validate on every access. The model validator _validate_runtime_mapping also calls to_index_schema(). Any code path accessing vector_field_dims (e.g., _validate_vectorizer_dims during startup) triggers two redundant schema constructions. Caching the result or computing these values once during validation would avoid the repeated work.
Additional Locations (1)
| return await asyncio.wait_for( | ||
| awaitable, | ||
| timeout=self.config.runtime.request_timeout_seconds, | ||
| ) |
There was a problem hiding this comment.
Unawaited coroutine leak in early guard path
Low Severity
run_guarded accepts an Awaitable[Any] parameter. If the caller passes a coroutine and the early guard (self.config is None or self._semaphore is None) raises RuntimeError, the coroutine is never awaited. Python emits a RuntimeWarning: coroutine was never awaited in this case, which can obscure the actual error during debugging.


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.
Note
Medium Risk
Introduces a new MCP server surface area that manages Redis index lifecycle and vectorizer initialization with concurrency/timeouts; failures here could impact startup/shutdown behavior and dependency handling when the
mcpextra is used.Overview
Adds a new optional
redisvl.mcppackage (guarded behind a newmcpextra) that can start and manage an MCP server process around RedisVL: YAML-driven config loading (with${VAR}/${VAR:-default}env substitution), runtime limits validation, and vectorizer class resolution.Implements
RedisVLMCPServerstartup/shutdown lifecycle to create/validate anAsyncSearchIndex, build a configured vectorizer off-thread, enforce request concurrency/timeouts via a semaphore, and fail fast on vector-dimension mismatches; adds deterministic exception mapping viamap_exception.Updates import-sanity tests to skip
redisvl.mcpwhen optional deps aren’t installed, and adds unit/integration tests covering config parsing/validation, settings env overrides, error mapping, and server startup/shutdown cleanup behavior.Written by Cursor Bugbot for commit 6b17caa. This will update automatically on new commits. Configure here.