Edit: Cleaned up MCP logs and check attempts.

deci committed May 14, 2025 at 15:36 UTC 2160a9b1580fc8cbbba1d420cdcc5724ff313f3d
2 files changed +53 -47
initialize.py
+44 -38
@@ -8,6 +8,9 @@ import shutil
8 from python.helpers.print_style import PrintStyle
9
10
11 +_NPM_CHECKS_DONE = False
12 +
13 +
14 # Helper function to ensure an MCP package is globally installed
15 def _ensure_mcp_package_globally_installed(package_name: str, executable_name: str):
16 PrintStyle(background_color="blue", font_color="white", padding=True).print(
@@ -56,10 +59,11 @@ def _ensure_mcp_package_globally_installed(package_name: str, executable_name: s
59 PrintStyle(font_color="red", padding=True).print(
60 f"ERROR: 'npm' command not found. Cannot check for or install '{executable_name}' from '{package_name}'."
61 )
59 - PrintStyle().print() # For a blank line after each attempt
62 + # PrintStyle().print() # For a blank line after each attempt
63
64
65 def initialize():
66 + global _NPM_CHECKS_DONE
67 current_settings = settings.get_settings()
68 mcp_servers_json_string = current_settings.get("mcp_servers", "[]")
69
@@ -76,48 +80,50 @@ def initialize():
80 )
81 mcp_server_configs = []
82
79 - if shutil.which("npm"):
80 - for server_config in mcp_server_configs:
81 - if not isinstance(server_config, dict):
82 - PrintStyle(font_color="orange", padding=True).print(
83 - f"Warning: Skipping MCP server config item as it's not a dictionary: {server_config}"
84 - )
85 - continue
86 -
87 - command = server_config.get("command")
88 - args = server_config.get("args", [])
89 - server_name = server_config.get("name", "Unknown MCP Server")
90 -
91 - if command == "npx" and "--package" in args:
92 - try:
93 - package_keyword_index = args.index("--package")
94 - # Expect package name at +1 and executable name at +2 from "--package"
95 - if package_keyword_index + 2 < len(args):
96 - package_name = args[package_keyword_index + 1]
97 - executable_name = args[package_keyword_index + 2]
98 - if package_name and executable_name: # Ensure they are not empty strings
99 - _ensure_mcp_package_globally_installed(package_name, executable_name)
83 + if not _NPM_CHECKS_DONE:
84 + if shutil.which("npm"):
85 + for server_config in mcp_server_configs:
86 + if not isinstance(server_config, dict):
87 + PrintStyle(font_color="orange", padding=True).print(
88 + f"Warning: Skipping MCP server config item as it's not a dictionary: {server_config}"
89 + )
90 + continue
91 +
92 + command = server_config.get("command")
93 + args = server_config.get("args", [])
94 + server_name = server_config.get("name", "Unknown MCP Server")
95 +
96 + if command == "npx" and "--package" in args:
97 + try:
98 + package_keyword_index = args.index("--package")
99 + # Expect package name at +1 and executable name at +2 from "--package"
100 + if package_keyword_index + 2 < len(args):
101 + package_name = args[package_keyword_index + 1]
102 + executable_name = args[package_keyword_index + 2]
103 + if package_name and executable_name: # Ensure they are not empty strings
104 + _ensure_mcp_package_globally_installed(package_name, executable_name)
105 + else:
106 + PrintStyle(font_color="orange", padding=True).print(
107 + f"Warning: Skipping MCP server '{server_name}' due to empty package or executable name extracted from args: {args}"
108 + )
109 else:
110 PrintStyle(font_color="orange", padding=True).print(
102 - f"Warning: Skipping MCP server '{server_name}' due to empty package or executable name extracted from args: {args}"
111 + f"Warning: Skipping MCP server '{server_name}' as package name or executable name could not be determined from args: {args}"
112 )
104 - else:
113 + except ValueError: # Should not happen if "--package" is in args, but good for safety
114 PrintStyle(font_color="orange", padding=True).print(
106 - f"Warning: Skipping MCP server '{server_name}' as package name or executable name could not be determined from args: {args}"
115 + f"Warning: '--package' keyword found but .index() failed for args: {args} in server '{server_name}'"
116 )
108 - except ValueError: # Should not happen if "--package" is in args, but good for safety
109 - PrintStyle(font_color="orange", padding=True).print(
110 - f"Warning: '--package' keyword found but .index() failed for args: {args} in server '{server_name}'"
111 - )
112 - except Exception as e:
113 - PrintStyle(font_color="red", padding=True).print(
114 - f"Error processing npx args for server '{server_name}': {e}. Args: {args}"
115 - )
116 - else:
117 - PrintStyle(font_color="red", padding=True).print(
118 - "ERROR: 'npm' command not found. Cannot attempt to install any MCP server packages."
119 - )
120 - PrintStyle().print() # Extra blank line after all attempts or npm not found message
117 + except Exception as e:
118 + PrintStyle(font_color="red", padding=True).print(
119 + f"Error processing npx args for server '{server_name}': {e}. Args: {args}"
120 + )
121 + else:
122 + PrintStyle(font_color="red", padding=True).print(
123 + "ERROR: 'npm' command not found. Cannot attempt to install any MCP server packages."
124 + )
125 + PrintStyle().print() # Extra blank line after all attempts or npm not found message
126 + _NPM_CHECKS_DONE = True
127
128 # chat model from user settings
129 chat_llm = ModelConfig(
python/helpers/mcp_handler.py
+9 -9
@@ -326,7 +326,7 @@ class MCPConfig(BaseModel):
326 from collections.abc import Mapping, Iterable
327
328 # DEBUG: Print the received servers_list
329 - PrintStyle(background_color="blue", font_color="white", padding=True).print(f"MCPConfig.__init__ received servers_list: {servers_list}")
329 + if servers_list: PrintStyle(background_color="blue", font_color="white", padding=True).print(f"MCPConfig.__init__ received servers_list: {servers_list}")
330
331 # This empties the servers list if MCPConfig is a Pydantic model and servers is a field.
332 # If servers is a field like `servers: List[MCPServer] = Field(default_factory=list)`,
@@ -501,11 +501,11 @@ class MCPClientBase(ABC):
501 Creates a temporary session, executes coro_func with it, and ensures cleanup.
502 """
503 operation_name = coro_func.__name__ # For logging
504 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Creating new session for operation '{operation_name}'...")
504 + # PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Creating new session for operation '{operation_name}'...")
505 async with AsyncExitStack() as temp_stack:
506 try:
507 stdio, write = await self._create_stdio_transport(temp_stack)
508 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name} - {operation_name}): Transport created. Initializing session...")
508 + # PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name} - {operation_name}): Transport created. Initializing session...")
509 session = await temp_stack.enter_async_context(
510 ClientSession(
511 stdio,
@@ -514,11 +514,11 @@ class MCPClientBase(ABC):
514 )
515 )
516 await session.initialize()
517 - PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name} - {operation_name}): Session initialized.")
517 + # PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name} - {operation_name}): Session initialized.")
518
519 result = await coro_func(session)
520
521 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name} - {operation_name}): Operation successful.")
521 + # PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name} - {operation_name}): Operation successful.")
522 return result
523 except Exception as e:
524 PrintStyle(background_color="#AA4455", font_color="white", padding=False).print(
@@ -534,7 +534,7 @@ class MCPClientBase(ABC):
534 raise RuntimeError(f"MCPClientBase ({self.server.name} - {operation_name}): _execute_with_session exited 'async with' block unexpectedly.")
535
536 async def update_tools(self) -> "MCPClientBase":
537 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Starting 'update_tools' operation...")
537 + # PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Starting 'update_tools' operation...")
538
539 async def list_tools_op(current_session: ClientSession):
540 response: ListToolsResult = await current_session.list_tools()
@@ -571,7 +571,7 @@ class MCPClientBase(ABC):
571 return self.tools
572
573 async def call_tool(self, tool_name: str, input_data: Dict[str, Any]) -> CallToolResult:
574 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Preparing for 'call_tool' operation for tool '{tool_name}'.")
574 + # PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Preparing for 'call_tool' operation for tool '{tool_name}'.")
575 if not self.has_tool(tool_name):
576 PrintStyle(font_color="orange").print(f"MCPClientBase ({self.server.name}): Tool '{tool_name}' not in cache for 'call_tool', refreshing tools...")
577 await self.update_tools() # This will use its own properly managed session
@@ -581,9 +581,9 @@ class MCPClientBase(ABC):
581 PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name}): Tool '{tool_name}' found after updating tools.")
582
583 async def call_tool_op(current_session: ClientSession):
584 - PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Executing 'call_tool' for '{tool_name}' via MCP session...")
584 + # PrintStyle(font_color="cyan").print(f"MCPClientBase ({self.server.name}): Executing 'call_tool' for '{tool_name}' via MCP session...")
585 response: CallToolResult = await current_session.call_tool(tool_name, input_data)
586 - PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name}): Tool '{tool_name}' call successful via session.")
586 + # PrintStyle(font_color="green").print(f"MCPClientBase ({self.server.name}): Tool '{tool_name}' call successful via session.")
587 return response
588
589 try: