{"record":{"id":"223e2d80dec1218e","repo":"OpenBB-finance/OpenBB","slug":"no-tools-found-in-category-subcategory-av","errorCode":null,"errorMessage":"No tools found in '{category}'/'{subcategory}'. Available categories: {', '.join(sorted(available))}","messagePattern":"No tools found in '(.+?)'/'(.+?)'\\. Available categories: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py","lineNumber":724,"sourceCode":"        @mcp.tool(tags={\"admin\"})\n        async def activate_category(\n            category: Annotated[\n                str, Field(description=\"Category name to activate all tools for\")\n            ],\n            ctx: Context,\n            subcategory: Annotated[\n                str | None,\n                Field(description=\"Optional subcategory to narrow activation\"),\n            ] = None,\n        ) -> str:\n            \"\"\"Activate all tools in a category (or subcategory) for this session.\"\"\"\n            if subcategory:\n                names = category_index.get_subcategory_names(category, subcategory)\n            else:\n                names = category_index.get_category_names(category)\n            if not names:\n                available = list(category_index.get_categories().keys())\n                raise ValueError(\n                    f\"No tools found in '{category}'\"\n                    + (f\"/'{subcategory}'\" if subcategory else \"\")\n                    + f\". Available categories: {', '.join(sorted(available))}\"\n                )\n            await ctx.enable_components(names=names)\n            scope = f\"'{category}'\" + (f\"/'{subcategory}'\" if subcategory else \"\")\n            return (\n                f\"Activated {len(names)} tools in {scope}\"\n                f\": {', '.join(sorted(names))}\"\n            )\n\n    # Expose prompts and resources as tools via transforms so that\n    # tool-only clients can list/render prompts and list/read resources.\n    mcp.add_transform(PromptsAsTools(mcp))\n    mcp.add_transform(ResourcesAsTools(mcp))\n\n    @mcp.tool(tags={\"resource\", \"admin\"})\n    async def install_skill(","sourceCodeStart":706,"sourceCodeEnd":742,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py#L706-L742","documentation":"Raised by the MCP server's category-activation tool when the category (or category/subcategory pair) resolves to zero tool names, meaning nothing can be activated for the session. This happens when the category key is wrong or when a valid category exists in the index but has no tools registered (extension installed but not exposed). The message lists available categories.","triggerScenarios":"Calling activate_category(category='crypto', subcategory='invalid') where the subcategory miss yields an empty name list; activating a category whose extension is installed but whose routes were excluded from MCP exposure via config; typos in category.","commonSituations":"MCP clients bulk-activating tool groups by name; OpenBB MCP config excluding routes (expose: false) so a category index exists but is empty; stale category names after upgrades.","solutions":["Use an exact category from the 'Available categories' list in the error message.","If the category is right but empty, check your MCP/OpenBB config for route exclusions and re-enable the extension's routes.","Verify the extension is installed and loaded (list_categories) before activating.","For subcategory activation, confirm the subcategory key with the listing tool first."],"exampleFix":"# before\nmsg = await activate_category(category=\"nonexistent\")\n\n# after\navailable = (await list_categories()).keys()\nmsg = await activate_category(category=next(c for c in available if \"equity\" in c))","handlingStrategy":"validation","validationCode":"async def activate_category_safe(mcp_client, category: str):\n    cats = await mcp_client.call_tool(\"list_categories\", {})\n    names = {c[\"name\"] for c in cats.result}\n    if category not in names:\n        raise ValueError(f\"{category!r} not in available categories: {sorted(names)}\")\n    return await mcp_client.call_tool(\"activate_category\", {\"category\": category})","typeGuard":"def is_activatable(category: str, subcategory: str | None, index_names: list[str]) -> bool:\n    return bool(index_names) and category in {n.split(\"_\")[0] for n in index_names}","tryCatchPattern":"try:\n    msg = await activate_category(category=cat)\nexcept ValueError as e:\n    if \"No tools found in\" in str(e):\n        # category exists but is empty or wrong: fall back to listing then activating by exact name\n        tools = await list_category_tools(category=sorted(category_index.get_categories())[0])\n    else:\n        raise","preventionTips":["Confirm the category yields tool names via the listing tool before activating.","Check MCP route-exclusion config if a category unexpectedly activates zero tools.","Log the available-categories list from the error to self-heal bad inputs."],"tags":["openbb","mcp","mcp-server","activation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}