11import sys
22from contextlib import AsyncExitStack
3- from typing import Self
3+ from typing import Any , Awaitable , Callable , Self
44
55from mcp import ClientSession , StdioServerParameters
66from mcp .client .stdio import stdio_client
@@ -17,12 +17,39 @@ class MCPClient:
1717 # Call client methods here...
1818 """
1919
20- client_session : ClientSession
21-
2220 def __init__ (self , server_path : str ):
2321 self .server_path = server_path
2422 self .exit_stack = AsyncExitStack ()
2523
24+ async def __aenter__ (self ) -> Self :
25+ self .client_session = await self ._connect_to_server ()
26+ return self
27+
28+ async def __aexit__ (self , * _ ) -> None :
29+ await self .exit_stack .aclose ()
30+
31+ async def _connect_to_server (self ) -> ClientSession :
32+ try :
33+ read , write = await self .exit_stack .enter_async_context (
34+ stdio_client (
35+ server = StdioServerParameters (
36+ command = "sh" ,
37+ args = [
38+ "-c" ,
39+ f"{ sys .executable } { self .server_path } 2>/dev/null" ,
40+ ],
41+ env = None ,
42+ )
43+ )
44+ )
45+ client_session = await self .exit_stack .enter_async_context (
46+ ClientSession (read , write )
47+ )
48+ await client_session .initialize ()
49+ return client_session
50+ except Exception :
51+ raise RuntimeError ("Error: Failed to connect to server" )
52+
2653 async def list_all_members (self ) -> None :
2754 """List all available tools, prompts, and resources."""
2855 print ("MCP Server Members" )
@@ -38,28 +65,13 @@ async def list_all_members(self) -> None:
3865
3966 print ("\n " + "=" * 50 )
4067
41- async def run_chat (self ) -> None :
42- """Start interactive chat with MCP server using OpenAI."""
43- try :
44- handler = OpenAIQueryHandler (self .client_session )
45- await chat .run_chat (handler )
46- except RuntimeError as e :
47- print (e )
48-
49- async def __aenter__ (self ) -> Self :
50- self .client_session = await self ._connect_to_server ()
51- return self
52-
53- async def __aexit__ (self , * _ ) -> None :
54- await self .exit_stack .aclose ()
55-
5668 async def _list_section (
5769 self ,
5870 section : str ,
59- list_func ,
71+ list_method : Callable [[], Awaitable [ Any ]] ,
6072 ) -> None :
6173 try :
62- items = getattr (await list_func (), section )
74+ items = getattr (await list_method (), section )
6375 if items :
6476 print (f"\n { section .upper ()} ({ len (items )} ):" )
6577 print ("-" * 30 )
@@ -71,24 +83,10 @@ async def _list_section(
7183 except Exception as e :
7284 print (f"\n { section .upper ()} : Error - { e } " )
7385
74- async def _connect_to_server (self ) -> ClientSession :
86+ async def run_chat (self ) -> None :
87+ """Start interactive chat with MCP server using OpenAI."""
7588 try :
76- stdio , write = await self .exit_stack .enter_async_context (
77- stdio_client (
78- server = StdioServerParameters (
79- command = "sh" ,
80- args = [
81- "-c" ,
82- f"{ sys .executable } { self .server_path } 2>/dev/null" ,
83- ],
84- env = None ,
85- )
86- )
87- )
88- client_session = await self .exit_stack .enter_async_context (
89- ClientSession (stdio , write )
90- )
91- await client_session .initialize ()
92- return client_session
93- except Exception :
94- raise RuntimeError ("Error: Failed to connect to server" )
89+ handler = OpenAIQueryHandler (self .client_session )
90+ await chat .run_chat (handler )
91+ except RuntimeError as e :
92+ print (e )
0 commit comments