Skip to main content
Glama

se_health

Read-onlyIdempotent

Check health of all Service Engines to diagnose issues when virtual service health degrades. Monitors CPU, memory, disk usage, and connectivity.

Instructions

[READ] Check health of all Service Engines — CPU, memory, disk usage, and connectivity.

Use when VS health degrades to check if the issue is at the SE level.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Core handler: check_se_health() queries virtualservice-inventory and serviceengine-inventory, builds SE→VS placement map, prints name/status/VS count for each SE.
    def check_se_health() -> None:
        """Check SE health and resource usage.
    
        VS count is reconstructed by inverting the VS→SE placement map from
        ``/virtualservice-inventory`` (``runtime.vip_summary[].service_engine[]``).
        On 22.x Controllers the per-SE ``runtime`` object does not expose any
        VS list field, so the previous attempts at ``se_vs_list`` / ``vs_ref`` /
        ``virtualservice_refs`` always produced 0 and gave false "idle SE"
        signals.
        """
        cfg = load_config()
        mgr = AviConnectionManager(cfg)
        session = mgr.connect()
    
        # Build SE-UUID → set of VS-UUIDs it hosts, then collapse to counts.
        # De-duping per VS (not per (VS, VIP) pair) ensures a VS with multiple
        # VIPs landing on the same SE still only counts once.
        vs_resp = session.get("virtualservice-inventory")
        se_vs_map: dict[str, set[str]] = {}
        for vs in (vs_resp.json() if hasattr(vs_resp, "json") else vs_resp).get("results", []):
            vs_uuid = vs.get("uuid") or (vs.get("config") or {}).get("uuid", "")
            if not vs_uuid:
                continue
            runtime = vs.get("runtime") or {}
            for vip in runtime.get("vip_summary") or []:
                for se in vip.get("service_engine") or []:
                    se_uuid = se.get("uuid")
                    if se_uuid:
                        se_vs_map.setdefault(se_uuid, set()).add(vs_uuid)
    
        resp = session.get("serviceengine-inventory")
        ses = (resp.json() if hasattr(resp, "json") else resp).get("results", [])
    
        console.print("\n[bold]Service Engine Health[/bold]")
        for se in ses:
            cfg_data = se.get("config", {}) or {}
            runtime = se.get("runtime", {}) or {}
            name = cfg_data.get("name", "N/A")
            uuid = se.get("uuid") or cfg_data.get("uuid", "")
            oper = (runtime.get("oper_status", {}) or {}).get("state", "N/A")
            vs_count = len(se_vs_map.get(uuid, set()))
    
            status_color = "green" if oper == "OPER_UP" else "red"
            console.print(
                f"  [{status_color}]{name}[/{status_color}]: {oper}, "
                f"VS count: {vs_count}"
            )
    
        console.print()
  • MCP tool registration: se_health() decorated with @mcp.tool and @vmware_tool, calls check_se_health via _capture_output.
    @mcp.tool(annotations={"readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": True})
    @vmware_tool(risk_level="low")
    def se_health() -> str:
        """[READ] Check health of all Service Engines — CPU, memory, disk usage, and connectivity.
    
        Use when VS health degrades to check if the issue is at the SE level.
        """
        from vmware_avi.ops.se_mgmt import check_se_health
        return _capture_output(check_se_health)
  • CLI registration: se_health command under 'se health' subcommand in the Typer CLI.
    @se_app.command("health")
    def se_health() -> None:
        """Check Service Engine health."""
        from vmware_avi.ops.se_mgmt import check_se_health
    
        check_se_health()
  • Tool listing test: 'se_health' listed as an expected MCP tool name.
    "se_health",
    # AKO mode
  • Helper: _capture_output captures Rich console output as a string for MCP tool responses.
    def _capture_output(func, *args, **kwargs) -> str:
        """Run a function and capture its Rich console output as plain text."""
        import importlib  # noqa: F401 — used via sys.modules lookup
        import sys
    
        buf = StringIO()
        from rich.console import Console
        capture_console = Console(file=buf, force_terminal=False, width=120)
    
        mod_name = func.__module__
        mod = sys.modules.get(mod_name)
        original_console = getattr(mod, "console", None) if mod else None
    
        if mod and original_console is not None:
            mod.console = capture_console
    
        try:
            func(*args, **kwargs)
        except SystemExit:
            pass
        finally:
            if mod and original_console is not None:
                mod.console = original_console
    
        return buf.getvalue()
Behavior4/5

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

Annotations already indicate read-only, idempotent behavior. Description adds that it checks specific health metrics, which provides useful context beyond the annotations without contradiction.

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?

Two concise sentences: first states purpose and scope, second gives usage guidance. No unnecessary words.

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

Completeness5/5

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

Given no parameters, comprehensive annotations, and available output schema, the description fully explains what the tool does and when to use it.

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?

No parameters exist, and schema description coverage is 100%. The description explains the tool's function, which is sufficient for a parameterless tool.

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 it checks health of Service Engines and lists specific metrics (CPU, memory, disk, connectivity). This distinguishes it from sibling tools like se_list or vs_status.

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 provides explicit context: 'Use when VS health degrades to check if the issue is at the SE level.' It does not mention when not to use or alternatives, but the use case is clearly defined.

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/zw008/VMware-AVI'

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