添加 server.py

This commit is contained in:
2025-04-16 19:52:59 +08:00
parent 3f48fa02d2
commit d7e2b24ea7

212
server.py Normal file
View File

@@ -0,0 +1,212 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Maya MCP Server
Core implementation of the Model Context Protocol server for Maya.
Version: 1.0.0
Author: Jeffrey Tsai
"""
import os
import sys
import json
import time
import traceback
import maya.cmds as cmds
import maya.api.OpenMaya as om
from port_config import SERVER_PORT
from log_config import get_logger, initialize_logging
# Initialize logging
initialize_logging()
logger = get_logger("Server")
# Import HTTP handler
try:
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event
logger.info("HTTP handler imported successfully")
except Exception as e:
logger.error(f"Error importing HTTP handler: {e}")
logger.error(traceback.format_exc())
# Global variables
_server_running = False
# Public functions
def start_server(port=SERVER_PORT):
"""
Start the MCP server
Args:
port (int): Server port number
Returns:
int: Port number if server started successfully, None otherwise
"""
global SERVER_PORT, _server_running
try:
# Check if server is already running
if _server_running:
logger.info(f"Server already running on port {SERVER_PORT}")
return SERVER_PORT
logger.info(f"Starting MCP server on port {port}...")
# Start HTTP server
http_port = start_http_server(port)
if http_port:
_server_running = True
SERVER_PORT = http_port
logger.info(f"MCP server successfully started on port {SERVER_PORT}")
# Get Maya info
try:
maya_info = {
"maya_version": cmds.about(version=True),
"maya_api_version": om.MGlobal.apiVersion(),
"os_name": cmds.about(operatingSystem=True),
"product_name": cmds.about(product=True)
}
logger.info(f"Maya info: {maya_info}")
# Broadcast Maya info event
try:
broadcast_event("maya_info", maya_info)
logger.debug("Maya info event broadcasted")
except Exception as e:
logger.warning(f"Error broadcasting Maya info: {e}")
logger.debug(traceback.format_exc())
except Exception as e:
logger.warning(f"Error getting Maya info: {e}")
logger.debug(traceback.format_exc())
return SERVER_PORT
else:
logger.error(f"Failed to start HTTP server on port {port}")
return None
except Exception as e:
logger.error(f"Error starting server: {e}")
logger.error(traceback.format_exc())
return None
def stop_server():
"""
Stop the MCP server
Returns:
bool: Whether server was successfully stopped
"""
global _server_running
try:
if _server_running:
logger.info("Stopping MCP server...")
# Stop HTTP server
success = stop_http_server()
if success:
_server_running = False
logger.info("MCP server stopped successfully")
else:
logger.error("Failed to stop HTTP server")
return success
else:
logger.info("Server is not running")
return False
except Exception as e:
logger.error(f"Error stopping server: {e}")
logger.error(traceback.format_exc())
return False
def is_server_running():
"""
Check if server is running
Returns:
bool: Whether server is running
"""
global _server_running
if _server_running:
return is_http_server_running()
return False
def get_scene_info():
"""
Get Maya scene information
Returns:
dict: Scene information
"""
try:
logger.debug("Getting scene information...")
# Get current file
try:
current_file = cmds.file(query=True, sceneName=True) or "untitled"
logger.debug(f"Current file: {current_file}")
except Exception as e:
logger.warning(f"Error getting current file: {e}")
logger.debug(traceback.format_exc())
current_file = "unknown"
# Get selection
try:
# Ensure to pass boolean True, not the string "True"
selection = cmds.ls(sl=True) or []
logger.debug(f"Selection: {selection}")
except Exception as e:
logger.warning(f"Error getting selection: {e}")
logger.debug(traceback.format_exc())
selection = []
# Get scene objects
try:
objects = cmds.ls(type="transform") or []
logger.debug(f"Found {len(objects)} transform objects")
except Exception as e:
logger.warning(f"Error getting objects: {e}")
logger.debug(traceback.format_exc())
objects = []
# Get cameras
try:
cameras = cmds.ls(type="camera") or []
logger.debug(f"Found {len(cameras)} cameras")
except Exception as e:
logger.warning(f"Error getting cameras: {e}")
logger.debug(traceback.format_exc())
cameras = []
# Get lights
try:
lights = cmds.ls(type="light") or []
logger.debug(f"Found {len(lights)} lights")
except Exception as e:
logger.warning(f"Error getting lights: {e}")
logger.debug(traceback.format_exc())
lights = []
# Create scene info
scene_info = {
"file": current_file,
"selection": selection,
"objects": objects[:10], # Limit to first 10
"cameras": cameras,
"lights": lights
}
logger.debug(f"Scene info retrieved: {len(str(scene_info))} bytes")
return scene_info
except Exception as e:
logger.error(f"Error getting scene info: {e}")
logger.error(traceback.format_exc())
return {"error": str(e)}