{
  "schema_version": 2,
  "id": "integrate/google-adk/search-tools",
  "title": "Redis search tools",
  "url": "https://redis.io/docs/latest/integrate/google-adk/search-tools/",
  "summary": "Vector, hybrid, text, range, and SQL search tools for Google ADK agents, plus the RedisVL MCP server.",
  "tags": [
    "docs",
    "integrate",
    "oss",
    "rs",
    "rc"
  ],
  "last_updated": "2026-09-17T14:55:03+01:00",
  "page_type": "content",
  "content_hash": "3f6020cfca816033c20ab02bbcae14b7e8275fc8e2ea1656bdbfbc3aaf07cacb",
  "sections": [
    {
      "id": "overview-1",
      "title": "Overview",
      "role": "overview",
      "text": "adk-redis provides five in-process search tools that wrap [RedisVL](https://redis.io/docs/latest/develop/ai/redisvl) query types into ADK-compatible tools. The LLM sees each tool as a callable function and gets back structured results. For multi-agent or polyglot deployments, the same RedisVL index can also be served over MCP via the `rvl mcp` server and consumed with ADK's native `McpToolset` (see the [RedisVL MCP server](#redisvl-mcp-server) section below)."
    },
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "| Tool | Query type | Use case |\n|------|-----------|----------|\n| `RedisVectorSearchTool` | KNN vector similarity | Conceptual/semantic queries |\n| `RedisHybridSearchTool` | Vector + BM25 | Queries with specific terms + concepts |\n| `RedisTextSearchTool` | BM25 keyword | Exact terms, error messages, IDs |\n| `RedisRangeSearchTool` | Distance threshold | Exhaustive retrieval within a radius |\n| `RedisSQLSearchTool` | SQL `SELECT` | Structured filters (`WHERE`, `BETWEEN`, parameterized) |"
    },
    {
      "id": "vector-search",
      "title": "Vector search",
      "role": "content",
      "text": "Embeds the query using a vectorizer and performs K-nearest-neighbor search.\n\n[code example]"
    },
    {
      "id": "hybrid-search",
      "title": "Hybrid search",
      "role": "content",
      "text": "Combines vector similarity with BM25 keyword matching. Auto-detects whether your Redis server supports native hybrid search (Redis 8.4+ with RedisVL 0.13+). Falls back to client-side aggregation if not.\n\n[code example]"
    },
    {
      "id": "text-search",
      "title": "Text search",
      "role": "content",
      "text": "Pure BM25 keyword search. No embeddings or vectorizer needed.\n\n[code example]"
    },
    {
      "id": "range-search",
      "title": "Range search",
      "role": "content",
      "text": "Returns all documents within a distance threshold instead of top-K. Useful for exhaustive retrieval.\n\n[code example]"
    },
    {
      "id": "sql-search",
      "title": "SQL search",
      "role": "content",
      "text": "`RedisSQLSearchTool` wraps `redisvl.query.SQLQuery`. The LLM emits a SQL `SELECT` statement (with optional `:name` parameter placeholders) and the tool translates it into the right `FT.SEARCH` or `FT.AGGREGATE` call. Best for structured filters: tag equality, numeric ranges, multi-predicate `WHERE` clauses. Requires `pip install 'adk-redis[sql]'`.\n\n[code example]\n\nThe LLM might emit a call like:\n\n[code example]\n\nwith `params={\"max_price\": 100}`. See the [redis_sql_search example](https://github.com/redis-developer/adk-redis/tree/main/examples/redis_sql_search) for a runnable demo."
    },
    {
      "id": "redisvl-mcp-server",
      "title": "RedisVL MCP server",
      "role": "content",
      "text": "The five tools above run in-process against a Python `SearchIndex`. To serve one Redis index to multiple agents (Python, JS, Claude Desktop), or to put server-side guardrails like `--read-only` and bearer auth between the agent and the index, run RedisVL's MCP server (`rvl mcp`) and connect ADK's native `McpToolset` to it.\n\n[code example]\n\nThe server is configured per index via a YAML file and exposes two tools: `search-records` (vector / fulltext / hybrid, chosen at server start, with schema-aware filter and return-field hints) and `upsert-records` (suppress with `--read-only`). Supports `stdio`, `sse`, and `streamable-http` transports; bearer auth on HTTP.\n\nInstall the CLI with `pip install 'redisvl[mcp]>=0.18.2'`. For a runnable demo, see the [redisvl_mcp_search example](https://github.com/redis-developer/adk-redis/tree/main/examples/redisvl_mcp_search)."
    },
    {
      "id": "when-to-choose-in-process-vs-mcp",
      "title": "When to choose in-process vs MCP",
      "role": "content",
      "text": "| Path | Use when |\n|------|----------|\n| In-process tools (above) | Single Python agent, fast onboarding, complex Python-side `FilterExpression` composition. |\n| MCP server | Multi-agent or polyglot deployments, server-side ops gates, schema-aware tool descriptions. |\n\nRange and SQL search have no MCP equivalent today; use the in-process tools for either."
    },
    {
      "id": "multi-tool-agent",
      "title": "Multi-tool agent",
      "role": "content",
      "text": "Wire multiple search tools into a single agent and let the LLM choose the right one:\n\n[code example]\n\nThe `name` and `description` on each tool matter: the LLM reads them to decide which tool to call and when. Specific descriptions like \"Find products by semantic similarity\" work better than generic ones like \"search documents\"."
    },
    {
      "id": "more-info",
      "title": "More info",
      "role": "content",
      "text": "- [redis_search_tools example](https://github.com/redis-developer/adk-redis/tree/main/examples/redis_search_tools): vector, text, and range tools with a product catalog\n- [redis_sql_search example](https://github.com/redis-developer/adk-redis/tree/main/examples/redis_sql_search): SQL `SELECT` against a bound index\n- [redisvl_mcp_search example](https://github.com/redis-developer/adk-redis/tree/main/examples/redisvl_mcp_search): same corpus served via `rvl mcp` + ADK `McpToolset`\n- [RedisVL documentation](https://redis.io/docs/latest/develop/ai/redisvl)"
    }
  ],
  "examples": [
    {
      "id": "vector-search-ex0",
      "language": "python",
      "code": "from redisvl.index import SearchIndex\nfrom redisvl.utils.vectorize import HFTextVectorizer\nfrom adk_redis import RedisVectorSearchTool, RedisVectorQueryConfig\n\nvectorizer = HFTextVectorizer(model=\"redis/langcache-embed-v2\")\nindex = SearchIndex.from_existing(\"products\", redis_url=\"redis://localhost:6379\")\n\nvector_tool = RedisVectorSearchTool(\n    index=index,\n    vectorizer=vectorizer,\n    config=RedisVectorQueryConfig(num_results=5),\n    return_fields=[\"name\", \"description\", \"price\"],\n    name=\"search_products\",\n    description=\"Find products by semantic similarity.\",\n)",
      "section_id": "vector-search"
    },
    {
      "id": "hybrid-search-ex0",
      "language": "python",
      "code": "from adk_redis import RedisHybridSearchTool, RedisHybridQueryConfig\n\nhybrid_tool = RedisHybridSearchTool(\n    index=index,\n    vectorizer=vectorizer,\n    config=RedisHybridQueryConfig(\n        text_field_name=\"content\",\n        combination_method=\"LINEAR\",\n        linear_alpha=0.7,\n    ),\n    name=\"search_docs\",\n    description=\"Search documents using semantic and keyword matching.\",\n)",
      "section_id": "hybrid-search"
    },
    {
      "id": "text-search-ex0",
      "language": "python",
      "code": "from adk_redis import RedisTextSearchTool, RedisTextQueryConfig\n\ntext_tool = RedisTextSearchTool(\n    index=index,\n    config=RedisTextQueryConfig(\n        text_field_name=\"content\",\n        text_scorer=\"BM25STD\",\n    ),\n    return_fields=[\"title\", \"content\"],\n    name=\"keyword_search\",\n    description=\"Search for exact terms and phrases.\",\n)",
      "section_id": "text-search"
    },
    {
      "id": "range-search-ex0",
      "language": "python",
      "code": "from adk_redis import RedisRangeSearchTool, RedisRangeQueryConfig\n\nrange_tool = RedisRangeSearchTool(\n    index=index,\n    vectorizer=vectorizer,\n    config=RedisRangeQueryConfig(distance_threshold=0.5),\n    return_fields=[\"title\", \"content\"],\n    name=\"range_search\",\n    description=\"Find all documents within a semantic distance threshold.\",\n)",
      "section_id": "range-search"
    },
    {
      "id": "sql-search-ex0",
      "language": "python",
      "code": "from adk_redis import RedisSQLSearchTool\n\nsql_tool = RedisSQLSearchTool(\n    index=index,\n    name=\"catalog_sql_search\",\n    description=(\n        \"Run a SQL SELECT against the product catalog. \"\n        \"Use :name placeholders for values.\"\n    ),\n)",
      "section_id": "sql-search"
    },
    {
      "id": "sql-search-ex1",
      "language": "sql",
      "code": "SELECT title, brand, price\nFROM products\nWHERE category = 'electronics' AND price < :max_price",
      "section_id": "sql-search"
    },
    {
      "id": "redisvl-mcp-server-ex0",
      "language": "python",
      "code": "from google.adk import Agent\nfrom google.adk.tools.mcp_tool import McpToolset\nfrom google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams\nfrom mcp import StdioServerParameters\n\nagent = Agent(\n    model=\"gemini-2.5-flash\",\n    name=\"redis_mcp_agent\",\n    instruction=\"Use the search-records tool to answer questions.\",\n    tools=[\n        McpToolset(\n            connection_params=StdioConnectionParams(\n                server_params=StdioServerParameters(\n                    command=\"rvl\",\n                    args=[\n                        \"mcp\",\n                        \"--config\",\n                        \"/path/to/mcp_config.yaml\",\n                        \"--read-only\",\n                    ],\n                ),\n                timeout=30,\n            ),\n            tool_filter=[\"search-records\"],\n        ),\n    ],\n)",
      "section_id": "redisvl-mcp-server"
    },
    {
      "id": "multi-tool-agent-ex0",
      "language": "python",
      "code": "from google.adk import Agent\n\nagent = Agent(\n    model=\"gemini-2.5-flash\",\n    name=\"search_agent\",\n    instruction=(\n        \"You have three search tools. Use search_products for conceptual \"\n        \"queries, keyword_search for exact terms, range_search for \"\n        \"exhaustive retrieval.\"\n    ),\n    tools=[vector_tool, text_tool, range_tool],\n)",
      "section_id": "multi-tool-agent"
    }
  ]
}
