From 0004ec6014daa85a261d3508f2415fb345e82184 Mon Sep 17 00:00:00 2001 From: Jeffreytsai1004 Date: Fri, 18 Apr 2025 01:29:18 +0800 Subject: [PATCH] Update --- .gitignore | 2 + Debug/reload_plugin.mel | 2 +- README.md | 14 +++--- fastapi_server.py | 28 ++++++++++- maya_mcp_plugin.py | 102 +++++++++++++++++++++++++++++++--------- restart_mcp.mel | 6 +-- server.py | 5 +- 7 files changed, 123 insertions(+), 36 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22a85b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/packages +/__pycache__ diff --git a/Debug/reload_plugin.mel b/Debug/reload_plugin.mel index 4444f94..3115844 100644 --- a/Debug/reload_plugin.mel +++ b/Debug/reload_plugin.mel @@ -12,6 +12,6 @@ pause -sec 1; // Load the plugin print("Loading Maya MCP plugin...\n"); -loadPlugin "D:/Dev/Tools/MayaMCP/maya_mcp_plugin.py"; +loadPlugin "d:/Personal/Document/maya/scripts/Maya_MCP/maya_mcp_plugin.py"; print("Plugin reload complete.\n"); diff --git a/README.md b/README.md index cd6ca50..19c62b4 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,13 @@ If the plugin doesn't load automatically, you can load it manually in the Script import sys sys.path.append(r"D:/Dev/Tools/MayaMCP") import maya.cmds as cmds -cmds.loadPlugin("D:/Dev/Tools/MayaMCP/maya_mcp_plugin.py") +cmds.loadPlugin("d:/Personal/Document/maya/scripts/Maya_MCP/maya_mcp_plugin.py") ``` If the MCP menu doesn't appear, you can create it manually: ```mel -source "D:/Dev/Tools/MayaMCP/install.mel"; +source "d:/Personal/Document/maya/scripts/Maya_MCP/install.mel"; forceMCPMenu(); ``` @@ -110,13 +110,13 @@ You can install FastAPI and UVicorn directly using Maya's Python interpreter: ```bash # For Windows -"C:\Program Files\Autodesk\Maya2025\bin\mayapy.exe" -m pip install fastapi uvicorn +"C:\Program Files\Autodesk\Maya2023\bin\mayapy.exe" -m pip install fastapi uvicorn # For macOS -/Applications/Autodesk/maya2025/Maya.app/Contents/bin/mayapy -m pip install fastapi uvicorn +/Applications/Autodesk/maya2023/Maya.app/Contents/bin/mayapy -m pip install fastapi uvicorn # For Linux -/usr/autodesk/maya2025/bin/mayapy -m pip install fastapi uvicorn +/usr/autodesk/maya2023/bin/mayapy -m pip install fastapi uvicorn ``` This will install the packages directly into Maya's Python environment, ensuring they are available when running the MCP server from within Maya. @@ -127,10 +127,10 @@ If you want to install FastAPI and UVicorn in an environment without internet ac ```bash # In an environment with internet access, download dependencies -pip download uvicorn fastapi -d ./packages +python -m pip download uvicorn fastapi -d ./packages # In the target environment, install -pip install --no-index --find-links=./packages uvicorn fastapi +python -m pip install --no-index --find-links=./packages uvicorn fastapi ``` ## License diff --git a/fastapi_server.py b/fastapi_server.py index b83e637..c87d044 100644 --- a/fastapi_server.py +++ b/fastapi_server.py @@ -306,13 +306,37 @@ def start_server(host=SERVER_HOST, port=SERVER_PORT): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - # Create a server config + # Create custom log configuration to avoid using default formatter (which calls isatty) + log_config = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "simple": { + "format": "%(levelname)s: %(message)s", + } + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "simple", + } + }, + "loggers": { + "uvicorn": {"handlers": ["console"], "level": "INFO"}, + "uvicorn.error": {"handlers": ["console"], "level": "INFO"}, + "uvicorn.access": {"handlers": ["console"], "level": "INFO"}, + } + } + + # Create server configuration config = uvicorn.Config( app=app, host=host, port=port, log_level="info", - loop="asyncio" + loop="asyncio", + log_config=log_config ) # Create a server instance diff --git a/maya_mcp_plugin.py b/maya_mcp_plugin.py index 47b601d..f34902e 100644 --- a/maya_mcp_plugin.py +++ b/maya_mcp_plugin.py @@ -221,19 +221,41 @@ def configure_port_cmd(*args): ) return - # Get the plugin path using a more reliable method + # Get plugin path using different methods import sys + import inspect + + # Method 1: Find from sys.path plugin_path = None for path in sys.path: if path.endswith('MayaMCP') and os.path.exists(path): plugin_path = path break + # Method 2: Get current script directory if not plugin_path: - # Fallback to a hardcoded path if needed - plugin_path = "D:/Dev/Tools/MayaMCP" - if not os.path.exists(plugin_path): - raise Exception(f"Could not find plugin path: {plugin_path}") + try: + # Get current module file path + current_file = inspect.getfile(inspect.currentframe()) + # Get directory + current_dir = os.path.dirname(os.path.abspath(current_file)) + if os.path.exists(current_dir): + plugin_path = current_dir + except Exception as e: + om.MGlobal.displayWarning(f"Failed to get path from current script: {e}") + + # Method 3: Get from __file__ + if not plugin_path: + try: + if '__file__' in globals(): + current_dir = os.path.dirname(os.path.abspath(__file__)) + if os.path.exists(current_dir): + plugin_path = current_dir + except Exception as e: + om.MGlobal.displayWarning(f"Failed to get path from __file__: {e}") + + if not plugin_path: + raise Exception("Failed to determine plugin path, please check installation") om.MGlobal.displayInfo(f"Using plugin path: {plugin_path}") @@ -361,19 +383,39 @@ def initializePlugin(plugin): plugin_path = os.path.dirname(plugin_fn.loadPath()) om.MGlobal.displayInfo(f"Plugin path: {plugin_path}") - # Get MayaMCP directory path - fix the path issue - mcp_dir = os.path.join(plugin_path, "MayaMCP") - mcp_dir = mcp_dir.replace('\\', '/') # Ensure forward slashes - om.MGlobal.displayInfo(f"MayaMCP directory: {mcp_dir}") + # Get plugin directory path - support multiple directory names + # Try multiple possible directory names + possible_dirs = ["MayaMCP", "Maya_MCP", "Maya-MCP", "mayamcp"] + mcp_dir = None - if os.path.exists(mcp_dir): - om.MGlobal.displayInfo(f"MayaMCP directory found: {mcp_dir}") - # Add MayaMCP directory to sys.path + # First, check if current directory contains plugin files + if os.path.exists(os.path.join(plugin_path, "server.py")): + mcp_dir = plugin_path + om.MGlobal.displayInfo(f"Found plugin files in current directory: {mcp_dir}") + else: + # Try all possible directory names + for dir_name in possible_dirs: + test_dir = os.path.join(plugin_path, dir_name) + test_dir = test_dir.replace('\\', '/') # Ensure forward slashes + if os.path.exists(test_dir): + mcp_dir = test_dir + om.MGlobal.displayInfo(f"Found plugin directory: {mcp_dir}") + break + + # If found, add to sys.path + if mcp_dir: if mcp_dir not in sys.path: sys.path.append(mcp_dir) - om.MGlobal.displayInfo(f"Added MayaMCP directory to sys.path: {mcp_dir}") + om.MGlobal.displayInfo(f"Added plugin directory to sys.path: {mcp_dir}") else: - om.MGlobal.displayInfo(f"MayaMCP directory not found at: {mcp_dir}") + om.MGlobal.displayInfo(f"Plugin directory not found in: {plugin_path}") + # Try to use the plugin's own directory + plugin_dir = os.path.dirname(os.path.abspath(__file__)) + if plugin_dir and os.path.exists(plugin_dir): + mcp_dir = plugin_dir + if mcp_dir not in sys.path: + sys.path.append(mcp_dir) + om.MGlobal.displayInfo(f"Added plugin file directory to sys.path: {mcp_dir}") # Ensure plugin path is also added to sys.path if plugin_path not in sys.path: @@ -401,15 +443,31 @@ def initializePlugin(plugin): om.MGlobal.displayInfo("Attempting to import server module...") # Add current directory to sys.path - # Cannot use __file__ in Maya plugin, use plugin_path instead - current_dir = plugin_path - if "MayaMCP" in current_dir: - current_dir = current_dir # Already in MayaMCP directory + # Try to use the plugin's own directory + try: + current_dir = os.path.dirname(os.path.abspath(__file__)) + except: + current_dir = plugin_path + + # Check if current directory contains necessary files + if os.path.exists(os.path.join(current_dir, "server.py")): + # Already in the correct directory + pass else: - # Try to find MayaMCP directory - mcp_dir = os.path.join(current_dir, "MayaMCP") - if os.path.exists(mcp_dir): - current_dir = mcp_dir + # Try to find the directory containing server.py + possible_dirs = ["MayaMCP", "Maya_MCP", "Maya-MCP", "mayamcp"] + found = False + + for dir_name in possible_dirs: + test_dir = os.path.join(plugin_path, dir_name) + if os.path.exists(os.path.join(test_dir, "server.py")): + current_dir = test_dir + found = True + break + + # If not found in subdirectories, check current directory + if not found and os.path.exists(os.path.join(plugin_path, "server.py")): + current_dir = plugin_path current_dir = current_dir.replace('\\', '/') # Ensure forward slashes om.MGlobal.displayInfo(f"Using directory: {current_dir}") diff --git a/restart_mcp.mel b/restart_mcp.mel index 0c52253..ee457b1 100644 --- a/restart_mcp.mel +++ b/restart_mcp.mel @@ -1,8 +1,8 @@ // Restart Maya MCP plugin // First, unload the plugin (if loaded) -if (`pluginInfo -query -loaded "d:/Dev/Tools/MayaMCP/maya_mcp_plugin.py"`) +if (`pluginInfo -query -loaded "d:/Personal/Document/maya/scripts/Maya_MCP/maya_mcp_plugin.py"`) { - unloadPlugin "d:/Dev/Tools/MayaMCP/maya_mcp_plugin.py"; + unloadPlugin "d:/Personal/Document/maya/scripts/Maya_MCP/maya_mcp_plugin.py"; print "Maya MCP plugin unloaded.\n"; } @@ -10,7 +10,7 @@ if (`pluginInfo -query -loaded "d:/Dev/Tools/MayaMCP/maya_mcp_plugin.py"`) pause -seconds 1; // Load the plugin using full path -loadPlugin "d:/Dev/Tools/MayaMCP/maya_mcp_plugin.py"; +loadPlugin "d:/Personal/Document/maya/scripts/Maya_MCP/maya_mcp_plugin.py"; print "Maya MCP plugin loaded.\n"; // Start the server (using FastAPI mode) diff --git a/server.py b/server.py index b557df7..959510a 100644 --- a/server.py +++ b/server.py @@ -133,7 +133,10 @@ def start_server(port=SERVER_PORT): # If FastAPI failed or not available, use HTTP handler if not USE_FASTAPI: from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event - port = start_http_server(port=port) + # Ensure port value is valid, if port becomes None, use SERVER_PORT + http_port = port if port is not None else SERVER_PORT + print(f"Attempting to start HTTP server on 127.0.0.1:{http_port}") + port = start_http_server(port=http_port) if port: _server_running = True # Log Maya info