Skip to main content
Glama

vm_status

Check the status of an Incus virtual machine or container to monitor its running state, IP address, resource usage, and available snapshots.

Instructions

Get the status of a VM/container (Incus).

Returns state (running/stopped), IP address, resource usage,
and available snapshots.

Args:
    vm: Name of the VM or container.

Returns:
    Formatted status information or error message.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
vmYes

Implementation Reference

  • The core implementation of vm_status that queries Incus CLI to get VM status information. Validates the VM name, runs 'incus list <vm> --format json', parses the JSON response, extracts network addresses, snapshots, and resource usage, then returns a VMInfo object.
    async def vm_status(vm: str) -> VMInfo:
        """Get detailed status of a VM/container.
    
        Uses `incus list <vm> --format json` for structured data.
        """
        _validate_vm_name(vm)
    
        result = await _run_incus("list", vm, "--format", "json")
        if result.exit_code != 0:
            raise RuntimeError(
                f"Failed to get status for {vm}: {result.stderr.strip()}"
            )
    
        try:
            instances = json.loads(result.stdout)
        except json.JSONDecodeError as e:
            raise RuntimeError(f"Failed to parse incus output: {e}")
    
        if not instances:
            raise RuntimeError(f"VM/container '{vm}' not found")
    
        # Find exact match (incus list does prefix matching)
        instance = None
        for inst in instances:
            if inst.get("name") == vm:
                instance = inst
                break
    
        if instance is None:
            raise RuntimeError(f"VM/container '{vm}' not found")
    
        # Extract network info
        ipv4 = ""
        ipv6 = ""
        state = instance.get("state", {})
        networks = state.get("network", {})
        for iface_name, iface in networks.items():
            if iface_name == "lo":
                continue
            for addr in iface.get("addresses", []):
                if addr.get("family") == "inet" and addr.get("scope") == "global":
                    ipv4 = ipv4 or addr.get("address", "")
                elif addr.get("family") == "inet6" and addr.get("scope") == "global":
                    ipv6 = ipv6 or addr.get("address", "")
    
        # Extract snapshots
        snapshot_names = []
        for snap in instance.get("snapshots", []) or []:
            if isinstance(snap, dict):
                snapshot_names.append(snap.get("name", ""))
            elif isinstance(snap, str):
                snapshot_names.append(snap)
    
        return VMInfo(
            name=instance.get("name", vm),
            status=instance.get("status", "Unknown"),
            type=instance.get("type", "unknown"),
            architecture=instance.get("architecture", ""),
            ipv4=ipv4,
            ipv6=ipv6,
            pid=state.get("pid", 0),
            processes=state.get("processes", 0),
            memory_usage=state.get("memory", {}).get("usage", 0),
            cpu_usage=state.get("cpu", {}).get("usage", 0),
            snapshots=snapshot_names,
        )
  • MCP tool registration for vm_status. Uses the @mcp.tool() decorator to expose the function as an MCP tool, wraps the underlying _vm_status implementation, catches exceptions, and formats the VMInfo object into a human-readable string.
    @mcp.tool()
    async def vm_status(vm: str) -> str:
        """Get the status of a VM/container (Incus).
    
        Returns state (running/stopped), IP address, resource usage,
        and available snapshots.
    
        Args:
            vm: Name of the VM or container.
    
        Returns:
            Formatted status information or error message.
        """
        try:
            info = await _vm_status(vm)
            return _format_vm_info(info)
        except (ValueError, RuntimeError, OSError) as e:
            return f"ERROR: {e}"
  • VMInfo dataclass defining the schema for VM status information. Includes fields for name, status, type, IP addresses, architecture, PID, processes, memory usage, CPU usage, and snapshots list.
    class VMInfo:
        """Status information for a single VM/container."""
    
        name: str
        status: str  # Running, Stopped, etc.
        type: str  # container or virtual-machine
        ipv4: str = ""
        ipv6: str = ""
        architecture: str = ""
        pid: int = 0
        processes: int = 0
        memory_usage: int = 0
        cpu_usage: int = 0
        snapshots: list[str] = field(default_factory=list)
  • Helper function that formats a VMInfo object into a human-readable string for the MCP tool response. Converts memory usage to MB, CPU time to seconds, and formats all fields with labels.
    def _format_vm_info(info: VMInfo) -> str:
        """Format VMInfo as a readable string."""
        lines = [
            f"Name: {info.name}",
            f"Status: {info.status}",
            f"Type: {info.type}",
        ]
        if info.architecture:
            lines.append(f"Architecture: {info.architecture}")
        if info.ipv4:
            lines.append(f"IPv4: {info.ipv4}")
        if info.ipv6:
            lines.append(f"IPv6: {info.ipv6}")
        if info.pid:
            lines.append(f"PID: {info.pid}")
        if info.processes:
            lines.append(f"Processes: {info.processes}")
        if info.memory_usage:
            mb = info.memory_usage / (1024 * 1024)
            lines.append(f"Memory: {mb:.1f} MB")
        if info.cpu_usage:
            secs = info.cpu_usage / 1_000_000_000
            lines.append(f"CPU Time: {secs:.2f}s")
        if info.snapshots:
            lines.append(f"Snapshots: {', '.join(info.snapshots)}")
        return "\n".join(lines)
  • Validation helper that ensures VM/container names are safe and valid. Checks that the name is not empty and matches the regex pattern requiring it to start with a letter and contain only alphanumeric characters and hyphens.
    def _validate_vm_name(name: str) -> None:
        """Validate that a VM/container name is safe."""
        if not name or not name.strip():
            raise ValueError("VM name cannot be empty")
        if not _VALID_NAME.match(name):
            raise ValueError(
                f"Invalid VM name '{name}': must start with a letter, "
                "contain only alphanumeric characters and hyphens"
            )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bobbyhiddn/Sympathy-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server