google-flights-mcp
Google Flights MCP — 让您的 agent 可以搜索整个日期范围内实时票价的工具,零广告
claude mcp add --transport http google-flights https://google-flights-mcp.flightpowers.com/mcp --header "x-rapidapi-key: YOUR_RAPIDAPI_KEY"托管服务。无需克隆,无需构建。已列入官方 MCP Registry 中,标识符为 com.flightpowers/google-flights-mcp。健康检查端点:/health。
需要 key 吗? 请先在 RapidAPI 上订阅 Google Flights Live API(提供免费额度),然后把您的 x-rapidapi-key 复制下来:https://rapidapi.com/mtnrabi/api/google-flights-live-appi
还没有 key? 先用免费服务器 —— 同样的搜索功能,无需注册:
claude mcp add --transport http google_flights-free https://google-flights-lulu.flightpowers.com/mcp
(服务由广告赞助:每条结果一条已明示的赞助卡片,扇出上限为 15,且无法渲染商家赞助卡片的客户端可能被进一步限制。)当广告、15 次搜索上限或这些客户端限制阻碍到您的使用体验时,再回到本页。
您的 agent 可具备
它提供的是两个工具,回答价格问题,而不是日期检索:
可以进行开放式提问。 比如“十月里去斯里兰卡最便宜的单程票”“5 月某个时间在罗马住 5 到 7 晚,从特拉维夫或拉纳卡出发”—— 每一个都只要一次工具调用。两个工具均接受出发日期范围、一个列表的目的地机场,/单向飞行需要固定返程。若有固定返程,也接受
nights夜晚数,而不是固定返回日,并在服务器内部展开。直接告诉你价高不高。 每个结果都包含 Google 针对该航线与时段给出的历史价格区间 ——
price_insights_low、price_insights_high,以及一个price_range_in_relation_to_other_periods的结论,值为low/typical/high。正因如此,agent 才能回答“209 美元在此航线属于常态,不要急着订”,而不只是报一个代码。直接可订票,而不只是浏览。 每个结果都含有一个外部
buy_link假向 Google Flights 订票页。可以查看花费。 每一条响应都携带
api_usage,显示本次调用消耗了多少上游请求、计划还剩多少,做到您可按这个报告查看(见费用报告(api_usage))。知道自己搜索了什么。 每条响应都带
search_coverage,模型可以被“诚实地说:回答是基于哪些日期、目的地得到的”。
注意: 结果是实时票价。差异性只保持几分钟 —— 绝不缓存或复用以往结果;重新搜索时,请注明数据获取的时间。
Related MCP server: Ignav Flights MCP Server
获取 key(免费版可用)
服务器自身不持有任何上游的凭据。每次搜索都被计入使用 您自己的 RapidAPI 订阅,所以 key 必须随请求一路携带。
订阅 Google Flights Live API: https://rapidapi.com/mtnab/api/google_flights-live-api>
复制好您的
api_key(名为x-rapidapi-key)。用下面三种方式中的任意一种,把 key 传给服务器。
如果没有 key,工具也不会静默失败,也不会产生花费 —— 工具直接随结果带 needs_api_key: true 并附注册链接和以上相应提示,好让模型把 peprue 用户。
三种传 key 的方式
方式 | 示例/操作 | 什么时候用 |
Header(推荐) | 添加一句请求头: | 凡是允许设 Header 的环境都可用。key 不进入 URL,也就不经过代理和访问日志。 |
Query 参数 | 例如 | 只支持填 URL 的托管平台(如 claude.ai 自定义连接器的)时用它。 |
客户端 API-key 字段 | 直接粘贴到客户端的“API key”栏 | 若工具让你在 Host 上加: |
以下规律生效:非空 key 最优先(左边起)。凡是 key 绝对不会进日志、不会在一条错误里被回显,也不会在 supply 结果里返回。
API 工具一览
工具 | 说明 |
| 实时单程票。输入:出发(IATA)、目的地:一字区/列表,和一个出发日期或日期区间;返回票价、航空公司、时长、转机次数、 |
| 实时往返票,以往返双程(paired legs) 计价,而非两个一方。输入:出发地、(或多个目的地)、出发日期或区间;以及 |
search_oneway_flights
search_oneway_flights(
from_airport: str, # origin IATA, e.g. "TLV"
to_airport: str | list[str], # destination IATA, or a list to compare
departure_date: str | None = None, # "YYYY-MM-DD"
departure_date_from: str | None = None,# first date of a range
departure_date_to: str | None = None, # last date of a range
max_stops: int | None = None, # 0 = non-stop only
airline_codes: list[str] | None = None,
exclude_airline_codes: list[str] | None = None,
departure_time_min: int | None = None, # hour, 0-23
departure_time_max: int | None = None,
arrival_time_min: int | None = None,
arrival_time_max: int | None = None,
currency: str = "usd",
max_price: int | None = None,
seat_type: int | None = None, # 1 economy, 2 premium economy, 3 business, 4 first
passengers: list[int] | None = None, # [adults, children, infants]
sort_by: str = "best", # "best" | "price" | "duration"
limit: int = 10, # results returned after merge + sort
max_searches: int | None = None, # cap the billed requests this call may make
use_fallback: bool = False, # slower, fewer empty results on hard routes
)search_roundtrip_flights
search_roundtrip_flights(
from_airport: str,
to_airport: str | list[str],
departure_date: str | None = None,
departure_date_from: str | None = None,
departure_date_to: str | None = None,
return_date: str | None = None, # use this OR nights, not both
nights: int | list[int] | None = None, # e.g. 7, or [5, 6, 7]
max_departure_stops: int | None = None,
max_return_stops: int | None = None,
departure_airline_codes: list[str] | None = None,
return_airline_codes: list[str] | None = None,
currency: str = "usd",
max_price: int | None = None,
seat_type: int | None = None,
passengers: list[int] | None = None,
sort_by: str = "best",
limit: int = 10,
max_searches: int | None = None,
use_fallback: bool = False,
)又注意:规则:sort_by 顺序由这一整服务在其已执行的所有搜索结果上进行合并套用,因此有几个组合被扩展其排序都可预期——快。
一个实际示例
用户: “我在特拉维夫,五天——一够一周——去 Cons this. 罗马或雅典的玩,5 月 1..”...
嗯——不多见了 Good Cà确认原文:
用户问题原 p:
“我在特拉维夫。从五月这半个月任意一天出发,去罗马或雅典,求最省的——周往返”
一次:
{
"name": "search_roundtrip_flights",
"arguments": {
"from_airport": "TLV",
"to_airport": ["FCO", "ATH"],
"departure_date_from": "2026-05-01",
"departure_date_to": "2026-05-15",
"nights": 7,
"sort_by": "price",
"limit": 5
}
}这组展开为 15 日 × 2 个目的地 =30 组合——恰为本次调用的上限。返回形状(字段真实,下面数仅示意,不是报价,自来之真跑调用):
{
"results": [
{
"from_airport": "Tel Aviv (TLV)",
"to_airport": "Rome (FCO)",
"departure_date": "2026-05-05",
"return_date": "2026-05-12",
"total_price": "$XXX",
"total_price_as_number": 0,
"total_duration_seconds": 0,
"total_stops": 0,
"price_range_in_relation_to_other_periods": "low",
"price_insights_low": 0,
"price_insights_high": 0,
"departure_flight_airline": "...",
"departure_flight_departure_description": "...",
"departure_flight_arrival_description": "...",
"departure_flight_duration": "...",
"departure_flight_stops": 0,
"departure_stops_info": [],
"return_flight_airline": "...",
"return_flight_departure_description": "...",
"return_flight_arrival_description": "...",
"return_flight_duration": "...",
"return_flight_stops": 0,
"return_stops_info": [],
"buy_link": "https://www.google.com/travel/flights?tfs=..."
}
],
"result_count": 5,
"search_coverage": {
"requested_combinations": 30,
"searched_combinations": 30,
"truncated": false,
"max_searches_per_request": 30,
"departure_dates_searched": ["2026-05-01", "..."],
"destinations_searched": ["ATH", "FCO"]
},
"api_usage": {
"requests_used_by_this_call": 30,
"plan_requests_remaining": 0,
"plan_requests_limit": 0,
"note": "This search used 30 of your RapidAPI plan's requests; ... remain in the current period. Each date and destination combination is one billed request."
}
}其余的响应 shape 也常见,全部正常:
这些日期没有班机。
results: []+message— Google 对极多航线/日结合确实没有任何票;这不是异常。可尝试贴近的日期、附近机场,或设use_fallback: true。部分搜索失败。 一种
partial数告诉你 个搜索中失败了几组,结果代表其余。区间太大。 看到
search_coverage.truncated: true加note—— 就会从整个窗口内均匀抽样(保留首尾),而非取头部 N 天。那样样本能代表全域。当您想容量增加可升max_searches,或收小听。没有 key / key 被拒回。
needs_api_key: true(支出零)并说明修复方法。常见:有效 RapidAPI Key 但未订阅此 API。额度用荆。
quota_exhausted: true跟随api_usage,还提「视出度和缩实际日期让剩余数量够用更久」。
用户看的费用(api_usage)
费用是您出自己的,因此可见记表条目。每条成功响应都带:
字段 | 含义 |
| 这 一次工具调用所耗的 上游计费请求数量。 |
| 本期 RapidAPI 计划还余多少。 |
| 你计划这些总数本来就。 |
| 一句汇总,模型在回答你之前很可以“直接告诉你” |
remaining / limit(计费还是上游返回才有,源没返回就跳过)note 也随之显示。模应 应该规则不多说只要你记住了这两句:一个日期 × 一个目的地 = 一次收费请求。。
调成本还可以这样微调(从直接到再细):每次调用某 max_searches(数字)上限。缩小日期区间、缩短目的地列表 「法由 to max_searches 做首级」
一次调用,干…相当于三十各斩
底层 REST 每次请求只能传一个 (origin,destination,date) 三组,如果用逐 day / 一个地夹就好决策调用的话:方案“最便宜 tore Sri Lanka anywhere October” → 会被拆成 31 独立 sub-task —— 模型也联 31 次询回、有 31 次失良机,而用户要查看自己信用卡以后可能才发现账单多少钱。
现在是一次调用。扇出电话在私侧服务器端分配给全国、实时负载、有上限、均匀抽样、buy_link 去重、合并、按您 sort_by 排序。并会在 完成后把整个目录以 search_coverage 与 api_usage 上报。
本服务(Paid) | 免费服务器 | |
每次调用 扇出上限 | 30(硬上限 60;可在每次传 | 15 |
广告 | 零 | 每一条带卡为广告 |
key | 要带上自己的 RapidAPI key | 无需 |
上报使用 | 每请求都 | n/a |
能被目录收录 | ✔ | ✘ |
本服务器不含任何广告。:这不像是“品味差”,而受平台规则入—— Anthropic 的商业模式和 OpenAI 的应用商店工具政策都禁在工具结果里的第三方广告;一个广告服务器可靠又可笑;而后面的可被列。
本地开发
git clone <this repo> && cd mcp_server_paid
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
cp example.env .env # fill it in; leave RAPIDAPI_KEY empty
set -a && . .env && set +a
.venv/bin/python -m src # streamable HTTP on http://localhost:8000/mcp设备本地进程就这么连:
claude mcp add --transport http google-flights-local http://localhost:8000/mcp --header "x-rapidapi-key: YOUR_RAPIDAPI_KEY"cts(124 条用例通过,已验):
.venv/bin/python -m pytest -q全部配置都在 example.env;每个都不解释。关注重点:
变量 | 默认值 | 为什么重要 |
|
| 每次调用的扇出上限。硬性上限为 60。 |
|
| 扇出的并发度。 |
|
| 连接池上限;serverless 实例共享文件描述符池。 |
|
| 与上游上限一致,因此本端绝不会先超时。 |
|
| 每次独立上游搜索请求返回的结果数量。 |
| RapidAPI listing | 未携带 key 的用户访问时,将该 URL 原样返回作为提示。 |
|
| 由 |
| (空) | 生产环境中请保持为空。 如果设置了该值,那么每个无 key 的调用方都会由该订阅提供服务,并将其费用计入该订阅。服务器在启动时会记录警告,而 |
| (空) | 设置后, |
| (空) | 为空时禁用文件输出;stdout 上的 |
操作路由:GET /health(公开、无需认证——注册中心会轮询它)、GET /metrics、GET /metrics/calls?hours=24。
部署目标是 Vercel,通过 api/index.py(一个 FastAPI 包装器,向 FastMCP 传入其 lifespan,并设置 stateless_http=True)部署。标准的 MCP 路径为 /mcp,不能带尾部斜杠。
绝不要提交真实密钥。example.env 附带的是占位符;请务必保持这样。
非关联声明
这是一个返回公开航班定价的独立 API。它与 Google 无关联、未经其认可或赞助。仅使用“Google Flights”来描述该公共数据源。票价由上游提供并提供,且随时变动,且不保证有效——购买前请务必在航空公司或预订网站上确认最终价格。
Available Tools
4 toolsfind_hotel_by_nameFlightPowers: find one hotel by nameARead-onlyInspect
FlightPowers single-property lookup: live Booking.com availability and pricing for one named property. Input: the hotel name a person would type (adding the city helps when a chain has many properties) plus check-in and check-out dates -- no internal property ID needed, the resolution is done for you. Returns the property's price, review score, room type and a booking link. Use it to check one specific hotel, or to track a single property's price over time.
price_as_seen_from prices the stay as a shopper resident in that country would see it. Gaps are real but usually modest and property-dependent, and rates move between calls, so call each country a few times on this same property before reporting a gap.
Rates go stale within minutes: never reuse an earlier result.
Requires the caller's own RapidAPI key for the Booking Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/booking-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage.
| Name | Required | Description | Default |
|---|---|---|---|
| adults | No | Number of adult guests. | |
| children | No | Number of children sharing the room. | |
| currency | No | ISO currency code for the prices returned, e.g. "usd". | |
| hotel_name | Yes | The property name a person would type, e.g. "Hotel Artemide". Adding the city ("Hotel Artemide Rome") disambiguates a chain with many properties. No internal property ID is needed. | |
| checkin_date | Yes | First night of the stay, "YYYY-MM-DD". | |
| checkout_date | Yes | Departure morning, "YYYY-MM-DD". Must be after checkin_date. | |
| price_as_seen_from | No | Two-letter country code, e.g. "de". Prices the stay as a shopper resident in that country would see it. Call each country a few times on this same property before reporting a gap, because rates move between calls and gaps are usually modest and property-dependent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| results | Yes | The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. |
| api_usage | No | What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed. |
| signup_url | No | Where the caller subscribes or changes plan. |
| result_count | No | |
| needs_api_key | No | True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it. |
| applied_filters | No | Which of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through. |
| quota_exhausted | No | True when the caller's RapidAPI plan has no requests left for the current period. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description fully discloses live external API behavior, the need for an API key, usage costs, and that rates can change between calls. It also warns 'never reuse an earlier result,' which is meaningful behavioral context beyond the readOnly/Idempotent annotations.
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 description is organized into clear, purposeful sections: the core lookup behavior, the price_as_seen_from caveat, freshness warning, and API key instructions. While a bit long, every section adds operational value and the structure makes it easy to scan.
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?
It covers what the tool returns, authentication requirements, cost attribution, freshness expectations, and a specific pricing-locale caveat. That is sufficient for correct invocation, though the exact output schema shape is not spelled out in the description.
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?
The input schema already has 100% coverage with detailed parameter descriptions, including disambiguation guidance and checkout-after-checkin constraints. The prose mostly repeats these details rather than adding new parameter-level meaning, so it meets the baseline but does not go beyond it.
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?
The description opens with 'FlightPowers single-property lookup' and says it returns availability, pricing, review score, room type, and a booking link. This clearly defines the tool's exact function and distinguishes it from broad hotel search or flight search siblings.
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 description explicitly says to use it 'to check one specific hotel, or to track a single property's price over time,' which gives clear usage guidance. It does not explicitly mention the sibling search_hotels tool as the alternative for broad searches, but the 'single-property' framing makes that distinction clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_hotelsFlightPowers: search hotelsARead-onlyInspect
FlightPowers hotel search: live Booking.com availability and nightly prices for a destination and date range. Input: a free-text destination the way a person would say it ("Rome", "Tokyo Shibuya"), plus check-in and check-out dates. Returns each property's price, review score, room type, location and a booking link.
Set price_as_seen_from to a two-letter country code to price the same stay the way a shopper resident in that country would see it, which no other travel tool here can do. Gaps are real but usually modest and property-dependent, and rates move between calls, so hold one named property fixed, call each country a few times, and never read one call per country as a gap.
Rates go stale within minutes: never reuse an earlier result, search again.
Requires the caller's own RapidAPI key for the Booking Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/booking-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage.
| Name | Required | Description | Default |
|---|---|---|---|
| adults | No | Number of adult guests. Defaults to the upstream default when omitted. | |
| filters | No | Property filters to apply, e.g. ["free_cancellation", "breakfast_included"]. An unknown name is rejected with the list of valid ones rather than being ignored. | |
| children | No | Number of children sharing the room. | |
| currency | No | ISO currency code for the prices returned, e.g. "usd". | |
| destination | Yes | Where to stay, in free text the way a person would say it, e.g. "Rome" or "Tokyo Shibuya". A city, district, landmark or region all work; no internal location ID is needed. | |
| checkin_date | Yes | First night of the stay, "YYYY-MM-DD". | |
| checkout_date | Yes | Departure morning, "YYYY-MM-DD". Must be after checkin_date. | |
| budget_per_night | No | Only return properties at or below this nightly price, in `currency`. | |
| price_as_seen_from | No | Two-letter country code, e.g. "de". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. For a rate-parity check hold one named property fixed and call each country a few times, because rates move between calls and one call per country can show a gap that is not there. Omit it for a neutral price. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| results | Yes | The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. |
| api_usage | No | What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed. |
| signup_url | No | Where the caller subscribes or changes plan. |
| result_count | No | |
| needs_api_key | No | True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it. |
| applied_filters | No | Which of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through. |
| quota_exhausted | No | True when the caller's RapidAPI plan has no requests left for the current period. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses several important behaviors: results are live and go stale within minutes, unknown filters are rejected rather than ignored, API usage is charged to the caller's own plan, and the first non-empty API key source wins. This goes well beyond what the annotations alone convey.
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 description is somewhat long, but nearly every sentence carries necessary operational or behavioral information. The repetition around rate-parity checks is slightly verbose but serves an important warning purpose, so the length is justified overall.
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 description covers what the tool returns, how to supply inputs, how pricing and filtering behave, how rate-parity checks should be performed, and how API keys and usage accounting work. Combined with the output schema, an agent has everything needed to invoke and interpret this tool correctly.
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?
The schema already covers 100% of parameters with meaningful descriptions, and the tool description adds further value by explaining the semantics of price_as_seen_from, including the country-code behavior and how to interpret rate-parity results. Parameter meaning is fully clear.
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?
The description clearly states that this is a hotel search tool for live Booking.com availability and nightly prices by destination and date range. It is immediately distinguishable from the flight-search siblings, and the title reinforces the purpose.
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 description gives direct guidance on when to use the tool and how to use it correctly, including the rate-parity workflow with price_as_seen_from, the need to hold one property fixed, and the warning that rates move between calls. It also explains API key handling and billing, leaving no ambiguity about operational usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_oneway_flightsFlightPowers: search one-way flightsARead-onlyInspect
FlightPowers one-way fare search: live prices read from Google Flights. Input: origin and destination IATA codes -- the destination may be several codes, as "BCN,LIS,ATH" or ["BCN","LIS","ATH"] -- plus either one departure date or a date range. Returns each flight's price, airline, duration, stops, a bookable buy_link, and Google's historical price range (price_insights_low / price_insights_high) so you can say whether a fare is actually a good deal.
Use it for any one-way fare question, including open-ended ones. For a flexible search make ONE call with a date range and/or several destinations -- do NOT call it once per date. 'Cheapest flight to Sri Lanka anywhere in October' is one call, not thirty.
Each date/destination combination is one billed request; the count and the plan's remaining quota come back in api_usage.
by_destination carries one entry per destination you asked for -- empty ones included, each with a reason -- so read it before telling a user a destination has no flights.
Requires the caller's own RapidAPI key for the Google Flights Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/google-flights-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum flights to return, after merging and sorting. | |
| sort_by | No | "best", "price", or "duration". Applied across all results. | best |
| currency | No | ISO currency code, default "usd". | usd |
| max_price | No | Only return flights at or below this price. | |
| max_stops | No | Maximum stops per flight. 0 means non-stop only. | |
| seat_type | No | 1 economy, 2 premium economy, 3 business, 4 first. | |
| passengers | No | Passenger counts as [adults, children, infants]. | |
| to_airport | Yes | Destination airport. One IATA code ("BCN"), several separated by commas ("BCN,LIS,ATH"), or a list (["BCN","LIS","ATH"]) -- every shape is accepted and the destinations are compared in the same search. | |
| from_airport | Yes | Origin IATA code, e.g. "TLV". One origin per search; a second one is refused rather than searched. | |
| max_searches | No | Cap the billed requests this call may make. Lower it to spend less of the plan's quota on a wide search; the range is then sampled evenly rather than cut short. | |
| use_fallback | No | Leave unset. Switches the search to a second, independent flight data source instead of the usual Google Flights page read. Unset already escalates to that source once, automatically, after a search's retries have failed. true forces it inline on every attempt -- much slower, and it can time out. false disables it entirely, that automatic retry included. | |
| airline_codes | No | Restrict to these airline codes, e.g. ["LY"]. | |
| departure_date | No | Single departure date, "YYYY-MM-DD". | |
| arrival_time_max | No | Latest arrival hour, 0-23. | |
| arrival_time_min | No | Earliest arrival hour, 0-23. | |
| departure_date_to | No | Last date of a departure range. | |
| departure_time_max | No | Latest departure hour, 0-23. | |
| departure_time_min | No | Earliest departure hour, 0-23. | |
| departure_date_from | No | First date of a departure range. | |
| exclude_airline_codes | No | Exclude these airline codes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Present when there is something the model must relay to the user rather than silently absorb -- no results, a degraded search, a missing key or a spent quota. |
| partial | No | Present when some searches failed but others succeeded. Plain text saying how much of the request the results cover. |
| results | Yes | The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. |
| api_usage | No | What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed. |
| signup_url | No | Where the caller subscribes or changes plan. |
| result_count | No | |
| needs_api_key | No | True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it. |
| search_status | No | Whether the underlying search actually completed, read from the backend's X-Search-Status header. 'ok': every combination searched returned results. 'empty': the search completed and Google genuinely has no itineraries for it -- a real answer, not a failure. 'partial': some combinations returned results and some failed, so the list is incomplete. 'degraded': every combination failed, so the search did not happen and an empty list means nothing; this case is also flagged with isError: true and is safe to retry. |
| by_destination | No | One entry per destination the REQUEST asked for, in request order, present whether or not that destination has any flights in `results`. A destination with an empty `rows` array is a hole in the answer, and `reason` says which kind of hole: 'no_flights' (searched, answered, Google has nothing), 'search_failed' (searched and the search errored, so nothing is known), 'not_in_limit' (searched, found flights, none fitted in `limit`) or 'not_searched' (never searched -- the per-call fan-out cap sampled it away). 'ok' means it has rows. Read this rather than inferring coverage from `results`: a destination missing from `results` looks identical to one that has no flights, and they are not the same answer. `rows` are the same row objects that are in `results`, in the same order -- nothing here is data the answer does not already contain. |
| quota_exhausted | No | True when the caller's RapidAPI plan has no requests left for the current period. |
| search_coverage | No | What was actually searched. Present whether or not the request was truncated, so a model can state honestly what its answer rests on. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses return fields (price, airline, duration, stops, buy_link, price_insights) and billing reporting via api_usage. It further explains fallback source behavior, max_searches sampling, and that usage counts against the caller's own RapidAPI plan, all beyond the annotations.
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?
Although lengthy, each paragraph serves a distinct purpose—result contents, invocation advice, billing, and API-key setup—and includes concrete examples without redundant filler. The structure is logical and easy to scan.
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 description covers key operational concerns an external agent needs: API key requirements, quota reporting, multi-destination/date handling, and fallback behavior. Since an output schema is present, no additional return-value documentation is necessary.
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?
All 20 parameters have schema descriptions, and the description adds practical semantics such as accepted shapes for to_airport, origin singularity, date-range versus single-date usage, and seat_type/passenger mappings. This goes well beyond the schema's basic property descriptions.
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?
Title and first sentence explicitly state 'one-way fare search' and 'live prices read from Google Flights,' clearly distinguishing it from sibling roundtrip/hotel tools. The verb 'search' plus resource 'flights' makes the purpose unambiguous.
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 description gives explicit guidance: 'Use it for any one-way fare question' and 'do NOT call it once per date,' with a concrete example of a single flexible search. It also explains API-key requirements, billing consequences, and that a second origin is refused rather than searched.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_roundtrip_flightsFlightPowers: search round-trip flightsARead-onlyInspect
FlightPowers round-trip fare search: live prices read from Google Flights, priced as paired legs rather than two separate one-ways. Input: origin and destination IATA codes -- the destination may be several codes, as "BCN,LIS,ATH" or ["BCN","LIS","ATH"] -- a departure date or range, and either a return date or a trip length in nights. Returns the total price for both legs, per-leg airline, stops and duration, and a single bookable buy_link for the trip.
Use it for any return-trip fare question. For a flexible search make ONE call: pass departure_date_from / departure_date_to for the outbound range and nights instead of return_date to compare trip lengths -- '5 to 7 nights in Rome sometime in May' is one call.
Each date/destination combination is one billed request; the count and the plan's remaining quota come back in api_usage.
by_destination carries one entry per destination you asked for -- empty ones included, each with a reason -- so read it before telling a user a destination has no flights.
Requires the caller's own RapidAPI key for the Google Flights Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/google-flights-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum trips to return, after merging and sorting. | |
| nights | No | Trip length in nights; a number, or a list like [5, 6, 7]. The return date is derived from each departure date. | |
| sort_by | No | "best", "price", or "duration". Applied across all results. | best |
| currency | No | ISO currency code, default "usd". | usd |
| max_price | No | Only return trips at or below this total price. | |
| seat_type | No | 1 economy, 2 premium economy, 3 business, 4 first. | |
| passengers | No | Passenger counts as [adults, children, infants]. | |
| to_airport | Yes | Destination airport. One IATA code ("BCN"), several separated by commas ("BCN,LIS,ATH"), or a list (["BCN","LIS","ATH"]) -- every shape is accepted and the destinations are compared in the same search. | |
| return_date | No | Fixed return date. Use this OR nights, not both. | |
| from_airport | Yes | Origin IATA code, e.g. "TLV". One origin per search; a second one is refused rather than searched. | |
| max_searches | No | Cap the billed requests this call may make. Lower it to spend less of the plan's quota on a wide search; the range is then sampled evenly rather than cut short. | |
| use_fallback | No | Leave unset. Switches the search to a second, independent flight data source instead of the usual Google Flights page read. Unset already escalates to that source once, automatically, after a search's retries have failed. true forces it inline on every attempt -- much slower, and it can time out. false disables it entirely, that automatic retry included. | |
| departure_date | No | Single outbound date, "YYYY-MM-DD". | |
| max_return_stops | No | Maximum stops on the return leg. | |
| departure_date_to | No | Last date of an outbound range. | |
| departure_date_from | No | First date of an outbound range. | |
| max_departure_stops | No | Maximum stops on the outbound leg. | |
| return_airline_codes | No | Restrict the return leg to these airlines. | |
| departure_airline_codes | No | Restrict the outbound leg to these airlines. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Present when there is something the model must relay to the user rather than silently absorb -- no results, a degraded search, a missing key or a spent quota. |
| partial | No | Present when some searches failed but others succeeded. Plain text saying how much of the request the results cover. |
| results | Yes | The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. |
| api_usage | No | What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed. |
| signup_url | No | Where the caller subscribes or changes plan. |
| result_count | No | |
| needs_api_key | No | True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it. |
| search_status | No | Whether the underlying search actually completed, read from the backend's X-Search-Status header. 'ok': every combination searched returned results. 'empty': the search completed and Google genuinely has no itineraries for it -- a real answer, not a failure. 'partial': some combinations returned results and some failed, so the list is incomplete. 'degraded': every combination failed, so the search did not happen and an empty list means nothing; this case is also flagged with isError: true and is safe to retry. |
| by_destination | No | One entry per destination the REQUEST asked for, in request order, present whether or not that destination has any flights in `results`. A destination with an empty `rows` array is a hole in the answer, and `reason` says which kind of hole: 'no_flights' (searched, answered, Google has nothing), 'search_failed' (searched and the search errored, so nothing is known), 'not_in_limit' (searched, found flights, none fitted in `limit`) or 'not_searched' (never searched -- the per-call fan-out cap sampled it away). 'ok' means it has rows. Read this rather than inferring coverage from `results`: a destination missing from `results` looks identical to one that has no flights, and they are not the same answer. `rows` are the same row objects that are in `results`, in the same order -- nothing here is data the answer does not already contain. |
| quota_exhausted | No | True when the caller's RapidAPI plan has no requests left for the current period. |
| search_coverage | No | What was actually searched. Present whether or not the request was truncated, so a model can state honestly what its answer rests on. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses external RapidAPI dependency, caller-provided key requirements, billing/quota consumption, retry and fallback behavior, and the fact that each destination/date combination is a billed request. This goes beyond the read-only annotation and gives accurate expectations of side effects.
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 description is thorough but somewhat long, with some details repeated across paragraphs and parameter descriptions. However, the content is organized into clear topical paragraphs and nearly every sentence carries practical guidance, making the length justified overall.
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?
Covers external API integration, authentication, billing, fallback source switching, result composition, and the meaning of api_usage and by_destination. Given the tool's complexity and external dependencies, the description contains all necessary context for correct invocation and interpretation.
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?
Every schema parameter has a meaningful description, and the description adds important semantic details such as single-origin refusal, accepted destination formats, nights vs return_date exclusivity, and even sampling behavior for max_searches. The prose supplements the schema rather than merely repeating it.
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?
Clearly identifies the tool as a round-trip flight fare search reading live prices from Google Flights and pricing paired legs, not separate one-ways. This distinguishes it from the sibling one-way search tool without ambiguity.
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?
Explicitly directs use for any return-trip fare question and gives concrete guidance for flexible date ranges, multi-destination searches, and quota control via max_searches. The instructions about return_date vs nights and fallback behavior leave little room for misuse.
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
v1.0.0- First observed
find_hotel_by_name - First observed
search_hotels - First observed
search_oneway_flights - First observed
search_roundtrip_flights
TDQS
Scored across 4 tools
Each tool targets a clearly distinct query type: one-way flights, round-trip flights, general hotel search, and specific hotel lookup. Even the two hotel tools are easy to differentiate because one is broad destination search and the other is single-property lookup.
Three tools follow the search_<subject> pattern: search_oneway_flights, search_roundtrip_flights, and search_hotels. find_hotel_by_name breaks the pattern by using find_ instead of search_, though it remains readable and predictable.
Four tools is a well-scoped set for a travel-search server. Each tool earns its place and the count avoids both bloat and thinness.
The core search workflows are covered: one-way flights, round-trip flights, hotel search, and named-hotel lookup. Obvious gaps include multi-city flight search and airport/place code resolution, but agents can work around these with external knowledge or by combining existing tools.
Maintenance
Related MCP Connectors
Google Flights search data: fares, routes, stops, and price insights via a hosted MCP server.
Flight Intelligence MCP — search, cheapest dates, multi-city, airline compare via Google Flights
Flight search, airfare analytics, flexible destinations
Live flight prices and working booking links for AI agents and travel apps.
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 gradedqualityDmaintenanceProvides 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.1123 npm50 PyPI6MIT
- AlicenseNot gradedqualityDmaintenanceEnables real-time one-way and round-trip flight searches from any MCP client without an API key or account, returning live fares, historical price insights, and bookable links supported by disclosed sponsored cards.1MIT