Gabriel commited on
Commit
f408d30
Β·
verified Β·
1 Parent(s): c4570e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -30
app.py CHANGED
@@ -9,9 +9,6 @@ from gradio.components.chatbot import ChatMessage
9
  from mcp import ClientSession, StdioServerParameters
10
  from mcp.client.stdio import stdio_client
11
  from anthropic import Anthropic
12
- from dotenv import load_dotenv
13
-
14
- load_dotenv()
15
 
16
  loop = asyncio.new_event_loop()
17
  asyncio.set_event_loop(loop)
@@ -20,10 +17,26 @@ class MCPClientWrapper:
20
  def __init__(self):
21
  self.session = None
22
  self.exit_stack = None
23
- self.anthropic = Anthropic()
24
  self.tools = []
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  def connect(self, server_path: str) -> str:
 
 
 
27
  return loop.run_until_complete(self._connect(server_path))
28
 
29
  async def _connect(self, server_path: str) -> str:
@@ -41,31 +54,46 @@ class MCPClientWrapper:
41
  env={"PYTHONIOENCODING": "utf-8", "PYTHONUNBUFFERED": "1"}
42
  )
43
 
44
- stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
45
- self.stdio, self.write = stdio_transport
46
-
47
- self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
48
- await self.session.initialize()
49
-
50
- response = await self.session.list_tools()
51
- self.tools = [{
52
- "name": tool.name,
53
- "description": tool.description,
54
- "input_schema": tool.inputSchema
55
- } for tool in response.tools]
56
-
57
- tool_names = [tool["name"] for tool in self.tools]
58
- return f"Connected to MCP server. Available tools: {', '.join(tool_names)}"
 
 
 
59
 
60
  def process_message(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]) -> tuple:
 
 
 
 
 
 
61
  if not self.session:
62
  return history + [
63
  {"role": "user", "content": message},
64
- {"role": "assistant", "content": "Please connect to an MCP server first."}
65
  ], gr.Textbox(value="")
66
 
67
- new_messages = loop.run_until_complete(self._process_query(message, history))
68
- return history + [{"role": "user", "content": message}] + new_messages, gr.Textbox(value="")
 
 
 
 
 
 
69
 
70
  async def _process_query(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]):
71
  claude_messages = []
@@ -192,10 +220,25 @@ class MCPClientWrapper:
192
  client = MCPClientWrapper()
193
 
194
  def gradio_interface():
195
- with gr.Blocks(title="MCP Weather Client") as demo:
196
- gr.Markdown("# MCP Weather Assistant")
197
- gr.Markdown("Connect to your MCP weather server and chat with the assistant")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
 
199
  with gr.Row(equal_height=True):
200
  with gr.Column(scale=4):
201
  server_path = gr.Textbox(
@@ -206,8 +249,9 @@ def gradio_interface():
206
  with gr.Column(scale=1):
207
  connect_btn = gr.Button("Connect")
208
 
209
- status = gr.Textbox(label="Connection Status", interactive=False)
210
 
 
211
  chatbot = gr.Chatbot(
212
  value=[],
213
  height=500,
@@ -224,15 +268,14 @@ def gradio_interface():
224
  )
225
  clear_btn = gr.Button("Clear Chat", scale=1)
226
 
227
- connect_btn.click(client.connect, inputs=server_path, outputs=status)
 
 
228
  msg.submit(client.process_message, [msg, chatbot], [chatbot, msg])
229
  clear_btn.click(lambda: [], None, chatbot)
230
 
231
  return demo
232
 
233
  if __name__ == "__main__":
234
- if not os.getenv("ANTHROPIC_API_KEY"):
235
- print("Warning: ANTHROPIC_API_KEY not found in environment. Please set it in your .env file.")
236
-
237
  interface = gradio_interface()
238
  interface.launch(debug=True)
 
9
  from mcp import ClientSession, StdioServerParameters
10
  from mcp.client.stdio import stdio_client
11
  from anthropic import Anthropic
 
 
 
12
 
13
  loop = asyncio.new_event_loop()
14
  asyncio.set_event_loop(loop)
 
17
  def __init__(self):
18
  self.session = None
19
  self.exit_stack = None
20
+ self.anthropic = None
21
  self.tools = []
22
+ self.api_key = None
23
+
24
+ def set_api_key(self, api_key: str) -> str:
25
+ """Set the Anthropic API key and initialize the client"""
26
+ if not api_key or not api_key.strip():
27
+ return "❌ Please provide a valid Anthropic API key"
28
+
29
+ try:
30
+ self.api_key = api_key.strip()
31
+ self.anthropic = Anthropic(api_key=self.api_key)
32
+ return "βœ… Anthropic API key set successfully"
33
+ except Exception as e:
34
+ return f"❌ Error setting API key: {str(e)}"
35
 
36
  def connect(self, server_path: str) -> str:
37
+ if not self.anthropic:
38
+ return "❌ Please set your Anthropic API key first"
39
+
40
  return loop.run_until_complete(self._connect(server_path))
41
 
42
  async def _connect(self, server_path: str) -> str:
 
54
  env={"PYTHONIOENCODING": "utf-8", "PYTHONUNBUFFERED": "1"}
55
  )
56
 
57
+ try:
58
+ stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
59
+ self.stdio, self.write = stdio_transport
60
+
61
+ self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
62
+ await self.session.initialize()
63
+
64
+ response = await self.session.list_tools()
65
+ self.tools = [{
66
+ "name": tool.name,
67
+ "description": tool.description,
68
+ "input_schema": tool.inputSchema
69
+ } for tool in response.tools]
70
+
71
+ tool_names = [tool["name"] for tool in self.tools]
72
+ return f"βœ… Connected to MCP server. Available tools: {', '.join(tool_names)}"
73
+ except Exception as e:
74
+ return f"❌ Failed to connect to MCP server: {str(e)}"
75
 
76
  def process_message(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]) -> tuple:
77
+ if not self.anthropic:
78
+ return history + [
79
+ {"role": "user", "content": message},
80
+ {"role": "assistant", "content": "❌ Please set your Anthropic API key first."}
81
+ ], gr.Textbox(value="")
82
+
83
  if not self.session:
84
  return history + [
85
  {"role": "user", "content": message},
86
+ {"role": "assistant", "content": "❌ Please connect to an MCP server first."}
87
  ], gr.Textbox(value="")
88
 
89
+ try:
90
+ new_messages = loop.run_until_complete(self._process_query(message, history))
91
+ return history + [{"role": "user", "content": message}] + new_messages, gr.Textbox(value="")
92
+ except Exception as e:
93
+ return history + [
94
+ {"role": "user", "content": message},
95
+ {"role": "assistant", "content": f"❌ Error processing message: {str(e)}"}
96
+ ], gr.Textbox(value="")
97
 
98
  async def _process_query(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]):
99
  claude_messages = []
 
220
  client = MCPClientWrapper()
221
 
222
  def gradio_interface():
223
+ with gr.Blocks(title="MCP client") as demo:
224
+ gr.Markdown("# MCP test")
225
+ gr.Markdown("Connect to mcp server and chat with the assistant")
226
+
227
+ # API Key Section
228
+ with gr.Row(equal_height=True):
229
+ with gr.Column(scale=4):
230
+ api_key_input = gr.Textbox(
231
+ label="Anthropic API Key",
232
+ placeholder="Enter your Anthropic API key (sk-ant-...)",
233
+ type="password",
234
+ value=""
235
+ )
236
+ with gr.Column(scale=1):
237
+ set_key_btn = gr.Button("Set API Key")
238
+
239
+ api_key_status = gr.Textbox(label="API Key Status", interactive=False)
240
 
241
+ # Server Connection Section
242
  with gr.Row(equal_height=True):
243
  with gr.Column(scale=4):
244
  server_path = gr.Textbox(
 
249
  with gr.Column(scale=1):
250
  connect_btn = gr.Button("Connect")
251
 
252
+ connection_status = gr.Textbox(label="Connection Status", interactive=False)
253
 
254
+ # Chat Section
255
  chatbot = gr.Chatbot(
256
  value=[],
257
  height=500,
 
268
  )
269
  clear_btn = gr.Button("Clear Chat", scale=1)
270
 
271
+ # Event handlers
272
+ set_key_btn.click(client.set_api_key, inputs=api_key_input, outputs=api_key_status)
273
+ connect_btn.click(client.connect, inputs=server_path, outputs=connection_status)
274
  msg.submit(client.process_message, [msg, chatbot], [chatbot, msg])
275
  clear_btn.click(lambda: [], None, chatbot)
276
 
277
  return demo
278
 
279
  if __name__ == "__main__":
 
 
 
280
  interface = gradio_interface()
281
  interface.launch(debug=True)