get_system_info
Retrieve detailed system information: OS, kernel, CPU, memory, disk usage, and update status. Gain a clear overview of your system's state for monitoring and diagnostics.
Instructions
Get comprehensive system information including OS, kernel, CPU, memory, disk usage, and update status. This is a good starting point for understanding system state.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| server | No | Server alias (e.g., 'pi1', 'web-server'). Uses default server if not specified. |
Implementation Reference
- src/tools/system.py:12-92 (handler)The main handler function for get_system_info. Calls multiple Webmin endpoints (get_webmin_version, get_system_hostname, detect_operating_system, collect_system_info) and assembles them into a comprehensive ToolResult with OS, kernel, CPU, memory, disk, process count, updates, and reboot status.
async def get_system_info(client: WebminClient) -> ToolResult: """Get comprehensive system information. Combines data from multiple Webmin endpoints to provide a complete system overview including OS, kernel, CPU, memory, and disk info. Args: client: Authenticated WebminClient instance. Returns: ToolResult with system information. """ try: # Gather data from multiple sources version = await client.call("webmin", "get_webmin_version") hostname = await client.call("webmin", "get_system_hostname") os_info = await client.call("webmin", "detect_operating_system") system_info = await client.call("system-status", "collect_system_info") # Parse OS info (returns flat list of key-value pairs) os_data = {} if isinstance(os_info, list): for i in range(0, len(os_info) - 1, 2): os_data[os_info[i]] = os_info[i + 1] # Parse CPU info from load array load = system_info.get("load", []) cpu_info = { "load_1min": load[0] if len(load) > 0 else None, "load_5min": load[1] if len(load) > 1 else None, "load_15min": load[2] if len(load) > 2 else None, "running_processes": load[3] if len(load) > 3 else None, "model": load[4] if len(load) > 4 else None, "vendor": load[5] if len(load) > 5 else None, "cache_kb": load[6] if len(load) > 6 else None, "cores": load[7] if len(load) > 7 else None, } # Parse memory info mem = system_info.get("mem", []) mem_info = { "total_kb": mem[0] if len(mem) > 0 else None, "used_kb": mem[1] if len(mem) > 1 else None, "buffers_kb": mem[2] if len(mem) > 2 else None, "cached_kb": mem[3] if len(mem) > 3 else None, "free_kb": mem[4] if len(mem) > 4 else None, } # Parse kernel info kernel = system_info.get("kernel", {}) return ToolResult.ok({ "hostname": hostname, "webmin_version": str(version), "os": { "type": os_data.get("os_type"), "name": os_data.get("real_os_type"), "version": os_data.get("real_os_version"), }, "kernel": { "os": kernel.get("os"), "version": kernel.get("version"), "arch": kernel.get("arch"), }, "cpu": cpu_info, "memory": mem_info, "disk": { "total_bytes": system_info.get("disk_total"), "used_bytes": system_info.get("disk_used"), "free_bytes": system_info.get("disk_free"), }, "process_count": system_info.get("procs"), "updates_available": len(system_info.get("poss", [])), "reboot_required": bool(system_info.get("reboot")), }) except Exception as e: return ToolResult.fail( code="SYSTEM_INFO_ERROR", message=f"Failed to get system info: {e}", ) - src/server.py:108-132 (registration)Registration of the get_system_info MCP tool in the TOOLS list with its name, description, and inputSchema (accepts optional 'server' parameter for multi-server support).
Tool( name="get_webmin_version", description=( "Get the version of the connected Webmin server. " "Returns the version string and hostname." ), inputSchema={ "type": "object", "properties": {**SERVER_PARAM}, "required": [], }, ), Tool( name="get_system_info", description=( "Get comprehensive system information including OS, kernel, " "CPU, memory, disk usage, and update status. " "This is a good starting point for understanding system state." ), inputSchema={ "type": "object", "properties": {**SERVER_PARAM}, "required": [], }, ), - src/server.py:1360-1361 (registration)Dispatch routing in call_tool: maps the 'get_system_info' tool name to system.get_system_info(client) call.
if name == "get_system_info": return await system.get_system_info(client) - src/models.py:35-66 (helper)ToolResult model used by the handler to return structured success/failure results via ToolResult.ok() and ToolResult.fail() class methods.
class ToolResult(BaseModel): """Generic result wrapper for MCP tool responses.""" success: bool = Field( description="Whether the operation succeeded", ) data: dict[str, Any] | None = Field( default=None, description="Result data on success", ) error: WebminError | None = Field( default=None, description="Error details on failure", ) @classmethod def ok(cls, data: dict[str, Any]) -> "ToolResult": """Create a successful result.""" return cls(success=True, data=data) @classmethod def fail( cls, code: str, message: str, details: dict[str, Any] | None = None, ) -> "ToolResult": """Create a failure result.""" return cls( success=False, error=WebminError(code=code, message=message, details=details), ) - tests/test_tools_system.py:19-58 (schema)Unit tests for get_system_info covering both success (verifying returned data structure) and error (verifying SYSTEM_INFO_ERROR code) scenarios.
class TestGetSystemInfo: """Tests for get_system_info tool.""" async def test_get_system_info_success(self, mock_client: AsyncMock) -> None: """Test successful system info retrieval.""" # Setup mock responses mock_client.call.side_effect = [ "2.105", # webmin::get_webmin_version "testhost", # webmin::get_system_hostname ["real_os_type", "Ubuntu Linux", "real_os_version", "24.04"], # detect_operating_system { # collect_system_info "load": [0.5, 0.3, 0.2, 100, "Test CPU", "TestVendor", 1024, 4], "mem": [4000000, 2000000, 100000, 500000, 1400000], "disk_total": 100000000000, "disk_used": 50000000000, "disk_free": 50000000000, "kernel": {"os": "Linux", "version": "6.1.0", "arch": "x86_64"}, "procs": 150, "poss": [{"name": "pkg1"}, {"name": "pkg2"}], "reboot": 0, }, ] result = await system.get_system_info(mock_client) assert result.success assert result.data["hostname"] == "testhost" assert result.data["webmin_version"] == "2.105" assert result.data["os"]["name"] == "Ubuntu Linux" assert result.data["cpu"]["cores"] == 4 assert result.data["updates_available"] == 2 async def test_get_system_info_error(self, mock_client: AsyncMock) -> None: """Test system info error handling.""" mock_client.call.side_effect = Exception("Connection failed") result = await system.get_system_info(mock_client) assert not result.success assert result.error.code == "SYSTEM_INFO_ERROR"