""" EcoMCP Modal Deployment Deploy MCP server to Modal serverless platform Run: modal deploy deploy_modal.py """ import os import json import asyncio from typing import Dict, Any try: import modal except ImportError: raise ImportError("Install modal: pip install modal") # Create Modal app app = modal.App("ecomcp-server") # Import the server from ecomcp_server_refined import EcoMCPServerRefined # Create server instance server = None def get_server(): """Get or create server instance""" global server if server is None: server = EcoMCPServerRefined() return server # ============================================================================ # HTTP API ENDPOINT # ============================================================================ @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def process_request(request: Dict[str, Any]) -> Dict: """ Process MCP request via HTTP Example request: { "method": "tools/call", "params": { "name": "analyze_product", "arguments": {"name": "Headphones"} } } """ server = get_server() # Ensure OPENAI_API_KEY is set from modal secret if not os.getenv("OPENAI_API_KEY"): return {"error": "OPENAI_API_KEY not configured"} try: # Build JSON-RPC message message = { "jsonrpc": "2.0", "method": request.get("method"), "params": request.get("params", {}), "id": 1 } # Process message response = await server.process_message(message) return response except Exception as e: return { "jsonrpc": "2.0", "error": {"code": -32603, "message": str(e)}, "id": 1 } # ============================================================================ # INDIVIDUAL TOOL ENDPOINTS # ============================================================================ @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def analyze_product(request: Dict[str, Any]) -> Dict: """Analyze product endpoint""" server = get_server() try: result = await server.call_tool("analyze_product", request) return result except Exception as e: return {"status": "error", "error": str(e)} @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def analyze_reviews(request: Dict[str, Any]) -> Dict: """Analyze reviews endpoint""" server = get_server() try: result = await server.call_tool("analyze_reviews", request) return result except Exception as e: return {"status": "error", "error": str(e)} @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def generate_listing(request: Dict[str, Any]) -> Dict: """Generate listing endpoint""" server = get_server() try: result = await server.call_tool("generate_listing", request) return result except Exception as e: return {"status": "error", "error": str(e)} @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def price_recommendation(request: Dict[str, Any]) -> Dict: """Price recommendation endpoint""" server = get_server() try: result = await server.call_tool("price_recommendation", request) return result except Exception as e: return {"status": "error", "error": str(e)} @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0", "openai>=1.0.0" ), secrets=[modal.Secret.from_name("openai-api-key")] ) @modal.web_endpoint(method="POST") async def competitor_analysis(request: Dict[str, Any]) -> Dict: """Competitor analysis endpoint""" server = get_server() try: result = await server.call_tool("competitor_analysis", request) return result except Exception as e: return {"status": "error", "error": str(e)} # ============================================================================ # HEALTH CHECK # ============================================================================ @app.function( image=modal.Image.debian_slim().pip_install( "httpx>=0.25.0", "python-dotenv>=1.0.0" ) ) @modal.web_endpoint(method="GET") async def health() -> Dict: """Health check endpoint""" server = get_server() return { "status": "healthy", "server": "ecomcp-v2.0", "cache_stats": server.cache.stats(), "metrics": server.metrics } if __name__ == "__main__": print(""" ============================================================ EcoMCP Modal Deployment ============================================================ Deploy to Modal: $ modal deploy deploy_modal.py This creates serverless endpoints for: - /process_request - Main MCP endpoint - /analyze_product - Product analysis - /analyze_reviews - Review analysis - /generate_listing - Listing generation - /price_recommendation - Pricing strategy - /competitor_analysis - Competitive analysis - /health - Health check Setup: 1. Install Modal: pip install modal 2. Authenticate: modal token new 3. Create secret: modal secret create openai-api-key --value sk-... 4. Deploy: modal deploy deploy_modal.py ============================================================ """)