sitatech commited on
Commit
a4d14b7
·
1 Parent(s): bdf0e91

[app] Implement BaseMCPClient

Browse files
Files changed (2) hide show
  1. mcp_client.py +78 -0
  2. mcp_server.py +1 -1
mcp_client.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from abc import ABC
2
+ from contextlib import AsyncExitStack
3
+ from typing import Any, TYPE_CHECKING
4
+
5
+ from mcp import ClientSession, StdioServerParameters
6
+ from mcp.client.stdio import stdio_client
7
+
8
+ if TYPE_CHECKING:
9
+ from mcp.types import CallToolResult
10
+
11
+
12
+ class BaseMCPClient(ABC):
13
+ def __init__(
14
+ self,
15
+ ):
16
+ self.session: ClientSession | None = None
17
+ self.exit_stack = AsyncExitStack()
18
+
19
+ def ensure_initialized(self):
20
+ if not self.session:
21
+ raise RuntimeError(
22
+ "Session is not initialized. Call connect_to_server first."
23
+ )
24
+
25
+ @property
26
+ async def tools(self):
27
+ self.ensure_initialized()
28
+ return await self.session.list_tools() # type: ignore
29
+
30
+ async def connect_to_server(
31
+ self,
32
+ server_command: str,
33
+ args: list[str] = [],
34
+ env: dict[str, str] | None = None,
35
+ ):
36
+ server_params = StdioServerParameters(
37
+ command=server_command,
38
+ args=args or [],
39
+ env=env,
40
+ )
41
+
42
+ stdio_transport = await self.exit_stack.enter_async_context(
43
+ stdio_client(server_params)
44
+ )
45
+ self.stdio, self.write = stdio_transport
46
+ self.session = await self.exit_stack.enter_async_context(
47
+ ClientSession(self.stdio, self.write)
48
+ )
49
+
50
+ await self.session.initialize()
51
+
52
+ response = await self.session.list_tools()
53
+ print(
54
+ "\nConnected successfully! \nAvailable tools:",
55
+ [tool.name for tool in response.tools],
56
+ "\n",
57
+ )
58
+
59
+ async def pre_tool_call(
60
+ self, tool_name: str, tool_args: dict[str, Any] | None = None
61
+ ) -> tuple[str, dict[str, Any] | None]:
62
+ return tool_name, tool_args
63
+
64
+ async def call_tool(
65
+ self, tool_name: str, tool_args: dict[str, Any] | None = None
66
+ ) -> CallToolResult:
67
+ self.ensure_initialized()
68
+
69
+ tool_name, tool_args = await self.pre_tool_call(tool_name, tool_args)
70
+ response = await self.session.call_tool(tool_name, tool_args) # type: ignore
71
+ return await self.post_tool_call(response)
72
+
73
+ async def post_tool_call(self, response: CallToolResult) -> CallToolResult:
74
+ return response
75
+
76
+ async def close(self):
77
+ if self.session:
78
+ await self.exit_stack.aclose()
mcp_server.py CHANGED
@@ -115,4 +115,4 @@ def try_item_with_auto_masking(
115
 
116
  if __name__ == "__main__":
117
  # Run the MCP server
118
- mcp.run(transport="stdio")
 
115
 
116
  if __name__ == "__main__":
117
  # Run the MCP server
118
+ mcp.run()