11from AgentCrew .modules import logger
2- from typing import Dict , Any , List , Optional , Callable
2+ from typing import Dict , Any , List , Optional , Callable , TextIO , AnyStr
33from mcp import ClientSession , StdioServerParameters
44from mcp .types import Prompt , ContentBlock , TextContent , ImageContent
55from mcp .client .stdio import stdio_client
88from .config import MCPServerConfig
99import asyncio
1010import threading
11+ import tempfile
12+ from datetime import datetime
13+
14+
15+ class MCPLogIO (TextIO ):
16+ """File-like object compatible with sys.stderr for MCP logging."""
17+
18+ def __init__ (self ):
19+ self .log_path = (
20+ tempfile .gettempdir () + f"/mcp_agentcrew_{ datetime .now ().timestamp ()} .log"
21+ )
22+ print (f"Routing MCP logs to { self .log_path } " )
23+ self .file = open (self .log_path , "w+" )
24+
25+ def write (self , data : AnyStr ) -> int :
26+ """Write data to the log file."""
27+ if isinstance (data , bytes ):
28+ # Convert bytes to string for writing
29+ str_data = data .decode ("utf-8" , errors = "replace" )
30+ else :
31+ str_data = str (data )
32+ self .file .write (str_data )
33+ self .file .flush () # Ensure data is written immediately
34+ return 0
35+
36+ def flush (self ):
37+ """Flush the file buffer."""
38+ self .file .flush ()
39+
40+ def close (self ):
41+ """Close the file."""
42+ self .file .close ()
43+
44+ def fileno (self ):
45+ """Return the file descriptor."""
46+ return self .file .fileno ()
47+
48+
49+ # Initialize the logger
50+ mcp_log_io = MCPLogIO ()
1151
1252
1353class MCPService :
@@ -69,7 +109,7 @@ async def _manage_single_connection(self, server_config: MCPServerConfig):
69109 self .server_prompts [server_id ] = prompts .prompts
70110
71111 except Exception as e :
72- print (f"{ str (e )} " )
112+ logger . warning (f"{ str (e )} " )
73113
74114 logger .info (
75115 f"MCPService: { server_id } setup complete. Waiting for shutdown signal."
@@ -83,9 +123,12 @@ async def _manage_single_connection(self, server_config: MCPServerConfig):
83123 env = server_config .env ,
84124 )
85125
86- async with stdio_client (server_params ) as (stdio , write_stream ):
126+ async with stdio_client (server_params , errlog = mcp_log_io ) as (
127+ read_stream ,
128+ write_stream ,
129+ ):
87130 logger .info (f"MCPService: stdio_client established for { server_id } " )
88- async with ClientSession (stdio , write_stream ) as session :
131+ async with ClientSession (read_stream , write_stream ) as session :
89132 logger .info (
90133 f"MCPService: ClientSession established for { server_id } "
91134 )
@@ -106,7 +149,7 @@ async def _manage_single_connection(self, server_config: MCPServerConfig):
106149 self .server_prompts [server_id ] = prompts .prompts
107150
108151 except Exception as e :
109- print (f"{ str (e )} " )
152+ logger . warning (f"{ str (e )} " )
110153
111154 logger .info (
112155 f"MCPService: { server_id } setup complete. Waiting for shutdown signal."
@@ -421,7 +464,6 @@ async def get_prompt(
421464 Prompt object if found, None otherwise
422465 """
423466
424- print (server_id , prompt_name )
425467 if server_id not in self .sessions or not self .connected_servers .get (server_id ):
426468 return {
427469 "content" : f"Cannot call tool: Server '{ server_id } ' is not connected" ,
0 commit comments