需要 Redis 8+ 或 Redis Cloud/Enterprise 等支持向量检索的部署,普通旧版 Redis 不行;MCP 功能要额外装 pip install redisvl[mcp];Docker 示例默认映射 6379 端口,本地已有 Redis 会冲突
redis-vl-python
redisMIT活跃维护面向 Redis 的 AI 原生 Python 客户端,把向量检索、缓存和 RAG 所需的数据操作封装成简单接口,省去自己拼装底层命令。
Redis Vector Library. The AI-native Python client for Redis.
pip install redisvl
docker run -d --name redis -p 6379:6379 redis:latestREADME 未说明;仅要求 Python >= 3.10 和一个可连接的 Redis 部署(Docker 示例用 redis:latest,即 Redis 8+ 自带向量检索)
Redis 官方 AI 原生 Python 客户端,把向量检索、语义缓存和 LLM 记忆直接建在 Redis 上
面向 Redis 的 AI 原生 Python 客户端,把向量检索、缓存和 RAG 所需的数据操作封装成简单接口,省去自己拼装底层命令。
核心能力
- 用 YAML 或字典定义 IndexSchema 管理索引与 CRUD
- 支持向量相似度检索并叠加 tag、数值、地理等元数据过滤
- 提供混合检索,融合语义与全文信号
- 内置语义缓存、LLM 记忆与语义路由等 AI 扩展
- 附带 rvl CLI 与 MCP Server 暴露已有索引给 MCP 客户端
容易踩的坑
- v0.31.0最新正式版2026-11-06 · 2026-11-06 09:05 UTC
RedisVL 0.31.0 adds Python 3.15 support, makes async paths that wrap a sync Redis client behave like a native async client, and changes how
HybridQuerytreats zero-valued combination parameters. Read the behaviour change below before upgrading if you setlinear_alpha,rrf_constantorrrf_windowto0.Highlights
Python 3.15 support
RedisVL now supports Python 3.15, and every extra installs on it except where an upstream package's own Python bounds block it:
voyageaion 3.15, andsql-redison 3.14 and later. Themcpextra now requiresbeartype>=0.23.1. (#768, @vishal-bala)Sync clients converted to async keep their configuration
SemanticCache,AsyncSearchIndexand the other async paths that accept a sync client now carry over more of that client's setup when they convert it:- TLS clients (
Redis(ssl=True, ...)), unix-socket clients and customSSLConnectionsubclasses now work. (#792, @Yarmoluk) - The client's retry policy is preserved, so the async client reconnects after a dropped connection. (#817, @Yarmoluk)
Sentinel-managed clients,
RedisClusterclients and clients with a sync-only setting such as OCSP validation now raiseValueErrorat conversion time, pointing you toredis_url. Previously they failed withTypeErroron the first command.Behaviour change: zero-valued hybrid parameters are honoured
HybridQuerypreviously droppedlinear_alpha=0andrrf_constant=0; it now sends them, so affected queries rank differently. The same applies to the MCP server'ssearch.params.linear_text_weight: 0andrrf_constant: 0on native hybrid search.rrf_window=0now returns a server error instead of being ignored. (#819, @hyeonsang010716)Other fixes
CohereTextVectorizer.aembedandaembed_manynow make non-blocking calls through Cohere's async client. If you pass your ownhttpx_client, also passasync_httpx_clientto keep async calls non-blocking. (#785, @Yarmoluk)- Normalised COSINE scores from
VectorQuery,VectorRangeQuery,AggregateHybridQueryandMultiVectorQuerystay within[0, 1]when floating-point rounding produces a slightly negative distance. (#823, @limjoobin) - Existing SVS-VAMANA indexes created without compression now load. (#790, @itsrayeedscodespace)
Dependencies
- The
fastmcpfloor is raised to the oldest release that works with the MCP server. (#807, @vishal-bala) - Dependabot alerts in
uv.lockare cleared and dev tooling moves to pytest 9. (#799, #813, @dependabot, @vishal-bala)
Contributors
Thanks to @Yarmoluk, @hyeonsang010716, @limjoobin and @itsrayeedscodespace for their contributions to this release, including first contributions from @hyeonsang010716 and @itsrayeedscodespace.
Full changelog: https://github.com/redis/redis-vl-python/compare/v0.30.0...v0.31.0
- TLS clients (
- v0.30.02026-11-02 · 2026-11-02 09:36 UTC
查看更新说明
Release Notes
perf: run SemanticCache.check() as KNN with a client-side threshold (FDE-85) (#754)
SemanticCache.check()andacheck()run as a KNN query with the distance threshold applied client-side. Lookups with a selective filter expression take up to about a third less time, and unfiltered lookups take 2–3% longer.feat(mcp): serve async Python functions as MCP tools (#758, #759, #760, #761)
The MCP server can now serve your own async Python functions as tools, called code tools. There are two ways to register one. If you run the server from your own process, decorate the function with
server.code_tool(...). If you runrvl mcp, mark the function with@code_toolfromredisvl.mcp, list its module underserver.code_tool_modulesand setserver.allow_code_tools: true. That flag defaults tofalsebecause importing a module runs its code with the server's privileges, and each module must be importable by the server process.A function qualifies only if it takes a
ToolContextas its first positional parameter, annotates its other parameters and has a description, either its docstring ordescription=. TheToolContextis the tool's only route to Redis. Its index handle stays inside the bound index, applies the binding's concurrency cap and request timeout to every call, and offers writes, addressed by document id, only to tools declared withwrites=True. Every call is checked against the read scope, the write scope for a writing tool and any per-toolscope=(when authentication is configured), and errors are mapped to the MCP error contract.feat(router): add async aroute and aroute_many to SemanticRouter (#784)
SemanticRoutergainsaroute(),aroute_many(),adisconnect()and anaindexproperty. The async index is created on first use. Routers given an SSL, unix-socket, Sentinel orRedisClusterclient can't convert it to async; passredis_urlto the router for async routing in those setups. Vectorizers without a nativeaembed(e.g. the defaultHFTextVectorizer) still embed synchronously; the Redis call is non-blocking either way. The async client is bound to the event loop that made the first call; calladisconnect()before switching loops.
🚀 Enhancement
- perf: run SemanticCache.check() as KNN with a client-side threshold (FDE-85) #754 (@vishal-bala)
- feat(mcp): serve async Python functions as MCP tools, in four stacked PRs (@vishal-bala)
- feat(router): add async aroute and aroute_many to SemanticRouter #784 (@Yarmoluk)
📝 Documentation
- docs: tighten PR template guidance and make Notes opt-in #803 (@vishal-bala)
🧪 Tests
- test(query): compare KNN results by id in test_search_and_query #804 (@vishal-bala)
CI/CD Changes
- fix(ci): route Dependabot PRs through the maintainer-dispatched service tests #802 (@vishal-bala)
- ci(release): Ditch
conventional-commitsplugin from auto releases [#798](http
- v0.29.02026-10-30 · 2026-10-30 11:09 UTC
查看更新说明
Release Notes
fix(router): apply per-route thresholds before max_k truncation (#766)
Fixed
SemanticRouter.route()androute_many()sometimes missing a route that met itsdistance_threshold. Each route's threshold is now applied before results are truncated tomax_k, so a closer route that fails its own threshold no longer displaces a farther one that passes. Previouslyroute()could return an emptyRouteMatchandroute_many()could return fewer matches than expected.fix(message-history): fall back within the requested session in get_relevant() (#765)
SemanticMessageHistory.get_relevant()andSemanticSessionManager.get_relevant()called with bothsession_tagandfall_back=Truenow fall back to the recent messages of that session. Previously they returned the recent messages of the instance's default session.perf(embeddings-cache): refresh and set TTLs in the same round trip as each lookup and write (#764)
EmbeddingsCachelookups and writes with a TTL configured, including those a vectorizer makes throughcache=, now refresh or set the expiry in the same round trip, so cached embedding calls are faster. With a TTL configured, a credential that cannot runEXPIREon the cache's keys now fails on a cache miss as well as on a hit.fix(index,router): keep SemanticRouter in step with the keyspace when a cluster UNLINK fails (#748)
On Redis Cluster,
SemanticRouter.remove_routeanddelete_route_referencesnow raisePartialDeletionErrorwhen some reference keys cannot be deleted, instead of returning normally. Deleting a route's last reference now removes the route, so code that readsto_dict()["routes"]by position should look routes up byname.fix(router): make Route.distance_threshold inclusive (#763)
SemanticRouternow treatsRoute.distance_thresholdas inclusive, consistent withVectorRangeQueryandSemanticCache: a reference whose distance exactly equals a route's threshold now matches that route instead of being dropped.perf: refresh SemanticCache hit TTLs in one pipelined round trip (FDE-84) (#753)
SemanticCache.check()andacheck()refresh the TTLs of all hits in one round trip, so lookups that return several hits from a cache with a TTL are faster.
🚀 Enhancement
- feat(index): debug-log query type, latency and result count in query() #750 (@jackiectl2)
🐛 Bug Fix
- fix(migration): support RESP3 key enumeration #730 (@Kuang-xianxin)
- fix(router): apply per-route thresholds before max_k truncation #766 (@vishal-bala)
- fix(message-history): fall back within the requested session in get_relevant() #765 (@vishal-bala)
- chore(deps): bump the uv group across 1 directory with 2 updates #751 (@dependabot[bot])
- fix(index,router): keep SemanticRouter in step with the keyspace when a cluster UNLINK fails #748 (@vishal-bala)
- fix: keep vector fields in from_existing on RESP2 unified FT.INFO replies #742 (@desty)
- fix(router): make Route.distance_threshold inclusive [#7
- v0.28.02026-10-09 · 2026-10-09 13:34 UTC
查看更新说明
Release Notes
feat(mcp): scope custom tool queries to a tenant from a verified token claim (#738, #745) @vishal-bala
Custom tool profiles can scope every query to a tenant read from the caller's verified token, with
lock.inject. The injected field is never offered to the model, and the server refuses to start an injecting profile when authentication is off, when it runs over stdio, or when another tool can reach the same index without the tenant scope.redisvl.query.filter.is_match_all_filteris now public. It returnsTruefor a filter that would match every document, includingNone,"*"and an uninitialisedFilterExpression.refactor(index): explicit client ownership and removal of the deprecated connection APIs (#726, #727, #728) @vishal-bala
SearchIndexandAsyncSearchIndexaccept a newowns_clientargument controlling whether the index closes its Redis client when it is disconnected or garbage collected. The default is unchanged: an index closes a client it created itself and never one passed asredis_client. Passowns_client=Trueto hand over a client you created, orowns_client=Falseto keep one the index would otherwise close.The deprecated connection APIs are removed. Each removed keyword now raises
TypeErrornaming its replacement, where previously the index keywords were silently ignored andurlfailed with an unrelated error from redis-py.Removed Use instead SearchIndex.connect(),SearchIndex.set_client()and theirAsyncSearchIndexcounterpartsredis_clientorredis_urlin the constructor, withowns_client=Trueif the index should close a client you suppliedconnection_argsandredis_kwargson the index constructorsconnection_kwargs, with the same valueRedisConnectionFactory.connect()get_redis_connection()orget_async_redis_connection()urlon all five connection factory functionsredis_urlAsyncSearchIndexno longer converts a sync Redis client for you. Pass an async client, or convert a non-cluster client yourself withRedisConnectionFactory.sync_to_async_redis(). Passing the wrong flavour of client to either index class now raisesTypeErrorat construction rather than failing at first use; an async client passed toSearchIndexpreviously raisedValueError.Three further behaviour changes can surface errors earlier than before:
urlpreviously took precedence overredis_urlon the async factory, so anAsyncSearchIndexbuilt with bothredis_urland aurlinsideconnection_kwargsconnected to the latter. That combination now raises.- An index given a
redis_clientand noredis_urlraisesRedisVLErrorwhen it tries to reconnect after that client is closed, instead of falling back toREDIS_URL. - A cache built from a
redis_urlraisesConnectionErrorwhen its async client is created rather than at the first command, so an unreachable server surfaces at construction.
fix(schema): use longitude first for GEO coordinates (#747) @fallintoplace
GEO validation and schema inference now expect
"longitude,latitude", the order Redis uses, instead of rejecting valid values such as-122.4194,37.7749. Values stored as"latitude,longitude"now fail validation when the longitude is beyond ±90; Redis was already misplacing or skipping them, so swap the order and reload. A swapped pair with both numbers within ±90 still passes, so validation cannot confirm that existing data is correct.fix(router): reject an empty reference id instead of matching every one (#718) @vishal-bala
`SemanticRouter.g
- v0.27.22026-09-10 · 2026-09-10 10:50 UTC
查看更新说明
Release Notes
fix: permit clear() when create_index=False, and drop its FT.INFO dependency (#704)
SemanticCache,MessageHistory,SemanticMessageHistoryandSemanticRouterconstructed withcreate_index=Falsecan now callclear()to remove their entries. Previously bothclear()anddelete()raisedValueErrorunder that flag;delete()still does, because it drops the index. This is a behavioural change: code that caughtValueErrorfromclear()and treated it as "unavailable" will now delete data.SearchIndex.clear()andAsyncSearchIndex.clear()no longer issueFT.INFO. They size their internal delete loop with aCountQueryinstead, so clearing an index is available to a credential built from+@read +@write, which is deniedFT.INFO. Clearing also no longer stops early on a page whose keys could not be deleted.EXTERNAL_INDEX_LIFECYCLE_CONFLICTinredisvl.extensions.constantsis renamed toEXTERNAL_INDEX_DROP_CONFLICT, and its message has changed. Code importing the old name, or matching on the old text, needs updating.
🐛 Bug Fix
- fix: escape glob metacharacters in SCAN match patterns #702 @vishal-bala
- fix: EmbeddingsCache batch writes silently dropped on async Redis Cluster #697 @vishal-bala
- fix: keep
paginategoing past a page whose matches were all dropped #701 @vishal-bala - fix: SemanticCache fails to connect to Sentinel instances with quoted passwords #732 @nnick14
- fix(tests): isolate the LangCache integration suite from its shared cache #725 @vishal-bala
- fix: permit clear() when create_index=False, and drop its FT.INFO dependency #704 @vishal-bala
- fix: cache clear() and migration key scans hang or crash on Redis Cluster #703 @vishal-bala
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Documentation • Recipes • GitHub
Introduction
Redis Vector Library (RedisVL) is the production-ready Python client for AI applications built on Redis. Lightning-fast vector search meets enterprise-grade reliability.
Perfect for building RAG pipelines with real-time retrieval, AI agents with memory and semantic routing, and recommendation systems with fast search and reranking.
| 🎯 Core Capabilities | 🚀 AI Extensions | 🛠️ Dev Utilities |
|---|---|---|
| Index ManagementSchema design, data loading, CRUD ops | Semantic CachingReduce LLM costs & boost throughput | CLIIndex management from terminal |
| Vector SearchSimilarity search with metadata filters | LLM MemoryAgentic AI context management | Async SupportAsync indexing and search for improved performance |
| Complex FilteringCombine multiple filter types | Semantic RoutingIntelligent query classification | Vectorizers8+ embedding provider integrations |
| Hybrid SearchCombine semantic & full-text signals | Embedding CachingCache embeddings for efficiency | RerankersImprove search result relevancy |
| MCP ServerExpose one or more existing Redis indexes to MCP clients |
💪 Getting Started
Installation
Install redisvl into your Python (>=3.10) environment using pip:
pip install redisvl
Install the MCP server extra when you want to expose one or more existing Redis indexes through MCP:
pip install redisvl[mcp]
For more detailed instructions, visit the installation guide. For MCP concepts and setup, see the RedisVL MCP docs and the MCP how-to guide.
Redis
Choose from multiple Redis deployment options:
Redis Cloud offers a fully managed Redis service with a free tier, perfect for getting started quickly.
Run Redis locally using Docker:
docker run -d --name redis -p 6379:6379 redis:latest
This runs Redis 8+ with built-in vector search capabilities.
Redis Enterprise provides enterprise-grade features for production deployments.
Configure Redis Sentinel for high availability:
# Connect via Sentinel
redis_url="redis+sentinel://sentinel1:26379,sentinel2:26379/mymaster"
Azure Managed Redis provides fully managed Redis Enterprise on Microsoft Azure.
💡 Tip: Enhance your experience and observability with the free Redis Insight GUI.
Overview
Index Management
-
Design a schema for your use case that models your dataset with built-in Redis indexable fields (e.g. text, tags, numerics, geo, and vectors).
index: name: user-idx prefix: user storage_type: json fields: - name: user type: tag - name: credit_score type: tag - name: job_title type: text attrs: sortable: true no_index: false # Index for search (default) unf: false # Normalize case for sorting (default) - name: embedding type: vector attrs: algorithm: flat dims: 4 distance_metric: cosine datatype: float32from redisvl.schema import IndexSchema schema = IndexSchema.from_yaml("schemas/schema.yaml")from redisvl.schema import IndexSchema schema = IndexSchema.from_dict({ "index": { "name": "user-idx", "prefix": "user", "storage_type": "json" }, "fields": [ {"name": "user", "type": "tag"}, {"name": "credit_score", "type": "tag"}, { "name": "job_title", "type": "text", "attrs": { "sortable": True, "no_index": False, # Index for search "unf": False # Normalize case for sorting } }, { "name": "embedding", "type": "vector", "attrs": { "algorithm": "flat", "datatype": "float32", "dims": 4, "distance_metric": "cosine" } } ] })📚 Learn more about schema design and schema creation.
-
Create a SearchIndex class with an input schema to perform admin and search operations on your index in Redis:
from redis import Redis from redisvl.index import SearchIndex # Define the index index = SearchIndex(schema, redis_url="redis://localhost:6379") # Create the index in Redis index.create()An async-compatible index class also available: AsyncSearchIndex.
-
Load and fetch data to/from your Redis instance:
data = {"user": "john", "credit_score": "high", "embedding": [0.23, 0.49, -0.18, 0.95]} # load list of dictionaries, specify the "id" field index.load([data], id_field="user") # fetch by "id" john = index.fetch("john")
Retrieval
Define queries and perform advanced searches over your indices, including vector search, complex filtering, and hybrid search combining semantic and full-text signals.
| Query Type | Use Case | Description |
|---|---|---|
VectorQuery | Semantic similarity search | Find similar vectors with optional filters |
RangeQuery | Distance-based search | Vector search within a defined distance range |
FilterQuery | Metadata filtering | Filter and search using metadata fields |
TextQuery | Full-text search | BM25-based keyword search with field weighting |
HybridQuery | Combined search | Combine semantic + full-text signals (Redis 8.4.0+) |
CountQuery | Counting records | Count documents matching filter criteria |
Vector Search
-
VectorQuery - Flexible vector queries with customizable filters enabling semantic search:
from redisvl.query import VectorQuery query = VectorQuery( vector=[0.16, -0.34, 0.98, 0.23], vector_field_name="embedding", num_results=3, # Optional: tune search performance with runtime parameters ef_runtime=100 # HNSW: higher for better recall ) # run the vector search query against the embedding field results = index.query(query) -
RangeQuery - Vector search within a defined range paired with customizable filters
Complex Filtering
Build complex filtering queries by combining multiple filter types (tags, numerics, text, geo, timestamps) using logical operators:
```python
from redisvl.query import VectorQuery
from redisvl.query.filter import Tag, Num
# Combine multiple filter types
tag_filter = Tag("user") == "john"
price_filter = Num("price") >= 100
# Create complex filtering query with combined filters
query = VectorQuery(
vector=[0.16, -0.34, 0.98, 0.23],
vector_field_name="embedding",
filter_expression=tag_filter & price_filter,
num_results=10
)
results = index.query(query)
```
- FilterQuery - Standard search using filters and full-text search
- CountQuery - Count the number of indexed records given attributes
- TextQuery - Full-text search with support for field weighting and BM25 scoring
Learn more about building complex filtering queries.
Hybrid Search
Combine semantic (vector) search with full-text (BM25) search signals for improved search quality:
-
HybridQuery - Native hybrid search combining text and vector similarity (Redis 8.4.0+):
from redisvl.query import HybridQuery hybrid_query = HybridQuery( text="running shoes", text_field_name="description", vector=[0.1, 0.2, 0.3], vector_field_name="embedding", combination_method="LINEAR", # or "RRF" num_results=10 ) results = index.query(hybrid_query) -
AggregateHybridQuery - Hybrid search using aggregation (compatible with earlier Redis versions)
Learn more about hybrid search.
Dev Utilities
Vectorizers
Integrate with popular embedding providers to greatly simplify the process of vectorizing unstructured data for your index and queries.
from redisvl.utils.vectorize import CohereTextVectorizer
# set COHERE_API_KEY in your environment
co = CohereTextVectorizer()
embedding = co.embed(
text="What is the capital city of France?",
input_type="search_query"
)
embeddings = co.embed_many(
texts=["my document chunk content", "my other document chunk content"],
input_type="search_document"
)
Learn more about using vectorizers in your embedding workflows.
Rerankers
Integrate with popular reranking providers to improve the relevancy of the initial search results from Redis
Extensions
RedisVL Extensions provide production-ready modules implementing best practices and design patterns for working with LLM memory and agents. These extensions encapsulate learnings from our user community and enterprise customers.
💡 Have an idea for another extension? Open a PR or reach out to us at [email protected]. We're always open to feedback.
Semantic Caching
Increase application throughput and reduce the cost of using LLM models in production by leveraging previously generated knowledge with the SemanticCache.
from redisvl.extensions.cache.llm import SemanticCache
# init cache with TTL and semantic distance threshold
llmcache = SemanticCache(
name="llmcache",
ttl=360,
redis_url="redis://localhost:6379",
distance_threshold=0.1 # Redis COSINE distance [0-2], lower is stricter
)
# store user queries and LLM responses in the semantic cache
llmcache.store(
prompt="What is the capital city of France?",
response="Paris"
)
# quickly check the cache with a slightly different prompt (before invoking an LLM)
response = llmcache.check(prompt="What is France's capital city?")
print(response[0]["response"])
>>> Paris
Learn more about semantic caching for LLMs.
Embedding Caching
Reduce computational costs and improve performance by caching embedding vectors with their associated text and metadata using the EmbeddingsCache.
from redisvl.extensions.cache.embeddings import EmbeddingsCache
from redisvl.utils.vectorize import HFTextVectorizer
# Initialize embedding cache
embed_cache = EmbeddingsCache(
name="embed_cache",
redis_url="redis://localhost:6379",
ttl=3600 # 1 hour TTL
)
# Initialize vectorizer with cache
vectorizer = HFTextVectorizer(
model="sentence-transformers/all-MiniLM-L6-v2",
cache=embed_cache
)
# First call computes and caches the embedding
embedding = vectorizer.embed("What is machine learning?")
# Subsequent calls retrieve from cache (much faster!)
cached_embedding = vectorizer.embed("What is machine learning?")
>>> Cache hit! Retrieved from Redis in <1ms
Learn more about embedding caching for improved performance.
LLM Memory
Improve personalization and accuracy of LLM responses by providing user conversation context. Manage access to memory data using recency or relevancy, powered by vector search with the MessageHistory.
from redisvl.extensions.message_history import SemanticMessageHistory
history = SemanticMessageHistory(
name="my-session",
redis_url="redis://localhost:6379",
distance_threshold=0.7
)
# Supports roles: system, user, llm, tool
# Optional metadata field for additional context
history.add_messages([
{"role": "user", "content": "hello, how are you?"},
{"role": "llm", "content": "I'm doing fine, thanks."},
{"role": "user", "content": "what is the weather going to be today?"},
{"role": "llm", "content": "I don't know", "metadata": {"model": "gpt-4"}}
])
# Get recent chat history
history.get_recent(top_k=1)
# >>> [{"role": "llm", "content": "I don't know", "metadata": {"model": "gpt-4"}}]
# Get relevant chat history (powered by vector search)
history.get_relevant("weather", top_k=1)
# >>> [{"role": "user", "content": "what is the weather going to be today?"}]
# Filter messages by role
history.get_recent(role="user") # Get only user messages
history.get_recent(role=["user", "system"]) # Or multiple roles
Learn more about LLM memory.
Semantic Routing
Build fast decision models that run directly in Redis and route user queries to the nearest "route" or "topic".
from redisvl.extensions.router import Route, SemanticRouter
routes = [
Route(
name="greeting",
references=["hello", "hi"],
metadata={"type": "greeting"},
distance_threshold=0.3,
),
Route(
name="farewell",
references=["bye", "goodbye"],
metadata={"type": "farewell"},
distance_threshold=0.3,
),
]
# build semantic router from routes
router = SemanticRouter(
name="topic-router",
routes=routes,
redis_url="redis://localhost:6379",
)
router("Hi, good morning")
# >>> RouteMatch(name='greeting', distance=0.273891836405)
Learn more about semantic routing.
Command Line Interface
Create, destroy, and manage Redis index configurations from a purpose-built CLI interface: rvl.
$ rvl --help
usage: rvl <command> [<args>]
Redis Vector Library CLI.
Command groups:
index Create, inspect, list, and delete Redis search indexes
stats Show statistics for an existing Redis search index
version Show the installed RedisVL version
mcp Run the RedisVL MCP server
Examples:
rvl index --help
rvl index create -s schema.yaml
rvl stats -i user_index
rvl mcp --config /path/to/mcp.yaml
Use rvl index --help to see documented subcommands such as create, info, listall, delete, and destroy. Use rvl stats --help to see both index-name and schema-path examples plus the shared Redis connection options for data-plane commands.
Run the MCP server over stdio (default):
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml
Or over Streamable HTTP for remote MCP clients:
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml --transport streamable-http --host 0.0.0.0 --port 8000
Or over SSE:
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml --transport sse --host 0.0.0.0 --port 9000
Use --read-only to expose search without upsert.
Read more about using the CLI and running RedisVL MCP.
MCP Server
RedisVL includes an MCP server that lets MCP-compatible clients search or upsert data in one or more existing Redis indexes through a small, stable tool contract.
The server:
- connects to one or more existing Redis Search indexes, each addressed by a logical id
- reconstructs each index's schema from Redis at startup
- uses each index's configured vectorizer for query embedding and optional upsert embedding
- exposes
list-indexesfor discovery,search-records, and (unless every index is read-only)upsert-records - supports stdio (default), Streamable HTTP, and SSE transports
A single configured index is the simplest case and works exactly as before — callers omit the index selector. With multiple indexes, clients call list-indexes first and pass the chosen index to search-records and upsert-records.
Run it over stdio (default):
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml
Run it over Streamable HTTP for remote clients:
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml --transport streamable-http --host 0.0.0.0 --port 8000
Use --read-only when clients should only search:
uvx --from redisvl[mcp] rvl mcp --config /path/to/mcp.yaml --read-only
For configuration details, tool arguments, and examples, see the RedisVL MCP docs and the MCP how-to guide.
🚀 Why RedisVL?
Redis is a proven, high-performance database that excels at real-time workloads. With RedisVL, you get a production-ready Python client that makes Redis's vector search, caching, and session management capabilities easily accessible for AI applications.
Built on the Redis Python client, RedisVL provides an intuitive interface for vector search, LLM caching, and conversational AI memory - all the core components needed for modern AI workloads.
😁 Helpful Links
For additional help, check out the following resources:
🫱🏼🫲🏽 Contributing
Please help us by contributing PRs, opening GitHub issues for bugs or new feature ideas, improving documentation, or increasing test coverage. Read more about how to contribute!
🚧 Maintenance
This project is supported by Redis, Inc on a good faith effort basis. To report bugs, request features, or receive assistance, please file an issue.