datarobot_genai.drmcputils.category_tree
category_tree
The tool-category tree behind GET /static/categories/.
Builds the two-level taxonomy (parents → leaf children, plus standalone leaves and
the marker-resolved buckets) with per-node live tool counts scoped to the tools
this server actually exposes, so a filter panel can render Data connectors
(18) and a picker can show the tools inside each leaf.
Each node is {value, label, count, dynamic, appliesTo, toolNames, children}.
value is the dr_* string a tool item reports in its categories and the
gallery's ?category= filter accepts, so a selection round-trips against
GET /static/tools/ without translation. label comes from
TOOL_CATEGORY_LABELS — one map, used by every consumer.
appliesTo names the server types a category is meaningful for: the static
taxonomy applies to ["global", "user"]; the marker-resolved buckets
(dr_user_tools, dr_dynamic_tools) apply to ["user"] only, since
global-mcp serves built-in tools exclusively.
Counts come from the server's real catalog (see resolve_catalog: the caller's
session headers must not narrow it), classified by build_tool_gallery_items —
the very function behind GET /static/tools/, so a node's contents and what
?category= returns are the same computation rather than two that agree by
inspection. Never from the static LEAF_CATEGORY_TOOLS map alone, which would
over-count tools a given server does not register. Proxied user-MCP tools carry no
category and are not bucketed anywhere.
This module has no route of its own: it used to be routes/tool_categories.py
serving a separate GET /toolCategories/, which meant two endpoints answered
"what categories exist" with different shapes and different completeness. The tree
IS the category endpoint now; only the builder lives here.
build_category_tree
Build the category tree for tools.
Returns the top-level nodes and the number of DISTINCT tools that landed in at
least one category — which is smaller than len(tools) whenever a server
exposes uncategorized tools (proxied user-MCP tools, foremost).
Source code in datarobot_genai/drmcputils/category_tree.py
ordered_top_level
Top-level categories, ordered alphabetically by display label.
Derived from the taxonomy (not hard-coded) so a new category flows through to the filter panel by existing. Alphabetical (case-insensitive, value as the tie-breaker) so the response order matches how a picker lists them.