@@ -78,12 +78,13 @@ def __init__(
7878class AWSMCPProxyClient (_ProxyClient ):
7979 """Proxy client that handles HTTP errors when connection fails."""
8080
81- def __init__ (self , transport : ClientTransport , ** kwargs ):
81+ def __init__ (self , transport : ClientTransport , max_connect_retry = 3 , ** kwargs ):
8282 """Constructor of AutoRefreshProxyCilent."""
8383 super ().__init__ (transport , ** kwargs )
84+ self ._max_connect_retry = max_connect_retry
8485
8586 @override
86- async def _connect (self ):
87+ async def _connect (self , retry = 0 ):
8788 """Enter as normal && initialize only once."""
8889 logger .debug ('Connecting %s' , self )
8990 try :
@@ -96,27 +97,36 @@ async def _connect(self):
9697 try :
9798 body = await response .aread ()
9899 jsonrpc_msg = JSONRPCMessage .model_validate_json (body ).root
99- except Exception :
100- logger .debug ('HTTP error is not a valid MCP message.' )
100+ except Exception as e :
101+ logger .debug ('HTTP error is not a valid MCP message.' , exc_info = e )
101102 raise http_error
102103
103104 if isinstance (jsonrpc_msg , JSONRPCError ):
104- logger .debug ('Converting HTTP error to MCP error %s ' , http_error )
105+ logger .debug ('Converting HTTP error to MCP error' , exc_info = http_error )
105106 # raising McpError so that the sdk can handle the exception properly
106107 raise McpError (error = jsonrpc_msg .error ) from http_error
107108 else :
108109 raise http_error
109- except RuntimeError :
110+ except RuntimeError as e :
111+ if isinstance (e .__cause__ , McpError ):
112+ raise e .__cause__
113+
114+ if retry > self ._max_connect_retry :
115+ raise e
116+
110117 try :
111- logger .warning ('encountered runtime error, try force disconnect.' )
118+ logger .warning ('encountered runtime error, try force disconnect.' , exc_info = e )
112119 await self ._disconnect (force = True )
113- except Exception :
120+ except httpx . TimeoutException :
114121 # _disconnect awaits on the session_task,
115122 # which raises the timeout error that caused the client session to be terminated.
116123 # the error is ignored as long as the counter is force set to 0.
117124 # TODO: investigate how timeout error is handled by fastmcp and httpx
118- logger .exception ('encountered another error, ignoring.' )
119- return await self ._connect ()
125+ logger .exception (
126+ 'Session was terminated due to timeout error, ignore and reconnect'
127+ )
128+
129+ return await self ._connect (retry + 1 )
120130
121131 async def __aexit__ (self , exc_type , exc_val , exc_tb ):
122132 """The MCP Proxy for AWS project is a proxy from stdio to http (sigv4).
0 commit comments