ChrisSacrumCor commited on
Commit
0ffb3f8
·
verified ·
1 Parent(s): 21790e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +572 -81
app.py CHANGED
@@ -21,7 +21,22 @@ class MCPClient:
21
  "linux": {
22
  "name": "MCP Linux",
23
  "space_url": "https://chrissacrumcor-mcp-linux.hf.space",
24
- "description": "Linux system operations"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  },
26
  "cisco": {
27
  "name": "MCP Cisco",
@@ -32,8 +47,431 @@ class MCPClient:
32
 
33
  self.conversation_history = []
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def call_mcp_server(self, server_key: str, endpoint: str, payload: Dict[str, Any]) -> Dict[str, Any]:
36
- """Make a call to an MCP server (FastAPI-based)"""
37
  try:
38
  server_config = self.mcp_servers[server_key]
39
 
@@ -73,18 +511,6 @@ class MCPClient:
73
  except Exception as e:
74
  return {"success": False, "error": f"Unexpected error: {str(e)}", "server": server_config['name']}
75
 
76
- def get_available_tools(self, server_key: str) -> List[Dict[str, Any]]:
77
- """Get available tools from an MCP server"""
78
- result = self.call_mcp_server(server_key, "tools/list", {})
79
- if result["success"]:
80
- data = result["data"]
81
- # Handle different response formats
82
- if isinstance(data, dict):
83
- return data.get("tools", data.get("result", []))
84
- elif isinstance(data, list):
85
- return data
86
- return []
87
-
88
  def execute_tool(self, server_key: str, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
89
  """Execute a tool on an MCP server"""
90
  payload = {
@@ -233,35 +659,96 @@ class MCPClient:
233
 
234
  status = f"[{timestamp}] Using: {self.mcp_servers[selected_server]['name']}"
235
 
236
- # Get available tools for the selected server
237
- tools = self.get_available_tools(selected_server)
238
-
239
- if not tools:
240
- # Try to get more info about the server
241
- server_check = self.call_mcp_server(selected_server, "", {})
242
- if not server_check["success"]:
243
- response = f"⚠️ Cannot connect to {self.mcp_servers[selected_server]['name']} server: {server_check.get('error', 'Unknown error')}"
244
- else:
245
- response = f"⚠️ No tools available from {self.mcp_servers[selected_server]['name']} server (but server is responsive)"
246
-
247
  self.conversation_history.append({"role": "assistant", "content": response})
248
- return response, status + " - Connection/Tools issue"
249
 
250
- # For now, just show available tools and generate a helpful response
251
- # In a full implementation, you'd use OpenAI to select and execute appropriate tools
252
- tools_info = "\n".join([f"- {tool.get('name', 'Unknown')}: {tool.get('description', 'No description')}"
253
- for tool in tools[:5]]) # Show first 5 tools
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
- server_info = {
256
- "server": self.mcp_servers[selected_server]['name'],
257
- "available_tools": len(tools),
258
- "sample_tools": tools_info
259
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
- response = self.generate_response(user_input, server_info)
262
  self.conversation_history.append({"role": "assistant", "content": response})
263
-
264
- return response, status + f" - {len(tools)} tools available"
265
 
266
  except Exception as e:
267
  error_response = f"❌ Error processing request: {str(e)}"
@@ -318,44 +805,42 @@ def create_gradio_interface():
318
  return history, ""
319
 
320
  def get_server_status():
 
 
 
321
  status_info = "## MCP Servers Status\n\n"
322
- for key, config in (mcp_client.mcp_servers.items() if mcp_client else []):
323
- try:
324
- # Try multiple health check endpoints
325
- health_urls = [
326
- f"{config['space_url']}/health",
327
- f"{config['space_url']}/",
328
- f"{config['space_url']}/docs"
329
- ]
330
-
331
- status = "🔴 Offline"
332
- for url in health_urls:
333
- try:
334
- response = requests.get(url, timeout=5)
335
- if response.status_code == 200:
336
- status = "🟢 Online"
337
- break
338
- elif response.status_code in [404, 422]: # Common for FastAPI
339
- status = "🟡 Running (different endpoint structure)"
340
- break
341
- except:
342
- continue
343
-
344
- except:
345
- status = "🔴 Offline"
346
-
347
- status_info += f"**{config['name']}**: {status}\n"
348
  status_info += f"- URL: {config['space_url']}\n"
349
  status_info += f"- Description: {config['description']}\n"
350
 
351
- # Try to get tools info for additional status
352
- if mcp_client:
353
- try:
354
- tools = mcp_client.get_available_tools(key)
355
- tools_count = len(tools) if tools else 0
356
- status_info += f"- Available Tools: {tools_count}\n"
357
- except:
358
- status_info += f"- Available Tools: Unable to fetch\n"
 
 
 
 
 
359
 
360
  status_info += "\n"
361
 
@@ -385,7 +870,7 @@ def create_gradio_interface():
385
 
386
  # Server selection
387
  server_choice = gr.Dropdown(
388
- choices=["Auto-detect", "terraform", "linux", "cisco"],
389
  value="Auto-detect",
390
  label="Select MCP Server"
391
  )
@@ -414,17 +899,23 @@ def create_gradio_interface():
414
 
415
  gr.Markdown("## 💡 Example Queries")
416
  gr.Markdown("""
417
- **Terraform:**
418
- - "Show me the current infrastructure state"
419
- - "Plan a new deployment"
 
 
 
 
420
 
421
- **Linux:**
422
- - "Check system resources"
423
- - "List running processes"
 
424
 
425
  **Cisco:**
426
- - "Show interface status"
427
- - "Check network configuration"
 
428
  """)
429
 
430
  # Event handlers
 
21
  "linux": {
22
  "name": "MCP Linux",
23
  "space_url": "https://chrissacrumcor-mcp-linux.hf.space",
24
+ "description": "Linux system operations",
25
+ # Known tools from the Linux server code
26
+ "tools": [
27
+ {
28
+ "name": "user_management",
29
+ "description": "Generate Linux user management commands for creating, deleting, and managing users and groups"
30
+ },
31
+ {
32
+ "name": "file_permissions",
33
+ "description": "Generate file permission and ownership commands for chmod, chown, and permission discovery"
34
+ },
35
+ {
36
+ "name": "system_commands",
37
+ "description": "Generate common Linux system administration commands for processes, disk, network, services, and firewall"
38
+ }
39
+ ]
40
  },
41
  "cisco": {
42
  "name": "MCP Cisco",
 
47
 
48
  self.conversation_history = []
49
 
50
+ def check_server_health(self, server_key: str) -> Dict[str, Any]:
51
+ """Check if MCP server is responsive"""
52
+ try:
53
+ server_config = self.mcp_servers[server_key]
54
+
55
+ # Try health endpoints
56
+ health_endpoints = ["/health", "/", "/docs"]
57
+
58
+ for endpoint in health_endpoints:
59
+ try:
60
+ url = f"{server_config['space_url']}{endpoint}"
61
+ response = requests.get(url, timeout=10)
62
+
63
+ if response.status_code == 200:
64
+ return {
65
+ "success": True,
66
+ "status": "online",
67
+ "endpoint": endpoint,
68
+ "response": response.json() if endpoint in ["/health", "/"] else {"status": "docs_available"}
69
+ }
70
+ elif response.status_code in [404, 422]:
71
+ return {
72
+ "success": True,
73
+ "status": "online_different_structure",
74
+ "endpoint": endpoint
75
+ }
76
+ except requests.RequestException:
77
+ continue
78
+
79
+ return {"success": False, "status": "offline", "error": "No responsive endpoints"}
80
+
81
+ except Exception as e:
82
+ return {"success": False, "status": "error", "error": str(e)}
83
+
84
+ def execute_linux_tool(self, tool_name: str, arguments: Dict[str, Any]) -> str:
85
+ """Execute Linux MCP tools - recreated from server logic"""
86
+
87
+ if tool_name == "user_management":
88
+ action = arguments.get("action", "")
89
+ username = arguments.get("username", "example_user")
90
+ groupname = arguments.get("groupname", "example_group")
91
+
92
+ if action == "add_user_to_group":
93
+ return f"""**Add User to Group Commands:**
94
+
95
+ ```bash
96
+ # Add user '{username}' to group '{groupname}'
97
+ sudo usermod -a -G {groupname} {username}
98
+
99
+ # Alternative methods:
100
+ sudo gpasswd -a {username} {groupname}
101
+ sudo adduser {username} {groupname} # Ubuntu/Debian
102
+
103
+ # Verify group membership:
104
+ groups {username}
105
+ id {username}
106
+ getent group {groupname}
107
+ ```"""
108
+
109
+ elif action == "create_user":
110
+ return f"""**Create User Commands:**
111
+
112
+ ```bash
113
+ # Create new user '{username}'
114
+ sudo useradd -m -s /bin/bash {username}
115
+ sudo passwd {username}
116
+
117
+ # Create user with specific group:
118
+ sudo useradd -m -g {groupname} -s /bin/bash {username}
119
+
120
+ # Add to sudo group (Ubuntu/Debian):
121
+ sudo usermod -a -G sudo {username}
122
+
123
+ # Add to wheel group (RHEL/CentOS):
124
+ sudo usermod -a -G wheel {username}
125
+
126
+ # Verify user creation:
127
+ id {username}
128
+ getent passwd {username}
129
+ ```"""
130
+
131
+ elif action == "delete_user":
132
+ return f"""**Delete User Commands:**
133
+
134
+ ```bash
135
+ # Delete user '{username}'
136
+ sudo userdel {username}
137
+
138
+ # Delete user and home directory:
139
+ sudo userdel -r {username}
140
+
141
+ # Remove user from all groups first (if needed):
142
+ sudo gpasswd -d {username} groupname
143
+
144
+ # Verify user deletion:
145
+ getent passwd {username}
146
+ # Should return no results if deleted successfully
147
+ ```"""
148
+
149
+ elif action == "list_groups":
150
+ return """**List Groups and Users Commands:**
151
+
152
+ ```bash
153
+ # List all groups:
154
+ cat /etc/group
155
+ getent group
156
+
157
+ # List groups for current user:
158
+ groups $USER
159
+ id $USER
160
+
161
+ # List groups for specific user:
162
+ groups username
163
+ id username
164
+
165
+ # List users in specific group:
166
+ getent group sudo
167
+ getent group wheel
168
+
169
+ # List all users:
170
+ cut -d: -f1 /etc/passwd
171
+ getent passwd
172
+ ```"""
173
+
174
+ else:
175
+ return f"❌ Unknown user management action: {action}. Available: add_user_to_group, create_user, delete_user, list_groups"
176
+
177
+ elif tool_name == "file_permissions":
178
+ action = arguments.get("action", "")
179
+ path = arguments.get("path", "/path/to/file")
180
+ permissions = arguments.get("permissions", "755")
181
+ owner = arguments.get("owner", "username")
182
+ recursive = arguments.get("recursive", False)
183
+
184
+ recursive_flag = "-R " if recursive else ""
185
+
186
+ if action == "chmod":
187
+ return f"""**Change File Permissions Commands:**
188
+
189
+ ```bash
190
+ # Change permissions for {path}
191
+ chmod {recursive_flag}{permissions} {path}
192
+
193
+ # Common permission examples:
194
+ # 755 = rwxr-xr-x (executable for owner, readable for others)
195
+ # 644 = rw-r--r-- (readable/writable for owner, readable for others)
196
+ # 600 = rw------- (readable/writable for owner only)
197
+ # 777 = rwxrwxrwx (full permissions for all - use with caution!)
198
+
199
+ # Symbolic notation examples:
200
+ chmod {recursive_flag}u+x {path} # Add execute for owner
201
+ chmod {recursive_flag}g-w {path} # Remove write for group
202
+ chmod {recursive_flag}o-r {path} # Remove read for others
203
+
204
+ # Verify permissions:
205
+ ls -la {path}
206
+ stat {path}
207
+ ```"""
208
+
209
+ elif action == "chown":
210
+ return f"""**Change File Ownership Commands:**
211
+
212
+ ```bash
213
+ # Change ownership for {path}
214
+ sudo chown {recursive_flag}{owner} {path}
215
+
216
+ # Change owner and group:
217
+ sudo chown {recursive_flag}{owner}:{owner} {path}
218
+ sudo chown {recursive_flag}{owner}:users {path}
219
+
220
+ # Change only group:
221
+ sudo chgrp {recursive_flag}{owner} {path}
222
+
223
+ # Verify ownership:
224
+ ls -la {path}
225
+ stat {path}
226
+ ```"""
227
+
228
+ elif action == "find_permissions":
229
+ return f"""**Find Files by Permissions:**
230
+
231
+ ```bash
232
+ # Find files with specific permissions in {path}
233
+ find {path} -type f -perm {permissions}
234
+ find {path} -type f -perm -{permissions} # At least these permissions
235
+
236
+ # Find files by owner:
237
+ find {path} -user {owner}
238
+ find {path} -group {owner}
239
+
240
+ # Find files with dangerous permissions:
241
+ find {path} -type f -perm -002 # World-writable files
242
+ find {path} -type f -perm -004 # World-readable files
243
+
244
+ # Find SUID/SGID files:
245
+ find {path} -type f -perm -4000 # SUID files
246
+ find {path} -type f -perm -2000 # SGID files
247
+
248
+ # Find world-writable directories:
249
+ find {path} -type d -perm 777
250
+ ```"""
251
+
252
+ else:
253
+ return f"❌ Unknown file permission action: {action}. Available: chmod, chown, find_permissions"
254
+
255
+ elif tool_name == "system_commands":
256
+ category = arguments.get("category", "")
257
+ target = arguments.get("target", "nginx")
258
+
259
+ if category == "process":
260
+ return f"""**Process Management Commands:**
261
+
262
+ ```bash
263
+ # List and analyze processes:
264
+ ps aux # List all processes with details
265
+ ps -ef # Alternative process listing
266
+ pstree # Show process tree
267
+ top # Real-time process monitor
268
+ htop # Enhanced process monitor
269
+
270
+ # Find and manage specific processes:
271
+ ps aux | grep {target} # Find specific process
272
+ pgrep -f {target} # Get PID by name
273
+ pkill -f {target} # Kill process by name
274
+ killall {target} # Kill all processes by name
275
+
276
+ # Process control:
277
+ kill -15 PID # Graceful termination (SIGTERM)
278
+ kill -9 PID # Force kill (SIGKILL)
279
+ kill -HUP PID # Reload configuration (SIGHUP)
280
+
281
+ # Background processes:
282
+ nohup command & # Run command in background
283
+ screen -S session_name # Start screen session
284
+ tmux new -s session_name # Start tmux session
285
+ ```"""
286
+
287
+ elif category == "service":
288
+ return f"""**Service Management Commands (systemd):**
289
+
290
+ ```bash
291
+ # Service status and control:
292
+ systemctl status {target} # Check service status
293
+ systemctl start {target} # Start service
294
+ systemctl stop {target} # Stop service
295
+ systemctl restart {target} # Restart service
296
+ systemctl reload {target} # Reload configuration
297
+
298
+ # Service persistence:
299
+ systemctl enable {target} # Enable at boot
300
+ systemctl disable {target} # Disable at boot
301
+ systemctl is-enabled {target} # Check if enabled
302
+
303
+ # Service discovery:
304
+ systemctl list-units # List all active services
305
+ systemctl list-units --failed # List failed services
306
+ systemctl list-unit-files # List all unit files
307
+
308
+ # Service logs:
309
+ journalctl -u {target} # View service logs
310
+ journalctl -u {target} -f # Follow service logs
311
+ journalctl -u {target} --since today # Today's logs
312
+ ```"""
313
+
314
+ elif category == "network":
315
+ return f"""**Network Diagnostic Commands:**
316
+
317
+ ```bash
318
+ # Network interface information:
319
+ ip addr show # Show IP addresses
320
+ ip link show # Show network interfaces
321
+ ip route show # Show routing table
322
+ ip neigh show # Show ARP table
323
+
324
+ # Port and connection analysis:
325
+ ss -tuln # Show listening ports
326
+ ss -tulpn # Show ports with process names
327
+ netstat -tuln # Alternative port listing
328
+ netstat -rn # Show routing table
329
+
330
+ # Connectivity testing:
331
+ ping -c 4 {target} # Test connectivity
332
+ traceroute {target} # Trace network path
333
+ mtr {target} # Network diagnostic tool
334
+ nslookup {target} # DNS lookup
335
+ dig {target} # DNS information
336
+
337
+ # Network utilities:
338
+ wget -O- ifconfig.me # Get public IP
339
+ curl -s ifconfig.me # Alternative public IP
340
+ curl -s ipinfo.io # Detailed IP information
341
+ ```"""
342
+
343
+ elif category == "disk":
344
+ return f"""**Disk Usage and Management Commands:**
345
+
346
+ ```bash
347
+ # Disk usage analysis:
348
+ df -h # Show disk usage (human readable)
349
+ df -i # Show inode usage
350
+ du -sh /* # Show directory sizes in root
351
+ du -sh /var/log/* | sort -hr # Sort by size
352
+
353
+ # Disk and filesystem information:
354
+ lsblk # List block devices
355
+ lsblk -f # Show filesystems
356
+ blkid # Show UUIDs and labels
357
+ fdisk -l # List disk partitions
358
+ parted -l # Alternative partition listing
359
+
360
+ # Mount management:
361
+ mount # Show mounted filesystems
362
+ findmnt # Tree view of mounts
363
+ mount /dev/sdb1 /mnt/backup # Mount filesystem
364
+ umount /mnt/backup # Unmount filesystem
365
+
366
+ # Cleanup commands:
367
+ apt autoremove # Remove unused packages (Debian/Ubuntu)
368
+ yum autoremove # Remove unused packages (RHEL/CentOS)
369
+ journalctl --disk-usage # Check journal disk usage
370
+ journalctl --vacuum-time=3d # Clean old journal entries
371
+ ```"""
372
+
373
+ elif category == "firewall":
374
+ return f"""**Firewall Management Commands:**
375
+
376
+ ```bash
377
+ # UFW (Uncomplicated Firewall):
378
+ sudo ufw status verbose # Check UFW status (detailed)
379
+ sudo ufw enable # Enable UFW
380
+ sudo ufw disable # Disable UFW
381
+
382
+ # UFW rule management:
383
+ sudo ufw allow {target} # Allow port/service
384
+ sudo ufw deny {target} # Block port/service
385
+ sudo ufw allow ssh # Allow SSH service
386
+ sudo ufw allow 80/tcp # Allow HTTP
387
+ sudo ufw allow 443/tcp # Allow HTTPS
388
+ sudo ufw allow from 192.168.1.0/24 # Allow from subnet
389
+
390
+ # UFW advanced operations:
391
+ sudo ufw delete allow 80 # Remove rule
392
+ sudo ufw insert 1 allow 22 # Insert rule at position
393
+ sudo ufw logging on # Enable logging
394
+
395
+ # iptables (advanced):
396
+ sudo iptables -L # List iptables rules
397
+ sudo iptables -L -n # List with numeric output
398
+ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Allow HTTP
399
+ sudo iptables-save > /etc/iptables/rules.v4 # Save rules
400
+ ```"""
401
+
402
+ else:
403
+ return f"❌ Unknown system command category: {category}. Available: process, service, network, disk, firewall"
404
+
405
+ else:
406
+ return f"❌ Unknown tool: {tool_name}. Available: user_management, file_permissions, system_commands"
407
+
408
+ def select_linux_tool_and_args(self, user_input: str) -> Dict[str, Any]:
409
+ """Analyze user input to select appropriate Linux tool and arguments"""
410
+ user_lower = user_input.lower()
411
+
412
+ # User management keywords
413
+ if any(word in user_lower for word in ["user", "group", "adduser", "useradd", "usermod"]):
414
+ if "add" in user_lower and "group" in user_lower:
415
+ return {"tool": "user_management", "args": {"action": "add_user_to_group", "username": "example_user", "groupname": "example_group"}}
416
+ elif "create" in user_lower or ("add" in user_lower and "user" in user_lower):
417
+ return {"tool": "user_management", "args": {"action": "create_user", "username": "new_user"}}
418
+ elif "delete" in user_lower and "user" in user_lower:
419
+ return {"tool": "user_management", "args": {"action": "delete_user", "username": "old_user"}}
420
+ else:
421
+ return {"tool": "user_management", "args": {"action": "list_groups"}}
422
+
423
+ # File permission keywords
424
+ elif any(word in user_lower for word in ["permission", "chmod", "chown", "file", "ownership"]):
425
+ if "chmod" in user_lower:
426
+ return {"tool": "file_permissions", "args": {"action": "chmod", "path": "/path/to/file", "permissions": "755"}}
427
+ elif "chown" in user_lower or "ownership" in user_lower:
428
+ return {"tool": "file_permissions", "args": {"action": "chown", "path": "/path/to/file", "owner": "username"}}
429
+ elif "find" in user_lower:
430
+ return {"tool": "file_permissions", "args": {"action": "find_permissions", "path": "/", "permissions": "777"}}
431
+ else:
432
+ return {"tool": "file_permissions", "args": {"action": "chmod", "path": "/path/to/file", "permissions": "644"}}
433
+
434
+ # System command keywords
435
+ elif any(word in user_lower for word in ["process", "service", "network", "disk", "firewall", "systemctl", "ps"]):
436
+ if any(word in user_lower for word in ["process", "ps", "top", "kill"]):
437
+ return {"tool": "system_commands", "args": {"category": "process"}}
438
+ elif any(word in user_lower for word in ["service", "systemctl", "daemon"]):
439
+ return {"tool": "system_commands", "args": {"category": "service"}}
440
+ elif any(word in user_lower for word in ["network", "ping", "ip", "interface"]):
441
+ return {"tool": "system_commands", "args": {"category": "network"}}
442
+ elif any(word in user_lower for word in ["disk", "df", "mount", "storage"]):
443
+ return {"tool": "system_commands", "args": {"category": "disk"}}
444
+ elif any(word in user_lower for word in ["firewall", "ufw", "iptables"]):
445
+ return {"tool": "system_commands", "args": {"category": "firewall"}}
446
+ else:
447
+ return {"tool": "system_commands", "args": {"category": "process"}}
448
+
449
+ # Default - show help
450
+ else:
451
+ return {"tool": "help", "args": {}}
452
+
453
+ def get_available_tools(self, server_key: str) -> List[Dict[str, Any]]:
454
+ """Get available tools from an MCP server"""
455
+ if server_key == "linux":
456
+ # Return known tools for Linux server
457
+ return self.mcp_servers["linux"]["tools"]
458
+
459
+ # For other servers, try to call them (though they might not have HTTP endpoints)
460
+ try:
461
+ result = self.call_mcp_server(server_key, "tools/list", {})
462
+ if result["success"]:
463
+ data = result["data"]
464
+ if isinstance(data, dict):
465
+ return data.get("tools", data.get("result", []))
466
+ elif isinstance(data, list):
467
+ return data
468
+ except:
469
+ pass
470
+
471
+ return []
472
+
473
  def call_mcp_server(self, server_key: str, endpoint: str, payload: Dict[str, Any]) -> Dict[str, Any]:
474
+ """Make a call to an MCP server (for non-Linux servers)"""
475
  try:
476
  server_config = self.mcp_servers[server_key]
477
 
 
511
  except Exception as e:
512
  return {"success": False, "error": f"Unexpected error: {str(e)}", "server": server_config['name']}
513
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  def execute_tool(self, server_key: str, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
515
  """Execute a tool on an MCP server"""
516
  payload = {
 
659
 
660
  status = f"[{timestamp}] Using: {self.mcp_servers[selected_server]['name']}"
661
 
662
+ # Check server health
663
+ health_check = self.check_server_health(selected_server)
664
+ if not health_check["success"]:
665
+ response = f"⚠️ Cannot connect to {self.mcp_servers[selected_server]['name']} server: {health_check.get('error', 'Server offline')}"
 
 
 
 
 
 
 
666
  self.conversation_history.append({"role": "assistant", "content": response})
667
+ return response, status + " - Server offline"
668
 
669
+ # Handle Linux server specifically (full functionality)
670
+ if selected_server == "linux":
671
+ tool_selection = self.select_linux_tool_and_args(user_input)
672
+
673
+ if tool_selection["tool"] == "help":
674
+ response = """**Available Linux MCP Tools:**
675
+
676
+ 🔧 **user_management**: Create, delete, and manage users and groups
677
+ 📁 **file_permissions**: Change file permissions and ownership (chmod, chown)
678
+ ⚙️ **system_commands**: System administration commands (processes, services, network, disk, firewall)
679
+
680
+ **Example commands you can ask for:**
681
+ - "Show me user management commands"
682
+ - "How do I change file permissions?"
683
+ - "Give me process management commands"
684
+ - "Show network diagnostic commands"
685
+ - "Help with service management"
686
+ - "Configure firewall rules"
687
+ - "Check disk usage commands"
688
+ """
689
+ else:
690
+ # Execute the selected Linux tool
691
+ result = self.execute_linux_tool(tool_selection["tool"], tool_selection["args"])
692
+ response = result
693
 
694
+ # Handle other servers (Terraform, Cisco)
695
+ else:
696
+ # Get available tools for the selected server
697
+ tools = self.get_available_tools(selected_server)
698
+
699
+ if tools:
700
+ # Show available tools and generate helpful response
701
+ tools_info = "\n".join([f"- {tool.get('name', 'Unknown')}: {tool.get('description', 'No description')}"
702
+ for tool in tools[:5]])
703
+
704
+ server_info = {
705
+ "server": self.mcp_servers[selected_server]['name'],
706
+ "available_tools": len(tools),
707
+ "sample_tools": tools_info
708
+ }
709
+
710
+ response = self.generate_response(user_input, server_info)
711
+ else:
712
+ # Provide guidance for servers without direct HTTP tool access
713
+ if selected_server == "terraform":
714
+ response = f"""**Terraform MCP Server**
715
+
716
+ I can help you with Terraform infrastructure management, but this server uses MCP protocol over SSE.
717
+
718
+ **Common Terraform operations:**
719
+ - Plan infrastructure changes (`terraform plan`)
720
+ - Apply configurations (`terraform apply`)
721
+ - Destroy resources (`terraform destroy`)
722
+ - Validate configurations (`terraform validate`)
723
+ - Import existing resources (`terraform import`)
724
+
725
+ **Server Status**: {health_check['status']}
726
+ **MCP Endpoint**: {self.mcp_servers[selected_server]['space_url']}/mcp/sse
727
+
728
+ *Note: For full functionality, this server requires MCP protocol connection.*
729
+ """
730
+
731
+ elif selected_server == "cisco":
732
+ response = f"""**Cisco MCP Server**
733
+
734
+ I can help you with Cisco network device management, but this server uses MCP protocol over SSE.
735
+
736
+ **Common Cisco operations:**
737
+ - Show interface configurations
738
+ - Configure VLANs
739
+ - Set up routing protocols
740
+ - Manage access control lists
741
+ - Check device status
742
+ - Configure port settings
743
+
744
+ **Server Status**: {health_check['status']}
745
+ **MCP Endpoint**: {self.mcp_servers[selected_server]['space_url']}/mcp/sse
746
+
747
+ *Note: For full functionality, this server requires MCP protocol connection.*
748
+ """
749
 
 
750
  self.conversation_history.append({"role": "assistant", "content": response})
751
+ return response, status + f" - {health_check['status']}"
 
752
 
753
  except Exception as e:
754
  error_response = f"❌ Error processing request: {str(e)}"
 
805
  return history, ""
806
 
807
  def get_server_status():
808
+ if not mcp_client:
809
+ return "Please initialize the OpenAI client first."
810
+
811
  status_info = "## MCP Servers Status\n\n"
812
+
813
+ for key, config in mcp_client.mcp_servers.items():
814
+ health_check = mcp_client.check_server_health(key)
815
+
816
+ if health_check["success"]:
817
+ if health_check["status"] == "online":
818
+ status_icon = "🟢"
819
+ status_text = "Online"
820
+ else:
821
+ status_icon = "🟡"
822
+ status_text = "Online (Different Structure)"
823
+ else:
824
+ status_icon = "🔴"
825
+ status_text = "Offline"
826
+
827
+ status_info += f"**{config['name']}**: {status_icon} {status_text}\n"
 
 
 
 
 
 
 
 
 
 
828
  status_info += f"- URL: {config['space_url']}\n"
829
  status_info += f"- Description: {config['description']}\n"
830
 
831
+ # Show tools for Linux server
832
+ if key == "linux" and "tools" in config:
833
+ status_info += f"- Available Tools: {len(config['tools'])}\n"
834
+ for tool in config['tools']:
835
+ status_info += f" - **{tool['name']}**: {tool['description']}\n"
836
+
837
+ # Show MCP endpoint info
838
+ status_info += f"- MCP Endpoint: {config['space_url']}/mcp/sse\n"
839
+
840
+ if health_check["success"] and "response" in health_check:
841
+ response_data = health_check["response"]
842
+ if isinstance(response_data, dict) and "service" in response_data:
843
+ status_info += f"- Service: {response_data.get('service', 'Unknown')}\n"
844
 
845
  status_info += "\n"
846
 
 
870
 
871
  # Server selection
872
  server_choice = gr.Dropdown(
873
+ choices=["Auto-detect", "linux", "terraform", "cisco"],
874
  value="Auto-detect",
875
  label="Select MCP Server"
876
  )
 
899
 
900
  gr.Markdown("## 💡 Example Queries")
901
  gr.Markdown("""
902
+ **Linux (Full Support):**
903
+ - "Show me user management commands"
904
+ - "How do I change file permissions?"
905
+ - "Give me process management commands"
906
+ - "Show network diagnostic commands"
907
+ - "Help with service management"
908
+ - "Configure firewall rules"
909
 
910
+ **Terraform:**
911
+ - "Show me terraform commands"
912
+ - "Plan infrastructure deployment"
913
+ - "Help with terraform apply"
914
 
915
  **Cisco:**
916
+ - "Show interface configuration"
917
+ - "Configure VLAN commands"
918
+ - "Help with port configuration"
919
  """)
920
 
921
  # Event handlers