Spaces:
Running on Zero
Running on Zero
| """MCP Server implementation for Flux Seamless Texture LoRA.""" | |
| import json | |
| import logging | |
| from typing import Any, Dict, List, Optional | |
| from pathlib import Path | |
| from datetime import datetime | |
| from config.settings import MCP_ENABLED, EXAMPLES_DIR | |
| from src.model_handler import ModelHandler | |
| from src.presets import list_presets, get_preset, get_preset_prompt, get_preset_params | |
| from src.image_processor import load_metadata, OUTPUT_DIR | |
| logger = logging.getLogger(__name__) | |
| class MCPServer: | |
| """MCP Server for exposing the Space via Model Context Protocol.""" | |
| def __init__(self, model_handler: ModelHandler): | |
| """Initialize the MCP server. | |
| Args: | |
| model_handler: Instance of ModelHandler. | |
| """ | |
| self.model_handler = model_handler | |
| self.history: List[Dict[str, Any]] = [] | |
| # Tools (Ferramentas) | |
| def tool_generate_texture( | |
| self, | |
| prompt: str, | |
| negative_prompt: str = "", | |
| guidance_scale: float = 7.5, | |
| num_inference_steps: int = 50, | |
| seed: Optional[int] = None, | |
| width: int = 1024, | |
| height: int = 1024, | |
| ) -> Dict[str, Any]: | |
| """Generate a texture image. | |
| Args: | |
| prompt: Text prompt for generation. | |
| negative_prompt: Negative prompt. | |
| guidance_scale: Guidance scale. | |
| num_inference_steps: Number of inference steps. | |
| seed: Random seed. | |
| width: Image width. | |
| height: Image height. | |
| Returns: | |
| Dictionary with image path and metadata. | |
| """ | |
| try: | |
| image, metadata = self.model_handler.generate( | |
| prompt=prompt, | |
| negative_prompt=negative_prompt, | |
| guidance_scale=guidance_scale, | |
| num_inference_steps=num_inference_steps, | |
| seed=seed, | |
| width=width, | |
| height=height, | |
| ) | |
| # Add to history | |
| history_entry = { | |
| "timestamp": datetime.now().timestamp(), | |
| "prompt": prompt, | |
| "params": { | |
| "negative_prompt": negative_prompt, | |
| "guidance_scale": guidance_scale, | |
| "num_inference_steps": num_inference_steps, | |
| "seed": seed, | |
| "width": width, | |
| "height": height, | |
| }, | |
| "image_path": metadata.get("image_path"), | |
| } | |
| self.history.append(history_entry) | |
| return { | |
| "success": True, | |
| "image_path": metadata.get("image_path"), | |
| "seed": metadata.get("seed"), | |
| "message": "Texture generated successfully", | |
| } | |
| except Exception as e: | |
| logger.error(f"Error in generate_texture: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e), | |
| } | |
| def tool_generate_batch_textures( | |
| self, | |
| prompts: List[str], | |
| guidance_scale: float = 7.5, | |
| num_inference_steps: int = 50, | |
| ) -> Dict[str, Any]: | |
| """Generate multiple textures in batch. | |
| Args: | |
| prompts: List of prompts. | |
| guidance_scale: Guidance scale. | |
| num_inference_steps: Number of inference steps. | |
| Returns: | |
| Dictionary with results. | |
| """ | |
| try: | |
| base_params = { | |
| "guidance_scale": guidance_scale, | |
| "num_inference_steps": num_inference_steps, | |
| } | |
| results = [] | |
| for image, metadata, idx in self.model_handler.generate_batch(prompts, base_params): | |
| if image is not None: | |
| results.append({ | |
| "index": idx, | |
| "success": True, | |
| "image_path": metadata.get("image_path"), | |
| }) | |
| else: | |
| results.append({ | |
| "index": idx, | |
| "success": False, | |
| "error": metadata.get("error"), | |
| }) | |
| return { | |
| "success": True, | |
| "total": len(prompts), | |
| "results": results, | |
| } | |
| except Exception as e: | |
| logger.error(f"Error in generate_batch_textures: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e), | |
| } | |
| def tool_get_presets(self) -> Dict[str, Any]: | |
| """Get list of available presets. | |
| Returns: | |
| Dictionary with preset names and details. | |
| """ | |
| presets = list_presets() | |
| preset_details = {} | |
| for name in presets: | |
| preset = get_preset(name) | |
| if preset: | |
| preset_details[name] = { | |
| "prompt": preset.get("prompt"), | |
| "guidance_scale": preset.get("guidance_scale"), | |
| "num_inference_steps": preset.get("num_inference_steps"), | |
| } | |
| return { | |
| "presets": presets, | |
| "details": preset_details, | |
| } | |
| def tool_get_history(self, limit: int = 10) -> Dict[str, Any]: | |
| """Get generation history. | |
| Args: | |
| limit: Maximum number of entries to return. | |
| Returns: | |
| Dictionary with history entries. | |
| """ | |
| recent = self.history[-limit:] if len(self.history) > limit else self.history | |
| return { | |
| "total": len(self.history), | |
| "entries": recent, | |
| } | |
| def tool_download_image(self, image_path: str) -> Dict[str, Any]: | |
| """Get information about an image for download. | |
| Args: | |
| image_path: Path to the image. | |
| Returns: | |
| Dictionary with image information. | |
| """ | |
| path = Path(image_path) | |
| if not path.exists(): | |
| return { | |
| "success": False, | |
| "error": "Image not found", | |
| } | |
| metadata = load_metadata(path) | |
| return { | |
| "success": True, | |
| "image_path": str(path), | |
| "metadata": metadata, | |
| } | |
| # Resources (Recursos) | |
| def resource_presets(self) -> str: | |
| """Get presets as a resource. | |
| Returns: | |
| JSON string of presets. | |
| """ | |
| presets = {} | |
| for name in list_presets(): | |
| preset = get_preset(name) | |
| if preset: | |
| presets[name] = preset | |
| return json.dumps(presets, indent=2) | |
| def resource_history(self) -> str: | |
| """Get history as a resource. | |
| Returns: | |
| JSON string of history. | |
| """ | |
| return json.dumps(self.history, indent=2) | |
| def resource_examples(self) -> str: | |
| """Get examples as a resource. | |
| Returns: | |
| JSON string of example information. | |
| """ | |
| examples = [] | |
| if EXAMPLES_DIR.exists(): | |
| for img_file in EXAMPLES_DIR.glob("*.{png,jpg,jpeg}"): | |
| examples.append({ | |
| "filename": img_file.name, | |
| "path": str(img_file), | |
| }) | |
| return json.dumps(examples, indent=2) | |
| def create_mcp_server(model_handler: ModelHandler) -> MCPServer: | |
| """Create an MCP server instance. | |
| Args: | |
| model_handler: Instance of ModelHandler. | |
| Returns: | |
| MCPServer instance. | |
| """ | |
| return MCPServer(model_handler) | |