Edit: Cleaned up MCP logs and check attempts.
deci committed
May 14, 2025 at 15:36 UTC
673435c7728ede740959a944ebf2fcb8e8457edb
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: