Newer
Older
navi-1 / navi / tools / mcp_status.py
"""Built-in tool to list connected MCP servers and their exposed tools."""

from navi.mcp import McpManager

from ._internal.base import Tool, ToolContext, ToolResult


class McpStatusTool(Tool):
    name = "mcp_status"
    description = (
        "List all configured MCP servers, their connection status, and the number of tools each exposes. "
        "Use this ONLY for discovery — to see which servers are connected and what tools exist. "
        "Do NOT use mcp_status to test whether a specific tool works. "
        "For testing individual tools, use test_mcp_tool instead."
    )
    parameters = {
        "type": "object",
        "properties": {},
        "required": [],
    }

    def __init__(self, mcp_manager: McpManager | None = None) -> None:
        self._mcp_manager = mcp_manager

    async def execute(self, params: dict, ctx: ToolContext | None = None) -> ToolResult:
        manager = self._mcp_manager
        if manager is None:
            from navi.api.deps import _mcp_manager as _global_mcp_manager
            manager = _global_mcp_manager
        if manager is None:
            return ToolResult(
                success=False,
                output="",
                error="MCP manager not available.",
            )

        lines: list[str] = []
        for name, client in manager.clients.items():
            status = "connected" if client.connected else "disconnected"
            lines.append(f"Server: {name} ({status})")
            try:
                tools = await client.list_tools()
                for t in tools:
                    lines.append(f"  - {t.name}: {t.description or 'no description'}")
            except Exception as exc:
                lines.append(f"  (failed to list tools: {exc})")

        if not lines:
            return ToolResult(success=True, output="No MCP servers configured.")

        return ToolResult(success=True, output="\n".join(lines))