diff --git a/mcp_factory.py b/mcp_factory.py index 82cdaae..182508a 100644 --- a/mcp_factory.py +++ b/mcp_factory.py @@ -2,7 +2,15 @@ import os from functools import lru_cache from fastmcp import FastMCP from fastmcp.server.auth import BearerAuthProvider -from oauth_middleware import ClerkOAuthMiddleware + +# Conditional import for OAuth middleware +try: + from oauth_middleware import ClerkOAuthMiddleware + OAUTH_AVAILABLE = True +except ImportError: + # OAuth middleware not available - will disable OAuth features + OAUTH_AVAILABLE = False + ClerkOAuthMiddleware = None @lru_cache def create_app() -> FastMCP: @@ -13,12 +21,19 @@ def create_app() -> FastMCP: "dependencies": ["httpx", "beautifulsoup4", "markitdown", "pydantic", "aiohttp", "playwright"] } - if os.getenv("ENABLE_AUTH", "false").lower() != "true": + enable_auth = os.getenv("ENABLE_AUTH", "false").lower() == "true" + + if not enable_auth or not OAUTH_AVAILABLE: # Development mode - no authentication + # Either auth is disabled OR OAuth dependencies not available app = FastMCP( name="Yargı MCP – DEV", **app_config ) + + if enable_auth and not OAUTH_AVAILABLE: + print("Warning: OAuth authentication requested but dependencies not available.") + print("Install with: uv pip install .[saas]") else: # Production mode - OAuth authentication via middleware app_config["instructions"] += " with OAuth authentication via Clerk." diff --git a/oauth_middleware.py b/oauth_middleware.py index 5755a6f..10a8ea1 100644 --- a/oauth_middleware.py +++ b/oauth_middleware.py @@ -7,7 +7,16 @@ import os import logging from typing import Optional, Dict, Any from fastmcp.server.middleware import Middleware, MiddlewareContext -from clerk_backend_api import Clerk, SDKError, authenticate_request, AuthenticateRequestOptions +try: + from clerk_backend_api import Clerk, SDKError, authenticate_request, AuthenticateRequestOptions + CLERK_AVAILABLE = True +except ImportError: + # Clerk SDK not available - OAuth features will be disabled + CLERK_AVAILABLE = False + Clerk = None + SDKError = Exception + authenticate_request = None + AuthenticateRequestOptions = None from mcp import McpError from mcp.types import ErrorData from starlette.responses import Response @@ -28,13 +37,17 @@ class ClerkOAuthMiddleware(Middleware): self.enable_auth = os.getenv("ENABLE_AUTH", "false").lower() == "true" self.clerk_secret = os.getenv("CLERK_SECRET_KEY") + # Check if Clerk SDK is available + if self.enable_auth and not CLERK_AVAILABLE: + raise ValueError("Clerk SDK not available. Install with: uv pip install .[saas]") + # Only require Clerk credentials if auth is enabled if self.enable_auth and not self.clerk_secret: raise ValueError("CLERK_SECRET_KEY environment variable is required when ENABLE_AUTH=true") - # Initialize Clerk client only if auth is enabled + # Initialize Clerk client only if auth is enabled and available self.clerk = None - if self.enable_auth and self.clerk_secret: + if self.enable_auth and self.clerk_secret and CLERK_AVAILABLE: self.clerk = Clerk(bearer_auth=self.clerk_secret) async def on_request(self, context: MiddlewareContext, call_next): diff --git a/oauth_router.py b/oauth_router.py index 1b626df..bf05cfe 100644 --- a/oauth_router.py +++ b/oauth_router.py @@ -13,7 +13,16 @@ from urllib.parse import urlencode from fastapi import APIRouter, Request, Response, HTTPException, Query from fastapi.responses import RedirectResponse, JSONResponse from starlette.responses import Response as StarletteResponse -from clerk_backend_api import Clerk, SDKError, authenticate_request, AuthenticateRequestOptions +try: + from clerk_backend_api import Clerk, SDKError, authenticate_request, AuthenticateRequestOptions + CLERK_AVAILABLE = True +except ImportError: + # Clerk SDK not available - OAuth features will be disabled + CLERK_AVAILABLE = False + Clerk = None + SDKError = Exception + authenticate_request = None + AuthenticateRequestOptions = None logger = logging.getLogger(__name__) @@ -29,13 +38,17 @@ clerk_frontend_url = os.getenv("CLERK_FRONTEND_URL", "http://localhost:3000") redirect_url = os.getenv("CLERK_OAUTH_REDIRECT_URL", f"{base_url}/auth/callback") enable_auth = os.getenv("ENABLE_AUTH", "false").lower() == "true" +# Check if Clerk SDK is available when auth is enabled +if enable_auth and not CLERK_AVAILABLE: + raise ValueError("Clerk SDK not available. Install with: uv pip install .[saas]") + # Only require Clerk credentials if auth is enabled if enable_auth and not clerk_secret: raise ValueError("CLERK_SECRET_KEY environment variable is required when ENABLE_AUTH=true") -# Initialize Clerk client only if auth is enabled +# Initialize Clerk client only if auth is enabled and available clerk = None -if enable_auth and clerk_secret: +if enable_auth and clerk_secret and CLERK_AVAILABLE: clerk = Clerk(bearer_auth=clerk_secret)