mirror of
https://github.com/jmagar/unraid-mcp.git
synced 2026-03-23 12:39:24 -07:00
feat(elicitation): add setup action to unraid_health
This commit is contained in:
@@ -194,3 +194,36 @@ class TestSafeDisplayUrl:
|
||||
# raises ValueError: Invalid IPv6 URL — this triggers the except branch.
|
||||
result = safe_display_url("https://[invalid")
|
||||
assert result == "<unparseable>"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_setup_action_calls_elicitation() -> None:
|
||||
"""setup action triggers elicit_and_configure and returns success message."""
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
tool_fn = _make_tool()
|
||||
|
||||
with patch(
|
||||
"unraid_mcp.tools.health.elicit_and_configure", new=AsyncMock(return_value=True)
|
||||
) as mock_elicit:
|
||||
result = await tool_fn(action="setup", ctx=MagicMock())
|
||||
|
||||
assert mock_elicit.called
|
||||
assert "configured" in result.lower() or "success" in result.lower()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_setup_action_returns_declined_message() -> None:
|
||||
"""setup action with declined elicitation returns appropriate message."""
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
tool_fn = _make_tool()
|
||||
|
||||
with patch("unraid_mcp.tools.health.elicit_and_configure", new=AsyncMock(return_value=False)):
|
||||
result = await tool_fn(action="setup", ctx=MagicMock())
|
||||
|
||||
assert (
|
||||
"not configured" in result.lower()
|
||||
or "declined" in result.lower()
|
||||
or "cancel" in result.lower()
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"""Health monitoring and diagnostics.
|
||||
|
||||
Provides the `unraid_health` tool with 3 actions for system health checks,
|
||||
connection testing, and subscription diagnostics.
|
||||
Provides the `unraid_health` tool with 4 actions for system health checks,
|
||||
connection testing, subscription diagnostics, and credential setup.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import time
|
||||
from typing import Any, Literal, get_args
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp import Context, FastMCP
|
||||
|
||||
from ..config.logging import logger
|
||||
from ..config.settings import (
|
||||
@@ -20,13 +20,14 @@ from ..config.settings import (
|
||||
)
|
||||
from ..core.client import make_graphql_request
|
||||
from ..core.exceptions import ToolError, tool_error_handler
|
||||
from ..core.setup import elicit_and_configure
|
||||
from ..core.utils import safe_display_url
|
||||
from ..subscriptions.utils import _analyze_subscription_status
|
||||
|
||||
|
||||
ALL_ACTIONS = {"check", "test_connection", "diagnose"}
|
||||
ALL_ACTIONS = {"check", "test_connection", "diagnose", "setup"}
|
||||
|
||||
HEALTH_ACTIONS = Literal["check", "test_connection", "diagnose"]
|
||||
HEALTH_ACTIONS = Literal["check", "test_connection", "diagnose", "setup"]
|
||||
|
||||
if set(get_args(HEALTH_ACTIONS)) != ALL_ACTIONS:
|
||||
_missing = ALL_ACTIONS - set(get_args(HEALTH_ACTIONS))
|
||||
@@ -57,10 +58,12 @@ def register_health_tool(mcp: FastMCP) -> None:
|
||||
@mcp.tool()
|
||||
async def unraid_health(
|
||||
action: HEALTH_ACTIONS,
|
||||
) -> dict[str, Any]:
|
||||
ctx: Context | None = None,
|
||||
) -> dict[str, Any] | str:
|
||||
"""Monitor Unraid MCP server and system health.
|
||||
|
||||
Actions:
|
||||
setup - Configure Unraid credentials via interactive elicitation
|
||||
check - Comprehensive health check (API latency, array, notifications, Docker)
|
||||
test_connection - Quick connectivity test (just checks { online })
|
||||
diagnose - Subscription system diagnostics
|
||||
@@ -68,6 +71,17 @@ def register_health_tool(mcp: FastMCP) -> None:
|
||||
if action not in ALL_ACTIONS:
|
||||
raise ToolError(f"Invalid action '{action}'. Must be one of: {sorted(ALL_ACTIONS)}")
|
||||
|
||||
if action == "setup":
|
||||
configured = await elicit_and_configure(ctx)
|
||||
if configured:
|
||||
return (
|
||||
"✅ Credentials configured successfully. You can now use all Unraid MCP tools."
|
||||
)
|
||||
return (
|
||||
"⚠️ Credentials not configured. "
|
||||
"Run `unraid_health action=setup` again to provide credentials."
|
||||
)
|
||||
|
||||
with tool_error_handler("health", action, logger):
|
||||
logger.info(f"Executing unraid_health action={action}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user