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

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

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"
            )
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the tool returns status information or an error message, which covers basic behavior, but lacks details on permissions, rate limits, or error conditions. It adds value by specifying the return format, but more behavioral context would improve transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose, followed by details on returns and parameters. Every sentence adds value without redundancy, and it uses clear sections (Args, Returns) for readability, making it efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (1 parameter) and the presence of an output schema (which handles return values), the description is mostly complete. It covers purpose, parameter semantics, and return overview adequately. However, without annotations, it could benefit from more behavioral details like error handling or prerequisites.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds meaning by explaining that the 'vm' parameter is the 'Name of the VM or container', which clarifies beyond the schema's generic string type. However, it doesn't provide examples or constraints (e.g., format, case-sensitivity), leaving some gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Get the status') and resource ('a VM/container (Incus)'), distinguishing it from siblings like vm_list (which lists VMs) or vm_exec (which executes commands). It explicitly mentions what information is retrieved, making the purpose unambiguous and distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when status information (state, IP, resource usage, snapshots) is needed for a specific VM/container, but does not explicitly state when not to use it or name alternatives. For example, it doesn't clarify if vm_list should be used first to find VM names, though this is reasonably inferred from context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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