#!/usr/bin/env python3 """ Quick setup script for Modal deployment of Spend Analyzer MCP """ import os import subprocess import sys from pathlib import Path def run_command(cmd, description): """Run a command and handle errors""" print(f"\nšŸ”„ {description}...") try: result = subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True) print(f"āœ… {description} completed successfully") if result.stdout: print(f"Output: {result.stdout.strip()}") return True except subprocess.CalledProcessError as e: print(f"āŒ {description} failed") print(f"Error: {e.stderr.strip()}") return False def check_modal_installed(): """Check if Modal CLI is installed""" try: subprocess.run(["modal", "--version"], check=True, capture_output=True) return True except (subprocess.CalledProcessError, FileNotFoundError): return False def get_user_input(prompt, required=True): """Get user input with validation""" while True: value = input(f"{prompt}: ").strip() if value or not required: return value print("This field is required. Please enter a value.") def main(): print("šŸš€ Spend Analyzer MCP - Modal Setup Script") print("=" * 50) # Check if Modal is installed if not check_modal_installed(): print("\nšŸ“¦ Installing Modal CLI...") if not run_command("pip install modal", "Installing Modal"): print("āŒ Failed to install Modal. Please install manually: pip install modal") sys.exit(1) else: print("āœ… Modal CLI is already installed") # Check if user is authenticated print("\nšŸ” Checking Modal authentication...") try: result = subprocess.run(["modal", "token", "current"], check=True, capture_output=True, text=True) print("āœ… Already authenticated with Modal") except subprocess.CalledProcessError: print("šŸ”‘ Need to authenticate with Modal...") if not run_command("modal token new", "Authenticating with Modal"): print("āŒ Authentication failed. Please run 'modal token new' manually") sys.exit(1) # Collect API keys and credentials print("\nšŸ“ Please provide your API keys and credentials:") print("(You can get these from the respective provider websites)") anthropic_key = get_user_input("Anthropic API Key (for Claude)") sambanova_key = get_user_input("SambaNova API Key (optional)", required=False) email_user = get_user_input("Email address") email_pass = get_user_input("Email app password") imap_server = get_user_input("IMAP server (default: imap.gmail.com)", required=False) or "imap.gmail.com" # Create Modal secrets print("\nšŸ”’ Creating Modal secrets...") secrets_to_create = [ (f"modal secret create anthropic-api-key ANTHROPIC_API_KEY={anthropic_key}", "Creating Anthropic API key secret"), (f"modal secret create email-credentials EMAIL_USER={email_user} EMAIL_PASS={email_pass} IMAP_SERVER={imap_server}", "Creating email credentials secret") ] if sambanova_key: secrets_to_create.append( (f"modal secret create sambanova-api-key SAMBANOVA_API_KEY={sambanova_key}", "Creating SambaNova API key secret") ) for cmd, description in secrets_to_create: if not run_command(cmd, description): print(f"āš ļø Failed to create secret. You may need to create it manually.") # Deploy to Modal print("\nšŸš€ Deploying to Modal...") if run_command("modal deploy modal_deployment.py", "Deploying application"): print("\nšŸŽ‰ Deployment completed successfully!") print("\nšŸ“‹ Next steps:") print("1. Check your Modal dashboard for the deployed app") print("2. Test the deployment with: modal run modal_deployment.py") print("3. View logs with: modal logs spend-analyzer-mcp-bmt") print("4. Monitor usage with: modal stats spend-analyzer-mcp-bmt") # Create local .env file env_content = f"""# Spend Analyzer MCP Environment Variables ANTHROPIC_API_KEY={anthropic_key} EMAIL_USER={email_user} EMAIL_PASS={email_pass} IMAP_SERVER={imap_server} """ if sambanova_key: env_content += f"SAMBANOVA_API_KEY={sambanova_key}\n" with open(".env", "w") as f: f.write(env_content) print("5. Created .env file for local development") else: print("\nāŒ Deployment failed. Please check the errors above and try again.") print("You can also deploy manually with: modal deploy modal_deployment.py") if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\nā¹ļø Setup cancelled by user") sys.exit(1) except Exception as e: print(f"\nāŒ Unexpected error: {e}") sys.exit(1)