Skip to content

Commit 0c0c110

Browse files
committed
feat(mcp): Routing mcp log to file
1 parent e93c00b commit 0c0c110

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

AgentCrew/modules/mcpclient/service.py

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from AgentCrew.modules import logger
2-
from typing import Dict, Any, List, Optional, Callable
2+
from typing import Dict, Any, List, Optional, Callable, TextIO, AnyStr
33
from mcp import ClientSession, StdioServerParameters
44
from mcp.types import Prompt, ContentBlock, TextContent, ImageContent
55
from mcp.client.stdio import stdio_client
@@ -8,6 +8,46 @@
88
from .config import MCPServerConfig
99
import asyncio
1010
import 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

1353
class 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

Comments
 (0)