#!/usr/bin/env python3
"""
Maya Plugin Installation Script
Automatically installs the Maya MCP plugin to the correct Maya plugins directory
"""
import os
import sys
import shutil
import platform
import subprocess
from pathlib import Path
def find_maya_installations():
"""Find Maya installations on the system"""
maya_paths = []
system = platform.system()
if system == "Windows":
# Common Maya installation paths on Windows
program_files = [
os.environ.get('PROGRAMFILES', 'C:\\Program Files'),
os.environ.get('PROGRAMFILES(X86)', 'C:\\Program Files (x86)')
]
for pf in program_files:
if pf:
autodesk_path = Path(pf) / "Autodesk"
if autodesk_path.exists():
for maya_dir in autodesk_path.glob("Maya*"):
mayapy_path = maya_dir / "bin" / "mayapy.exe"
if mayapy_path.exists():
maya_paths.append({
'version': maya_dir.name,
'path': maya_dir,
'mayapy': mayapy_path
})
elif system == "Darwin": # macOS
# Common Maya paths on macOS
apps_path = Path("/Applications")
for maya_dir in apps_path.glob("Autodesk/maya*"):
mayapy_path = maya_dir / "Maya.app" / "Contents" / "bin" / "mayapy"
if mayapy_path.exists():
maya_paths.append({
'version': maya_dir.name,
'path': maya_dir,
'mayapy': mayapy_path
})
elif system == "Linux":
# Common Maya paths on Linux
usr_path = Path("/usr/autodesk")
if usr_path.exists():
for maya_dir in usr_path.glob("maya*"):
mayapy_path = maya_dir / "bin" / "mayapy"
if mayapy_path.exists():
maya_paths.append({
'version': maya_dir.name,
'path': maya_dir,
'mayapy': mayapy_path
})
return maya_paths
def get_windows_documents_path():
"""Get the actual Windows Documents folder path"""
try:
import winreg
# Try to get Documents folder from registry
with winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") as key:
documents_path, _ = winreg.QueryValueEx(key, "Personal")
return Path(documents_path)
except (ImportError, OSError, FileNotFoundError):
pass
try:
# Try using Windows API
import ctypes.wintypes
CSIDL_PERSONAL = 5 # My Documents
SHGFP_TYPE_CURRENT = 0 # Current value
buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf)
return Path(buf.value)
except (ImportError, AttributeError, OSError):
pass
# Fallback to environment variables and common paths
user_profile = os.environ.get('USERPROFILE')
if user_profile:
# Try common document folder names
for doc_name in ['Documents', 'Document', 'My Documents', '文档']:
doc_path = Path(user_profile) / doc_name
if doc_path.exists():
return doc_path
# Default fallback
return Path(user_profile) / "Documents"
return None
def get_maya_plugins_directory():
"""Get the Maya plugins directory for the current platform"""
system = platform.system()
if system == "Windows":
# Windows: Get actual Documents path + maya\plug-ins\
documents_path = get_windows_documents_path()
if documents_path:
maya_plugins_path = documents_path / "maya" / "plug-ins"
print(f"Detected Documents path: {documents_path}")
print(f"Maya plugins path: {maya_plugins_path}")
return maya_plugins_path
elif system == "Darwin": # macOS
# macOS: ~/Library/Preferences/Autodesk/maya/plug-ins/
home = Path.home()
return home / "Library" / "Preferences" / "Autodesk" / "maya" / "plug-ins"
elif system == "Linux":
# Linux: ~/maya/plug-ins/
home = Path.home()
return home / "maya" / "plug-ins"
return None
def find_maya_plugins_directories():
"""Find all possible Maya plugins directories"""
directories = []
system = platform.system()
if system == "Windows":
# Primary: User's Documents/maya/plug-ins
documents_path = get_windows_documents_path()
if documents_path:
maya_plugins = documents_path / "maya" / "plug-ins"
directories.append({
'path': maya_plugins,
'type': 'user_documents',
'description': f'User Documents Maya plugins ({documents_path})'
})
# Alternative: USERPROFILE/Documents/maya/plug-ins (if different)
user_profile = os.environ.get('USERPROFILE')
if user_profile:
alt_path = Path(user_profile) / "Documents" / "maya" / "plug-ins"
if alt_path != maya_plugins:
directories.append({
'path': alt_path,
'type': 'userprofile_documents',
'description': f'UserProfile Documents Maya plugins ({alt_path})'
})
# Maya environment variable paths
maya_app_dir = os.environ.get('MAYA_APP_DIR')
if maya_app_dir:
directories.append({
'path': Path(maya_app_dir) / "plug-ins",
'type': 'maya_app_dir',
'description': f'MAYA_APP_DIR plugins ({maya_app_dir})'
})
elif system == "Darwin": # macOS
home = Path.home()
directories.extend([
{
'path': home / "Library" / "Preferences" / "Autodesk" / "maya" / "plug-ins",
'type': 'user_prefs',
'description': 'User Preferences Maya plugins'
},
{
'path': home / "maya" / "plug-ins",
'type': 'user_maya',
'description': 'User Maya plugins'
}
])
elif system == "Linux":
home = Path.home()
directories.extend([
{
'path': home / "maya" / "plug-ins",
'type': 'user_maya',
'description': 'User Maya plugins'
},
{
'path': home / ".maya" / "plug-ins",
'type': 'user_maya_hidden',
'description': 'User Maya plugins (hidden)'
}
])
return directories
def test_plugin_with_mayapy(mayapy_path, plugin_path):
"""Test the plugin using mayapy"""
try:
# Create a simple test script
test_script = f'''
import sys
sys.path.append(r"{plugin_path.parent}")
try:
import maya_mcp
print("✓ Plugin imports successfully")
if hasattr(maya_mcp, "initializePlugin"):
print("✓ Plugin has initializePlugin function")
if hasattr(maya_mcp, "uninitializePlugin"):
print("✓ Plugin has uninitializePlugin function")
print("✓ Plugin validation passed")
except Exception as e:
print(f"✗ Plugin validation failed: {{e}}")
sys.exit(1)
'''
# Run the test with mayapy
result = subprocess.run(
[str(mayapy_path), "-c", test_script],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
print(f"✓ Plugin tested successfully with {mayapy_path}")
print(result.stdout)
return True
else:
print(f"✗ Plugin test failed with {mayapy_path}")
print(result.stderr)
return False
except subprocess.TimeoutExpired:
print(f"✗ Plugin test timed out with {mayapy_path}")
return False
except Exception as e:
print(f"✗ Error testing plugin with {mayapy_path}: {e}")
return False
def install_plugin():
"""Install the Maya MCP plugin"""
# Get script directory and plugin source
script_dir = Path(__file__).parent.absolute()
project_root = script_dir.parent
plugin_source = project_root / "plug-ins" / "maya_mcp.py"
if not plugin_source.exists():
print(f"Error: Plugin source not found at {plugin_source}")
return False
# Find Maya installations
maya_installations = find_maya_installations()
if maya_installations:
print("Found Maya installations:")
for maya in maya_installations:
print(f" - {maya['version']}: {maya['path']}")
print(f" mayapy: {maya['mayapy']}")
else:
print("No Maya installations found in standard locations")
# Find all possible Maya plugins directories
possible_dirs = find_maya_plugins_directories()
print(f"\nDetected possible Maya plugins directories:")
for i, dir_info in enumerate(possible_dirs):
exists_marker = "✓" if dir_info['path'].exists() else "✗"
print(f" {i+1}. {exists_marker} {dir_info['description']}")
print(f" Path: {dir_info['path']}")
# Get primary plugins directory (first one that exists, or first one if none exist)
plugins_dir = None
for dir_info in possible_dirs:
if dir_info['path'].exists():
plugins_dir = dir_info['path']
print(f"\nUsing existing directory: {plugins_dir}")
break
if not plugins_dir and possible_dirs:
# Use the first (primary) directory
plugins_dir = possible_dirs[0]['path']
print(f"\nUsing primary directory: {plugins_dir}")
if not plugins_dir:
print(f"Error: Could not determine Maya plugins directory for {platform.system()}")
print("Please manually copy plug-ins/maya_mcp.py to your Maya plugins directory")
return False
# Create plugins directory if it doesn't exist
try:
plugins_dir.mkdir(parents=True, exist_ok=True)
print(f"✓ Created plugins directory: {plugins_dir}")
except Exception as e:
print(f"Error creating plugins directory {plugins_dir}: {e}")
return False
# Copy plugin file
plugin_dest = plugins_dir / "maya_mcp.py"
try:
shutil.copy2(plugin_source, plugin_dest)
print(f"✓ Maya MCP plugin installed successfully to: {plugin_dest}")
# Test plugin with available Maya installations
if maya_installations:
print("\nTesting plugin with available Maya installations:")
for maya in maya_installations:
print(f"\nTesting with {maya['version']}...")
test_plugin_with_mayapy(maya['mayapy'], plugin_dest)
# Also install to other existing directories if they exist
installed_paths = [plugin_dest]
for dir_info in possible_dirs[1:]: # Skip the first one (already installed)
if dir_info['path'].exists() and dir_info['path'] != plugins_dir:
try:
alt_dest = dir_info['path'] / "maya_mcp.py"
shutil.copy2(plugin_source, alt_dest)
print(f"✓ Also installed to: {alt_dest}")
installed_paths.append(alt_dest)
except Exception as e:
print(f"⚠ Could not install to {dir_info['path']}: {e}")
print(f"\nPlugin installed to {len(installed_paths)} location(s)")
print("\nNext steps:")
print("1. Start Maya")
print("2. The plugin should auto-load and start listening on port 7022")
print("3. If it doesn't auto-load, use Maya's Plugin Manager to load 'maya_mcp.py'")
print("4. Start the MCP server with: npx maya-mcp-server")
if len(possible_dirs) > len(installed_paths):
print(f"\nNote: Found {len(possible_dirs)} possible plugin directories.")
print("If the plugin doesn't load, you may need to copy it manually to your Maya's specific plugins directory.")
return True
except Exception as e:
print(f"Error copying plugin file: {e}")
print(f"Please manually copy {plugin_source} to {plugins_dir}")
return False
def main():
"""Main entry point"""
print("Maya MCP Plugin Installer")
print("=" * 40)
if install_plugin():
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()