Skip to main content
Glama

Bing Flights MCP Server

PyPI version Python 3.10+ License: MIT

A Model Context Protocol (MCP) server that scrapes flight information from Bing Flights using Playwright. This project provides both a standalone Python scraper module and an MCP server wrapper for integration with MCP-compatible applications.

šŸ“¦ View on PyPI

Features

  • šŸ” Search for one-way and round-trip flights

  • āœˆļø Support for multiple passengers (adults, children, infants)

  • šŸ’ŗ All cabin classes (Economy, Premium Economy, Business, First)

  • šŸ¤– Headless or headed browser modes

  • šŸ“Š Structured JSON responses

  • šŸ”§ Easy integration via MCP protocol

Related MCP server: fli

Project Structure

bing-flights-mcp/
ā”œā”€ā”€ pyproject.toml             # Package configuration
ā”œā”€ā”€ requirements.txt           # Python dependencies
ā”œā”€ā”€ README.md                  # This file
ā”œā”€ā”€ bing_flights_scraper/      # Standalone scraper module
│   ā”œā”€ā”€ __init__.py
│   └── scraper.py
ā”œā”€ā”€ mcp_server.py              # MCP server implementation
└── tests/                     # Test suite
    ā”œā”€ā”€ __init__.py
    ā”œā”€ā”€ test_mcp.py
    └── test_e2e.py

Installation

The easiest way to use this MCP server is with uvx:

uvx bing-flights-mcp

This will automatically install the package and its dependencies in an isolated environment.

Installation via pip

You can also install from PyPI:

pip install bing-flights-mcp

After installation, install the Playwright browser:

playwright install chromium

Development Installation

For development or if you want to modify the code:

  1. Clone or download this repository

  2. Create and activate a virtual environment

    On Windows:

    python -m venv venv
    venv\Scripts\activate

    On macOS/Linux:

    python -m venv venv
    source venv/bin/activate
  3. Install dependencies

    pip install -r requirements.txt
  4. Install Playwright browsers

    playwright install chromium

Usage

As an MCP Server

If you installed via PyPI, run:

uvx bing-flights-mcp

Or add to your MCP settings configuration:

{
  "mcpServers": {
    "bing-flights": {
      "command": "uvx",
      "args": ["bing-flights-mcp"]
    }
  }
}

Running from Source

If you're developing or running from source:

python mcp_server.py

Available Tools

The MCP server exposes two tools:

1. search_flights

Search for flight options from Bing Flights.

Parameters:

  • origin (string, required): Origin airport code (e.g., "SEA")

  • destination (string, required): Destination airport code (e.g., "ICN")

  • departure_date (string, required): Departure date in YYYY-MM-DD format

  • return_date (string, optional): Return date for round-trip searches

  • adults (integer, optional, default=1): Number of adult passengers

  • children (integer, optional, default=0): Number of child passengers

  • infants (integer, optional, default=0): Number of infant passengers

  • cabin_class (integer, optional, default=0): 0=Economy, 1=Premium Economy, 2=Business, 3=First

  • max_results (integer, optional, default=10): Maximum number of results

  • headless (boolean, optional, default=true): Run browser in headless mode

Example MCP Tool Call:

{
  "origin": "SEA",
  "destination": "ICN",
  "departure_date": "2025-11-30",
  "return_date": "2025-12-02",
  "adults": 1,
  "cabin_class": 0,
  "max_results": 10,
  "headless": true
}

2. get_scraper_status

Check scraper health and configuration.

Example Response:

{
  "status": "healthy",
  "version": "1.0.1",
  "capabilities": {
    "one_way_search": true,
    "round_trip_search": true,
    "cabin_classes": ["economy", "premium_economy", "business", "first"],
    "max_results": 50,
    "headless_mode": true
  }
}

As a Standalone Python Module

You can also use the scraper directly in your Python code:

from bing_flights_scraper import BingFlightsScraper

# Create scraper instance
scraper = BingFlightsScraper(headless=True)

try:
    # Search for flights
    results = scraper.search_flights(
        origin="SEA",
        destination="ICN",
        departure_date="2025-11-30",
        return_date="2025-12-02",
        adults=1,
        cabin_class=0,
        max_results=10
    )
    
    # Process results
    print(f"Found {results['results_count']} flights")
    for flight in results['flights']:
        print(f"Price: ${flight['price']['total']}")
        print(f"Airlines: {', '.join(flight['airlines'])}")
        print(f"Departure: {flight['outbound']['departure_time']}")
        print(f"Arrival: {flight['outbound']['arrival_time']}")
        print(f"Duration: {flight['outbound']['duration']}")
        print("---")
finally:
    scraper.close()

Response Format

The scraper returns results in the following JSON structure:

{
  "search_params": {
    "origin": "SEA",
    "destination": "ICN",
    "departure_date": "2025-11-30",
    "return_date": "2025-12-02",
    "trip_type": "round-trip",
    "passengers": {
      "adults": 1,
      "children": 0,
      "infants": 0
    },
    "cabin_class": "economy"
  },
  "results_count": 10,
  "flights": [
    {
      "price": {
        "total": 1200.00,
        "currency": "USD",
        "per_person": 1200.00
      },
      "airlines": ["Korean Air", "Delta"],
      "outbound": {
        "departure_time": "10:30",
        "arrival_time": "14:45",
        "duration": "13h 15m",
        "stops": 1,
        "layovers": [],
        "flight_numbers": []
      },
      "booking_link": "https://www.bing.com/...",
      "result_index": 1
    }
  ],
  "timestamp": "2025-10-23T02:19:00Z"
}

Configuration Options

Cabin Classes

  • 0 - Economy

  • 1 - Premium Economy

  • 2 - Business

  • 3 - First Class

Browser Modes

  • headless=True - Browser runs in the background (faster, no UI)

  • headless=False - Browser window visible (useful for debugging)

Troubleshooting

Common Issues

Issue: Playwright browser not found

Solution: Run `playwright install chromium`

Issue: Timeout waiting for flight results

Solution: 
- Check your internet connection
- Try with headless=False to see what's happening
- Verify the airport codes are valid
- Ensure the dates are in the future

Issue: No results returned

Solution:
- Verify airport codes are correct (use IATA codes like "SEA", "ICN")
- Check that dates are in YYYY-MM-DD format
- Try different date ranges
- Some routes may not have available flights

Issue: Import errors

Solution:
- Ensure virtual environment is activated
- Run `pip install -r requirements.txt` again
- Verify Python version is 3.10 or higher

Debugging

To debug scraping issues, run with headless=False:

scraper = BingFlightsScraper(headless=False)

This will show the browser window so you can see what's being loaded.

Running Tests

Basic Tests

Run the basic unit tests that verify module imports and URL construction:

python tests/test_mcp.py

End-to-End Tests

Run comprehensive end-to-end tests that perform actual flight searches:

python tests/test_e2e.py

Note: E2E tests make real web requests to Bing Flights and may take several minutes to complete. They include:

  1. Invalid Parameters Test - Verifies error handling

  2. One-Way Search Test - Real search from SEA to ICN

  3. Round-Trip Search Test - Real search from LAX to JFK

  4. Multiple Passengers Test - Search with 2 adults and 1 child

The tests use headless browser mode and future dates to ensure valid searches.

Technical Details

Web Scraping Approach

  • Uses Playwright for browser automation

  • Waits for dynamic content to load

  • Extracts data from Bing Flights result cards

  • Handles multiple selector patterns for robustness

Error Handling

The scraper uses minimal error handling and allows exceptions to propagate:

  • Network errors → Raises exception

  • Timeout errors → Raises PlaywrightTimeoutError

  • Invalid parameters → Raises ValueError

  • Parsing errors → Returns partial results or empty list

This design allows the MCP client to implement appropriate retry logic and error recovery.

Limitations

  • Only returns outbound flight details (return flight info not available on Bing results page)

  • Maximum results limited by what's visible on the initial page load

  • No pagination support (first page results only)

  • Scraping depends on Bing's page structure (may break if they change their HTML)

Dependencies

  • fastmcp>=0.1.0 - MCP server framework

  • playwright>=1.40.0 - Browser automation

  • python-dateutil>=2.8.2 - Date parsing utilities

Contributing

When contributing, please:

  1. Test changes with both headless and headed modes

  2. Verify compatibility with the MCP protocol

  3. Update documentation for new features

  4. Follow existing code style and patterns

License

MIT License - See LICENSE file for details

Disclaimer

This tool scrapes publicly available data from Bing Flights. Please:

  • Use responsibly and respect rate limits

  • Review Bing's Terms of Service

  • Do not use for commercial purposes without proper authorization

  • Be aware that web scraping may break if the website changes

Support

For issues, questions, or contributions, please open an issue on the project repository.

Available Tools

2 tools
get_scraper_statusA

Check scraper health and configuration.

Returns: Dictionary with scraper status information including: - status: Current status ("healthy") - version: Scraper version - capabilities: Supported features

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the return format (a dictionary with specific fields) and implies a read-only operation, but lacks details on error handling, rate limits, authentication needs, or side effects. This is adequate but has clear gaps for a tool with no annotation coverage.

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 front-loaded with the core purpose in the first sentence, followed by a structured breakdown of the return values. Every sentence adds value without redundancy, making it efficient and well-organized for quick comprehension.

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?

Given the tool's simplicity (0 parameters, output schema exists), the description is reasonably complete. It explains the purpose and output format, though it could benefit from more behavioral context (e.g., error cases). The output schema likely covers return details, reducing the need for extensive description.

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?

The input schema has 0 parameters with 100% coverage, so the schema fully documents the absence of inputs. The description doesn't need to add parameter information, and it appropriately focuses on the output. A baseline of 4 is justified since there are no parameters to explain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Check') and resource ('scraper health and configuration'), making it immediately understandable. However, it doesn't differentiate from the sibling tool 'search_flights' (which appears unrelated), so it doesn't fully earn a 5.

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?

The description provides no guidance on when to use this tool versus alternatives or in what context. It simply states what the tool does without any usage instructions, prerequisites, or exclusions, leaving the agent to infer appropriate usage scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_flightsA

Search for flights on Bing Flights.

Args: origin: Origin airport code (e.g., "SEA") destination: Destination airport code (e.g., "ICN") departure_date: Departure date in YYYY-MM-DD format return_date: Return date in YYYY-MM-DD format (optional) adults: Number of adult passengers (default: 1) children: Number of child passengers (default: 0) infants: Number of infant passengers (default: 0) cabin_class: 0=Economy, 1=Premium Economy, 2=Business, 3=First (default: 0) max_results: Maximum number of results to return (default: 10) headless: Run browser in headless mode (default: True)

Returns: Dictionary containing flight search results with structure: - search_params: Search parameters used - results_count: Number of results returned - flights: List of flight options with pricing, airline, times, etc. - timestamp: When the search was performed

ParametersJSON Schema
NameRequiredDescriptionDefault
originYes
destinationYes
departure_dateYes
return_dateNo
adultsNo
childrenNo
infantsNo
cabin_classNo
max_resultsNo
headlessNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that the tool runs a browser (via 'headless' parameter) but doesn't disclose important behavioral traits like rate limits, authentication requirements, potential costs, error conditions, or whether this is a read-only operation. The description is insufficient for a mutation/read classification.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Args, Returns) and efficiently explains 10 parameters and return structure. While comprehensive, it maintains appropriate density without wasted words. The only minor improvement would be front-loading the core purpose more prominently.

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?

Given the complexity (10 parameters, no annotations, but has output schema), the description is reasonably complete. It thoroughly documents all parameters and return structure. However, it lacks important contextual information about behavioral constraints, error handling, and usage boundaries that would be needed for optimal agent operation.

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?

The description provides excellent parameter semantics that fully compensate for the 0% schema description coverage. Each parameter is clearly explained with examples (e.g., 'SEA' for origin), formats ('YYYY-MM-DD'), defaults, and meaningful mappings (cabin_class codes to class names). This adds substantial value beyond the bare schema.

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 the tool's purpose: 'Search for flights on Bing Flights.' It specifies the exact action (search) and resource (flights), and distinguishes it from the only sibling tool (get_scraper_status) by focusing on flight search rather than scraper status checking.

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?

The description provides no guidance on when to use this tool versus alternatives. While it mentions Bing Flights as the source, there's no context about when this search method is preferred over other flight search tools or APIs, nor any prerequisites or limitations for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 2 tool updates
    • First observedget_scraper_status
    • First observedsearch_flights

TDQS

A3.6/5.0
Disambiguation5/5

The two tools have completely distinct purposes: get_scraper_status is for health/configuration monitoring, while search_flights is for flight search operations. There is no overlap or ambiguity between these functions.

Naming Consistency5/5

Both tools follow a consistent verb_noun naming pattern (get_scraper_status, search_flights) with clear, descriptive names. The naming convention is uniform throughout the tool set.

Tool Count2/5

With only 2 tools, this server feels severely under-scoped for a flight search domain. A typical flight search service would need tools for booking, fare details, filtering, or itinerary management, making this set incomplete for practical use.

Completeness2/5

The tool surface is highly incomplete for flight search functionality. While search_flights covers basic search, there are no tools for booking, retrieving booking details, managing itineraries, or handling cancellations, leaving significant gaps in the domain coverage.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Integrates Google Flights data into AI workflows for natural language flight searches, price comparisons, flexible date searches, and multi-city itinerary planning with support for various cabin classes and passenger types.
    9
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables flight search and fare calendar exploration by interacting with Google Flights' API, supporting detailed filters for origin, destination, dates, cabin class, airlines, and more.
    3,128
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to search and compare flights across multiple providers (Skyscanner, Google Flights, Kiwi.com) with smart caching, parallel queries, and flexible filtering.
    1
    MIT

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/chonseng/bing-flights-mcp'

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