plan_flight
Generate optimized flight routes between two airports with performance estimates, including aircraft type, cruise altitude, and mass. Input departure and arrival details to calculate efficient flight plans.
Instructions
Plan a flight route between two airports with performance estimates
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| aircraft | Yes | ||
| arrival | Yes | ||
| departure | Yes | ||
| route_options | No |
Implementation Reference
- aerospace_mcp/tools/core.py:79-215 (handler)The plan_flight function implements the core logic of the tool: it processes departure and arrival dictionaries, constructs a PlanRequest, resolves airports, calculates the great circle route, and optionally computes performance estimates using OpenAP before returning a formatted JSON response.def plan_flight( departure: dict, arrival: dict, aircraft: dict | None = None, route_options: dict | None = None, ) -> str: """Plan a flight route between two airports with performance estimates. Args: departure: Dict with departure info (city, country, iata) arrival: Dict with arrival info (city, country, iata) aircraft: Optional aircraft config (ac_type, cruise_alt_ft, route_step_km) route_options: Optional route options Returns: JSON string with flight plan details """ try: # Build request object request_data = { "depart_city": departure["city"], "arrive_city": arrival["city"], } # Add optional fields if departure.get("country"): request_data["depart_country"] = departure["country"] if arrival.get("country"): request_data["arrive_country"] = arrival["country"] if departure.get("iata"): request_data["prefer_depart_iata"] = departure["iata"] if arrival.get("iata"): request_data["prefer_arrive_iata"] = arrival["iata"] # Add aircraft options (ac_type is required by PlanRequest) if aircraft and aircraft.get("ac_type"): request_data["ac_type"] = aircraft["ac_type"] if aircraft.get("cruise_alt_ft"): request_data["cruise_alt_ft"] = aircraft["cruise_alt_ft"] if aircraft.get("route_step_km"): request_data["route_step_km"] = aircraft["route_step_km"] else: # Use a default aircraft type if none provided request_data["ac_type"] = "A320" # Default aircraft type # Create and validate request try: request = PlanRequest(**request_data) except Exception as e: return f"Invalid request: {str(e)}" # Resolve airports try: depart_airport = _resolve_endpoint( request.depart_city, request.depart_country, request.prefer_depart_iata ) arrive_airport = _resolve_endpoint( request.arrive_city, request.arrive_country, request.prefer_arrive_iata ) except AirportResolutionError as e: return f"Airport resolution error: {str(e)}" # Calculate route route_points = great_circle_points( depart_airport.lat, depart_airport.lon, arrive_airport.lat, arrive_airport.lon, step_km=request.route_step_km, ) # Build response response = { "departure": { "airport": { "iata": depart_airport.iata, "icao": depart_airport.icao, "name": depart_airport.name, "city": depart_airport.city, "country": depart_airport.country, "coordinates": { "lat": depart_airport.lat, "lon": depart_airport.lon, }, } }, "arrival": { "airport": { "iata": arrive_airport.iata, "icao": arrive_airport.icao, "name": arrive_airport.name, "city": arrive_airport.city, "country": arrive_airport.country, "coordinates": { "lat": arrive_airport.lat, "lon": arrive_airport.lon, }, } }, "route": { "distance_km": route_points["distance_km"], "distance_nm": route_points["distance_nm"], "initial_bearing_deg": route_points["initial_bearing_deg"], "final_bearing_deg": route_points["final_bearing_deg"], "points": [ {"lat": p[0], "lon": p[1], "distance_km": p[2]} for p in route_points["points"] ], }, } # Add performance estimates if available if request.ac_type and OPENAP_AVAILABLE: try: performance, engine_name = estimates_openap( request.ac_type, request.cruise_alt_ft, request.mass_kg, route_points["distance_km"], ) response["performance"] = performance response["engine"] = engine_name except OpenAPError as e: response["performance_note"] = ( f"Performance estimation failed: {str(e)}" ) elif request.ac_type: response["performance_note"] = ( f"OpenAP not available - no performance estimates for {request.ac_type}" ) return json.dumps(response, indent=2) except Exception as e: logger.error(f"Flight planning error: {str(e)}", exc_info=True) return f"Flight planning error: {str(e)}"
- aerospace_mcp/fastmcp_server.py:85-85 (registration)Registers the plan_flight tool function with the FastMCP server instance.mcp.tool(plan_flight)
- aerospace_mcp/core.py:37-64 (schema)Pydantic BaseModel PlanRequest defines the structured input schema for the flight planning tool, including fields for departure/arrival locations, aircraft type, and performance parameters. Used for validation in the handler.class PlanRequest(BaseModel): # You can pass cities, or override with explicit IATA depart_city: str = Field(..., description="e.g., 'San Jose'") arrive_city: str = Field(..., description="e.g., 'Tokyo'") depart_country: str | None = Field( None, description="ISO alpha-2 country code (optional)" ) arrive_country: str | None = Field( None, description="ISO alpha-2 country code (optional)" ) prefer_depart_iata: str | None = Field( None, description="Force a particular departure airport by IATA" ) prefer_arrive_iata: str | None = Field( None, description="Force a particular arrival airport by IATA" ) # Aircraft/performance knobs ac_type: str = Field(..., description="ICAO aircraft type (e.g., 'A320', 'B738')") cruise_alt_ft: int = Field(35000, ge=8000, le=45000) mass_kg: float | None = Field( None, description="If not set, defaults to 85% MTOW when available" ) route_step_km: float = Field( 25.0, gt=1.0, description="Sampling step for polyline points" ) backend: Literal["openap"] = "openap" # Placeholder for future backends