Skip to main content
Glama
xiaonieli7

Flight Ticket MCP Server

by xiaonieli7

getTransferFlightsByThreePlace

Find connecting flights between departure, transfer, and arrival airports with customizable layover time constraints for optimal travel planning.

Instructions

航班中转路线查询 - 根据出发地、中转地、目的地、最小转机时间、最大转机时间查询中转航班信息,最小转机时间默认为2小时,最大转机时间默认为5小时

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
from_placeNo北京
max_transfer_timeNo
min_transfer_timeNo
to_placeNo纽约
transfer_placeNo香港

Implementation Reference

  • Core handler function that implements the tool logic: resolves airport codes, fetches direct flights for each leg via scraping, computes valid transfers within time constraints, returns list of FlightTransfer objects.
    def getTransferFlightsByThreePlace(from_place: str, transfer_place: str, to_place: str,departure_date: str, min_transfer_time: float = 2.0, max_transfer_time: float = 5.0) -> List[FlightTransfer]: """ 查询从出发地通过中转地到目的地的联程航班信息。 Args: from_place (str): 出发地城市或机场 transfer_place (str): 中转地城市或机场 to_place (str): 目的地城市或机场 min_transfer_time (float): 最小中转时间(单位:小时),默认 2 小时 max_transfer_time (float): 最大中转时间(单位:小时),默认 5 小时 Returns: List[str]: 符合条件的航班列表,每个航班用字典表示。 """ logger.info(f"开始查询中转航班...") logger.info(f"始发地: {from_place},中转地:{transfer_place}, 目的地: {to_place}") try: # 获取所有城市的三字码 from_code = _get_location_codev2(from_place) transfer_code = _get_location_codev2(transfer_place) to_code = _get_location_codev2(to_place) logger.info(f"三字码查询成功!始发地: {from_code},中转地{transfer_code}, 目的地: {to_code}") # 获取两段行程列表 first_trips = _get_direct_airline(from_code, transfer_code) after_trips = _get_direct_airline(transfer_code, to_code) logger.info(f"行程分段查询成功! {from_place} - {transfer_place} {len(first_trips)}") logger.info(f"{transfer_place} - {to_place} {len(after_trips)}") # 计算换乘路线 select_trips = [] index=1 for trip1 in first_trips: arrival_time = trip1.schedule.arrival_time arrival_time = datetime.strptime(arrival_time, "%H:%M").time() arrival_time = datetime.combine(datetime.today(), arrival_time) for trip2 in after_trips: departure_time = trip2.schedule.departure_time departure_time = datetime.strptime(departure_time, "%H:%M").time() departure_time = datetime.combine(datetime.today(), departure_time) if (departure_time - arrival_time > timedelta(hours=min_transfer_time) and departure_time - arrival_time < timedelta(hours=max_transfer_time)): # 符合换乘时间要求,添加到结果列表 logger.info(f"符合换乘时间要求: {trip1.flight_number} {arrival_time} - {trip2.flight_number} {departure_time}") transfer=FlightTransfer( transfer_id=f"{index}", first_flight=trip1, second_flight=trip2, departure_date=departure_date, transfer_time=round((departure_time - arrival_time).total_seconds() / 3600,3) ) index += 1 logger.info(f"添加中转航班: {transfer.first_flight.flight_number} -> {transfer.second_flight.flight_number}, 中转时间: {transfer.transfer_time}小时") select_trips.append(transfer) logger.info(f"查询到 {len(select_trips)} 条中转航班信息") return select_trips except Exception as e: logger.warning(f"查询中转航班信息失败:{from_place}-{transfer_place}-{to_place}, 错误: {str(e)}", exc_info=True)
  • MCP tool registration using @mcp.tool() decorator. This is the entry point handler for the MCP server, which logs the call and delegates to the core implementation in flight_transfer_tools.
    @mcp.tool() def getTransferFlightsByThreePlace(from_place: str="北京", transfer_place: str="香港", to_place: str="纽约",min_transfer_time: float = 2.0, max_transfer_time: float = 5.0): """航班中转路线查询 - 根据出发地、中转地、目的地、最小转机时间、最大转机时间查询中转航班信息,最小转机时间默认为2小时,最大转机时间默认为5小时""" logger.debug(f"调用航班中转查询工具:: from_place={from_place}, transfer_place={transfer_place}, to_place={to_place}") logger.debug(f"最短换乘时间: min_transfer_time={from_place},默认2小时 最长换乘时间:max_transfer_time={max_transfer_time}, 默认5小时") return flight_transfer_tools.getTransferFlightsByThreePlace(from_place, transfer_place, to_place, min_transfer_time, max_transfer_time)
  • Helper function to resolve city name to IATA airport code by scraping chahangxian.com using Selenium.
    def _get_location_codev2(place: str) -> str: ''' 获取城市对应的机场三字码(IATA Code)。 Args: place (str): 城市名称,例如 "北京" Returns: Optional[str]: 对应的机场三字码,如 "PEK" 或 "PVG";如果找不到则返回 None。 ''' options = webdriver.ChromeOptions() options.add_argument('--headless') # 无头模式,不打开浏览器窗口 driver = webdriver.Chrome(options=options) try: url = 'https://www.chahangxian.com/' # 示例:百度汉语 # 打开网页 driver.get(url) time.sleep(2) # 输入一个字 search_box = driver.find_element(By.CLASS_NAME, "search") # 百度汉语的输入框ID是kw input_box = search_box.find_element(By.NAME, "keyword") # 百度汉语的输入框ID是kw input_box.clear() input_box.send_keys(place) input_box.send_keys(Keys.ENTER) time.sleep(2) return driver.current_url.split("/")[-2] except Exception as e: logger.warning(f"查询{place}城市三字码错误" + str(e)) finally: driver.close()
  • Helper function to fetch direct flights between two IATA codes by scraping chahangxian.com, parsing flight details into Flight objects.
    def _get_direct_airline(from_code: str, to_code: str) -> list: ''' :param from_code: :param to_code: :return: ''' options = webdriver.ChromeOptions() options.add_argument('--headless') # 无头模式,不打开浏览器窗口 driver = webdriver.Chrome(options=options) try: url = f"https://www.chahangxian.com/{from_code.lower()}-{to_code.lower()}/" driver.get(url) time.sleep(1) tabs = driver.find_elements(By.CLASS_NAME, "J_link") # 修改为你目标网站的内容类名 if len(tabs) == 0: logger.warning(f"航班为空 {from_code}-{to_code}") else: result = [] index=1 for tab in tabs: transfer = tab.find_elements(By.CLASS_NAME, "transfer") if len(transfer) == 0: box = tab.find_element(By.CLASS_NAME, "airline-box") img = box.find_element(By.TAG_NAME, 'img') airline = img.get_attribute('alt') message = tab.text.splitlines() schedule = FlightSchedule( departure_time=message[3], arrival_time=message[7], duration="", timezone="" ) mPrice = message[13].split(" ")[1].split("~") price = FlightPrice( economy=float(mPrice[0]), business=float(mPrice[-1]), first=0, ) flight = Flight( flight_id=f"{index}", flight_number=message[0], airline=airline, aircraft=message[1], origin=message[4], destination=message[8], schedule=schedule, price=price, seat_config=SeatConfiguration(), services={}, ) index += 1 result.append(flight) if len(result) == 0: logger.warning("没有直飞,建议转机") else: # print(len(result), result) return result except Exception as e: logger.warning(f"直飞查询失败 {from_code}-{to_code}" + str(e)) finally: driver.close()

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/xiaonieli7/FlightTicketMCP'

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