
Aviasales Flight Prices
io.github.stufentlyv0.5.0更新于 Oct 9, 2026
Flight price search via Aviasales/Travelpayouts: fares by route, cheapest days, flexible dates.
概览
让助手按航线、最便宜日期、灵活日期、预算和附近机场查询 Aviasales/Travelpayouts 的缓存机票价格。
- 功能
- 十三个只读工具用于回答机票价格问题:search_flights 查询两个城市在某天或某月的票价,get_prices_calendar 给出最便宜的出行日,get_flexible_date_prices 比较前后几天,另有 get_latest_prices、get_popular_directions、get_city_directions、get_alternative_directions 用于灵感搜索和邻近机场,search_by_price_range 用于预算查询。参考类工具(lookup_airlines、lookup_airports、lookup_cities、lookup_countries、find_nearest_airports)把地名解析为 IATA 代码并按距离排序机场。响应带有 status、price_summary 和提示信息,价格始终为经济舱成人单价。
- 适用场景
- 适合让助手用自然语言回答机票价格问题:某航线某月的票价、最便宜的出行日、改一天是否更便宜,或在预算内能飞往哪里。它面向行程规划和灵感搜索,而不是订票,因为它只做搜索并给出外链。
- 运行要求
- 以本地 stdio 进程运行,通常由 MCP 客户端启动容器镜像 ghcr.io/stufently/aviasales-mcp,需要 Docker;README 提到后续会支持 PyPI/uvx。必须提供免费的 Travelpayouts API 令牌,放在 AVIASALES_API_TOKEN 中。可选设置包括 AVIASALES_MARKET、AVIASALES_PARTNER_ID、AVIASALES_DEFAULT_CURRENCY 和 AVIASALES_LOCALE。需要能访问 Travelpayouts Data API 的网络。
安装
在 SourceWeft 中
- 打开 控制台中的 Aviasales Flight Prices,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
aviasales-mcp
MCP server for flight price search via Aviasales / Travelpayouts Data API. Thirteen read-only tools that let Claude Code, Claude Desktop, Cursor or any other MCP client answer flight-price questions: fares by route and month, the cheapest day to fly, flexible dates, budget and inspiration search, plus airport/city/airline lookup.
Unlike Google-Flights-scraping MCP servers, place names do not have to be
guessed into IATA codes by the model: lookup_cities and find_nearest_airports
resolve them.
Common prompts
Ask your agent in plain language — it picks the tool.
Install
You need two things: Docker, and a free Travelpayouts API token from https://www.travelpayouts.com/programs/100/tools/api.
The server ships as a container image, ghcr.io/stufently/aviasales-mcp. Your
MCP client starts it on demand, so there is nothing to install beyond pasting one
block below. To check the image starts, send it one initialize — it should
print a JSON reply naming the server, "name":"Aviasales". This does not test
the token itself; a wrong one surfaces as an error on the first search:
:latest follows releases; pin a version tag (:0.5.0) if you would rather
upgrade by hand. The package is also PyPI-ready; once it is on PyPI, uvx aviasales-mcp will work wherever docker run -i --rm … image does below.
MCP client configs
Every block runs the same command. -e AVIASALES_API_TOKEN with no value hands
the container the variable the client sets in env, so the token is written in
exactly one place. AVIASALES_MARKET is optional but worth setting — see
Configuration; delete it and its -e pair if you do not need it.
Keep the token out of anything you commit. A project-level
.mcp.json,.cursor/mcp.jsonor.zed/settings.jsonis a normal thing to check into git, and a token pasted there goes with it. Prefer the user-level config file, or.gitignorethe project one.
Claude Code
--scope user makes it available in every project and keeps the token in
~/.claude.json, out of the repository. Check with claude mcp list.
Claude Desktop, Cursor, Windsurf
All three take the same mcpServers JSON; only the file differs:
Claude Desktop starts with a trimmed PATH and may not find docker by name: if
the server fails to start, replace "docker" with its absolute path
(which docker).
Zed
~/.config/zed/settings.json (or zed: open settings):
Codex
Or by hand in ~/.codex/config.toml:
Any other stdio client
Command docker, arguments
run -i --rm -e AVIASALES_API_TOKEN ghcr.io/stufently/aviasales-mcp:latest, and
AVIASALES_API_TOKEN in the environment the client gives the process. The
server is also listed in the official MCP registry as
io.github.stufently/aviasales-mcp, which clients with a registry browser can
install from directly.
Tools
Flight prices
search_flights, get_prices_calendar, get_flexible_date_prices and
get_latest_prices accept adults (1–9), children (0–8), infants (0–8) and
trip_class (economy/comfort/business/first).
The Data API serves a cache of recent searches and takes no passenger
parameters, so the party is encoded into each ticket's booking_link instead —
the link opens Aviasales with the full party and class pre-filled and shows the
real total. The prices themselves are always per adult in economy, which is
what the price_note field on every price response spells out for the model.
search_flights also takes depart_after / depart_before (HH:MM, 24-hour)
to keep only departures in a time window; set depart_after later than
depart_before for a window that wraps midnight (red-eyes).
Tickets carry duration_total (door-to-door minutes), duration_to /
duration_back (flight time per direction) and layover_minutes (combined
ground time between connections). Every price response also carries a
price_summary (min/median/max) so the model can tell a good fare from a bad one
without a second search.
Reference data
The lookup_* tools take search, limit (default 50, max 500) and locale,
and return {status, total, returned, truncated, data}. Always pass search:
the underlying datasets are ~10k airports and ~9.6k cities, which is far more
than any model can hold in context. Matches are ranked (exact code, then exact
city code, then name), and airports with no scheduled service sort last. Each
dataset is downloaded once per process and cached for 24 hours.
find_nearest_airports answers the question lookup_airports cannot: the
closest airport is rarely named after the town. It resolves near="Pattaya"
against the cached city and airport datasets and ranks by great-circle distance —
no third-party geocoder involved.
Errors and empty results
Every response carries status ("ok" or "error"), so an empty data list is
never confused with a failure. Bad input is refused before the API call, with the
expected format spelled out ("departure_at must be \"YYYY-MM-DD\" or \"YYYY-MM\"…"), and both error and empty responses carry a hint naming what to
try next. On a rejected argument the hint says what to substitute and which tool
resolves it — enough for the model to fix the call itself on the second attempt.
Setup
Building the image yourself from a checkout, instead of pulling it:
- Get an API token at https://www.travelpayouts.com/programs/100/tools/api
- Copy
.env.exampleto.envand fill in your token - Build and run with Docker:
Configuration
AVIASALES_MARKET is worth setting: the price cache is per market, and the same
route in the same currency comes back at a different price for ru and us.
HTTP transport
By default the server speaks stdio, which is what local MCP clients expect.
Setting MCP_PORT switches it to streamable-HTTP so it can be reached remotely:
The endpoint is then http://<host>:8080/mcp, and every request must present
the token as Authorization: Bearer <token>; anything else gets a 401.
Some MCP clients cannot set headers. MCP_AUTH_ALLOW_QUERY_TOKEN=true also
accepts ?token=<token>, but note that uvicorn — and any proxy in front of it —
writes the full URL to its access log, so the secret ends up in logs. Prefer the
header.
There is no TLS here: terminate it at a reverse proxy if the port is reachable from anywhere untrusted.
Without MCP_AUTH_TOKEN the port is unauthenticated and anyone who reaches it
can spend your Travelpayouts quota. Loopback binds are allowed (with a warning);
binding anything else refuses to start unless you also set
MCP_ALLOW_INSECURE_HTTP=true.
Limitations
- Prices are a cache of recent searches, not live availability. A fare can be
gone by the time the link opens;
expires_atsays when the quote lapses. - Prices are always per adult in economy. Passenger count and cabin change the booking link, never the quoted number.
- No booking. This server searches and links out; it never holds or buys.
- Cache coverage is uneven. An empty result means nobody searched that route recently, not that the route does not exist.
get_latest_prices, the matrices and nearby airports come from the older v2 response shape: they name the sellingagencyrather than the airline and carry no flight number.- Rate limits are per endpoint (600/min for most, 60/min for the week and nearby matrices). The server retries 429s and warns when the published quota runs low.
Development
CI runs the suite on Python 3.12, 3.13 and 3.14 plus a Docker image build — see
.github/workflows/ci.yml.
License
GPL-3.0-or-later — see LICENSE.
来源:README.md,提交 917b5b9
工具
0版本历史
1- v0.5.0最新Oct 9, 2026
