"""Built-in tool that returns the current list of available tools."""
from __future__ import annotations
import json
from pathlib import Path
from navi.mcp.tools import build_mcp_name
from ._internal.base import Tool, ToolResult
_USER_ENABLED_FILE = Path("tools/enabled.json")
def _load_user_enabled_tools() -> list[str]:
try:
return json.loads(_USER_ENABLED_FILE.read_text())
except Exception:
return []
class ListToolsTool(Tool):
name = "list_tools"
description = (
"Returns the list of tools available to a specific profile. "
"Requires a profile_id — no default output."
)
parameters = {
"type": "object",
"properties": {
"profile_id": {
"type": "string",
"description": "Profile ID. Returns only the tools enabled for this profile.",
}
},
"required": ["profile_id"],
}
def __init__(
self,
registry=None,
profile_registry=None,
mcp_manager=None,
) -> None:
self._registry = registry
self._profile_registry = profile_registry
self._mcp_manager = mcp_manager
async def execute(self, params: dict) -> ToolResult:
if self._registry is None:
return ToolResult(success=False, output="Registry not available.", error="no_registry")
profile_id = params.get("profile_id")
if profile_id and self._profile_registry is not None:
try:
profile = self._profile_registry.get(profile_id)
except Exception:
return ToolResult(success=False, output=f"Profile '{profile_id}' not found.", error="profile_not_found")
names = list(profile.enabled_tools)
extra = _load_user_enabled_tools()
for name in extra:
if name not in names:
names.append(name)
# Expand MCP server groups into concrete tool names
if profile.mcp_servers and self._mcp_manager:
for server_name, groups in profile.mcp_servers.items():
if "*" in groups:
prefix = build_mcp_name(server_name, "")
for tool in self._registry.all():
if tool.name.startswith(prefix) and tool.name not in names:
names.append(tool.name)
else:
for group_name in groups:
for tool_name in self._mcp_manager.resolve_group(server_name, group_name):
full_name = build_mcp_name(server_name, tool_name)
if full_name not in names:
names.append(full_name)
tools = []
for name in names:
try:
tools.append(self._registry.get(name))
except Exception:
pass
lines = [f"Tools for profile '{profile_id}' ({len(tools)} total):"]
for tool in tools:
lines.append(f"• {tool.name}: {tool.description}")
return ToolResult(success=True, output="\n".join(lines))
return ToolResult(
success=False,
output="Missing required argument: profile_id. Specify a profile ID to see its enabled tools.",
error="missing_profile_id",
)