/ check_api_keys.py
check_api_keys.py
  1  #!/usr/bin/env python
  2  """Script to check API key configurations for Ultimate MCP Server using rich formatting."""
  3  
  4  import asyncio
  5  import sys
  6  from pathlib import Path
  7  
  8  # Add project root to path for imports
  9  sys.path.insert(0, str(Path(__file__).parent))
 10  
 11  from rich.console import Console
 12  from rich.panel import Panel
 13  from rich.table import Table
 14  from rich.text import Text
 15  
 16  from ultimate_mcp_server.config import get_config
 17  from ultimate_mcp_server.constants import Provider
 18  from ultimate_mcp_server.core.server import Gateway
 19  from ultimate_mcp_server.utils import get_logger
 20  
 21  # Initialize rich console
 22  console = Console()
 23  
 24  logger = get_logger("api_key_checker")
 25  
 26  # Map provider names to the corresponding environment variable names
 27  # Used for informational display only
 28  PROVIDER_ENV_VAR_MAP = {
 29      "openai": "OPENAI_API_KEY",
 30      "anthropic": "ANTHROPIC_API_KEY",
 31      "deepseek": "DEEPSEEK_API_KEY",
 32      "gemini": "GEMINI_API_KEY",
 33      "openrouter": "OPENROUTER_API_KEY",
 34  }
 35  
 36  
 37  async def check_api_keys():
 38      """
 39      Check API key configurations and display a comprehensive report.
 40  
 41      This async function:
 42      1. Loads the current configuration settings from all sources (environment variables,
 43         .env file, configuration files)
 44      2. Initializes a minimal Gateway instance to access provider configurations
 45      3. Checks if API keys are properly configured for all supported providers
 46      4. Displays formatted results using rich tables and panels, including:
 47         - Provider-by-provider API key status
 48         - Configuration loading priority information
 49         - How to set API keys properly
 50         - Example .env file content
 51  
 52      The function checks keys for all providers defined in the Provider enum,
 53      including OpenAI, Anthropic, DeepSeek, Gemini, and OpenRouter.
 54  
 55      Returns:
 56          int: Exit code (0 for success)
 57      """
 58      # Force load config to ensure we get the latest resolved settings
 59      cfg = get_config()
 60  
 61      # Create Gateway with minimal initialization (no tools) - kept for potential future checks
 62      gateway = Gateway(name="api-key-checker", register_tools=False)  # noqa: F841
 63  
 64      console.print(
 65          Panel(
 66              "Checking API Key Configuration based on loaded settings",
 67              title="[bold cyan]Ultimate MCP Server API Key Check[/bold cyan]",
 68              expand=False,
 69              border_style="blue",
 70          )
 71      )
 72  
 73      # Create table for results
 74      table = Table(title="Provider API Key Status", show_header=True, header_style="bold magenta")
 75      table.add_column("Provider", style="dim", width=12)
 76      table.add_column("API Key Status", style="cyan")
 77      table.add_column("Relevant Env Var", style="yellow")
 78      table.add_column("Status", style="bold")
 79  
 80      # Check each provider based on the loaded configuration
 81      for provider_name in [p.value for p in Provider]:
 82          # Get provider config from the loaded GatewayConfig object
 83          provider_config = getattr(cfg.providers, provider_name, None)
 84  
 85          # Check if key exists in the loaded config
 86          # This key would have been resolved from .env, env vars, or config file by get_config()
 87          config_key = provider_config.api_key if provider_config else None
 88  
 89          # Format key for display (if present)
 90          key_display = Text("Not set in config", style="dim yellow")
 91          status_text = Text("NOT CONFIGURED", style="red")
 92          status_icon = "❌"
 93  
 94          if config_key:
 95              if len(config_key) > 8:
 96                  key_display = Text(f"{config_key[:4]}...{config_key[-4:]}", style="green")
 97              else:
 98                  key_display = Text("[INVALID KEY FORMAT]", style="bold red")
 99              status_text = Text("CONFIGURED", style="green")
100              status_icon = "✅"
101  
102          # Get the corresponding environment variable name for informational purposes
103          env_var_name = PROVIDER_ENV_VAR_MAP.get(provider_name, "N/A")
104  
105          # Add row to table
106          table.add_row(
107              provider_name.capitalize(),
108              key_display,
109              env_var_name,
110              f"[{status_text.style}]{status_icon} {status_text}[/]",
111          )
112  
113      # Print the table
114      console.print(table)
115  
116      # Configuration Loading Info Panel
117      config_info = Text.assemble(
118          ("1. ", "bold blue"),
119          ("Environment Variables", "cyan"),
120          (" (e.g., ", "dim"),
121          ("GATEWAY_PROVIDERS__OPENAI__API_KEY=...", "yellow"),
122          (")\n", "dim"),
123          ("2. ", "bold blue"),
124          ("Values in a ", "cyan"),
125          (".env", "yellow"),
126          (" file in the project root\n", "cyan"),
127          ("3. ", "bold blue"),
128          ("Values in a config file", "cyan"),
129          (" (e.g., ", "dim"),
130          ("gateway_config.yaml", "yellow"),
131          (")\n", "dim"),
132          ("4. ", "bold blue"),
133          ("Default values defined in the configuration models", "cyan"),
134      )
135      console.print(
136          Panel(config_info, title="[bold]Configuration Loading Priority[/]", border_style="blue")
137      )
138  
139      # How to Set Keys Panel
140      set_keys_info = Text.assemble(
141          ("Ensure API keys are available via one of the methods above,\n", "white"),
142          ("preferably using ", "white"),
143          ("environment variables", "cyan"),
144          (" or a ", "white"),
145          (".env", "yellow"),
146          (" file.", "white"),
147      )
148      console.print(Panel(set_keys_info, title="[bold]How to Set API Keys[/]", border_style="green"))
149  
150      # Example .env Panel
151      env_example_lines = []
152      for env_var in PROVIDER_ENV_VAR_MAP.values():
153          env_example_lines.append(
154              Text.assemble(
155                  (env_var, "yellow"),
156                  "=",
157                  ("your_", "dim"),
158                  (env_var.lower(), "dim cyan"),
159                  ("_here", "dim"),
160              )
161          )
162      env_example_content = Text("\n").join(env_example_lines)
163      console.print(
164          Panel(
165              env_example_content,
166              title="[bold dim]Example .env file content[/]",
167              border_style="yellow",
168          )
169      )
170  
171      console.print(
172          "[bold green]Run your example scripts or the main server after setting the API keys.[/bold green]"
173      )
174      return 0
175  
176  
177  if __name__ == "__main__":
178      exit_code = asyncio.run(check_api_keys())
179      sys.exit(exit_code)