
Rihla
io.github.leojg由 GitHub 帳號 leojg 發布v0.1.0更新於 Oct 27, 2026
Flexible multi-leg, multi-airport flight search - cheapest valid combination across an itinerary.
概覽
Rihla 是本地 MCP 伺服器,用於彈性的多段、多機場航班搜尋,為整趟行程估價並找出最便宜的有效組合。
- 可以做什麼
- 把地名解析成 IATA 機場代碼,並附上鄰近替代機場,且不消耗搜尋配額
- 依彈性機場、出發時間窗與停留天數搜尋多段行程,回傳排序後最便宜的組合
- 標示每段航班的價格來源,區分參考價與可預訂票價,並在部分航段無法估價時回傳部分結果
- 為排序後的行程提供訂票連結
- 適用情境
- 適合規劃含多段航程、多個可選機場或彈性日期的旅行,想要整趟行程最便宜的組合而非逐段比價時使用。也適合離線示範,因為不需金鑰即可用確定性的模擬資料執行。
- 執行需求
- 本機 Python 3.10 以上的程序,從 PyPI 安裝(rihla-mcp,可用 uvx 執行),透過 stdio 通訊。取得即時價格需要 TRAVELPAYOUTS_TOKEN 中的 Travelpayouts Data API 權杖,並可選用 SERPAPI_KEY 中的 SerpApi 金鑰;RIHLA_PROFILE 用來選擇 local、hosted 或 mock 資料來源。未設定金鑰時會退回離線模擬資料。使用即時來源需要網路連線。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Rihla,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Rihla
Rihla (رحلة), "the journey." Named for Ibn Battuta's 14th-century travelogue — the record of history's farthest-traveling explorer, who left Tangier for Mecca and kept going for 29 years and 75,000 miles.
Flexible multi-leg, multi-airport flight search that finds the cheapest route across an entire itinerary — available as a CLI and as an MCP server for AI agents.
Consumer flight sites price one leg at a time. Rihla treats the whole trip as a single optimization problem:
"Leave Montevideo — or Buenos Aires, it's a ferry ride away — around September 15 for Europe. Stay 20–30 days, then Japan for 15, then home. What's the cheapest combination?"
That query has three legs, flexible airports on both ends of each, a flexible departure window, and stay-duration constraints linking the legs. Rihla prices each leg's date×airport grid once, then finds the cheapest valid combinations in pure local compute — so even a 3–4 leg flexible query costs only a handful of API calls.
Note the airport substitution at work: it enters Europe through Amsterdam, leaves from Frankfurt, and flies home into Buenos Aires — each leg independently picks the cheapest airport pair from its sets.
Quick start
Requires Python ≥ 3.10.
Runs offline out of the box (no keys needed — a deterministic mock data source):
For live prices, copy .env.example to .env and add at least a
Travelpayouts token (free). See
Data sources.
Writing a query
A query is a small JSON file: your origin airports, the ordered stops, a departure window for the first leg, and how long to stay at each stop. Downstream date windows are derived — you never hand-compute "if I leave Sep 15 and stay 20–30 days, when do I fly to Tokyo?"
origins— IATA codes tried as one origin set; the cheapest wins per date.stops— each stop is a region name or a list of IATA codes. Built-in regions:EUROPE(MAD, BCN, LIS, CDG, FCO, AMS, FRA),TOKYO(NRT, HND),MVD_AREA(MVD, EZE, AEP). Make the last stop your origin set to fly home.earliest/latest— the departure window for the first leg only.stays—[min, max]nights at each intermediate stop (len(stays) == len(stops) - 1).date_step— sample every N days across date windows (coarser = fewer API calls).top— how many ranked combinations to return.currency— optional ISO 4217 code (defaultUSD).
rihla -i walks you through these questions and prints the resulting JSON to save for
reuse. Add --links to any run to show booking URLs.
Reading results
Rihla is honest about data quality rather than pretending everything is bookable:
- Each flight is tagged with its source, and
cachedwhen the price is indicative (Travelpayouts data is aggregated search history, not a live fare) versus a real, bookable fare (SerpApi / Google Flights). - If some legs can't be priced (thin routes are real — cached sources have gaps), you get a partial result over the legs that were found, never a silently wrong total.
- For unpriced legs, Rihla shows the nearest cached fares outside your departure window — a hint to shift or widen dates.
Ranking is price-only in v0.1. Open-jaw within a region is allowed by default (enter Europe at one city, leave from another); the cost of repositioning inside the region is not modeled.
Data sources & profiles
Configure via .env (see .env.example) or environment variables:
TRAVELPAYOUTS_TOKEN, SERPAPI_KEY, and RIHLA_PROFILE:
local(default) — every source whose key is set, including SerpApi.hosted— redistribution-licensed sources only (SerpApi disabled: it scrapes Google, so do not serve it from a public hosted instance).mock— force the offline fetcher, no network.
With no keys set, Rihla falls back to the mock source and says so.
MCP server
Rihla ships an MCP server (stdio) so agents like Claude can run trip searches:
or in any MCP client config:
(The server also loads a .env from its working directory, so env is optional if you
run it from a checkout.)
It exposes two read-only tools with an enforced etiquette:
resolve_airports— the agent proposes IATA codes for the traveler's named places; Rihla validates and enriches them (nearby alternatives included). Cheap and quota-free.search_trip— the priced, quota-limited search. Tool descriptions instruct the agent to get the traveler's explicit confirmation of the airports before spending quota here.
mcp-name: io.github.leojg/rihla
How it works
Leg prices are independent — the MVD→Europe fare doesn't depend on the Tokyo dates. So Rihla fetches each leg's date×airport grid once, then enumerates valid date combinations (respecting the stay constraints) entirely in memory. The combinatorial explosion lives in local compute, not in API calls.
Adding a data source (Duffel, Kiwi, …) is one more class implementing a one-method
protocol: quote(origin, dest, day) -> Quote.
Scope (v0.1): flight search only — no lodging, no booking or payments, single adult, one cabin. Search returns booking links, never handles the transaction.
Development
License
Licensed under the Apache License 2.0 — see LICENSE.
來源:README.md,提交 24a35e4
工具
0版本歷史
1- v0.1.0最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分