Skip to main content
Glama

search_flights

Search for available flights between two cities. Specify departure date, optional return date, and passenger count.

Instructions

Search for available flights between two cities.

Args: origin: Departure city name or airport code (e.g. "New York" or "JFK") destination: Arrival city name or airport code (e.g. "Tokyo" or "NRT") departure_date: Departure date in YYYY-MM-DD format return_date: Return date for round trips in YYYY-MM-DD format (omit for one-way) passengers: Number of passengers (default: 1)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
originYes
destinationYes
departure_dateYes
return_dateNo
passengersNo

Implementation Reference

  • The MCP tool handler for search_flights, decorated with @mcp.tool(). It delegates to flights.search().
    @mcp.tool()
    def search_flights(
        origin: str,
        destination: str,
        departure_date: str,
        return_date: Optional[str] = None,
        passengers: int = 1,
    ) -> list:
        """
        Search for available flights between two cities.
    
        Args:
            origin: Departure city name or airport code (e.g. "New York" or "JFK")
            destination: Arrival city name or airport code (e.g. "Tokyo" or "NRT")
            departure_date: Departure date in YYYY-MM-DD format
            return_date: Return date for round trips in YYYY-MM-DD format (omit for one-way)
            passengers: Number of passengers (default: 1)
        """
        return flights.search(origin, destination, departure_date, return_date, passengers)
  • The @mcp.tool() decorator registers search_flights as an MCP tool.
    @mcp.tool()
    def search_flights(
        origin: str,
        destination: str,
        departure_date: str,
        return_date: Optional[str] = None,
        passengers: int = 1,
    ) -> list:
        """
        Search for available flights between two cities.
    
        Args:
            origin: Departure city name or airport code (e.g. "New York" or "JFK")
            destination: Arrival city name or airport code (e.g. "Tokyo" or "NRT")
            departure_date: Departure date in YYYY-MM-DD format
            return_date: Return date for round trips in YYYY-MM-DD format (omit for one-way)
            passengers: Number of passengers (default: 1)
        """
        return flights.search(origin, destination, departure_date, return_date, passengers)
  • Custom HTTP route registration for POST /api/tools/search_flights as an alternative REST endpoint.
    @mcp.custom_route("/api/tools/search_flights", methods=["POST"])
    async def api_search_flights(request: Request) -> JSONResponse:
        body = await request.json()
        result = flights.search(
            body["origin"], body["destination"], body["departure_date"],
            body.get("return_date"), body.get("passengers", 1),
        )
        return JSONResponse(result)
  • The flights.search() helper function that queries mock data and returns results or a not-found message.
    def search(
        origin: str,
        destination: str,
        departure_date: str,
        return_date: str | None,
        passengers: int,
    ) -> list[dict]:
        results = query_flights(origin, destination, departure_date, return_date, passengers)
        if not results:
            return [{"message": f"No flights found from '{origin}' to '{destination}'. Try major city names or airport codes (e.g. 'New York', 'JFK')."}]
        return results
  • Mock data schema (_ROUTES) and the query_flights function containing the matching and pricing logic.
    _ROUTES = [
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "Tokyo", "destination_code": "NRT",
            "options": [
                {"airline": "ANA", "flight": "NH010", "duration": 14.0, "stops": 0, "price": 850},
                {"airline": "JAL", "flight": "JL004", "duration": 13.5, "stops": 0, "price": 920},
                {"airline": "Delta", "flight": "DL169", "duration": 15.5, "stops": 1, "price": 680},
                {"airline": "United", "flight": "UA837", "duration": 16.0, "stops": 1, "price": 620},
            ],
        },
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "Paris", "destination_code": "CDG",
            "options": [
                {"airline": "Air France", "flight": "AF011", "duration": 7.5, "stops": 0, "price": 520},
                {"airline": "Delta", "flight": "DL263", "duration": 7.5, "stops": 0, "price": 490},
                {"airline": "United", "flight": "UA57", "duration": 8.5, "stops": 1, "price": 380},
                {"airline": "Norse Atlantic", "flight": "N0701", "duration": 8.0, "stops": 0, "price": 310},
            ],
        },
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "London", "destination_code": "LHR",
            "options": [
                {"airline": "British Airways", "flight": "BA178", "duration": 7.0, "stops": 0, "price": 480},
                {"airline": "American", "flight": "AA100", "duration": 7.0, "stops": 0, "price": 460},
                {"airline": "Virgin Atlantic", "flight": "VS004", "duration": 7.0, "stops": 0, "price": 445},
                {"airline": "Norse Atlantic", "flight": "N0001", "duration": 7.5, "stops": 0, "price": 290},
            ],
        },
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "Barcelona", "destination_code": "BCN",
            "options": [
                {"airline": "Iberia", "flight": "IB6251", "duration": 8.0, "stops": 0, "price": 510},
                {"airline": "Level", "flight": "IB2671", "duration": 8.5, "stops": 0, "price": 350},
                {"airline": "American", "flight": "AA068", "duration": 9.5, "stops": 1, "price": 430},
            ],
        },
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "Sydney", "destination_code": "SYD",
            "options": [
                {"airline": "Qantas", "flight": "QF12", "duration": 21.5, "stops": 1, "price": 1250},
                {"airline": "United", "flight": "UA870", "duration": 22.0, "stops": 1, "price": 1100},
                {"airline": "Air New Zealand", "flight": "NZ6", "duration": 23.0, "stops": 1, "price": 1050},
            ],
        },
        {
            "origin": "New York", "origin_code": "JFK",
            "destination": "Bali", "destination_code": "DPS",
            "options": [
                {"airline": "Singapore Airlines", "flight": "SQ026", "duration": 22.0, "stops": 1, "price": 1100},
                {"airline": "Cathay Pacific", "flight": "CX830", "duration": 23.5, "stops": 1, "price": 980},
                {"airline": "Qatar Airways", "flight": "QR706", "duration": 24.0, "stops": 1, "price": 950},
            ],
        },
        {
            "origin": "London", "origin_code": "LHR",
            "destination": "Paris", "destination_code": "CDG",
            "options": [
                {"airline": "Air France", "flight": "AF1681", "duration": 1.5, "stops": 0, "price": 120},
                {"airline": "British Airways", "flight": "BA308", "duration": 1.5, "stops": 0, "price": 135},
                {"airline": "EasyJet", "flight": "EZY8872", "duration": 1.5, "stops": 0, "price": 65},
            ],
        },
        {
            "origin": "London", "origin_code": "LHR",
            "destination": "Barcelona", "destination_code": "BCN",
            "options": [
                {"airline": "Vueling", "flight": "VY7822", "duration": 2.5, "stops": 0, "price": 95},
                {"airline": "British Airways", "flight": "BA482", "duration": 2.5, "stops": 0, "price": 145},
                {"airline": "Ryanair", "flight": "FR4476", "duration": 2.5, "stops": 0, "price": 55},
            ],
        },
        {
            "origin": "Sydney", "origin_code": "SYD",
            "destination": "Bali", "destination_code": "DPS",
            "options": [
                {"airline": "Jetstar", "flight": "JQ37", "duration": 6.0, "stops": 0, "price": 220},
                {"airline": "Qantas", "flight": "QF43", "duration": 6.0, "stops": 0, "price": 310},
                {"airline": "Air Asia", "flight": "D7237", "duration": 8.5, "stops": 1, "price": 180},
            ],
        },
        {
            "origin": "Paris", "origin_code": "CDG",
            "destination": "Rome", "destination_code": "FCO",
            "options": [
                {"airline": "Air France", "flight": "AF1010", "duration": 2.0, "stops": 0, "price": 110},
                {"airline": "Alitalia", "flight": "AZ319", "duration": 2.0, "stops": 0, "price": 130},
                {"airline": "EasyJet", "flight": "EZY6920", "duration": 2.0, "stops": 0, "price": 75},
            ],
        },
    ]
    
    
    def _matches(query: str, city: str, code: str) -> bool:
        q = query.strip().lower()
        return q in city.lower() or q == code.lower()
    
    
    def query_flights(
        origin: str,
        destination: str,
        departure_date: str,
        return_date: str | None,
        passengers: int,
    ) -> list[dict]:
        results = []
        for route in _ROUTES:
            orig_match = _matches(origin, route["origin"], route["origin_code"])
            dest_match = _matches(destination, route["destination"], route["destination_code"])
            if not (orig_match and dest_match):
                # Also try reverse (for flexibility, but mark as reverse)
                continue
            for opt in route["options"]:
                outbound_price = opt["price"] * passengers
                total = outbound_price * (2 if return_date else 1)
                results.append({
                    "airline": opt["airline"],
                    "flight_number": opt["flight"],
                    "origin": f"{route['origin']} ({route['origin_code']})",
                    "destination": f"{route['destination']} ({route['destination_code']})",
                    "departure_date": departure_date,
                    "return_date": return_date,
                    "duration": f"{opt['duration']:.1f}h",
                    "stops": opt["stops"],
                    "trip_type": "round-trip" if return_date else "one-way",
                    "price_per_person": opt["price"],
                    "total_price": total,
                    "currency": "USD",
                })
        return sorted(results, key=lambda x: x["total_price"])
Behavior3/5

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

No annotations provided, so the description carries the full burden. It indicates 'Search' implying read-only, but does not disclose other behaviors like rate limits, authentication, pagination, or sorting. Adequate but lacks depth.

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?

Brief and structured with a main sentence and clear parameter descriptions. No unnecessary information; every line adds value. Front-loaded with the tool's purpose.

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

Completeness2/5

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

Lacks any description of the output or return value. Since no output schema exists, the agent has no idea what the response contains (e.g., flight details, pricing). Incomplete for a search tool with siblings that may have similar outputs.

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

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description adds crucial context: examples for origin/destination, date format YYYY-MM-DD, default passengers=1, and conditional return_date. This significantly compensates for the schema gap.

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 'Search for available flights between two cities.' It specifies the verb (search), resource (flights), and scope (origin and destination), which distinguishes it from sibling tools like search_hotels or search_poi.

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?

No guidance on when to use this tool versus alternatives (e.g., plan_trip, search_hotels). It does not mention prerequisites or exclusion criteria, leaving the agent to infer usage from the name and parameters alone.

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/ismailrz/travel-mcp-server'

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