From 252c737b5b4fc8707bf5738dfcaa80fa4ad68939 Mon Sep 17 00:00:00 2001 From: lingchenma Date: Mon, 9 Jun 2025 11:36:09 +0800 Subject: [PATCH 1/3] Add log printing to the file --- photoshop_mcp_server/registry.py | 35 ++++++++++++--------- photoshop_mcp_server/server.py | 11 +++++-- photoshop_mcp_server/tools/session_tools.py | 20 +++++------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/photoshop_mcp_server/registry.py b/photoshop_mcp_server/registry.py index 378c4f2..6ffc5ff 100644 --- a/photoshop_mcp_server/registry.py +++ b/photoshop_mcp_server/registry.py @@ -9,17 +9,16 @@ from collections.abc import Callable from typing import Literal -from loguru import logger from mcp.server.fastmcp import FastMCP from photoshop_mcp_server.decorators import debug_tool, log_tool_call # Set of modules that have been registered _registered_modules: set[str] = set() - +logger = None def register_from_module( - mcp_server: FastMCP, module_name: str, registry_type: Literal["tool", "resource"] + mcp_server: FastMCP, module_name: str, registry_type: Literal["tool", "resource"],**keys ) -> list[str]: """Register all tools or resources from a module. @@ -43,10 +42,14 @@ def register_from_module( # Check if the module has a register function if hasattr(module, "register") and callable(module.register): - logger.info( - f"Registering {registry_type}s from {module_name} using register() function" - ) - module.register(mcp_server) + if logger: + logger.info( + f"Registering {registry_type}s from {module_name} using register() function" + ) + if module.register.__code__.co_argcount == 2: + module.register(mcp_server, logger) + else: + module.register(mcp_server) _registered_modules.add(registry_key) # We can't know what items were registered, so return empty list return registered_items @@ -67,7 +70,7 @@ def register_from_module( def register_all( - mcp_server: FastMCP, package_name: str, registry_type: Literal["tool", "resource"] + mcp_server: FastMCP, package_name: str, registry_type: Literal["tool", "resource"],**keys ) -> dict[str, list[str]]: """Register all tools or resources from all modules in a package. @@ -94,7 +97,7 @@ def register_all( if module_name.split(".")[-1] in skip_modules: continue - items = register_from_module(mcp_server, module_name, registry_type) + items = register_from_module(mcp_server, module_name, registry_type,**keys) if items: registered_items[module_name] = items @@ -110,7 +113,7 @@ def register_all( def register_all_tools( - mcp_server: FastMCP, package_name: str = "photoshop_mcp_server.tools" + mcp_server: FastMCP, package_name: str = "photoshop_mcp_server.tools",**keys ) -> dict[str, list[str]]: """Register all tools from all modules in a package. @@ -122,11 +125,11 @@ def register_all_tools( Dictionary mapping module names to lists of registered tool names. """ - return register_all(mcp_server, package_name, "tool") + return register_all(mcp_server, package_name, "tool",**keys) def register_all_resources( - mcp_server: FastMCP, package_name: str = "photoshop_mcp_server.resources" + mcp_server: FastMCP, package_name: str = "photoshop_mcp_server.resources" , **keys ) -> dict[str, list[str]]: """Register all resources from all modules in a package. @@ -138,6 +141,8 @@ def register_all_resources( Dictionary mapping module names to lists of registered resource names. """ + global logger + logger = keys.get("logger",None) return register_all(mcp_server, package_name, "resource") @@ -179,7 +184,8 @@ def register_tool( decorated_func = func mcp_server.tool(name=tool_name)(decorated_func) - logger.info(f"Registered tool: {tool_name}") + if logger: + logger.info(f"Registered tool: {tool_name}") return tool_name @@ -196,5 +202,6 @@ def register_resource(mcp_server: FastMCP, func: Callable, path: str) -> str: """ mcp_server.resource(path)(func) - logger.info(f"Registered resource: {path}") + if logger: + logger.info(f"Registered resource: {path}") return path diff --git a/photoshop_mcp_server/server.py b/photoshop_mcp_server/server.py index 31bec28..d95974c 100644 --- a/photoshop_mcp_server/server.py +++ b/photoshop_mcp_server/server.py @@ -4,6 +4,7 @@ import os import sys from typing import Any +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from mcp.server.fastmcp import FastMCP @@ -14,10 +15,14 @@ from photoshop_mcp_server.registry import register_all_resources, register_all_tools # Configure logging +log_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), "mcp_photoshop.log") logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - handlers=[logging.StreamHandler(sys.stdout)], + handlers=[ + logging.StreamHandler(sys.stderr), + logging.FileHandler(log_file, encoding='utf-8') + ], ) logger = logging.getLogger("photoshop-mcp-server") @@ -50,14 +55,14 @@ def create_server( # Register all resources dynamically logger.info("Registering resources...") - registered_resources = register_all_resources(server_mcp) + registered_resources = register_all_resources(server_mcp, logger = logger) logger.info( f"Registered resources from modules: {list(registered_resources.keys())}" ) # Register all tools dynamically logger.info("Registering tools...") - registered_tools = register_all_tools(server_mcp) + registered_tools = register_all_tools(server_mcp, logger = logger) logger.info(f"Registered tools from modules: {list(registered_tools.keys())}") # Apply additional configuration if provided diff --git a/photoshop_mcp_server/tools/session_tools.py b/photoshop_mcp_server/tools/session_tools.py index 81c071a..f286497 100644 --- a/photoshop_mcp_server/tools/session_tools.py +++ b/photoshop_mcp_server/tools/session_tools.py @@ -1,12 +1,11 @@ """Session-related MCP tools for Photoshop.""" - +from logging import Logger from typing import Any from photoshop_mcp_server.ps_adapter.action_manager import ActionManager from photoshop_mcp_server.registry import register_tool - - -def register(mcp): +from mcp.server.fastmcp import FastMCP +def register(mcp:FastMCP,logger:Logger = None): """Register session-related tools. Args: @@ -76,9 +75,9 @@ def get_active_document_info() -> dict[str, Any]: return doc_info except Exception as e: - print(f"Error getting active document info: {e}") import traceback - + if logger: + logger.error(f"Error getting active document info: {e}") tb_text = traceback.format_exc() traceback.print_exc() @@ -99,18 +98,15 @@ def get_selection_info() -> dict[str, Any]: """ try: - print("Getting selection information using Action Manager") - + logger.info("Getting selection information using Action Manager") # Use Action Manager to get selection info selection_info = ActionManager.get_selection_info() - print( - f"Selection info retrieved successfully: {selection_info.get('success', False)}" - ) + logger.info(f"Selection info retrieved successfully: {selection_info.get('success', False)}") return selection_info except Exception as e: - print(f"Error getting selection info: {e}") + logger.error(f"Error getting selection info: {e}") import traceback tb_text = traceback.format_exc() From 100eac721d4167d30639c4f1280da8def9e9f784 Mon Sep 17 00:00:00 2001 From: lingchenma Date: Mon, 9 Jun 2025 11:39:00 +0800 Subject: [PATCH 2/3] Add log printing to the file --- photoshop_mcp_server/server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/photoshop_mcp_server/server.py b/photoshop_mcp_server/server.py index d95974c..2c6739c 100644 --- a/photoshop_mcp_server/server.py +++ b/photoshop_mcp_server/server.py @@ -4,7 +4,6 @@ import os import sys from typing import Any -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from mcp.server.fastmcp import FastMCP From 2ae0fe7fcd750055c41628bef72472e21482ea30 Mon Sep 17 00:00:00 2001 From: lingchenma Date: Tue, 10 Jun 2025 10:02:50 +0800 Subject: [PATCH 3/3] print is replaced by logger --- photoshop_mcp_server/registry.py | 2 +- .../resources/document_resources.py | 17 +++++++--- photoshop_mcp_server/tools/document_tools.py | 32 +++++++++---------- photoshop_mcp_server/tools/layer_tools.py | 8 ++--- photoshop_mcp_server/tools/session_tools.py | 19 ++++++----- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/photoshop_mcp_server/registry.py b/photoshop_mcp_server/registry.py index 6ffc5ff..31ffd6d 100644 --- a/photoshop_mcp_server/registry.py +++ b/photoshop_mcp_server/registry.py @@ -143,7 +143,7 @@ def register_all_resources( """ global logger logger = keys.get("logger",None) - return register_all(mcp_server, package_name, "resource") + return register_all(mcp_server, package_name, "resource", **keys) def register_tool( diff --git a/photoshop_mcp_server/resources/document_resources.py b/photoshop_mcp_server/resources/document_resources.py index e7a2475..023c459 100644 --- a/photoshop_mcp_server/resources/document_resources.py +++ b/photoshop_mcp_server/resources/document_resources.py @@ -1,9 +1,9 @@ """Document-related MCP resources.""" from photoshop_mcp_server.ps_adapter.application import PhotoshopApp +from logging import Logger - -def register(mcp): +def register(mcp, logger:Logger = None): """Register document-related resources. Args: @@ -37,11 +37,18 @@ def get_document_info() -> dict: doc = ps_app.get_active_document() if not doc: return {"error": "No active document"} - + if isinstance(doc.width,float): + width = doc.width + else: + width = doc.width.value + if isinstance(doc.height,float): + height = doc.height + else: + height = doc.height.value return { "name": doc.name, - "width": doc.width.value, - "height": doc.height.value, + "width": width, + "height": height, "resolution": doc.resolution, "layers_count": len(doc.artLayers), } diff --git a/photoshop_mcp_server/tools/document_tools.py b/photoshop_mcp_server/tools/document_tools.py index 0a79f1f..a049866 100644 --- a/photoshop_mcp_server/tools/document_tools.py +++ b/photoshop_mcp_server/tools/document_tools.py @@ -1,12 +1,14 @@ """Document-related MCP tools.""" import photoshop.api as ps +from logging import Logger from photoshop_mcp_server.ps_adapter.application import PhotoshopApp from photoshop_mcp_server.registry import register_tool -def register(mcp): + +def register(mcp,logger:Logger = None): """Register document-related tools. Args: @@ -33,9 +35,7 @@ def create_document( dict: Result of the operation. """ - print( - f"Creating document: width={width}, height={height}, name={name}, mode={mode}" - ) + logger.info(f"Creating document: width={width}, height={height}, name={name}, mode={mode}") ps_app = PhotoshopApp() try: # Validate mode parameter @@ -53,9 +53,7 @@ def create_document( } # Create document - print( - f"Calling ps_app.create_document with width={width}, height={height}, name={name}, mode={mode}" - ) + logger.info(f"Calling ps_app.create_document with width={width}, height={height}, name={name}, mode={mode}") doc = ps_app.create_document( width=width, height=height, name=name, mode=mode ) @@ -68,37 +66,37 @@ def create_document( # Get document properties safely try: - print("Document created, getting properties") + logger.info("Document created, getting properties") doc_name = doc.name - print(f"Document name: {doc_name}") + logger.info(f"Document name: {doc_name}") # Get width safely doc_width = width # Default fallback if hasattr(doc, "width"): width_obj = doc.width - print(f"Width object type: {type(width_obj)}") + logger.info(f"Width object type: {type(width_obj)}") if hasattr(width_obj, "value"): doc_width = width_obj.value else: try: doc_width = float(width_obj) except (TypeError, ValueError): - print(f"Could not convert width to float: {width_obj}") - print(f"Document width: {doc_width}") + logger.error(f"Could not convert width to float: {width_obj} ") + logger.info(f"Document width: {doc_width}") # Get height safely doc_height = height # Default fallback if hasattr(doc, "height"): height_obj = doc.height - print(f"Height object type: {type(height_obj)}") + logger.info(f"Height object type: {type(height_obj)}") if hasattr(height_obj, "value"): doc_height = height_obj.value else: try: doc_height = float(height_obj) except (TypeError, ValueError): - print(f"Could not convert height to float: {height_obj}") - print(f"Document height: {doc_height}") + logger.error(f"Could not convert height to float: {height_obj} ") + logger.info(f"Document height: {doc_height}") return { "success": True, @@ -107,7 +105,7 @@ def create_document( "height": doc_height, } except Exception as prop_error: - print(f"Error getting document properties: {prop_error}") + logger.error(f"Error getting document properties: {prop_error}") import traceback traceback.print_exc() @@ -120,7 +118,7 @@ def create_document( "warning": f"Created document but couldn't get properties: {prop_error!s}", } except Exception as e: - print(f"Error creating document: {e}") + logger.error(f"Error creating document: {e}") import traceback tb_text = traceback.format_exc() diff --git a/photoshop_mcp_server/tools/layer_tools.py b/photoshop_mcp_server/tools/layer_tools.py index ec92635..e62e0c0 100644 --- a/photoshop_mcp_server/tools/layer_tools.py +++ b/photoshop_mcp_server/tools/layer_tools.py @@ -1,12 +1,12 @@ """Layer-related MCP tools.""" import photoshop.api as ps +from logging import Logger from photoshop_mcp_server.ps_adapter.application import PhotoshopApp from photoshop_mcp_server.registry import register_tool - -def register(mcp): +def register(mcp,logger:Logger = None): """Register layer-related tools. Args: @@ -176,9 +176,7 @@ def create_solid_color_layer( return {"success": False, "error": "No active document"} try: - print( - f"Creating solid color layer: name='{name}', color=({color_r}, {color_g}, {color_b})" - ) + logger.info(f"Creating solid color layer: name='{name}', color=({color_r}, {color_g}, {color_b})") # Escape special characters in the name for JavaScript escaped_name = ( diff --git a/photoshop_mcp_server/tools/session_tools.py b/photoshop_mcp_server/tools/session_tools.py index f286497..89ecb41 100644 --- a/photoshop_mcp_server/tools/session_tools.py +++ b/photoshop_mcp_server/tools/session_tools.py @@ -25,18 +25,18 @@ def get_session_info() -> dict[str, Any]: """ try: - print("Getting Photoshop session information using Action Manager") + if logger: + logger.info("Getting Photoshop session information using Action Manager") # Use Action Manager to get session info session_info = ActionManager.get_session_info() - print( - f"Session info retrieved successfully: {session_info.get('success', False)}" - ) + if logger: + logger.info(f"Session info retrieved successfully: {session_info.get('success', False)}") return session_info except Exception as e: - print(f"Error getting Photoshop session info: {e}") + logger.error(f"Error getting Photoshop session info: {e}") import traceback tb_text = traceback.format_exc() @@ -64,13 +64,12 @@ def get_active_document_info() -> dict[str, Any]: """ try: - print("Getting active document information using Action Manager") - + if logger: + logger.info("Getting active document information using Action Manager") # Use Action Manager to get document info doc_info = ActionManager.get_active_document_info() - print( - f"Document info retrieved successfully: {doc_info.get('success', False)}" - ) + if logger: + logger.info(f"Document info retrieved successfully: {doc_info.get('success', False)}") return doc_info