|
9 | 9 | from ols.app.models.config import MCPServerConfig |
10 | 10 | from ols.utils.mcp_utils import ( |
11 | 11 | build_mcp_config, |
| 12 | + filter_tools_by_available_ui, |
12 | 13 | gather_mcp_tools, |
13 | 14 | get_mcp_tools, |
14 | 15 | get_servers_requiring_client_headers, |
@@ -647,3 +648,70 @@ async def test_no_servers_configured(self): |
647 | 648 | result = await get_mcp_tools("test query") |
648 | 649 |
|
649 | 650 | assert result == [] |
| 651 | + |
| 652 | + |
| 653 | +class TestFilterToolsByAvailableUI: |
| 654 | + """Tests for filter_tools_by_available_ui function.""" |
| 655 | + |
| 656 | + @staticmethod |
| 657 | + def _make_tool(name: str, metadata: dict | None = None) -> MagicMock: |
| 658 | + tool = MagicMock(spec=StructuredTool) |
| 659 | + tool.name = name |
| 660 | + tool.metadata = metadata |
| 661 | + return tool |
| 662 | + |
| 663 | + def test_none_available_ids_returns_all(self): |
| 664 | + """When available_ui_ids is None, all tools pass through.""" |
| 665 | + tool_with_ui = self._make_tool( |
| 666 | + "perses", {"_meta": {"olsUi": {"id": "perses-dashboard"}}} |
| 667 | + ) |
| 668 | + tool_without_ui = self._make_tool("kubectl", {"mcp_server": "k8s"}) |
| 669 | + result = filter_tools_by_available_ui([tool_with_ui, tool_without_ui], None) |
| 670 | + assert len(result) == 2 |
| 671 | + |
| 672 | + def test_empty_list_excludes_tools_with_ui_id(self): |
| 673 | + """Empty available list excludes tools that declare olsUi.id.""" |
| 674 | + tool_with_ui = self._make_tool( |
| 675 | + "perses", {"_meta": {"olsUi": {"id": "perses-dashboard"}}} |
| 676 | + ) |
| 677 | + tool_without_ui = self._make_tool("kubectl", {"mcp_server": "k8s"}) |
| 678 | + result = filter_tools_by_available_ui([tool_with_ui, tool_without_ui], []) |
| 679 | + assert len(result) == 1 |
| 680 | + assert result[0].name == "kubectl" |
| 681 | + |
| 682 | + def test_matching_id_passes(self): |
| 683 | + """Tool with matching olsUi.id passes the filter.""" |
| 684 | + tool = self._make_tool( |
| 685 | + "perses", {"_meta": {"olsUi": {"id": "perses-dashboard"}}} |
| 686 | + ) |
| 687 | + result = filter_tools_by_available_ui([tool], ["perses-dashboard"]) |
| 688 | + assert len(result) == 1 |
| 689 | + assert result[0].name == "perses" |
| 690 | + |
| 691 | + def test_non_matching_id_excluded(self): |
| 692 | + """Tool with non-matching olsUi.id is excluded.""" |
| 693 | + tool = self._make_tool( |
| 694 | + "perses", {"_meta": {"olsUi": {"id": "perses-dashboard"}}} |
| 695 | + ) |
| 696 | + result = filter_tools_by_available_ui([tool], ["other-ui"]) |
| 697 | + assert len(result) == 0 |
| 698 | + |
| 699 | + def test_tool_without_meta_passes(self): |
| 700 | + """Tool without _meta always passes.""" |
| 701 | + tool = self._make_tool("kubectl", {"mcp_server": "k8s"}) |
| 702 | + result = filter_tools_by_available_ui([tool], []) |
| 703 | + assert len(result) == 1 |
| 704 | + |
| 705 | + def test_tool_with_none_metadata_passes(self): |
| 706 | + """Tool with None metadata always passes.""" |
| 707 | + tool = self._make_tool("kubectl", None) |
| 708 | + result = filter_tools_by_available_ui([tool], []) |
| 709 | + assert len(result) == 1 |
| 710 | + |
| 711 | + def test_tool_with_meta_but_no_ols_ui_passes(self): |
| 712 | + """Tool with _meta but no olsUi field always passes.""" |
| 713 | + tool = self._make_tool( |
| 714 | + "kubectl", {"_meta": {"ui": {"resourceUri": "ui://foo"}}} |
| 715 | + ) |
| 716 | + result = filter_tools_by_available_ui([tool], []) |
| 717 | + assert len(result) == 1 |
0 commit comments