Google Flights MCP
This MCP server provides Google Flights search and airport lookup capabilities for travel planning.
Search one-way or round-trip flights by origin, destination, and date, with passengers, cabin, max stops, sorting, currency, and max results; results include booking links.
Find the cheapest departure date within a date range, optionally for a fixed round-trip length, scanning up to 14 days.
Compare cheapest fares across multiple origin/destination airport combinations, up to 6 routes.
Look up IATA airport codes offline by city, airport name, or code.
Searches Google Flights for one-way and round-trip itineraries, returning prices, stops, durations and a Google Flights deep link for booking. Also finds the cheapest travel dates within a range, compares fares across multiple origin/destination airports, and looks up airports by city or name.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Flights MCPFind me the cheapest flights from Milan to London next month, nonstop only."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Flights MCP
An MCP server that lets Claude, ChatGPT and any other MCP client search Google Flights: prices, stops, durations, cheapest day in a range, nearby-airport comparison and a deep link to book.
Not affiliated with or endorsed by Google. See Legal before using it.
Tools
Tool | What it does |
| One-way or round-trip search for a date: passengers, cabin, max stops, sorting |
| Cheapest day in a date range (optionally for a fixed trip length) |
| Cheapest fare across several origin/destination airports (e.g. MXP/LIN/BGY → LHR/LGW) |
| Offline lookup of IATA codes from a city or airport name |
| Tells the assistant whether a newer version is on GitHub (called once per conversation) |
Every search result includes a google_flights_url so you can verify and book.
Related MCP server: Ignav Flights MCP Server
Install
You only need uv (it fetches Python and the dependencies for you). Nothing to clone or build.
Do this once first (warm-up). The very first run downloads and builds everything (about a minute), which is longer than the start-up timeout of most clients, so the first launch from Claude would appear to fail. Pre-download it in a terminal, then register it:
uvx --from git+https://github.com/marcopa84/GoogleFlightsMCP google-flights-mcp --versionAfter that, starting takes ~2 seconds.
Let Claude install it for you
Paste this into Claude Code (or Claude Desktop with file access) and it will do the setup, asking before it touches any config:
Install this MCP server for me and check it works: https://github.com/marcopa84/GoogleFlightsMCP
Follow INSTALL_FOR_AI.md in that repo.If you cloned the repo and open Claude Code in it, you also get three slash commands:
/install (set up), /doctor (diagnose problems), /flights <request> (search in plain language).
Or do it by hand:
Claude Code
claude mcp add google-flights -- uvx --from git+https://github.com/marcopa84/GoogleFlightsMCP google-flights-mcpClaude Desktop
Settings → Developer → Edit Config, then add:
{
"mcpServers": {
"google-flights": {
"command": "/usr/local/bin/uvx",
"args": ["--from", "git+https://github.com/marcopa84/GoogleFlightsMCP", "google-flights-mcp"]
}
}
}Replace /usr/local/bin/uvx with the output of which uvx (Claude Desktop does not see your shell PATH).
Keep any other keys already in the file.
Then quit Claude Desktop completely (⌘Q on macOS, tray icon → Quit on Windows; closing the window is not
enough), reopen it, start a new chat and ask: "Find me the cheapest flights from Milan to London next month,
nonstop only." If the tools do not appear, check ~/Library/Logs/Claude/mcp-server-google-flights.log.
ChatGPT (and other remote clients)
ChatGPT connects to servers on the public internet, so run the HTTP transport and expose it with a tunnel. You need a ChatGPT plan with custom connectors / Developer Mode (check OpenAI's current docs for eligibility).
# terminal 1
uvx --from git+https://github.com/marcopa84/GoogleFlightsMCP google-flights-mcp --transport http --port 8000 --allow-any-host
# terminal 2 (any tunnel works; this one needs no account)
cloudflared tunnel --url http://localhost:8000In ChatGPT: Settings → Connectors → Advanced → Developer mode → add a connector with
https://<your-tunnel>.trycloudflare.com/mcp, authentication none.
⚠️ This server has no authentication. Anyone who learns your tunnel URL can make your machine search
Google Flights. Stop the tunnel when you are done, and do not leave it running unattended.
Prefer --public-host <your-tunnel-hostname> over --allow-any-host if the hostname is stable.
From a clone
git clone https://github.com/marcopa84/GoogleFlightsMCP && cd GoogleFlightsMCP
uv sync
uv run google-flights-mcp # stdio
uv run pytest # tests (offline)
uv run pytest -m live # real Google Flights checkConfiguration (environment variables, all optional)
Variable | Default | Meaning |
|
|
|
| – | Enables the SerpAPI |
|
| Seconds identical searches are cached |
|
| Minimum seconds between upstream requests |
|
| Max days a single |
| – | HTTP(S) proxy for the Google backend |
| built-in | See below |
|
|
|
In Claude Desktop pass them with an "env": { ... } block next to command/args.
Cookie consent (EU)
From the EU, Google answers automated requests with a cookie-consent page instead of results. The Google
backend therefore sends the same SOCS cookie a browser stores after clicking Accept all. That is a
choice made on your behalf: set GFLIGHTS_CONSENT_COOKIE to your own value (copy the SOCS cookie from
your browser) or to an empty string to send nothing (searches from the EU will then fail).
Updates
Installed with uvx --from git+..., the server picks up the latest commit every time it starts. So to
update, just quit the client completely and reopen it (Claude Desktop: ⌘Q / tray → Quit). While the app stays
open the old version keeps running; the assistant calls check_for_updates once per conversation and tells you
when a restart would bring in a newer version.
How it works
MCP client ──► tools (server.py) ──► FlightService (cache, rate limit, validation, fallback)
├─ GoogleFlightsBackend (fast-flights: Google's public web page)
└─ SerpApiBackend (official paid API, optional)There is no official Google Flights API. The default backend reads the public page like a browser and can
break when Google changes it; the weekly CI job runs a live canary so you find out quickly. If it breaks,
update first (uvx --refresh ...) and open an issue.
Legal and fair use
This is not legal advice. Points to be aware of:
Google's Terms of Service restrict automated access. Scraping can violate them even for public pages.
In the EU, a site operator may contractually forbid scraping of databases that are not otherwise protected (CJEU, Ryanair v PR Aviation).
The project is meant for personal, low-volume use: it caches, rate-limits and caps range scans. Do not host it as a public service, resell the data, or raise the limits to bulk-harvest prices.
For anything commercial use the
serpapibackend or a licensed flight-data provider.Prices are indicative; always confirm on the booking site.
Contributing
INSTALL_FOR_AI.md is written for AI assistants; keep it in sync when install steps change.
PRs welcome — especially new backends (implement Backend.search in src/google_flights_mcp/backends/).
License
MIT
Available Tools
4 toolscompare_airportsBRead-only
Compare the cheapest fare across several origin/destination airport combinations (max 6).
| Name | Required | Description | Default |
|---|---|---|---|
| cabin | No | economy | |
| adults | No | ||
| origins | Yes | One or more origin IATA codes, e.g. ['MXP','LIN','BGY'] | |
| currency | No | EUR | |
| max_stops | No | ||
| return_date | No | ||
| destinations | Yes | One or more destination IATA codes | |
| departure_date | Yes | Date as YYYY-MM-DD |
Output Schema
| Name | Required | Description |
|---|---|---|
| routes | Yes | |
| currency | Yes | |
| return_date | No | |
| departure_date | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds one genuinely useful behavioral constraint (max 6 combinations) that the schema does not enforce via maxItems, but it says nothing about result ordering, per-combination failures, or cost/latency of fanning out across many combos.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the scope limit is stated inline where it matters. Nothing could be trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, but for an 8-parameter, low-coverage tool the description is thin: no mention of round-trip vs one-way handling (return_date), cabin/currency effects, or how ties among combos are resolved. Adequate to call the tool, not to call it confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 38% (3 of 8 params): cabin, adults, currency, max_stops, and return_date are undocumented in both schema and description. The description only gestures at origins/destinations and fares, so it does not compensate for the coverage gap on an 8-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Compare) and resource (cheapest fare across origin/destination airport combinations), plus a precise scope limit of max 6. It does not name or contrast against the siblings find_cheapest_dates or search_flights, so the agent must infer the boundary between this batch-comparison tool and a single search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use, when-not-to-use, or alternative-tool guidance is given. The agent can loosely infer this is for multi-airport comparison, but nothing tells it how this differs from search_flights or find_cheapest_dates, and the max-6 budget is stated without explaining what happens if exceeded.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_airportBRead-only
Look up IATA airport codes by city or airport name (offline).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | City, airport name or IATA code, e.g. 'Milano' or 'heathrow' |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description's '(offline)' wording reinforces the openWorldHint=false annotation with useful plain-language context, but adds nothing about result count, pagination, or how ambiguous queries are resolved.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the action, the resource, and the accepted input forms; there is no filler to cut.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the two-parameter surface is small. The only real gap is that nothing tells the agent how to use 'limit' or what happens with an unmatched query, which keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%: 'query' is documented in the schema itself, while 'limit' is undocumented in both places, though its default, min, and max make it fairly self-explanatory. The description adds no parameter detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('look up') and resource ('IATA airport codes') plus the input domain ('by city or airport name'), which is enough to separate it from search_flights and find_cheapest_dates. It does not explicitly differentiate itself from compare_airports, which also works on airports, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use statement, no mention of alternatives among the siblings, and no stated prerequisites. The '(offline)' note hints at the data source but gives no guidance on when this lookup is the right choice versus compare_airports or search_flights.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_cheapest_datesARead-only
Find the cheapest day to fly within a date range (one search per day, max 14 days).
| Name | Required | Description | Default |
|---|---|---|---|
| cabin | No | economy | |
| adults | No | ||
| origin | Yes | 3-letter IATA airport code, e.g. MXP | |
| currency | No | EUR | |
| end_date | Yes | Date as YYYY-MM-DD | |
| max_stops | No | ||
| start_date | Yes | Date as YYYY-MM-DD | |
| destination | Yes | 3-letter IATA airport code, e.g. MXP | |
| trip_length_days | No | If set, search round trips of this length |
Output Schema
| Name | Required | Description |
|---|---|---|
| best | Yes | |
| note | No | |
| dates | Yes | |
| origin | Yes | |
| scanned | Yes | |
| currency | Yes | |
| destination | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuinely non-obvious operational behavior: the tool issues one search per day and is capped at 14 days, which tells an agent about cost/latency and a hard input boundary. It stops short of explaining round-trip semantics or what happens when trip_length_days is null.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the core action first and the key constraint second. No filler, no restated name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return values need no explanation, and the description covers purpose plus the 14-day limit. But for a 9-parameter tool with an optional round-trip mode (trip_length_days) that interacts with end_date, and with several undocumented parameters, the definition leaves real gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 56%, and the description adds nothing beyond 'date range', which the start_date/end_date parameters already imply. Parameters such as currency, adults, and max_stops remain undocumented in both places, so the prose does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find the cheapest day to fly within a date range'), which is clearly distinct from the sibling search_flights (specific itineraries) and find_airport (airport lookup). It does not name those siblings explicitly, so the differentiation is left to inference rather than spelled out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(one search per day, max 14 days)' implies when the tool is appropriate and constrains the input range, but there is no explicit guidance on when to prefer this over search_flights or compare_airports. Usage is implied rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_flightsBRead-only
Search flights between two airports on a given date (one-way or round-trip).
sort_by: 'price' (default), 'duration' or 'departure'.
| Name | Required | Description | Default |
|---|---|---|---|
| cabin | No | economy | |
| adults | No | ||
| origin | Yes | 3-letter IATA airport code, e.g. MXP | |
| infants | No | ||
| sort_by | No | price | |
| children | No | ||
| currency | No | EUR | |
| max_stops | No | 0 = nonstop only; omit for any | |
| destination | Yes | 3-letter IATA airport code, e.g. MXP | |
| max_results | No | ||
| return_date | No | YYYY-MM-DD; omit for one-way | |
| departure_date | Yes | Date as YYYY-MM-DD |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | Yes | |
| origin | Yes | |
| backend | Yes | |
| currency | Yes | |
| destination | Yes | |
| itineraries | Yes | |
| return_date | No | |
| departure_date | Yes | |
| google_flights_url | Yes | Open this link to see/book on Google Flights |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and external-data scope are covered. The description adds only the trip-shape and sort behavior, disclosing nothing about result limits (max_results defaults to 10, caps at 30), caching, or availability that would otherwise be invisible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose statement is front-loaded in one clean sentence, and the second line is short. The sort_by line is slightly cryptic in form (bare key: values) but contains no wasted prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with just 42% schema coverage, the description should carry more weight, especially on passenger-composition semantics and result caps. It does not explain the max_stops/max_results tradeoffs beyond the schema text, nor how it relates to the three sibling search tools; the output schema does relieve it of explaining return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 42% of 12 parameters. The description usefully enumerates the sort_by values ('price' default, 'duration', 'departure'), which the schema leaves as a bare string, but it says nothing about adults/children/infants, cabin, currency, or max_results, leaving most parameters unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('search flights between two airports on a given date') and clarifies the supported trip shapes (one-way/round-trip). It does not, however, distinguish itself from siblings like find_cheapest_dates or compare_airports, so an agent still has to infer which search entry point applies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the agent learns this searches a single origin-destination pair on a date, and the sort_by hint suggests ranking behavior. No when-to-use, when-not-to-use, or sibling routing is given (e.g., use find_cheapest_dates to scan a window).
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.
4 tool updates
v0.1.0- First observed
compare_airports - First observed
find_airport - First observed
find_cheapest_dates - First observed
search_flights
TDQS
Scored across 4 tools
The four tools are mostly distinct by scope: find_cheapest_dates scans a date range, compare_airports tests multiple airport pairs, search_flights handles a single date, and find_airport is an offline code lookup. The only mild overlap is that find_cheapest_dates and search_flights both return fares, though their descriptions clearly separate date-range scanning from single-date search.
All names follow a consistent verb_noun snake_case pattern (find_cheapest_dates, compare_airports, search_flights, find_airport). Verbs accurately reflect each action and no convention mixing is present.
Four tools is well within the sensible 3-15 range and each tool earns its place by covering a distinct query style. Nothing feels redundant or bloated for a flight-search server.
The surface covers single-date search, flexible-date scanning, multi-airport comparison, and code lookup, forming a coherent search workflow. Minor gaps exist for auxiliary parameters like passenger counts, cabin class, or nonstop-only filters, but agents can work around them.
Maintenance
Related MCP Connectors
Google Flights search data: fares, routes, stops, and price insights via a hosted MCP server.
Flight search MCP server providing search, pagination, and itinerary details for AI assistants.
Flight Intelligence MCP — search, cheapest dates, multi-city, airline compare via Google Flights
Real-time Google Flights fares for agents. Three things people do with this server. Scan for deals: one call takes a date range and a list of destination airports, expands every combination server side, and returns each fare with Google's own low, typical or high verdict. Put live search in your app: flat JSON with a bookable link on every result, and round trips priced as paired legs. Run a 24/7 AI travel agent: add the server, sign in with Google, and schedule it. No ads, no sponsored content. You bring your own RapidAPI key, so every search is billed to your plan and never to anyone else's. Add https://flights.flightpowers.com/mcp , click Sign in, sign in with Google, and paste your RapidAPI key once on the page that opens. Scripts and clients without a sign-in button send the key as x-rapidapi-key on the same URL.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI clients to explore cheapest destinations, optimize multi-leg flight itineraries, and reference airport/region data via MCP tools and resources.MIT
- AlicenseNot gradedqualityFmaintenanceProvides live flight prices, booking links, and airport lookup via a hosted MCP server. Enables search for flights and direct booking URL retrieval.1MIT
- AlicenseAqualityAmaintenanceEnables MCP clients to search one-way, round-trip, and multi-city itineraries and retrieve fares, flight legs, carbon emissions and price history as structured JSON.126 npm48 PyPI6MIT
- AlicenseAqualityBmaintenanceEnables real-time flight fare searches across date ranges and multiple destinations, with historical price insights and booking links. Provides one-way and round-trip search tools through MCP.41MIT