Skip to main content
Glama
altunoren

googleflights-mcp

by altunoren

googleflights-mcp

Search Google Flights from Claude, Codex, or any MCP client — running entirely on your own machine.

Python 3.10+ License: MIT MCP

A local stdio MCP server that searches Google Flights and returns structured, price-sorted flight options — no central server, no hosting cost, no shared-IP ban risk, no API key. Every user runs their own copy on their own IP.

Exposes one tool: search_flights.

{
  "count": 5,
  "cheapest_price": 2715,
  "results": [
    {
      "airlines": ["Turkish Airlines"],
      "price": 2715,
      "currency": "TRY",
      "stops": 0,
      "stops_label": "direkt",
      "departure": "2026-09-14 21:15",
      "arrival": "2026-09-14 22:40",
      "duration_label": "1h 25m"
    }
  ]
}

Table of contents

Related MCP server: google-flights-mcp

Why this exists

Google doesn't offer a public Flights API. googleflights-mcp scrapes the same public web interface Google Flights itself uses, wraps it in the Model Context Protocol, and runs as a local process launched by your MCP client — so your assistant can search real flight prices without a hosted backend or shared API key.

What can you use it for?

Once it's connected, your assistant can answer real travel questions by actually querying Google Flights — not guessing from training data. A few concrete things people use it for:

  • Find the cheapest option, fast — "what's the cheapest flight from IST to AYT next Friday?" gets a real, price-sorted answer in one round trip.

  • Compare a handful of dates before booking — ask the assistant to check 3–5 candidate dates in a row (or see the scripted version below) to spot the cheapest day to fly without opening a browser tab per date.

  • Plan round trips — pass both departure_date and return_date and get a real round-trip fare instead of adding two one-ways together.

  • Stick to an airline (or alliance) — loyalty-program members can filter to airlines: ["TK"] or compare two carriers head-to-head with ["TK", "PC"]. See Filtering by airline.

  • Direct flights only — business travelers or anyone avoiding layovers can set max_stops: 0.

  • Book for a groupadults/children produce real per-passenger pricing instead of a single-traveler estimate.

  • Shop in your own currency — set currency to TRY, EUR, whatever you think in, instead of mentally converting from USD.

  • Compare cabins — run the same search with seat: "economy" and then seat: "business" to see the real upgrade cost, not a rule-of-thumb multiplier.

  • Factor in carbon emissions — every result includes carbon_grams and carbon_vs_typical_grams, so an assistant can point out the lower-emission option on a route, not just the cheapest one.

  • Automate price-watching — since flights.py has zero MCP dependency, you can import and call search() from your own script or cron job (see Recipes) to track a route's price over time — no separate scraping code to maintain.

  • General travel-assistant conversations — trip planning, "which is cheaper, flying into JFK or EWR," multi-city comparisons — anything you'd ask a human travel agent, phrased naturally in chat.

Installation

Requires Python 3.10+.

git clone https://github.com/altunoren/googleflights-mcp.git
cd googleflights-mcp
pip install -e .

Or install isolated, without cloning:

pipx install git+https://github.com/altunoren/googleflights-mcp.git
# or
uv tool install git+https://github.com/altunoren/googleflights-mcp.git

Any of these gives you the googleflights-mcp command on your PATH.

Client configuration

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "googleflights": {
      "command": "googleflights-mcp"
    }
  }
}

Claude Code (CLI)

claude mcp add googleflights -- googleflights-mcp

Codex CLI (~/.codex/config.toml)

[mcp_servers.googleflights]
command = "googleflights-mcp"
args = []

If googleflights-mcp isn't on your client's PATH (common with pipx/uv tool installs or restricted app sandboxes), use the absolute path instead — e.g. python -m googleflights_mcp, or the full path to the binary inside your virtualenv (/path/to/venv/bin/googleflights-mcp).

How to use it

You don't call the tool yourself — you just talk to your assistant, and it maps your request onto search_flights's parameters. Some example prompts, grouped by what they exercise:

You ask

What happens under the hood

"List one-way economy flights from IST to AYT on September 14th, in TRY."

trip="one-way", seat="economy", currency="TRY"

"Gidiş-dönüş, 20 Ekim gidiş 27 Ekim dönüş, IST-AYT"

return_date set → trip auto-switches to round-trip

"Only Turkish Airlines flights from IST to AYT"

airlines=["TK"] — see Filtering by airline

"Direct flights only, no layovers"

max_stops=0

"2 adults 1 child, business class, IST to JFK"

adults=2, children=1, seat="business"

"What's the cheapest flight next Friday?"

assistant resolves "next Friday" to YYYY-MM-DD itself

"Which option produces less CO2?"

assistant compares carbon_grams across the returned results

Whatever you ask, the model calls search_flights and gets back options sorted by price, cheapest first — it doesn't have to guess, it's reading a real Google Flights response.

search_flights reference

Param

Type

Required

Default

Description

from_airport

str

yes

3-letter IATA departure code (e.g. IST)

to_airport

str

yes

3-letter IATA arrival code (e.g. AYT)

departure_date

str

yes

YYYY-MM-DD

return_date

str

no

None

YYYY-MM-DD; if given, trip becomes round-trip

trip

str

no

one-way

one-way | round-trip

seat

str

no

economy

economy | premium-economy | business | first

adults

int

no

1

Number of adults

children

int

no

0

Number of children

currency

str

no

USD

ISO currency code (e.g. TRY, EUR)

max_results

int

no

20

Max number of options to return

max_stops

int

no

None

Max connections (0 = nonstop only)

airlines

list[str]

no

None

2-letter IATA airline codes to filter by (e.g. ["TK"]). Omit for all airlines, mixed.

Each result includes airline names, price, stop count, departure/arrival times, per-leg detail, total duration, and estimated carbon emissions vs. the route's typical emissions. Errors (no flights found, network failure, consent wall not bypassed) come back as {"error": "...", "query": {...}} instead of raising, so a failed search never crashes your MCP session.

Known limitation — round-trip legs: for trip="round-trip", price is the correct total round-trip fare, but legs/departure/arrival only describe the outbound leg. Google Flights' results page returns outbound options with the combined price first; picking the specific return flight is a separate follow-up request that this tool doesn't perform yet. If you need the return flight's schedule, run a second one-way search in the opposite direction for the return date.

Filtering by airline

airlines takes a list of 2-letter IATA airline codes (not airport codes) — e.g. TK for Turkish Airlines, PC for Pegasus, BA for British Airways. Three ways to use it:

  • One specific airlineairlines: ["TK"] returns only Turkish Airlines flights.

  • Several specific airlinesairlines: ["TK", "PC"] returns flights from either carrier, still sorted together by price.

  • Mixed / all airlines (default) — omit airlines entirely (or pass null/an empty list). You'll get every airline serving the route, mixed in one price-sorted list — which is what the example at the top of this README shows.

Verified against a live search (ISTLHR): no filter returned Turkish Airlines, British Airways, Austrian, and LOT mixed together; airlines: ["TK"] returned only Turkish Airlines; airlines: ["BA"] returned only British Airways.

Ask your assistant in plain language too — e.g. "IST'ten LHR'ye sadece British Airways ile" or "only show Turkish Airlines and Pegasus flights" — the model will map that to the airlines parameter for you.

Recipes for power users

src/googleflights_mcp/flights.py has zero MCP dependency, so you can drive it directly from a plain Python script — useful for anything beyond a single chat query.

Recipe: cheapest day to fly

Check a whole date range and find the cheapest day to depart:

import datetime as dt
from googleflights_mcp.flights import search

start = dt.date.today() + dt.timedelta(days=14)
candidates = []

for offset in range(7):  # check a week of candidate dates
    d = (start + dt.timedelta(days=offset)).isoformat()
    out = search(from_airport="IST", to_airport="AYT", departure_date=d,
                 currency="TRY", max_results=1)
    if "error" not in out:
        candidates.append((d, out["cheapest_price"]))

candidates.sort(key=lambda c: c[1])
for date, price in candidates:
    print(f"{date}: {price} TRY")

Recipe: compare two airlines head-to-head

from googleflights_mcp.flights import search

for code, name in [("TK", "Turkish Airlines"), ("PC", "Pegasus")]:
    out = search(from_airport="IST", to_airport="AYT", departure_date="2026-09-14",
                 currency="TRY", airlines=[code], max_results=1)
    price = out.get("cheapest_price", "no flights")
    print(f"{name}: {price}")

Recipe: price-watch cron job

Run the date-range check above on a schedule (cron, GitHub Actions, a launchd/systemd timer, or Claude Code's own /loop/schedule skills if you're driving this from an agent) and alert yourself — email, Slack webhook, whatever you prefer — whenever cheapest_price drops below a threshold you set. Because search() returns plain dicts, wiring it into any alerting pipeline is just a few lines.

Requests originating from the EU/Turkey are frequently redirected to Google's consent.google.com "before you continue" cookie page. This project does not use fast_flights.get_flights's default fetcher, which breaks on that page (AttributeError: 'NoneType' object has no attribute 'text'). Instead it sends its own request with consent-bypass cookies and parses the resulting HTML directly — see src/googleflights_mcp/flights.py. If Google changes its consent flow and the bypass stops working, the tool returns a clear {"error": "..."} instead of crashing.

Development

pip install -e '.[dev]'
pytest -q            # fast tests, no network
pytest -q -m live     # includes a live Google Flights smoke test

src/googleflights_mcp/flights.py has no MCP dependency — you can import and call search(...) directly:

from googleflights_mcp.flights import search
import datetime as dt, json

d = (dt.date.today() + dt.timedelta(days=14)).isoformat()
out = search(from_airport="IST", to_airport="AYT", departure_date=d,
             trip="one-way", seat="economy", currency="TRY", max_results=5)
print(json.dumps(out, ensure_ascii=False, indent=2))

Project layout:

src/googleflights_mcp/
├── __init__.py
├── __main__.py     # `python -m googleflights_mcp`
├── server.py        # FastMCP + search_flights tool
└── flights.py       # fetch + parse + normalize (MCP-independent)
tests/
├── test_normalize.py    # no network, always runs
└── test_smoke_live.py   # live network, opt-in via `-m live`

FAQ

Does this work with ChatGPT? Not as-is. This project is deliberately built as a local stdio MCP server — no hosting cost, no shared-IP ban risk (see Why this exists). ChatGPT's web/desktop app currently only supports remote MCP connectors reachable over a public HTTPS URL; it can't spawn and talk to a local subprocess on your machine the way Claude Desktop, Claude Code, and Codex CLI do. To use it from ChatGPT you'd have to rewrite the transport to HTTP/SSE and deploy it somewhere public — which reintroduces the hosting cost and shared-IP risk this project was built to avoid. It works out of the box with the three clients listed in Client configuration.

Can I say "find me a cheap flight" and it just works? Yes, in Claude Desktop, Claude Code, or Codex CLI, once configured — plain language in your own words maps onto search_flights's parameters automatically. See How to use it for example prompts.

Does it have reminders / price-drop alerts? Not built in. search_flights is a single request-response query — it doesn't run in the background or notify you on its own. For "tell me when the price drops" behavior, you (or an agent you run) need to poll it on a schedule and alert yourself — see Recipe: price-watch cron job.

Troubleshooting

{"error": "Google consent wall not bypassed ..."} The bundled consent cookies may be stale. Open an issue with the date and your region — a cookie refresh is usually a one-line fix.

{"error": "No flights found for ..."} Either the route/date genuinely has no results, or Google served an unexpected page layout. Try a well-known route (e.g. ISTAYT) to confirm the server itself is working.

Client can't find the googleflights-mcp command Use an absolute path in your client config — see the note under Client configuration.

This tool scrapes Google Flights' public web interface — it is not an official Google API. It's intended for personal/local use only. Heavy automated request volume can lead to IP blocking. Compliance with Google's Terms of Service is your responsibility.

License

MIT

Available Tools

1 tool
search_flightsA

Search Google Flights for available flights between two airports.

Airport codes are 3-letter IATA codes (e.g. IST, AYT, JFK). Dates are YYYY-MM-DD. Returns structured flight options sorted by price.

airlines optionally restricts results to specific 2-letter IATA airline codes, e.g. ["TK"] for Turkish Airlines only, or ["TK", "PC"] for Turkish Airlines + Pegasus. Omit it (or pass None/empty) to search all airlines mixed together in one result list.

ParametersJSON Schema
NameRequiredDescriptionDefault
seatNoeconomy
tripNoone-way
adultsNo
airlinesNo
childrenNo
currencyNoUSD
max_stopsNo
to_airportYes
max_resultsNo
return_dateNo
from_airportYes
departure_dateYes

TDQS

A3.8/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does disclose that results are 'structured flight options sorted by price' and how the airlines parameter changes result inclusion. However, it does not mention potential rate limits, request failures, result field structure, or that this is a read-only operation, leaving some behavioral ambiguity.

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 organized into short, focused paragraphs: core purpose, format conventions, and airline behavior. It is concise enough to read quickly and front-loads the most critical information. The examples for airline codes are slightly verbose but useful for correct invocation.

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

Completeness3/5

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

For a tool with 12 parameters, no annotations, and no output schema, this description covers the essential required inputs and one key optional parameter, but it leaves several optional semantics implicit. An agent can make a basic correct call using the required fields, but it would need to infer the behavior of trip, return_date, max_stops, and max_results without further guidance. The mention of 'structured flight options sorted by price' gives some return context but not enough to fully anticipate the response.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate. It adds valuable meaning for the three required parameters by specifying IATA codes and YYYY-MM-DD date format, and it thoroughly explains the airlines parameter. However, several optional parameters like trip, seat, max_stops, currency, and max_results rely on their names alone, with no explanation of allowed values or interactions such as how return_date and trip relate.

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 opens with a specific verb and resource: 'Search Google Flights for available flights between two airports.' It clearly states the tool's input scope and result type, making the purpose immediately obvious. With no sibling tools to differentiate from, this is fully sufficient.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: whenever flight search between two airports is needed. It explicitly covers how to format airports and dates and how to use the airlines parameter. There are no sibling tools or exclusions to mention, so the absence of explicit 'when not to use' guidance is not a significant gap.

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.

  1. 1 tool updatev0.1.0
    • First observedsearch_flights

TDQS

A3.9/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no risk of overlap or confusion. The single tool has a clear, distinct purpose.

Naming Consistency5/5

The tool name 'search_flights' follows a clear verb_noun pattern, which is consistent and intuitive. There is only one tool, so there are no naming inconsistencies.

Tool Count3/5

A single-tool server feels thin but is acceptable for a focused flight search service. The count is not excessive, but the server is minimal in scope.

Completeness4/5

The search tool covers the core flight search functionality, including airport codes, dates, and airline filters, and returns structured results. Minor gaps such as round-trip or multi-city search are not explicitly supported, but they are not critical for a basic search service.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    A remote MCP server that searches Google Flights for flight information and airport codes. It enables users to find flights, locate airports, and generate travel dates through natural language interactions.
    -
  • A
    license
    A
    quality
    D
    maintenance
    MCP server that enables Google Flights search via SerpApi, supporting one-way, round-trip, and multi-city itineraries with defaults for Business class, Star Alliance, and EUR pricing. It provides flight search, booking options, and usage tracking.
    4
    132 npm
    MIT