Skip to main content

adk-tool-search

ADK-native deferred tool discovery for large function and MCP catalogs.

SearchableToolset exposes four lightweight management tools initially. The model searches the catalog, activates an exact result, and ADK exposes the selected tool on the next model step. Selected tools execute through ADK's normal tool pipeline, preserving authentication, confirmation, callbacks, plugins, tracing, and lifecycle behavior.

Why

Large tool catalogs increase prompt size and make tool selection less reliable. Tool search keeps full schemas out of the initial model request while retaining a searchable local catalog.

Initial request: search_tools, load_tool, unload_tool, clear_loaded_tools
       ↓
search_tools("weather by city")
       ↓
[{"name": "get_weather", "description": "...", "score": 4.2}]
       ↓
load_tool("get_weather")
       ↓
Next model step: management tools + get_weather

Install

pip install adk-tool-search

Function Tools

from google.adk.agents import LlmAgent

from adk_tool_search import SearchableToolset


def get_weather(location: str) -> dict:
    """Get current weather for a location.

    Args:
        location: City or coordinates.
    """
    return {"location": location, "temperature": 22}


toolset = SearchableToolset(
    namespace="assistant",
    tools=[get_weather],
    max_loaded_tools=20,
)

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    instruction=(
        "Use search_tools to discover capabilities, load_tool to activate an exact result, "
        "then call the activated tool."
    ),
    tools=[toolset],
)

Loaded names are persisted in session state under:

adk_tool_search.loaded_tools.<namespace>

MCP Tools

Wrap the McpToolset instead of detaching its tools at startup:

from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset, StdioConnectionParams
from mcp import StdioServerParameters

from adk_tool_search import SearchableToolset


mcp = McpToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="npx",
            args=["-y", "@modelcontextprotocol/server-github"],
        )
    )
)

github_tools = SearchableToolset(
    namespace="github",
    source=mcp,
    tool_name_prefix="github",
)

agent = LlmAgent(
    name="github_assistant",
    model="gemini-2.5-flash",
    tools=[github_tools],
)

The wrapper delegates source authentication and close(), so ADK retains ownership of MCP connections and cleanup. Use one prefixed SearchableToolset per authenticated MCP server because ADK supports one authentication configuration per toolset.

Public API

SearchableToolset

SearchableToolset(
    *,
    namespace: str,
    tools: Iterable[BaseTool | Callable] = (),
    source: BaseToolset | None = None,
    always_available: Iterable[BaseTool | Callable] = (),
    index_factory: Callable[[], BM25ToolIndex] | None = None,
    top_k: int = 5,
    max_loaded_tools: int = 20,
    tool_name_prefix: str | None = None,
)
  • tools: static deferred tools. Mutually exclusive with source.
  • source: one dynamic ADK toolset, including McpToolset.
  • always_available: tools exposed on every model request but excluded from search.
  • index_factory: creates an exclusively owned index for each context-specific source snapshot.
  • top_k: maximum search results.
  • max_loaded_tools: active deferred-tool budget.
  • tool_name_prefix: ADK-compatible prefix for management and active tools.

The toolset exposes:

  • search_tools(query)
  • load_tool(tool_name)
  • unload_tool(tool_name)
  • clear_loaded_tools()

load_tool does not execute another tool internally. The selected tool is executed normally by ADK on a subsequent model step.

ToolCatalog

Normalizes callables to stable FunctionTool instances, validates names, rejects duplicates, and extracts descriptions and parameter metadata.

BM25ToolIndex

Indexes tool names, descriptions, argument names, and argument descriptions. It supports custom stopwords and minimum token lengths.

ToolSearchResult

Structured retrieval result containing name, description, and score.

Multiple Sources

Use one searchable toolset per source and prefix each surface:

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    tools=[
        SearchableToolset(namespace="github", source=github_mcp, tool_name_prefix="github"),
        SearchableToolset(namespace="slack", source=slack_mcp, tool_name_prefix="slack"),
    ],
)

This preserves independent authentication, lifecycle, catalog refresh, and loaded-tool state.

Development

uv sync --all-extras
uv run ruff format --check .
uv run ruff check .
uv run pytest

Live model tests require .env credentials:

uv run pytest -m llm

The default test suite also starts a local stdio MCP subprocess and exercises real MCP listing, calling, and cleanup without network access. Live LLM tests use the ADK_TOOL_SEARCH_LLM_MODEL, ADK_TOOL_SEARCH_LLM_API_BASE, and ADK_TOOL_SEARCH_LLM_API_KEY values from .env.

Release files for adk-tool-search 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for adk-tool-search 0.3.0
File Size Uploaded
adk_tool_search-0.3.0.tar.gz 13.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for adk-tool-search 0.3.0
File Interpreter ABI Platform
adk_tool_search-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.3 kB

Release files / adk_tool_search-0.3.0.tar.gz

Download URL adk_tool_search-0.3.0.tar.gz
Size 13.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3af1b15c224c08cd5562a4e1be43748482efb40b92b83e732f77dd79ac8933e5
BLAKE2b-256 checksum
How to use checksums
d7c41688102fd8f29dc5313ef06076397a2ace62d6ed923f3a48fe43f2a8d495
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / adk_tool_search-0.3.0-py3-none-any.whl

Download URL adk_tool_search-0.3.0-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1438a1cdb977a7efd8006d05f718aa31d0d54b50d507cc46f88893864fddc680
BLAKE2b-256 checksum
How to use checksums
c75b36062918e480d2236d0c46e498e21c091a5bbbdb5e13a5cf38d766162ce4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page