Skip to main content
Glama

fuel_reserve_calculator

Calculate required fuel reserves per FAR, JAR-OPS, or ICAO regulations. Get contingency, alternate, and final reserve components from trip fuel, flight time, and holding altitude.

Instructions

Calculate required fuel reserves per aviation regulations.

Args: regulation: Regulatory framework - "FAR_91", "FAR_121", "JAR_OPS", or "ICAO" trip_fuel_kg: Planned trip fuel in kg cruise_fuel_flow_kg_hr: Cruise fuel flow rate in kg/hr flight_time_min: Planned flight time in minutes alternate_fuel_kg: Fuel to fly to alternate airport in kg holding_altitude_ft: Expected holding altitude for reserve calculations

Returns: Formatted string with fuel reserve breakdown per the selected regulation, including contingency, alternate, and final reserve components.

Raises: No exceptions are raised directly; errors are returned as formatted strings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
regulationYes
trip_fuel_kgYes
cruise_fuel_flow_kg_hrYes
flight_time_minYes
alternate_fuel_kgNo
holding_altitude_ftNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for fuel_reserve_calculator. Calculates required fuel reserves per FAR 91, FAR 121, JAR-OPS, and ICAO regulations. Takes regulation type, trip fuel, cruise fuel flow, flight time, alternate fuel, and holding altitude as parameters. Returns a formatted string with fuel reserve breakdown including contingency, alternate, and final reserve components.
    def fuel_reserve_calculator(
        regulation: Literal["FAR_91", "FAR_121", "JAR_OPS", "ICAO"],
        trip_fuel_kg: float,
        cruise_fuel_flow_kg_hr: float,
        flight_time_min: float,
        alternate_fuel_kg: float = 0,
        holding_altitude_ft: float = 1500,
    ) -> str:
        """Calculate required fuel reserves per aviation regulations.
    
        Args:
            regulation: Regulatory framework - "FAR_91", "FAR_121", "JAR_OPS", or "ICAO"
            trip_fuel_kg: Planned trip fuel in kg
            cruise_fuel_flow_kg_hr: Cruise fuel flow rate in kg/hr
            flight_time_min: Planned flight time in minutes
            alternate_fuel_kg: Fuel to fly to alternate airport in kg
            holding_altitude_ft: Expected holding altitude for reserve calculations
    
        Returns:
            Formatted string with fuel reserve breakdown per the selected regulation,
            including contingency, alternate, and final reserve components.
    
        Raises:
            No exceptions are raised directly; errors are returned as formatted strings.
        """
        try:
            reserves = {}
            notes = []
    
            if regulation == "FAR_91":
                # FAR 91.151 - VFR: 30 min day, 45 min night
                # FAR 91.167 - IFR: 45 min at normal cruise
                reserves["final_reserve_kg"] = cruise_fuel_flow_kg_hr * (45 / 60)
                reserves["contingency_kg"] = 0  # Not required under Part 91
                reserves["alternate_kg"] = alternate_fuel_kg
                notes.append("FAR 91.167: 45 min fuel at normal cruise")
    
            elif regulation == "FAR_121":
                # FAR 121.639 - Domestic: 45 min at normal cruise
                # Plus alternate fuel if required
                # Plus 10% contingency
                reserves["contingency_kg"] = trip_fuel_kg * 0.10
                reserves["alternate_kg"] = alternate_fuel_kg
                reserves["final_reserve_kg"] = cruise_fuel_flow_kg_hr * (45 / 60)
                notes.append("FAR 121.639: 10% contingency + 45 min reserve")
    
            elif regulation == "JAR_OPS":
                # JAR-OPS 1.255
                # 5% trip fuel contingency (or 5 min @ holding)
                # Alternate fuel
                # 30 min final reserve at 1500 ft over alternate
                holding_fuel_flow = cruise_fuel_flow_kg_hr * 0.8  # Lower at holding
                reserves["contingency_kg"] = max(
                    trip_fuel_kg * 0.05, holding_fuel_flow * (5 / 60)
                )
                reserves["alternate_kg"] = alternate_fuel_kg
                reserves["final_reserve_kg"] = holding_fuel_flow * (30 / 60)
                notes.append("JAR-OPS: 5% contingency + 30 min final reserve")
    
            elif regulation == "ICAO":
                # ICAO Annex 6
                # 5% trip fuel or 5 min at holding
                # Alternate fuel
                # 30 min final reserve at 1500 ft
                holding_fuel_flow = cruise_fuel_flow_kg_hr * 0.8
                reserves["contingency_kg"] = max(
                    trip_fuel_kg * 0.05, holding_fuel_flow * (5 / 60)
                )
                reserves["alternate_kg"] = alternate_fuel_kg
                reserves["final_reserve_kg"] = holding_fuel_flow * (30 / 60)
                notes.append("ICAO Annex 6: 5% contingency + 30 min final reserve")
    
            else:
                return f"Error: Unknown regulation '{regulation}'"
    
            # Calculate totals
            total_reserves = sum(reserves.values())
            total_fuel = trip_fuel_kg + total_reserves
    
            # Extra fuel recommendation
            extra_fuel_recommended = trip_fuel_kg * 0.05  # Additional 5% margin
    
            result = {
                "regulation": regulation,
                "trip_fuel_kg": round(trip_fuel_kg, 1),
                "reserves": {k: round(v, 1) for k, v in reserves.items()},
                "total_reserves_kg": round(total_reserves, 1),
                "total_required_fuel_kg": round(total_fuel, 1),
                "extra_fuel_recommended_kg": round(extra_fuel_recommended, 1),
                "total_with_extra_kg": round(total_fuel + extra_fuel_recommended, 1),
                "flight_time_min": flight_time_min,
                "cruise_fuel_flow_kg_hr": cruise_fuel_flow_kg_hr,
                "holding_altitude_ft": holding_altitude_ft,
                "notes": notes,
            }
    
            # Format reserve breakdown
            reserve_lines = [
                f"  {k.replace('_', ' ').title()}: {v:>8.1f} kg"
                for k, v in reserves.items()
            ]
            reserve_str = "\n".join(reserve_lines)
    
            output = f"""
    FUEL RESERVE CALCULATION
    ========================
    Regulation: {regulation}
    Flight Time: {flight_time_min:.0f} min
    Cruise Fuel Flow: {cruise_fuel_flow_kg_hr:.1f} kg/hr
    
    Fuel Breakdown:
      Trip Fuel:             {trip_fuel_kg:>8.1f} kg
    
    Reserves:
    {reserve_str}
      ─────────────────────────────────
      Total Reserves:        {total_reserves:>8.1f} kg
    
    TOTAL REQUIRED:          {total_fuel:>8.1f} kg
    
    Recommended Extra:       {extra_fuel_recommended:>8.1f} kg
    Total with Extra:        {total_fuel + extra_fuel_recommended:>8.1f} kg
    
    Notes:
      • {chr(10) + "  • ".join(notes)}
    
    {json.dumps(result, indent=2)}
    """
            return output.strip()
    
        except Exception as e:
            logger.error(f"Fuel reserve calculation error: {str(e)}", exc_info=True)
            return f"Error calculating fuel reserves: {str(e)}"
  • Type signature for fuel_reserve_calculator. Uses Literal type for regulation (FAR_91, FAR_121, JAR_OPS, ICAO) with typed float parameters for trip_fuel_kg, cruise_fuel_flow_kg_hr, flight_time_min, alternate_fuel_kg (default 0), and holding_altitude_ft (default 1500).
    def fuel_reserve_calculator(
        regulation: Literal["FAR_91", "FAR_121", "JAR_OPS", "ICAO"],
        trip_fuel_kg: float,
        cruise_fuel_flow_kg_hr: float,
        flight_time_min: float,
        alternate_fuel_kg: float = 0,
        holding_altitude_ft: float = 1500,
    ) -> str:
  • ToolMetadata entry in the TOOL_REGISTRY for fuel_reserve_calculator. Describes the tool for the search/discovery system with the category 'performance', parameter descriptions, and keywords.
    ToolMetadata(
        name="fuel_reserve_calculator",
        description="Calculate required fuel reserves per aviation regulations (FAR/JAR/ICAO)",
        category="performance",
        parameters={
            "regulation": "Regulatory framework: FAR_91, FAR_121, JAR_OPS, or ICAO",
            "trip_fuel_kg": "Planned trip fuel in kg",
            "cruise_fuel_flow_kg_hr": "Cruise fuel flow rate in kg/hr",
            "flight_time_min": "Planned flight time in minutes",
            "alternate_fuel_kg": "Fuel to fly to alternate airport in kg",
        },
        keywords=[
            "fuel",
            "reserve",
            "contingency",
            "far",
            "jar",
            "icao",
            "regulation",
            "planning",
        ],
    ),
  • Registration in the FastMCP server: imported from .tools.performance (line 122) and registered via mcp.tool(fuel_reserve_calculator) (line 236).
    from .tools.performance import (
        density_altitude_calculator,
        fuel_reserve_calculator,
        landing_performance,
        stall_speed_calculator,
        takeoff_performance,
        true_airspeed_converter,
        weight_and_balance,
    )
    
    # --- Propellers & UAVs: BEMT analysis, energy estimation ---
    from .tools.propellers import (
        get_propeller_database,
        propeller_bemt_analysis,
        uav_energy_estimate,
    )
    
    # --- Rockets: 3-DOF trajectories, sizing, launch optimization ---
    from .tools.rockets import (
        estimate_rocket_sizing,
        optimize_launch_angle,
        rocket_3dof_trajectory,
    )
    
    # --- Tool Discovery: search and categorize available aerospace tools ---
    from .tools.tool_search import (
        list_tool_categories,
        search_aerospace_tools,
    )
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    # Initialize FastMCP server
    mcp = FastMCP("aerospace-mcp")
    
    # =============================================================================
    # TOOL REGISTRATION
    # =============================================================================
    # aerospace-mcp supports deferred tool loading for efficient context usage.
    # When using with Anthropic's API, configure the mcp_toolset like this:
    #
    #   {
    #     "type": "mcp_toolset",
    #     "mcp_server_name": "aerospace-mcp",
    #     "default_config": {"defer_loading": true},
    #     "configs": {
    #       "search_aerospace_tools": {"defer_loading": false},
    #       "list_tool_categories": {"defer_loading": false}
    #     }
    #   }
    #
    # This loads only the discovery tools initially. Claude uses search_aerospace_tools
    # to find relevant tools, which returns tool_reference blocks that the API
    # automatically expands into full tool definitions.
    # =============================================================================
    
    # --- DISCOVERY TOOLS (should NOT be deferred) ---
    # These tools enable Claude to discover other tools dynamically
    mcp.tool(search_aerospace_tools)
    mcp.tool(list_tool_categories)
    
    # --- DISCOVERABLE TOOLS (can be deferred for context efficiency) ---
    # Core flight planning tools
    mcp.tool(search_airports)
    mcp.tool(plan_flight)
    mcp.tool(calculate_distance)
    mcp.tool(get_aircraft_performance)
    mcp.tool(get_system_status)
    
    # Atmospheric tools
    mcp.tool(get_atmosphere_profile)
    mcp.tool(wind_model_simple)
    
    # Coordinate frame tools
    mcp.tool(transform_frames)
    mcp.tool(geodetic_to_ecef)
    mcp.tool(ecef_to_geodetic)
    
    # Aerodynamics tools
    mcp.tool(wing_vlm_analysis)
    mcp.tool(airfoil_polar_analysis)
    mcp.tool(calculate_stability_derivatives)
    mcp.tool(get_airfoil_database)
    
    # Propeller/UAV tools
    mcp.tool(propeller_bemt_analysis)
    mcp.tool(uav_energy_estimate)
    mcp.tool(get_propeller_database)
    
    # Rocket tools
    mcp.tool(rocket_3dof_trajectory)
    mcp.tool(estimate_rocket_sizing)
    mcp.tool(optimize_launch_angle)
    
    # Orbital mechanics tools
    mcp.tool(elements_to_state_vector)
    mcp.tool(state_vector_to_elements)
    mcp.tool(propagate_orbit_j2)
    mcp.tool(calculate_ground_track)
    mcp.tool(hohmann_transfer)
    mcp.tool(orbital_rendezvous_planning)
    mcp.tool(lambert_problem_solver)
    
    # GNC tools
    mcp.tool(kalman_filter_state_estimation)
    mcp.tool(lqr_controller_design)
    
    # Performance tools
    mcp.tool(density_altitude_calculator)
    mcp.tool(true_airspeed_converter)
    mcp.tool(stall_speed_calculator)
    mcp.tool(weight_and_balance)
    mcp.tool(takeoff_performance)
    mcp.tool(landing_performance)
    mcp.tool(fuel_reserve_calculator)
  • CLI registration: imported from .tools.performance (line 82) and mapped in TOOL_MAP under key 'fuel_reserve_calculator' (line 155) for CLI-based invocation.
    from .tools.performance import (
        density_altitude_calculator,
        fuel_reserve_calculator,
        landing_performance,
        stall_speed_calculator,
        takeoff_performance,
        true_airspeed_converter,
        weight_and_balance,
    )
    from .tools.propellers import (
        get_propeller_database,
        propeller_bemt_analysis,
        uav_energy_estimate,
    )
    from .tools.rockets import (
        estimate_rocket_sizing,
        optimize_launch_angle,
        rocket_3dof_trajectory,
    )
    from .tools.tool_search import (
        CATEGORIES,
        TOOL_REGISTRY,
        list_tool_categories,
        search_aerospace_tools,
    )
    
    # Complete mapping of tool name -> callable for all 44 tools
    TOOL_MAP: dict[str, Callable[..., str]] = {
        # Discovery
        "search_aerospace_tools": search_aerospace_tools,
        "list_tool_categories": list_tool_categories,
        # Core
        "search_airports": search_airports,
        "plan_flight": plan_flight,
        "calculate_distance": calculate_distance,
        "get_aircraft_performance": get_aircraft_performance,
        "get_system_status": get_system_status,
        # Atmosphere
        "get_atmosphere_profile": get_atmosphere_profile,
        "wind_model_simple": wind_model_simple,
        # Frames
        "transform_frames": transform_frames,
        "geodetic_to_ecef": geodetic_to_ecef,
        "ecef_to_geodetic": ecef_to_geodetic,
        # Aerodynamics
        "wing_vlm_analysis": wing_vlm_analysis,
        "airfoil_polar_analysis": airfoil_polar_analysis,
        "calculate_stability_derivatives": calculate_stability_derivatives,
        "get_airfoil_database": get_airfoil_database,
        # Propellers
        "propeller_bemt_analysis": propeller_bemt_analysis,
        "uav_energy_estimate": uav_energy_estimate,
        "get_propeller_database": get_propeller_database,
        # Rockets
        "rocket_3dof_trajectory": rocket_3dof_trajectory,
        "estimate_rocket_sizing": estimate_rocket_sizing,
        "optimize_launch_angle": optimize_launch_angle,
        # Orbits
        "elements_to_state_vector": elements_to_state_vector,
        "state_vector_to_elements": state_vector_to_elements,
        "propagate_orbit_j2": propagate_orbit_j2,
        "calculate_ground_track": calculate_ground_track,
        "hohmann_transfer": hohmann_transfer,
        "orbital_rendezvous_planning": orbital_rendezvous_planning,
        "lambert_problem_solver": lambert_problem_solver,
        # GNC
        "kalman_filter_state_estimation": kalman_filter_state_estimation,
        "lqr_controller_design": lqr_controller_design,
        # Performance
        "density_altitude_calculator": density_altitude_calculator,
        "true_airspeed_converter": true_airspeed_converter,
        "stall_speed_calculator": stall_speed_calculator,
        "weight_and_balance": weight_and_balance,
        "takeoff_performance": takeoff_performance,
        "landing_performance": landing_performance,
        "fuel_reserve_calculator": fuel_reserve_calculator,
Behavior4/5

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

No annotations are provided, so the description carries full burden. It discloses return format (formatted string with components) and error handling (errors returned as formatted strings). For a read-only calculator, this is transparent, though no explicit statement about side effects.

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 a well-structured docstring with purpose, args, returns, and raises. It is concise with no unnecessary information, and the purpose is front-loaded.

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?

The description covers inputs, outputs, and error handling. With 6 parameters and an output schema (not visible but indicated), it is largely complete. However, specifics on how each regulation affects calculations could enhance completeness.

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 has 0% description coverage, but the description includes an Args section with brief explanations for all parameters (e.g., 'trip_fuel_kg: Planned trip fuel in kg'). This adds meaning beyond the schema titles.

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 'Calculate required fuel reserves per aviation regulations.' This provides a specific verb and resource, and the tool is distinct from siblings which are other aerospace calculations.

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

Usage Guidelines3/5

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

The description gives a clear context (aviation regulations) but does not provide explicit guidance on when to use this tool vs alternatives. Usage is implied but no exclusions or alternative tools are mentioned.

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/cheesejaguar/aerospace-mcp'

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