This commit is contained in:
2025-04-18 01:29:18 +08:00
parent 3da72c2629
commit 0004ec6014
7 changed files with 123 additions and 36 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/packages
/__pycache__

View File

@@ -12,6 +12,6 @@ pause -sec 1;
// Load the plugin // Load the plugin
print("Loading Maya MCP plugin...\n"); 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"); print("Plugin reload complete.\n");

View File

@@ -23,13 +23,13 @@ If the plugin doesn't load automatically, you can load it manually in the Script
import sys import sys
sys.path.append(r"D:/Dev/Tools/MayaMCP") sys.path.append(r"D:/Dev/Tools/MayaMCP")
import maya.cmds as cmds 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: If the MCP menu doesn't appear, you can create it manually:
```mel ```mel
source "D:/Dev/Tools/MayaMCP/install.mel"; source "d:/Personal/Document/maya/scripts/Maya_MCP/install.mel";
forceMCPMenu(); forceMCPMenu();
``` ```
@@ -110,13 +110,13 @@ You can install FastAPI and UVicorn directly using Maya's Python interpreter:
```bash ```bash
# For Windows # 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 # 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 # 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. 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 ```bash
# In an environment with internet access, download dependencies # 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 # 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 ## License

View File

@@ -306,13 +306,37 @@ def start_server(host=SERVER_HOST, port=SERVER_PORT):
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
asyncio.set_event_loop(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( config = uvicorn.Config(
app=app, app=app,
host=host, host=host,
port=port, port=port,
log_level="info", log_level="info",
loop="asyncio" loop="asyncio",
log_config=log_config
) )
# Create a server instance # Create a server instance

View File

@@ -221,19 +221,41 @@ def configure_port_cmd(*args):
) )
return return
# Get the plugin path using a more reliable method # Get plugin path using different methods
import sys import sys
import inspect
# Method 1: Find from sys.path
plugin_path = None plugin_path = None
for path in sys.path: for path in sys.path:
if path.endswith('MayaMCP') and os.path.exists(path): if path.endswith('MayaMCP') and os.path.exists(path):
plugin_path = path plugin_path = path
break break
# Method 2: Get current script directory
if not plugin_path: if not plugin_path:
# Fallback to a hardcoded path if needed try:
plugin_path = "D:/Dev/Tools/MayaMCP" # Get current module file path
if not os.path.exists(plugin_path): current_file = inspect.getfile(inspect.currentframe())
raise Exception(f"Could not find plugin path: {plugin_path}") # 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}") om.MGlobal.displayInfo(f"Using plugin path: {plugin_path}")
@@ -361,19 +383,39 @@ def initializePlugin(plugin):
plugin_path = os.path.dirname(plugin_fn.loadPath()) plugin_path = os.path.dirname(plugin_fn.loadPath())
om.MGlobal.displayInfo(f"Plugin path: {plugin_path}") om.MGlobal.displayInfo(f"Plugin path: {plugin_path}")
# Get MayaMCP directory path - fix the path issue # Get plugin directory path - support multiple directory names
mcp_dir = os.path.join(plugin_path, "MayaMCP") # Try multiple possible directory names
mcp_dir = mcp_dir.replace('\\', '/') # Ensure forward slashes possible_dirs = ["MayaMCP", "Maya_MCP", "Maya-MCP", "mayamcp"]
om.MGlobal.displayInfo(f"MayaMCP directory: {mcp_dir}") mcp_dir = None
if os.path.exists(mcp_dir): # First, check if current directory contains plugin files
om.MGlobal.displayInfo(f"MayaMCP directory found: {mcp_dir}") if os.path.exists(os.path.join(plugin_path, "server.py")):
# Add MayaMCP directory to sys.path 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: if mcp_dir not in sys.path:
sys.path.append(mcp_dir) 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: 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 # Ensure plugin path is also added to sys.path
if plugin_path not in sys.path: if plugin_path not in sys.path:
@@ -401,15 +443,31 @@ def initializePlugin(plugin):
om.MGlobal.displayInfo("Attempting to import server module...") om.MGlobal.displayInfo("Attempting to import server module...")
# Add current directory to sys.path # Add current directory to sys.path
# Cannot use __file__ in Maya plugin, use plugin_path instead # Try to use the plugin's own directory
current_dir = plugin_path try:
if "MayaMCP" in current_dir: current_dir = os.path.dirname(os.path.abspath(__file__))
current_dir = current_dir # Already in MayaMCP directory 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: else:
# Try to find MayaMCP directory # Try to find the directory containing server.py
mcp_dir = os.path.join(current_dir, "MayaMCP") possible_dirs = ["MayaMCP", "Maya_MCP", "Maya-MCP", "mayamcp"]
if os.path.exists(mcp_dir): found = False
current_dir = mcp_dir
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 current_dir = current_dir.replace('\\', '/') # Ensure forward slashes
om.MGlobal.displayInfo(f"Using directory: {current_dir}") om.MGlobal.displayInfo(f"Using directory: {current_dir}")

View File

@@ -1,8 +1,8 @@
// Restart Maya MCP plugin // Restart Maya MCP plugin
// First, unload the plugin (if loaded) // 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"; 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; pause -seconds 1;
// Load the plugin using full path // 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"; print "Maya MCP plugin loaded.\n";
// Start the server (using FastAPI mode) // Start the server (using FastAPI mode)

View File

@@ -133,7 +133,10 @@ def start_server(port=SERVER_PORT):
# If FastAPI failed or not available, use HTTP handler # If FastAPI failed or not available, use HTTP handler
if not USE_FASTAPI: if not USE_FASTAPI:
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event 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: if port:
_server_running = True _server_running = True
# Log Maya info # Log Maya info