diff --git a/src/proxmox_mcp/formatting/formatters.py b/src/proxmox_mcp/formatting/formatters.py index 529deb7..1008f53 100644 --- a/src/proxmox_mcp/formatting/formatters.py +++ b/src/proxmox_mcp/formatting/formatters.py @@ -138,21 +138,20 @@ class ProxmoxFormatters: Returns: Formatted command output string """ - status_emoji = ProxmoxTheme.ACTIONS['success' if success else 'error'] - cmd_emoji = ProxmoxTheme.ACTIONS['command'] - result = [ - ProxmoxFormatters.format_section_header("Console Command Result"), - f"{status_emoji} Status: {ProxmoxColors.colorize('SUCCESS' if success else 'FAILED', ProxmoxColors.GREEN if success else ProxmoxColors.RED)}", - f"{cmd_emoji} Command: {command}", - "\n📤 Output:", + f"{ProxmoxTheme.ACTIONS['command']} Console Command Result", + f" • Status: {'SUCCESS' if success else 'FAILED'}", + f" • Command: {command}", + "", + "Output:", output.strip() ] if error: result.extend([ - "\n❌ Error:", - ProxmoxColors.colorize(error.strip(), ProxmoxColors.RED) + "", + "Error:", + error.strip() ]) return "\n".join(result) diff --git a/src/proxmox_mcp/formatting/templates.py b/src/proxmox_mcp/formatting/templates.py index aa3cf19..5b6e1ab 100644 --- a/src/proxmox_mcp/formatting/templates.py +++ b/src/proxmox_mcp/formatting/templates.py @@ -184,3 +184,30 @@ class ProxmoxTemplates: ]) return "\n".join(result) + + @staticmethod + def cluster_status(status: Dict[str, Any]) -> str: + """Template for cluster status output. + + Args: + status: Cluster status data + + Returns: + Formatted cluster status string + """ + result = [f"{ProxmoxTheme.SECTIONS['configuration']} Proxmox Cluster"] + + # Basic cluster info + result.extend([ + "", + f" • Name: {status.get('name', 'N/A')}", + f" • Quorum: {'OK' if status.get('quorum') else 'NOT OK'}", + f" • Nodes: {status.get('nodes', 0)}", + ]) + + # Add resource count if available + resources = status.get('resources', []) + if resources: + result.append(f" • Resources: {len(resources)}") + + return "\n".join(result) diff --git a/src/proxmox_mcp/tools/base.py b/src/proxmox_mcp/tools/base.py index 0a9744e..4b12b54 100644 --- a/src/proxmox_mcp/tools/base.py +++ b/src/proxmox_mcp/tools/base.py @@ -43,6 +43,8 @@ class ProxmoxTool: formatted = ProxmoxTemplates.storage_list(data) elif resource_type == "containers": formatted = ProxmoxTemplates.container_list(data) + elif resource_type == "cluster": + formatted = ProxmoxTemplates.cluster_status(data) else: # Fallback to JSON formatting for unknown types import json diff --git a/src/proxmox_mcp/tools/cluster.py b/src/proxmox_mcp/tools/cluster.py index 9a7537a..da3e8ed 100644 --- a/src/proxmox_mcp/tools/cluster.py +++ b/src/proxmox_mcp/tools/cluster.py @@ -26,6 +26,6 @@ class ClusterTools(ProxmoxTool): "nodes": len([node for node in result if node.get("type") == "node"]), "resources": [res for res in result if res.get("type") == "resource"] } - return self._format_response(status) + return self._format_response(status, "cluster") except Exception as e: self._handle_error("get cluster status", e) diff --git a/src/proxmox_mcp/tools/vm.py b/src/proxmox_mcp/tools/vm.py index 33c795e..e55e991 100644 --- a/src/proxmox_mcp/tools/vm.py +++ b/src/proxmox_mcp/tools/vm.py @@ -31,18 +31,37 @@ class VMTools(ProxmoxTool): try: result = [] for node in self.proxmox.nodes.get(): - vms = self.proxmox.nodes(node["node"]).qemu.get() - result.extend([{ - "vmid": vm["vmid"], - "name": vm["name"], - "status": vm["status"], - "node": node["node"], - "cpu": vm.get("cpu", 0), - "memory": { - "used": vm.get("mem", 0), - "total": vm.get("maxmem", 0) - } - } for vm in vms]) + node_name = node["node"] + vms = self.proxmox.nodes(node_name).qemu.get() + for vm in vms: + vmid = vm["vmid"] + # Get VM config for CPU cores + try: + config = self.proxmox.nodes(node_name).qemu(vmid).config.get() + result.append({ + "vmid": vmid, + "name": vm["name"], + "status": vm["status"], + "node": node_name, + "cpus": config.get("cores", "N/A"), + "memory": { + "used": vm.get("mem", 0), + "total": vm.get("maxmem", 0) + } + }) + except Exception: + # Fallback if can't get config + result.append({ + "vmid": vmid, + "name": vm["name"], + "status": vm["status"], + "node": node_name, + "cpus": "N/A", + "memory": { + "used": vm.get("mem", 0), + "total": vm.get("maxmem", 0) + } + }) return self._format_response(result, "vms") except Exception as e: self._handle_error("get VMs", e)