From 649599fcfe3fdc9c44c63996a03299d352c047d3 Mon Sep 17 00:00:00 2001 From: "toma.tanigawa" Date: Fri, 18 Apr 2025 20:23:41 +0900 Subject: [PATCH] Add: Shader management tool --- UnityMcpServer/src/server.py | 3 +- UnityMcpServer/src/tools/__init__.py | 2 + UnityMcpServer/src/tools/manage_shader.py | 67 +++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 UnityMcpServer/src/tools/manage_shader.py diff --git a/UnityMcpServer/src/server.py b/UnityMcpServer/src/server.py index 90d0c72..55360b5 100644 --- a/UnityMcpServer/src/server.py +++ b/UnityMcpServer/src/server.py @@ -61,7 +61,8 @@ def asset_creation_strategy() -> str: "- `manage_scene`: Manages scenes.\\n" "- `manage_gameobject`: Manages GameObjects in the scene.\\n" "- `manage_script`: Manages C# script files.\\n" - "- `manage_asset`: Manages prefabs and assets.\\n\\n" + "- `manage_asset`: Manages prefabs and assets.\\n" + "- `manage_shader`: Manages shaders.\\n\\n" "Tips:\\n" "- Create prefabs for reusable GameObjects.\\n" "- Always include a camera and main light in your scenes.\\n" diff --git a/UnityMcpServer/src/tools/__init__.py b/UnityMcpServer/src/tools/__init__.py index 8cfc38e..4d8d63c 100644 --- a/UnityMcpServer/src/tools/__init__.py +++ b/UnityMcpServer/src/tools/__init__.py @@ -3,6 +3,7 @@ from .manage_scene import register_manage_scene_tools from .manage_editor import register_manage_editor_tools from .manage_gameobject import register_manage_gameobject_tools from .manage_asset import register_manage_asset_tools +from .manage_shader import register_manage_shader_tools from .read_console import register_read_console_tools from .execute_menu_item import register_execute_menu_item_tools @@ -14,6 +15,7 @@ def register_all_tools(mcp): register_manage_editor_tools(mcp) register_manage_gameobject_tools(mcp) register_manage_asset_tools(mcp) + register_manage_shader_tools(mcp) register_read_console_tools(mcp) register_execute_menu_item_tools(mcp) print("Unity MCP Server tool registration complete.") diff --git a/UnityMcpServer/src/tools/manage_shader.py b/UnityMcpServer/src/tools/manage_shader.py new file mode 100644 index 0000000..c447a3a --- /dev/null +++ b/UnityMcpServer/src/tools/manage_shader.py @@ -0,0 +1,67 @@ +from mcp.server.fastmcp import FastMCP, Context +from typing import Dict, Any +from unity_connection import get_unity_connection +import os +import base64 + +def register_manage_shader_tools(mcp: FastMCP): + """Register all shader script management tools with the MCP server.""" + + @mcp.tool() + def manage_shader( + ctx: Context, + action: str, + name: str, + path: str, + contents: str, + ) -> Dict[str, Any]: + """Manages shader scripts in Unity (create, read, update, delete). + + Args: + action: Operation ('create', 'read', 'update', 'delete'). + name: Shader name (no .cs extension). + path: Asset path (default: "Assets/"). + contents: Shader code for 'create'/'update'. + + Returns: + Dictionary with results ('success', 'message', 'data'). + """ + try: + # Prepare parameters for Unity + params = { + "action": action, + "name": name, + "path": path, + } + + # Base64 encode the contents if they exist to avoid JSON escaping issues + if contents is not None: + if action in ['create', 'update']: + # Encode content for safer transmission + params["encodedContents"] = base64.b64encode(contents.encode('utf-8')).decode('utf-8') + params["contentsEncoded"] = True + else: + params["contents"] = contents + + # Remove None values so they don't get sent as null + params = {k: v for k, v in params.items() if v is not None} + + # Send command to Unity + response = get_unity_connection().send_command("manage_shader", params) + + # Process response from Unity + if response.get("success"): + # If the response contains base64 encoded content, decode it + if response.get("data", {}).get("contentsEncoded"): + decoded_contents = base64.b64decode(response["data"]["encodedContents"]).decode('utf-8') + response["data"]["contents"] = decoded_contents + del response["data"]["encodedContents"] + del response["data"]["contentsEncoded"] + + return {"success": True, "message": response.get("message", "Operation successful."), "data": response.get("data")} + else: + return {"success": False, "message": response.get("error", "An unknown error occurred.")} + + except Exception as e: + # Handle Python-side errors (e.g., connection issues) + return {"success": False, "message": f"Python error managing shader: {str(e)}"} \ No newline at end of file