Skip to content

datarobot_genai.drmcputils.routes.tool_gallery

/toolGallery/* — rich tool metadata routes for UIs, shared by both servers.

The first (and currently only) route is GET /toolGallery/tools/. The group is designed to grow (e.g. /toolGallery/categories/), and every route under /toolGallery is gated by the same predicate — see register_tool_gallery_routes.

The MCP tools/list response is intentionally lean: agents/LLMs never see the UI-oriented fields (display_name, description_ui, auth_provider) — they are stripped before FastMCP registration (see DRTOOLS_PRIVATE_METADATA_KEYS). The tools route re-attaches them via an injected ui_metadata_provider (drtools' get_tool_ui_metadata) — injected, not imported, because drmcputils may not import drtools — and derives each tool's categories from the single-source-of-truth taxonomy. It returns the full catalog (not the per-request filtered/CodeMode view), paginated via limit/offset.

register_tool_gallery_routes(mcp: Any, base_path: str = _DEFAULT_BASE_PATH, gate: ToolGalleryGate | None = None, ui_metadata_provider: UiMetadataProvider | None = None) -> None

Register every /toolGallery/* route on the FastMCP server, all sharing gate.

tools is the first route (GET <base_path>/tools/). New gallery routes are added in one place here and inherit the same gating automatically — the gate is applied uniformly to the whole group rather than wired per route at the call site.

Parameters:

Name Type Description Default
mcp Any

FastMCP server instance.

required
base_path str

Group prefix. Configurable so a mounted server (user-mcp) can prefix it via prefix_mount_path while global-mcp uses the bare /toolGallery.

_DEFAULT_BASE_PATH
gate ToolGalleryGate | None

Optional async predicate (Request) -> bool applied to every route in the group. When it returns False (or raises), the route responds 404 so the feature stays hidden. Both servers pass a feature-flag gate.

None
ui_metadata_provider UiMetadataProvider | None

Optional () -> {tool_name: {display_name, description_ui, auth_provider}} callable supplying the UI-only fields. Injected (rather than imported) so this module avoids a forbidden drmcputils -> drtools import; both servers pass drtools' get_tool_ui_metadata. When unset, those fields fall back to defaults (provider classified as datarobot).

None
Source code in datarobot_genai/drmcputils/routes/tool_gallery.py
def register_tool_gallery_routes(
    mcp: Any,
    base_path: str = _DEFAULT_BASE_PATH,
    gate: ToolGalleryGate | None = None,
    ui_metadata_provider: UiMetadataProvider | None = None,
) -> None:
    """Register every ``/toolGallery/*`` route on the FastMCP server, all sharing *gate*.

    ``tools`` is the first route (``GET <base_path>/tools/``). New gallery routes are
    added in one place here and inherit the same gating automatically — the gate is
    applied uniformly to the whole group rather than wired per route at the call site.

    Args:
        mcp: FastMCP server instance.
        base_path: Group prefix. Configurable so a mounted server (user-mcp) can prefix
            it via ``prefix_mount_path`` while global-mcp uses the bare ``/toolGallery``.
        gate: Optional async predicate ``(Request) -> bool`` applied to every route in
            the group. When it returns ``False`` (or raises), the route responds ``404``
            so the feature stays hidden. Both servers pass a feature-flag gate.
        ui_metadata_provider: Optional ``() -> {tool_name: {display_name, description_ui,
            auth_provider}}`` callable supplying the UI-only fields. Injected (rather than
            imported) so this module avoids a forbidden ``drmcputils -> drtools`` import;
            both servers pass drtools' ``get_tool_ui_metadata``. When unset, those fields
            fall back to defaults (provider classified as ``datarobot``).
    """
    prefix = base_path.rstrip("/")

    # (sub-path, handler) for each route in the group. Add new gallery routes here;
    # they are gated identically. ``tools`` is the first.
    routes: list[tuple[str, Callable[[Request], Awaitable[JSONResponse]]]] = [
        ("/tools/", _make_tools_handler(mcp, ui_metadata_provider)),
    ]
    for sub_path, handler in routes:
        _register_gated_route(mcp, f"{prefix}{sub_path}", gate, handler)

    logger.info(
        "toolGallery routes registered under %s (%d route(s), gated=%s)",
        prefix,
        len(routes),
        gate is not None,
    )