From 2ab61be2df65d1c44315b99fd50cbb2c18688106 Mon Sep 17 00:00:00 2001 From: Jacob Magar Date: Mon, 16 Mar 2026 10:42:51 -0400 Subject: [PATCH] feat(auth): wire GoogleProvider into FastMCP, log auth status on startup - Call _build_google_auth() at module level before mcp = FastMCP(...) - Pass auth=_google_auth to FastMCP() constructor - Add startup log in run_server(): INFO when OAuth enabled (with redirect URI), WARNING when open/unauthenticated - Add test verifying mcp has no auth provider when Google vars are absent (baseline + post-wire) --- tests/test_auth_builder.py | 22 ++++++++++++++++++++++ unraid_mcp/server.py | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/tests/test_auth_builder.py b/tests/test_auth_builder.py index fa2c0f1..62ca1e5 100644 --- a/tests/test_auth_builder.py +++ b/tests/test_auth_builder.py @@ -87,3 +87,25 @@ def test_build_google_auth_warns_on_stdio_transport(monkeypatch): _build_google_auth() assert any("stdio" in m.lower() for m in warning_messages) + + +def test_mcp_instance_has_no_auth_by_default(): + """The FastMCP mcp instance has no auth provider when Google vars are absent.""" + import os + + for var in ("GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "UNRAID_MCP_BASE_URL"): + os.environ.pop(var, None) + + import importlib + + import unraid_mcp.config.settings as s + + importlib.reload(s) + + import unraid_mcp.server as srv + + importlib.reload(srv) + + # FastMCP stores auth on ._auth_provider or .auth + auth = getattr(srv.mcp, "_auth_provider", None) or getattr(srv.mcp, "auth", None) + assert auth is None diff --git a/unraid_mcp/server.py b/unraid_mcp/server.py index 21a2ccf..bff0e56 100644 --- a/unraid_mcp/server.py +++ b/unraid_mcp/server.py @@ -117,11 +117,15 @@ def _build_google_auth() -> "GoogleProvider | None": return GoogleProvider(**kwargs) +# Build auth provider — returns GoogleProvider when configured, None otherwise. +_google_auth = _build_google_auth() + # Initialize FastMCP instance mcp = FastMCP( name="Unraid MCP Server", instructions="Provides tools to interact with an Unraid server's GraphQL API.", version=VERSION, + auth=_google_auth, middleware=[ _logging_middleware, error_middleware, @@ -181,6 +185,19 @@ def run_server() -> None: "Only use this in trusted networks or for development." ) + if _google_auth is not None: + from .config.settings import UNRAID_MCP_BASE_URL + + logger.info( + "Google OAuth ENABLED — clients must authenticate before calling tools. " + f"Redirect URI: {UNRAID_MCP_BASE_URL}/auth/callback" + ) + else: + logger.warning( + "No authentication configured — MCP server is open to all clients on the network. " + "Set GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET + UNRAID_MCP_BASE_URL to enable OAuth." + ) + logger.info( f"Starting Unraid MCP Server on {UNRAID_MCP_HOST}:{UNRAID_MCP_PORT} using {UNRAID_MCP_TRANSPORT} transport..." )