Skip to main content
Glama

Ureanl-Blender-MCP

interface.py10.5 kB
""" Interface module to connect the MCP server with the extended Blender addon. This module provides functions to install, load, and use the extended Blender addon. """ import os import sys import shutil import logging import tempfile from pathlib import Path from typing import Optional, Dict, Any, List, Tuple logger = logging.getLogger(__name__) class BlenderAddonManager: """ Manages installation and interaction with the extended Blender addon. """ def __init__(self, base_dir: Optional[str] = None): """ Initialize the BlenderAddonManager. Args: base_dir: Base directory of the project. If None, will try to determine automatically. """ if base_dir is None: # Try to determine the base directory self.base_dir = os.path.abspath(os.path.join( os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) )) else: self.base_dir = os.path.abspath(base_dir) self.original_addon_dir = os.path.join(self.base_dir, "blender-mcp") self.extended_addon_dir = os.path.join(self.base_dir, "src", "unreal_blender_mcp", "blender_addon") # Verify directories exist if not os.path.isdir(self.original_addon_dir): logger.warning(f"Original addon directory not found: {self.original_addon_dir}") if not os.path.isdir(self.extended_addon_dir): logger.warning(f"Extended addon directory not found: {self.extended_addon_dir}") def create_installable_addon(self, output_dir: Optional[str] = None) -> str: """ Create an installable version of the extended Blender addon. This will copy the original addon files and the extended addon implementation into a single installable directory structure. Args: output_dir: Directory where to create the installable addon. If None, a temporary directory will be used. Returns: Path to the created installable addon. """ # Create a temporary directory if no output directory specified if output_dir is None: output_dir = tempfile.mkdtemp(prefix="unreal_blender_mcp_addon_") else: os.makedirs(output_dir, exist_ok=True) addon_dir = os.path.join(output_dir, "blender_mcp_extended") os.makedirs(addon_dir, exist_ok=True) # Copy the original addon.py to the installable directory shutil.copy( os.path.join(self.original_addon_dir, "addon.py"), os.path.join(addon_dir, "original_addon.py") ) # Copy extended addon files for filename in os.listdir(self.extended_addon_dir): # Skip __pycache__ directory if filename == "__pycache__": continue src_path = os.path.join(self.extended_addon_dir, filename) dst_path = os.path.join(addon_dir, filename) if os.path.isfile(src_path): shutil.copy(src_path, dst_path) elif os.path.isdir(src_path): shutil.copytree(src_path, dst_path, dirs_exist_ok=True) # Create a new __init__.py file that imports and uses the extended addon init_path = os.path.join(addon_dir, "__init__.py") with open(init_path, "w") as f: f.write(""" # Extended BlenderMCP Addon for unreal-blender-mcp # # This is an extension of the original BlenderMCP addon that adds new functionality # while maintaining compatibility with the original. import bpy import os import sys # Add the current directory to the Python path to ensure imports work if __file__ not in sys.path: sys.path.append(os.path.dirname(__file__)) # Import from extended_addon from extended_addon import ExtendedBlenderMCPServer, register_extended, unregister_extended bl_info = { "name": "Extended Blender MCP", "author": "unreal-blender-mcp", "version": (0, 4), "blender": (3, 0, 0), "location": "View3D > Sidebar > ExtBlenderMCP", "description": "Extended version of BlenderMCP for unreal-blender-mcp", "category": "Interface", } def register(): # Register the extended addon register_extended() def unregister(): # Unregister the extended addon unregister_extended() if __name__ == "__main__": register() """) logger.info(f"Created installable extended addon at: {addon_dir}") return addon_dir def get_blender_addon_path(self, blender_version: str = "3.0") -> Optional[str]: """ Get the path where Blender addons should be installed. Args: blender_version: Blender version string (e.g., "3.0") Returns: Path to the Blender addons directory, or None if not found. """ # Get platform-specific Blender addon paths addon_paths = [] # Check for user preferences addon path - this is where most users install addons if sys.platform == "win32": # Windows appdata = os.environ.get("APPDATA") if appdata: addon_paths.append(os.path.join(appdata, "Blender Foundation", "Blender", blender_version, "scripts", "addons")) elif sys.platform == "darwin": # macOS home = os.path.expanduser("~") addon_paths.append(os.path.join(home, "Library", "Application Support", "Blender", blender_version, "scripts", "addons")) else: # Linux home = os.path.expanduser("~") addon_paths.append(os.path.join(home, ".config", "blender", blender_version, "scripts", "addons")) # Also check if BLENDER_USER_SCRIPTS environment variable is set user_scripts = os.environ.get("BLENDER_USER_SCRIPTS") if user_scripts: addon_paths.append(os.path.join(user_scripts, "addons")) # Return the first path that exists for path in addon_paths: if os.path.isdir(path): return path # If none of the paths exist, return the first one (it will need to be created) return addon_paths[0] if addon_paths else None def install_to_blender(self, blender_version: str = "3.0", force: bool = False) -> bool: """ Install the extended addon to the Blender addons directory. Args: blender_version: Blender version string (e.g., "3.0") force: If True, overwrite existing installation Returns: True if installation was successful, False otherwise. """ # Get Blender addon path blender_addon_path = self.get_blender_addon_path(blender_version) if not blender_addon_path: logger.error("Failed to determine Blender addon path") return False # Create the Blender addon directory if it doesn't exist os.makedirs(blender_addon_path, exist_ok=True) # Create the installable addon installable_addon = self.create_installable_addon() # Define the target directory in the Blender addons folder target_dir = os.path.join(blender_addon_path, "blender_mcp_extended") # Check if the addon is already installed if os.path.exists(target_dir): if force: # Remove existing installation shutil.rmtree(target_dir) else: logger.warning(f"Addon already installed at {target_dir}. Use force=True to overwrite.") return False # Copy the installable addon to the Blender addons directory shutil.copytree(installable_addon, target_dir) logger.info(f"Installed extended addon to Blender at: {target_dir}") return True def generate_blender_startup_script(self, port: int = 8401) -> str: """ Generate a Python script that can be run in Blender to start the extended addon server. Args: port: Port number for the server to listen on Returns: String containing Python code to start the extended addon server """ script = f""" import bpy # Try to load the extended addon if not already loaded if not 'blender_mcp_extended' in bpy.context.preferences.addons: try: bpy.ops.preferences.addon_enable(module='blender_mcp_extended') print("Enabled blender_mcp_extended addon") except Exception as e: print(f"Error enabling blender_mcp_extended addon: {{str(e)}}") # Import the extended addon module try: from blender_mcp_extended.extended_addon import ExtendedBlenderMCPServer # Set port in scene settings bpy.context.scene.extended_blendermcp_port = {port} print(f"Set extended BlenderMCP port to {{bpy.context.scene.extended_blendermcp_port}}") # Create and start the server if not hasattr(bpy.types, "extended_blendermcp_server") or not bpy.types.extended_blendermcp_server: bpy.types.extended_blendermcp_server = ExtendedBlenderMCPServer(port={port}) # Start the server bpy.types.extended_blendermcp_server.start() bpy.context.scene.extended_blendermcp_server_running = True print(f"Started extended BlenderMCP server on port {port}") except Exception as e: print(f"Error starting extended BlenderMCP server: {{str(e)}}") """ return script def main(): """ Main function for testing the BlenderAddonManager. """ logging.basicConfig(level=logging.INFO) # Create an instance of the BlenderAddonManager manager = BlenderAddonManager() # Create and install the addon addon_dir = manager.create_installable_addon() print(f"Created installable addon at: {addon_dir}") # Generate a startup script script = manager.generate_blender_startup_script(port=8401) print("\nBlender Startup Script:") print(script) print("\nYou can now install this addon in Blender by:") print(f"1. Copying {addon_dir} to your Blender addons directory") print("2. Enabling the 'Extended Blender MCP' addon in Blender preferences") print("3. Using the script above to start the extended server") if __name__ == "__main__": main()

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/tahooki/unreal-blender-mcp'

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