Skip to content

datarobot_genai.drtools.core.tool_metadata

tool_metadata

Tool metadata decorator for drtools.

This module provides a decorator that stores metadata about tools without creating any dependency on drmcp. The metadata can be discovered and used by drmcp to register the tools.

tool_metadata

tool_metadata(**metadata: Any) -> Callable[[Callable[P, R]], Callable[P, R]]

Store tool metadata to a function without MCP registration.

Records the function and its metadata in a registry that drmcp discovers via :func:get_registered_tools to register the tool. The function is returned unchanged — no wrapper — so the registry and direct callers see the real function (including its true coroutine-ness).

Parameters:

Name Type Description Default
**metadata Any

Keyword arguments for tool metadata (tags, name, description, etc.)

{}
Returns
Decorator that registers the function and attaches its metadata, then
returns it unchanged.
Source code in datarobot_genai/drtools/core/tool_metadata.py
def tool_metadata(**metadata: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Store tool metadata to a function without MCP registration.

    Records the function and its metadata in a registry that drmcp discovers via
    :func:`get_registered_tools` to register the tool. The function is returned
    unchanged — no wrapper — so the registry and direct callers see the real
    function (including its true coroutine-ness).

    Args:
        **metadata: Keyword arguments for tool metadata (tags, name, description, etc.)

    Returns
    -------
        Decorator that registers the function and attaches its metadata, then
        returns it unchanged.
    """

    def decorator(func: Callable[P, R]) -> Callable[P, R]:
        _TOOL_REGISTRY.append((func, metadata))
        # Expose the metadata on the function for direct access; the function
        # itself is returned untouched so callers and FastMCP see the original.
        func._tool_metadata = metadata  # type: ignore[attr-defined]
        return func

    return decorator

get_registered_tools

get_registered_tools() -> list[tuple[Callable, dict[str, Any]]]

Get all registered tools and their metadata.

Returns
List of (function, metadata) tuples.
Source code in datarobot_genai/drtools/core/tool_metadata.py
def get_registered_tools() -> list[tuple[Callable, dict[str, Any]]]:
    """Get all registered tools and their metadata.

    Returns
    -------
        List of (function, metadata) tuples.
    """
    return _TOOL_REGISTRY.copy()

get_tool_ui_metadata

get_tool_ui_metadata() -> dict[str, dict[str, Any]]

Build tool_name -> {display_name, description_ui, auth_provider} from the registry.

These UI-only keys are stripped before FastMCP registration (see DRTOOLS_PRIVATE_METADATA_KEYS), so agents/LLMs never see them. The tools-gallery route re-attaches them by calling this — it is injected into register_tool_gallery_routes as the ui_metadata_provider because drmcputils (where the route lives) may not import drtools. Owning this here keeps the metadata keys with the registry that defines them.

Source code in datarobot_genai/drtools/core/tool_metadata.py
def get_tool_ui_metadata() -> dict[str, dict[str, Any]]:
    """Build ``tool_name -> {display_name, description_ui, auth_provider}`` from the registry.

    These UI-only keys are stripped before FastMCP registration (see
    ``DRTOOLS_PRIVATE_METADATA_KEYS``), so agents/LLMs never see them. The tools-gallery
    route re-attaches them by calling this — it is injected into
    ``register_tool_gallery_routes`` as the ``ui_metadata_provider`` because ``drmcputils``
    (where the route lives) may not import ``drtools``. Owning this here keeps the metadata
    keys with the registry that defines them.
    """
    lookup: dict[str, dict[str, Any]] = {}
    for func, metadata in get_registered_tools():
        name = metadata.get("name") or func.__name__
        lookup[name] = {
            "display_name": metadata.get("display_name"),
            "description_ui": metadata.get("description_ui"),
            "auth_provider": metadata.get("auth_provider"),
        }
    return lookup