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
| Name | Required | Description | Default |
|---|---|---|---|
| regulation | Yes | ||
| trip_fuel_kg | Yes | ||
| cruise_fuel_flow_kg_hr | Yes | ||
| flight_time_min | Yes | ||
| alternate_fuel_kg | No | ||
| holding_altitude_ft | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
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", ], ), - aerospace_mcp/fastmcp_server.py:120-236 (registration)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) - aerospace_mcp/cli.py:80-155 (registration)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,