|
6 | 6 | import typing as t |
7 | 7 | from collections import defaultdict |
8 | 8 | from contextlib import asynccontextmanager |
9 | | -from typing import Literal, Optional |
| 9 | +from typing import Literal, Optional, TextIO |
10 | 10 |
|
11 | 11 | import uvicorn |
12 | 12 | from mcp import server, types |
|
24 | 24 | from mcpm.profile.profile_config import ProfileConfigManager |
25 | 25 | from mcpm.schemas.server_config import ServerConfig |
26 | 26 | from mcpm.utils.config import PROMPT_SPLITOR, RESOURCE_SPLITOR, RESOURCE_TEMPLATE_SPLITOR, TOOL_SPLITOR |
| 27 | +from mcpm.utils.errlog_manager import ServerErrorLogManager |
27 | 28 |
|
28 | 29 | from .client_connection import ServerConnection |
29 | 30 | from .transport import RouterSseTransport |
@@ -60,6 +61,7 @@ def __init__(self, reload_server: bool = False, profile_path: str | None = None, |
60 | 61 | if reload_server: |
61 | 62 | self.watcher = ConfigWatcher(self.profile_manager.profile_path) |
62 | 63 | self.strict: bool = strict |
| 64 | + self.error_log_manager = ServerErrorLogManager() |
63 | 65 |
|
64 | 66 | def get_unique_servers(self) -> list[ServerConfig]: |
65 | 67 | profiles = self.profile_manager.list_profiles() |
@@ -110,11 +112,13 @@ async def add_server(self, server_id: str, server_config: ServerConfig) -> None: |
110 | 112 | raise ValueError(f"Server with ID {server_id} already exists") |
111 | 113 |
|
112 | 114 | # Create client based on connection type |
113 | | - client = ServerConnection(server_config) |
| 115 | + errlog: TextIO = self.error_log_manager.open_errlog_file(server_id) |
| 116 | + client = ServerConnection(server_config, errlog=errlog) |
114 | 117 |
|
115 | 118 | # Connect to the server |
116 | 119 | await client.wait_for_initialization() |
117 | 120 | if not client.healthy(): |
| 121 | + self.error_log_manager.close_errlog_file(server_id) |
118 | 122 | raise ValueError(f"Failed to connect to server {server_id}") |
119 | 123 |
|
120 | 124 | response = client.session_initialized_response |
@@ -218,6 +222,7 @@ async def remove_server(self, server_id: str) -> None: |
218 | 222 | # Remove the server from all collections |
219 | 223 | del self.server_sessions[server_id] |
220 | 224 | del self.capabilities_mapping[server_id] |
| 225 | + self.error_log_manager.close_errlog_file(server_id) |
221 | 226 |
|
222 | 227 | # Delete registered tools, resources and prompts |
223 | 228 | for key in list(self.tools_mapping.keys()): |
@@ -574,4 +579,7 @@ async def shutdown(self): |
574 | 579 | if client.healthy(): |
575 | 580 | await client.request_for_shutdown() |
576 | 581 |
|
| 582 | + # close all errlog files |
| 583 | + self.error_log_manager.close_all() |
| 584 | + |
577 | 585 | logger.info("all alive client sessions have been shut down") |
0 commit comments