diff --git a/mcp_servers.d/navi_ui.json b/mcp_servers.d/navi_ui.json index 6b8626f..d97d5f8 100644 --- a/mcp_servers.d/navi_ui.json +++ b/mcp_servers.d/navi_ui.json @@ -1,6 +1,6 @@ { "transport": "streamable_http", - "url": "http://localhost:8001/mcp", + "url": "http://127.0.0.1:8098/mcp", "groups": { "ui": ["render_component"] }, diff --git a/tests/unit/mcp/test_ui_server.py b/tests/unit/mcp/test_ui_server.py index 4e113c5..70c13ba 100644 --- a/tests/unit/mcp/test_ui_server.py +++ b/tests/unit/mcp/test_ui_server.py @@ -1,6 +1,8 @@ """Unit tests for the internal navi_ui MCP server.""" import json +from pathlib import Path +from urllib.parse import urlparse import pytest @@ -10,6 +12,36 @@ from navi.mcp.ui_server.components.registry import ComponentRegistry, discover_components +class TestMcpConfigPointsAtTheServedEndpoint: + """navi reaches its own navi_ui server the way it reaches any other MCP server: + through ``mcp_servers.d/navi_ui.json``. Nothing keeps that file in step with the + port ``server.py`` binds, and it drifted to the pre-8099/8098 defaults — the + server then failed to connect on every start and ``render_component`` surfaced + only as an unregistered phantom in list_tools. Assert the file against the live + FastMCP object, not against a second copy of the same setting. + """ + + @staticmethod + def _config() -> dict: + root = Path(__file__).resolve().parents[3] + return json.loads((root / "mcp_servers.d" / "navi_ui.json").read_text()) + + def test_url_is_the_endpoint_the_server_actually_binds(self): + from navi.mcp.ui_server import server as server_module + + settings = server_module.mcp.settings + expected = f"http://{settings.host}:{settings.port}{settings.streamable_http_path}" + + assert self._config()["url"] == expected + + def test_host_is_the_loopback_literal_the_server_binds(self): + """``localhost`` may resolve to ::1; the server binds IPv4 only.""" + assert urlparse(self._config()["url"]).hostname == "127.0.0.1" + + def test_transport_matches_the_mounted_asgi_app(self): + assert self._config()["transport"] == "streamable_http" + + class TestComponentDiscovery: def test_discovers_nested_subclasses(self): """Intermediate subclasses of UIComponent must be discovered."""