Skip to main content
Glama

get_assets

Retrieve reference data for fleets, aircraft, airports, or flight phases from the EMS system to support flight data analytics and monitoring.

Instructions

Get reference data: fleets, aircraft, airports, or flight phases.

Args: ems_system_id: EMS system ID (from list_ems_systems). asset_type: Type of assets to retrieve. fleet_id: Filter aircraft by fleet ID (only for asset_type="aircraft").

Returns: Formatted list of the requested asset type.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ems_system_idYes
asset_typeYes
fleet_idNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main async handler function for get_assets tool. Retrieves reference data (fleets, aircraft, airports, flight phases) from EMS API based on ems_system_id and asset_type parameters. Supports optional fleet_id filter for aircraft queries. Returns formatted string output.
    async def get_assets(
        ems_system_id: int,
        asset_type: Literal["fleets", "aircraft", "airports", "flight_phases"],
        fleet_id: int | None = None,
    ) -> str:
        """Get reference data: fleets, aircraft, airports, or flight phases.
    
        Args:
            ems_system_id: EMS system ID (from list_ems_systems).
            asset_type: Type of assets to retrieve.
            fleet_id: Filter aircraft by fleet ID (only for asset_type="aircraft").
    
        Returns:
            Formatted list of the requested asset type.
        """
        client = get_client()
    
        try:
            if asset_type == "fleets":
                path = f"/api/v2/ems-systems/{ems_system_id}/assets/fleets"
                data = await client.get(path)
                return _format_fleets(data)
    
            elif asset_type == "aircraft":
                path = f"/api/v2/ems-systems/{ems_system_id}/assets/aircraft"
                params: dict[str, Any] = {}
                if fleet_id is not None:
                    params["fleetId"] = fleet_id
                data = await client.get(path, params=params)
                return _format_aircraft(data)
    
            elif asset_type == "airports":
                path = f"/api/v2/ems-systems/{ems_system_id}/assets/airports"
                data = await client.get(path)
                return _format_airports(data)
    
            elif asset_type == "flight_phases":
                path = f"/api/v2/ems-systems/{ems_system_id}/assets/flight-phases"
                data = await client.get(path)
                return _format_flight_phases(data)
    
            else:
                return (
                    f"Error: Unknown asset_type '{asset_type}'. "
                    "Valid types: fleets, aircraft, airports, flight_phases."
                )
    
        except EMSNotFoundError:
            return f"Error: EMS system {ems_system_id} not found."
        except EMSAPIError as e:
            return f"Error getting {asset_type}: {e.message}"
  • Function signature defines the input/output schema: ems_system_id (int), asset_type (Literal with 4 valid values), optional fleet_id (int | None), returns string. The Literal type restricts asset_type to valid values: 'fleets', 'aircraft', 'airports', 'flight_phases'.
    async def get_assets(
        ems_system_id: int,
        asset_type: Literal["fleets", "aircraft", "airports", "flight_phases"],
        fleet_id: int | None = None,
    ) -> str:
  • The @mcp.tool decorator registers the get_assets function with the FastMCP server instance, making it available as an MCP tool.
    @mcp.tool
  • Module import statement that triggers tool registration. Importing ems_mcp.tools.assets causes the @mcp.tool decorated functions to be registered with the FastMCP server instance.
    import ems_mcp.tools.assets  # noqa: E402, F401
  • Four helper formatting functions that convert API response data into human-readable formatted strings: _format_fleets, _format_aircraft, _format_flight_phases, _format_airports. Each handles empty lists and formats multiple items with appropriate details.
    def _format_fleets(fleets: list[dict[str, Any]]) -> str:
        """Format fleets list for display."""
        if not fleets:
            return "No fleets found."
    
        lines = [f"Found {len(fleets)} fleet(s):"]
        for f in fleets:
            name = f.get("name", "Unknown")
            fleet_id = f.get("id", "?")
            desc = f.get("description", "")
            if desc:
                lines.append(f"  - {name} (ID: {fleet_id}): {desc}")
            else:
                lines.append(f"  - {name} (ID: {fleet_id})")
        return "\n".join(lines)
    
    
    def _format_aircraft(aircraft: list[dict[str, Any]]) -> str:
        """Format aircraft list for display."""
        if not aircraft:
            return "No aircraft found."
    
        lines = [f"Found {len(aircraft)} aircraft:"]
        for a in aircraft:
            name = a.get("name", "Unknown")
            aircraft_id = a.get("id", "?")
            fleet_name = a.get("fleetName", "Unknown")
            lines.append(f"  - {name} (ID: {aircraft_id}) [Fleet: {fleet_name}]")
        return "\n".join(lines)
    
    
    def _format_flight_phases(phases: list[dict[str, Any]]) -> str:
        """Format flight phases list for display."""
        if not phases:
            return "No flight phases found."
    
        lines = [f"Found {len(phases)} flight phase(s):"]
        for p in phases:
            name = p.get("name", "Unknown")
            phase_id = p.get("id", "?")
            desc = p.get("description", "")
            if desc:
                lines.append(f"  - {name} (ID: {phase_id}): {desc}")
            else:
                lines.append(f"  - {name} (ID: {phase_id})")
        return "\n".join(lines)
    
    
    def _format_airports(airports: list[dict[str, Any]]) -> str:
        """Format airports list for display."""
        if not airports:
            return "No airports found."
    
        lines = [f"Found {len(airports)} airport(s):"]
        for a in airports:
            icao = a.get("codeIcao", "????")
            iata = a.get("codeIata")
            name = a.get("name", "Unknown")
            city = a.get("city", "")
            country = a.get("country", "")
    
            location = ", ".join(part for part in (city, country) if part)
            id_str = f" (ID: {a.get('id', '?')})"
    
            codes = f"{icao}/{iata}" if iata else icao
    
            line = f"  - {codes}: {name}"
            if location:
                line += f" [{location}]"
            line += id_str
            lines.append(line)
        return "\n".join(lines)
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states the tool 'gets' data (implying read-only) and returns a 'formatted list', but lacks critical details: whether it's paginated, rate-limited, requires specific permissions, or how errors are handled. For a tool with 3 parameters and no annotation coverage, this leaves significant gaps in understanding its behavior.

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

Conciseness4/5

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

The description is appropriately sized and front-loaded: the first sentence states the purpose clearly, followed by structured sections for Args and Returns. There's minimal waste, though the 'Args' section could be more integrated into the flow rather than a separate block.

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

Completeness3/5

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

Given the tool has 3 parameters, no annotations, and an output schema exists (which covers return values), the description is moderately complete. It explains the purpose and parameters to some extent but lacks behavioral context (e.g., error handling, performance) and usage guidance, making it adequate but with clear gaps for effective agent use.

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

Parameters3/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 some value by explaining ems_system_id comes from 'list_ems_systems', asset_type options (though the enum already lists them), and that fleet_id filters aircraft only for asset_type='aircraft'. However, it doesn't fully document all parameters (e.g., data types, constraints beyond the enum) or provide examples, leaving room for improvement.

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

Purpose4/5

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

The description clearly states the tool retrieves reference data for specific asset types (fleets, aircraft, airports, flight phases), using the verb 'Get' with the resource 'reference data'. However, it doesn't explicitly differentiate from sibling tools like 'list_ems_systems' or 'get_field_info', which might also retrieve reference data in different contexts.

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

Usage Guidelines2/5

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

The description provides minimal guidance: it mentions filtering aircraft by fleet ID only for asset_type='aircraft', but offers no explicit advice on when to use this tool versus alternatives like 'list_databases' or 'query_database'. There's no mention of prerequisites (e.g., needing an EMS system ID from list_ems_systems) or typical use cases.

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/mattsq/ems-mcp'

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