Skip to main content
Glama
ion-aluminium

Nano Banana MCP Server (CLIProxyAPI Edition)

settings.py7 kB
from dataclasses import dataclass, field from enum import Enum import os from pathlib import Path from dotenv import load_dotenv from ..core.exceptions import ADCConfigurationError from .constants import AUTH_ERROR_MESSAGES class ModelTier(str, Enum): """Model selection options.""" FLASH = "flash" # Speed-optimized (Gemini 2.5 Flash) PRO = "pro" # Quality-optimized (Gemini 3 Pro) AUTO = "auto" # Automatic selection class AuthMethod(Enum): """Authentication method options.""" API_KEY = "api_key" # Developer API + API Key VERTEX_AI = "vertex_ai" # Vertex AI API + ADC AUTO = "auto" # Auto-detect class ThinkingLevel(str, Enum): """Gemini 3 thinking levels for advanced reasoning.""" LOW = "low" # Minimal latency, less reasoning HIGH = "high" # Maximum reasoning (default for Pro) class MediaResolution(str, Enum): """Media resolution for vision processing.""" LOW = "low" # Faster, less detail MEDIUM = "medium" # Balanced HIGH = "high" # Maximum detail @dataclass class ServerConfig: """Server configuration settings.""" gemini_api_key: str | None = None cliproxy_base_url: str | None = None cliproxy_api_key: str | None = None cliproxy_config_path: str | None = None server_name: str = "nanobanana-mcp-server" transport: str = "stdio" # stdio or http host: str = "127.0.0.1" port: int = 9000 mask_error_details: bool = False max_concurrent_requests: int = 10 image_output_dir: str = "" auth_method: AuthMethod = AuthMethod.AUTO gcp_project_id: str | None = None gcp_region: str = "us-central1" @classmethod def from_env(cls) -> "ServerConfig": """Load configuration from environment variables.""" load_dotenv() # Auth method auth_method_str = os.getenv("NANOBANANA_AUTH_METHOD", "auto").lower() try: auth_method = AuthMethod(auth_method_str) except ValueError: auth_method = AuthMethod.AUTO api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY") cliproxy_base_url = os.getenv("CLIPROXY_BASE_URL") or os.getenv("CLIPROXY_API_BASE") cliproxy_api_key = os.getenv("CLIPROXY_API_KEY") cliproxy_config_path = os.getenv("CLIPROXY_CONFIG") gcp_project = os.getenv("GCP_PROJECT_ID") or os.getenv("GOOGLE_CLOUD_PROJECT") gcp_region = os.getenv("GCP_REGION") or os.getenv("GOOGLE_CLOUD_LOCATION") or "us-central1" # Validation logic if cliproxy_base_url: # CLIProxyAPI mode: skip Gemini auth validation auth_method = AuthMethod.API_KEY else: if auth_method == AuthMethod.API_KEY: if not api_key: raise ValueError(AUTH_ERROR_MESSAGES["api_key_required"]) elif auth_method == AuthMethod.VERTEX_AI: if not gcp_project: raise ADCConfigurationError(AUTH_ERROR_MESSAGES["vertex_ai_project_required"]) else: # AUTO if not api_key: if not gcp_project: raise ValueError(AUTH_ERROR_MESSAGES["no_auth_configured"]) auth_method = AuthMethod.VERTEX_AI else: auth_method = AuthMethod.API_KEY # Handle image output directory output_dir = os.getenv("IMAGE_OUTPUT_DIR", "").strip() if not output_dir: # Default to ~/nanobanana-images in user's home directory for better compatibility output_dir = str(Path.home() / "nanobanana-images") # Convert to absolute path and ensure it exists output_path = Path(output_dir).resolve() output_path.mkdir(parents=True, exist_ok=True) return cls( gemini_api_key=api_key, cliproxy_base_url=cliproxy_base_url, cliproxy_api_key=cliproxy_api_key, cliproxy_config_path=cliproxy_config_path, auth_method=auth_method, gcp_project_id=gcp_project, gcp_region=gcp_region, transport=os.getenv("FASTMCP_TRANSPORT", "stdio"), host=os.getenv("FASTMCP_HOST", "127.0.0.1"), port=int(os.getenv("FASTMCP_PORT", "9000")), mask_error_details=os.getenv("FASTMCP_MASK_ERRORS", "false").lower() == "true", image_output_dir=str(output_path), ) @dataclass class BaseModelConfig: """Shared base configuration for all models.""" max_images_per_request: int = 4 max_inline_image_size: int = 20 * 1024 * 1024 # 20MB default_image_format: str = "png" request_timeout: int = 60 # seconds @dataclass class FlashImageConfig(BaseModelConfig): """Gemini 2.5 Flash Image configuration (speed-optimized).""" model_name: str = "gemini-2.5-flash-image" max_resolution: int = 1024 supports_thinking: bool = False supports_grounding: bool = False supports_media_resolution: bool = False @dataclass class ProImageConfig(BaseModelConfig): """Gemini 3 Pro Image configuration (quality-optimized).""" model_name: str = "gemini-3-pro-image-preview" max_resolution: int = 3840 # 4K default_resolution: str = "high" # low/medium/high default_thinking_level: ThinkingLevel = ThinkingLevel.HIGH default_media_resolution: MediaResolution = MediaResolution.HIGH supports_thinking: bool = True supports_grounding: bool = True supports_media_resolution: bool = True enable_search_grounding: bool = True request_timeout: int = 90 # Pro model needs more time for 4K @dataclass class ModelSelectionConfig: """Configuration for intelligent model selection.""" default_tier: ModelTier = ModelTier.AUTO auto_quality_keywords: list[str] = field(default_factory=lambda: [ "4k", "high quality", "professional", "production", "high-res", "high resolution", "detailed", "sharp", "crisp", "hd", "ultra", "premium", "magazine", "print" ]) auto_speed_keywords: list[str] = field(default_factory=lambda: [ "quick", "fast", "draft", "prototype", "sketch", "rapid", "rough", "temporary", "test" ]) @classmethod def from_env(cls) -> "ModelSelectionConfig": """Load model selection config from environment.""" load_dotenv() model_tier_str = os.getenv("NANOBANANA_MODEL", "auto").lower() try: default_tier = ModelTier(model_tier_str) except ValueError: default_tier = ModelTier.AUTO return cls(default_tier=default_tier) @dataclass class GeminiConfig: """Legacy Gemini API configuration (backward compatibility).""" model_name: str = "gemini-2.5-flash-image" max_images_per_request: int = 4 max_inline_image_size: int = 20 * 1024 * 1024 # 20MB default_image_format: str = "png" request_timeout: int = 60 # seconds - increased for image generation

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ion-aluminium/nanobanana-mcp-cliproxyapi'

If you have feedback or need assistance with the MCP directory API, please join our Discord server