LetsFG — Flights & Hotels

io.github.LetsFG由 GitHub 帳號 LetsFG 發布v2026.5.77更新於 Oct 24, 2026

Search and book flights and hotels: hundreds of airlines, plus bookable hotel rates.

已驗證Streamable HTTP可網頁執行位置與生活商業與電商

概覽

AI 產生的概覽

LetsFG 讓 AI 助理搜尋全球即時機票與飯店價格並完成預訂,費用先圈存在已綁定的卡片上,直到產生真實航空公司 PNR。

可以做什麼
  • 依航線與日期搜尋航班,支援艙等篩選與城市多機場擴展
  • 取得並反覆輪詢搜尋結果,直到報價全部回傳
  • 以旅客與聯絡人資料預訂選定的報價,並輪詢直到開票(PNR)或釋放圈存
  • 搜尋並預訂飯店房價,每個報價會標明是否可退款
  • 透過開發者 API 金鑰使用帳戶與付款工具,適合預付制的高用量商業用途
適用情境
適合希望助理在同一次對話中既查找又真正預訂機票或飯店的場合,不必手動比對多個分頁。適用於個人旅遊規劃與由代理程式驅動的預訂流程;多數代理程式並不需要另外的付費開發者 API。
執行需求
遠端端點 letsfg.co/mcp 並以 OAuth 授權,或使用本機 npm 套件 letsfg-mcp(stdio)。本機伺服器需要連線流程取得的 LETSFG_BEARER_TOKEN;開發者 API 路徑需要 LETSFG_API_KEY。首次預訂時須加入付款卡,搜尋本身免費。需要連線至 LetsFG 伺服器的網路。
安裝前請注意
預訂會產生實際支出:機票或飯店費用會圈存在已綁定的卡片上,並在產生 PNR 或飯店確認後請款。卡片資料在 Revolut 設定流程中輸入,不會交給助理。預訂會把真實旅客與聯絡人資料送交 LetsFG 及其賣方;失敗或需人工處理的預訂不要貿然重試。LETSFG_API_KEY 與 LETSFG_BEARER_TOKEN 屬於機密。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 LetsFG — Flights & Hotels,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.LetsFG%2Fletsfg/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "letsfg-flights-hotels": {
      "type": "http",
      "url": "https://letsfg.co/developers/api/mcp"
    }
  }
}

README

[LetsFG]

We're LetsFG — a community of travelers.

Finding a flight or hotel shouldn't mean checking 47 tabs. Or 3 hours of searching.
Or having that feeling you could've got a better deal if you'd just waited a little longer.

So we built something about it.
One total price. No tracking. No price that goes up because you looked twice.


[Add to Claude]    [Star to show love]    [Try on letsfg.co]    [pip install]


[Follow on Instagram]    [Follow on TikTok]    [Follow on X]


Join the community. Help others find cheaper flights. Spread the word.
⭐ Star the repo. Share with a friend ✈️

[Share on X]   [Share on LinkedIn]   [Share on Reddit]   [Share on WhatsApp]   [Share on Telegram]   [Send via Email]


Flights and hotels. Both live.

Every airline in the world. Real prices. One function call.

LetsFG gives your AI agent flight and hotel search and booking superpowers. Our server-side engine scans the entire world for the cheapest price. Search is free. Booking is real: the fare is held on your card, a LetsFG booking agent buys the ticket, and you get the airline's PNR.

The same flight costs $20–$50 less because you skip OTA inflation, cookie tracking, and surge pricing.

Claude: LetsFG is in Claude's connector directory: add it there, no URL to paste. Other agents: add https://letsfg.co/mcp as an MCP server. Approving the connection opens letsfg.co/connect: one tap, no card. The card is asked for at your first booking, in a 0.00 Revolut setup (nothing is charged, no Revolut account needed). That token searches for free and books. Scripts: send the same token as Authorization: Bearer to the PFS endpoints. Developer API: a separate paid product for high-volume commercial use; most agents do not need it. → Get started


[GitHub stars] [PyPI] [npm] [Connector Health] [MCPVault: claimed] [MIT License]


Supporters

[Evomi - Residential Proxies $0.49/GB]

Real prices: LetsFG vs Google Flights

We searched 5 routes on Google Flights and LetsFG on the same day (2026-08-05), for flights departing 2026-09-16. Same airline, same number of stops — LetsFG was cheaper every time:

RouteAirlineGoogle FlightsLetsFGYou Save
LAX → Paris (CDG)JetBlue, 1 stop$363$334$29
SFO → London (LHR)JetBlue, 1 stop$349$333$16
LA → New York (JFK)JetBlue, nonstop$174$157$17
London → Singapore (SIN)Shenzhen Airlines, 1 stop$395$380$15
Chicago → Dubai (DXB)Air Canada + Emirates, 2 stops$517$461$56

$133 cheaper across 5 routes in a verified comparison (2026-08-05). LetsFG returns the same prices however often you run the search, because it doesn't track you.

Why the difference? LetsFG compares the same flight across many sellers — Skyscanner, Kayak, Momondo, plus airline websites (Ryanair, United, Southwest, EasyJet, Spirit, Norwegian, AirAsia, and more) — and shows the cheapest. No cookie tracking: the same search returns the same prices however often you run it.


Real hotel prices: LetsFG vs Booking.com

Same hotel, same room type, same 2-night stay, same free-cancellation policy — checked on the same day (2026-08-05) for a 2026-09-16 check-in:

HotelBooking.comLetsFGYou Save
Hotel Boss, Warsaw$206$169$37
ibis Styles Paris Gare de l'Est$663$525$138
Copthorne Tara Hotel, London Kensington$379$347$32

$207 cheaper across 3 hotels in a verified comparison (2026-08-05), matching each property's own free-cancellation rate against Booking.com's free-cancellation rate for the identical dates and room type. Prices quoted in PLN at booking, converted to USD at that day's rate.

Why the difference? LetsFG's price does not rise with demand or with who is searching, and there is no loyalty-program cross-subsidy. At booking the price is held on your card, not taken, and it is charged only once the hotel confirms. The comparison above uses free-cancellation rates on both sides; LetsFG also sells non-refundable rates, and every offer says which it is.


Try it right now — no install needed

Human users: Use letsfg.co and search flights instantly in your browser:

Search any route, compare live results, and book the flights you want — no installation needed.

Agents / scripts (free server-side): Get a Bearer token by putting a payment method on file (nothing is charged) → use POST /api/search and POST /api/agent-book. This is PFS — Programmatic Flight Search powered by the letsfg.co engine. Search is free; the token is short-lived and refreshes itself. See letsfg.co/for-agents for the full guide.

When you're ready to integrate it into your own agent, keep reading.


Three ways to use LetsFG

Path 1 — MCP / CLI / SDKPath 2 — PFS (Programmatic Flight Search via letsfg.co)Path 3 — Developer API
Best forAI agents (Claude, ChatGPT, Cursor, Windsurf), personal use — easiest way inScripts/agents calling the API directly with a Bearer tokenHigh-volume commercial integrations that want prepaid billing. Most agents should not use this
Speed8–10 s to first results8–10 s to first results2–5 s (discover) · 8–10 s to first results (full search)
Search costFree (connect once: one tap, no card)Free (connect once: one tap, no card)Look-to-book: 200 free after every booking, then $0.01
Bookingbook_flight — fare held on your card, agent buys the ticket, real PNRPOST /api/agent-book — same flowPOST /flights/book — same flow, no booking fee
SetupAdd https://letsfg.co/mcp as an MCP server and approve (one tap, no card)Same token, sent as Authorization: Bearer — see belowletsfg.co/developers
Runs whereOur servers (ranking local in the SDK)Our serversOur servers
  • MCP / CLI / SDK (Path 1): add https://letsfg.co/mcp as an MCP server in Claude, ChatGPT, Cursor or Windsurf and approve the connection. The consent step opens letsfg.co/connect: one tap, no card. The card is asked for at the first booking (any card, or Revolut Pay / Google Pay) in a 0.00 Revolut setup: nothing is charged, no Revolut account is needed, and card details go to Revolut, never to LetsFG. The token you get back searches for free, and once the card is added the same token books. The Python and JS SDKs read that token from LETSFG_BEARER_TOKEN or ~/.letsfg/config.json and apply the open-source ranking algorithm locally. (letsfg auth runs this same connect flow from the terminal: it registers itself as an OAuth client, opens letsfg.co/connect in a browser for a person to approve, and stores the token.)

  • PFS — Programmatic Flight Search (Path 2): For scripts and agents that call the API directly. letsfg.co is human-only by default (Cloudflare Turnstile + bot protection), so the token from the connect flow is the only programmatic way in. Send it on every request:

    1. Search: POST https://letsfg.co/api/search with Authorization: Bearer <token> → { search_id }
    2. Poll: GET https://letsfg.co/api/results/<search_id> (never counts against the rate limit)
    3. Book: POST https://letsfg.co/api/agent-book → { booking_ref } within seconds
    4. Wait: POST https://letsfg.co/api/agent-book/status with { booking_ref } every 20–30 s until completed (PNR), failed (hold released, nothing charged) or needs_attention

    POST /api/agent-access/request still answers 402 with add_card_url and these steps as JSON, so an agent that starts from the endpoint lands in the same place. The MPP lane (a wallet, no card) is unchanged: answer the WWW-Authenticate: Payment challenge ($0.01 once) and verify with Authorization: Payment. The Stripe setup_url / SetupIntent lanes were retired on 2026-09-02 and every token they issued was revoked; reconnect at letsfg.co/connect. Full guide and response schema: letsfg.co/for-agents.

  • Developer API (Path 3): Server-side search and booking at letsfg.co/developers. Look-to-book search (200 free after every booking, then $0.01), real booking through POST /flights/book on a connected Revolut method, full NL query parsing, a /discover endpoint that checks 20 destinations in one call (2–5 s), hotels, and a free sandbox at /sandbox/flights/* that simulates booking end to end (states, questions, failures, real timings). Full docs: letsfg.co/developers/api/docs.

Free server-side search: Use Path 1 or PFS — connect once at letsfg.co/connect (one tap, no card) and searches run free on our servers. No Playwright, no local install beyond the SDK.
Booking from your own product: Use the Developer API (Path 3) — look-to-book search, POST /flights/book, and no booking or transaction fee. Hotels work on both the token from the connect flow and a Developer API key.


Pricing

How you use itSearchFlight bookingHotel bookingRuns where?
MCP Server✅ Free (connect once at letsfg.co/connect, no card)Price held, captured on a real PNR. No separate feePrice held, captured once the hotel confirms. No reservation feeOur servers
CLI / Python SDK / npm✅ Free (same token)SameSameOur servers
PFS (raw API via letsfg.co)✅ Free (same token, or $0.01 once via MPP)SamePrice held, captured once the hotel confirms. No reservation feeOur servers
Developer API200 free per booking, then $0.01Price held, captured on a real PNR. No booking fee, no transaction feePrice held, captured once the hotel confirms. No reservation feeOur servers

MCP / CLI / SDK / PFS = free search, real booking, no separate fee. Connect once (one tap, no card) and searching is free. The card is asked for at the first booking, in a 0.00 Revolut setup (nothing is charged). No credits, no unlock step. Booking works exactly like the website checkout: book_flight / POST /api/agent-book holds the price shown on your card, a LetsFG booking agent buys the ticket from the seller, and the hold is captured only once a real airline PNR exists. If the booking fails the hold is released and nothing is charged. The price you see is the price you pay; nothing is added at booking.

Hotels = the price on the offer, held then captured, on every path. Booking holds the full price on your card, LetsFG books and pays the hotel, and the hold is captured only once the hotel confirms; a failed booking releases it. There is no reservation fee, no deposit and no pay link. Every rate type is sold, and each offer says whether it is refundable and until when. See Hotels below.

Developer API = business use, look-to-book. letsfg.co/developers books flights itself — POST /flights/book holds the fare on your connected Revolut method and a LetsFG booking agent buys the ticket, exactly like the other paths. Search is not priced per call: you get 200 free searches after every booking you make, and booking resets the counter. Past that, blocks of 500 for $5.00 ($0.01 each). No booking fee, no transaction fee on top: the amount the search returned is the amount charged. Minimum top-up: $5.

The monthly per-search tiers ($0.50 / $0.20 / $0.10) were retired on 2026-09-08 along with Stripe. Payments are Revolut: POST /agents/connect-payment returns a one-time link that saves a card, and nothing is charged to connect.

💡 Know someone who travels? The more people discover LetsFG, the more airlines we cover — and the better it gets for everyone. ⭐ Star · Share with a friend


Why developers star this repo

Google Flights / ExpediaLetsFG
PriceVaries by site and searchStable across repeat searches. $133 cheaper across 5 routes, verified 2026-08-05.
CoverageOne site's sourcesEvery airline in the world — OTAs, budget carriers, full-service
Speed30 s+ (page loads, ads, redirects)CLI/PFS: 8–10 s to first results · API discover: 2–5 s
Repeat search raises price?YesNever
Works in AI agents?No APIMCP · CLI · PFS (connect once, free) · Developer API (prepaid)
BookingRedirects to OTA checkoutReal airline PNR, e-ticket to inbox
Cabin class filterNoEconomy, premium, business, first
Cost to youVaries by siteCLI/PFS: free search; no booking fee and no transaction fee. Developer API: 200 free searches after every booking, then $0.01/search; no booking fee, no transaction fee.

Get started

Everything runs on our servers. One connection covers the MCP, the SDKs and the raw API.

🔌 MCP — connect once, search and book

Add the remote server and approve the connection. The consent step opens letsfg.co/connect: one tap, no card, and you are in. The card is asked for at the first booking (0.00 setup, nothing charged).

bash
# Claude Codeclaude mcp add --transport http letsfg https://letsfg.co/mcp
json
// Cursor (~/.cursor/mcp.json) — Windsurf uses "serverUrl" instead of "url"{ "mcpServers": { "letsfg": { "url": "https://letsfg.co/mcp" } } }

Claude: LetsFG is in Claude's official connector directory. Open claude.ai/directory/letsfg, add it and approve the connection. No URL to paste. Once added, it works in Claude Desktop and the Claude phone app too.

ChatGPT: add it at chatgpt.com in a browser (the ChatGPT phone app has no way to add one): Plugins > Add > Add custom MCP server, URL https://letsfg.co/mcp, authentication OAuth, tick I understand, Create as a plugin. Once added, it works in the ChatGPT phone app too.

Then, in the chat: "find me the cheapest flight from London to Barcelona on June 15 and book it". search_flights returns offers; book_flight holds the fare on your card and starts a LetsFG booking agent; get_flight_booking reports the PNR when it lands (4–11 minutes).

🖥️ CLI / SDK — same token, ranking runs locally

bash
pip install letsfgexport LETSFG_BEARER_TOKEN=<token from the connect flow>letsfg search LHR BCN 2026-06-15letsfg search LHR JFK 2026-06-15 --cabin C   # cabin class: M economy, W premium, C business, F first

The SDKs read the token from LETSFG_BEARER_TOKEN or ~/.letsfg/config.json. letsfg auth performs that connect flow itself: it registers as an OAuth client, opens https://letsfg.co/connect for a person to approve, and writes the token to ~/.letsfg/config.json. Add --no-browser to print the URL instead of opening one.

🔌 PFS — Programmatic Flight Search (free, server-side)

Run LetsFG's full search on our servers from any script. Access requires the token from the connect flow: letsfg.co is human-only (Cloudflare Turnstile), so that token is the only programmatic way in. Connecting is one tap and needs no card; the card is asked for at the first booking.

bash
# 1. Search with the tokencurl -X POST https://letsfg.co/api/search \  -H "Authorization: Bearer <token>" \  -H "Content-Type: application/json" \  -d '{"origin":"LHR","destination":"BCN","date_from":"2026-06-15"}'# → {"search_id":"ws_abc123","status":"searching"}
# 2. Poll until done (keep going while split_ticket_pending is true)curl https://letsfg.co/api/results/ws_abc123 -H "Authorization: Bearer <token>"
# 3. Book — the fare is HELD on the card, a LetsFG agent buys the ticketcurl -X POST https://letsfg.co/api/agent-book \  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \  -d '{"search_id":"ws_abc123","offer_id":"wo_abc123","contact_email":"[email protected]",       "passenger":{"given_name":"Ada","family_name":"Lovelace","born_on":"1990-04-01","gender":"f",                    "nationality":"GB","phone_number":"+447700900000","phone_country":"GB",                    "address_line1":"1 Analytical Way","address_city":"London","address_postal":"N1 9GU","address_country":"GB"}}'# → {"booking_ref":"eyJ..."} within seconds
# 4. Wait for the PNR (every 20–30 s; a booking takes 4–11 minutes)curl -X POST https://letsfg.co/api/agent-book/status \  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \  -d '{"booking_ref":"eyJ..."}'# → {"state":"completed","pnr":"ABC123","charged_amount":93,"currency":"EUR"}

failed means the hold was released and nothing was charged; needs_attention means a human at LetsFG is checking it, do not book again. A missing passenger detail returns missing_fields and charges nothing. Without a card the endpoint answers payment_method_required with add_card_url. Full guide and response schema: letsfg.co/for-agents.

⚡ Developer API — server-side search, booking and hotels

A separate product for high-volume commercial integrations; most agents should not use it. Look-to-book search, results in seconds, and real booking through POST /flights/book — plus /discover (20 destinations in one call), async polling, NL query parsing, hotels, and a free sandbox where booking works end to end (same responses, states, questions and timings as production, no money) - build your booking flow there first.

bash
# Register, then search with your API keycurl -X POST https://letsfg.co/developers/api/v1/agents/register \  -H "Content-Type: application/json" \  -d '{"agent_name":"my-agent","email":"[email protected]"}'
curl -X POST https://letsfg.co/developers/api/v1/flights/search \  -H "X-API-Key: letsfg_..." \  -H "Content-Type: application/json" \  -d '{"origin":"LHR","destination":"BCN","date_from":"2026-06-15"}'

Pricing: 200 searches free after every booking, then blocks of 500 for $5.00 ($0.01 each). No booking fee, no transaction fee. Minimum top-up $5. Test for free in the sandbox first, booking included. Full docs: letsfg.co/developers/api/docs.

Full search → book flow (MCP / PFS agent path, no unlock step)
search_flights  LON → BCN, 2026-04-01, return 2026-04-08get_flight_results  (while more offers are still landing)book_flight     search_id + offer_id + one traveller's real details + contact_email                → booking_ref in seconds; price HELD on the connected cardget_flight_booking  every 20–30 s → completed (PNR, charged_amount) | failed (hold released) | needs_attention

Over raw HTTP the same four steps are POST /api/search, GET /api/results/<id>, POST /api/agent-book, POST /api/agent-book/status.

letsfg unlock was retired on 2026-09-08 and its route answers 410 Gone. There is no unlock step on either lane: booking holds the fare and captures only against a real PNR, which is what unlock existed to protect against. See CLI Commands.

💡 Like what you see? Support us — ⭐ Star · Share with a friend


Works everywhere your agent runs

MCP Server (Claude / ChatGPT / Cursor / Windsurf / OpenClaw)

Use the hosted server. It carries your token for you, and book_flight books for real.

json
{  "mcpServers": {    "letsfg": {      "url": "https://letsfg.co/mcp"    }  }}

Approve the connection when your client asks; the consent step opens letsfg.co/connect: one tap, no card. The card is asked for at the first booking (0.00 setup, nothing charged). Tools: search_flights, get_flight_results, book_flight, get_flight_booking, plus the hotel tools.

The stdio package (npx -y letsfg-mcp) works too if you give it a token in LETSFG_BEARER_TOKEN; its authenticate tool returns the current connect instructions.

Optional: use the Developer API instead (look-to-book search, POST /flights/book, hotels)
json
{  "mcpServers": {    "letsfg": {      "command": "npx",      "args": ["-y", "letsfg-mcp"],      "env": {        "LETSFG_API_KEY": "letsfg_your_api_key"      }    }  }}

This is a separate paid product for high-volume commercial use — most agents should stick with the free connect flow above and skip this. A human setting this up deliberately gets a key at letsfg.co/developers.

5-minute quickstarts: Claude · Cursor · Windsurf

Python SDK

python
from letsfg import LetsFG
bt = LetsFG()  # reads LETSFG_API_KEY from envflights = bt.search("LHR", "JFK", "2026-04-15")print(f"{flights.total_results} offers, cheapest: {flights.cheapest.summary()}")

JavaScript SDK

typescript
import { LetsFG } from 'letsfg';
const bt = new LetsFG({ apiKey: 'letsfg_...' });const flights = await bt.search('LHR', 'JFK', '2026-04-15');console.log(`${flights.totalResults} offers`);

Python SDK (cloud search)

python
from letsfg.local import search_local
# Reads LETSFG_BEARER_TOKEN env var or ~/.letsfg/config.json (the token from the connect flow)result = await search_local("GDN", "BCN", "2026-06-15")
for offer in result.offers[:5]:    print(f"{offer.airlines[0]}: {offer.currency} {offer.price}")

⇄ Split tickets — two tickets, one trip

A long-haul searched as one journey comes back as one through-fare, because everyone is reselling the same ticket. Searched as two independent legs through a hub, each leg is booked from whatever is cheapest for that hop — whichever airline, whichever seller. Usually that lands on two different airlines (often a low-cost carrier for the short leg and a separate airline for the long one), but the only rule is "cheapest for each leg". Nobody sells the combination as one ticket, so nobody quotes it — which is exactly why it is cheaper.

LetsFG builds that itinerary for you and returns it alongside the through-fares. Split offers are flagged, never disguised:

FieldValue on a split offer
split_ticket"true"
combo_type"virtual_interlining"
self_transfer"unprotected"
python
for o in offers:    if o.get("split_ticket") == "true":        print(o["price"], "— two separate tickets, self-transfer not protected")

Read self_transfer before you present the price. unprotected means the two tickets are not linked: if the first flight is late and the connection is missed, the second airline owes nothing — no rebooking, no refund, no duty of care. That is the trade you are being offered in exchange for the saving, and it has to reach the traveller. We only build a split when the connection has a real buffer, and we say so on the offer — but an agent that relays the price without the condition is misrepresenting it.

The probe is gated. Two extra connector fan-outs cost real money, so a split is only attempted when the through-fare is expensive enough, the journey long enough, and the market has somewhere to break the trip. Most searches never fire it, and a search that fires it does not always find a saving.

It lands after completed. See Polling: completed is not the end.

Where it runs. letsfg.co, and the agent lane behind it — the CLI, the Python and JS SDKs, and the MCP server. The paid Developer API is served by a different backend; self_transfer is returned there, but split-ticket offers are not part of that contract.

What it actually saves

RouteCheapest single ticketSplit — two ticketsYou saveConnect viaTwo airlinesLayover
Stuttgart → Shanghai$552$461$91 (16%)BudapestWizz Air + Qatar Airways6 h
Katowice → Dubai$283$216$67 (24%)IstanbulWizz Air + Pegasus15 h
Chongqing → Gdansk$429$387$42 (10%)StockholmChina Eastern + Ryanair10 h
Vilnius → Bangkok$370$337$33 (9%)AthensRyanair + Air Arabia5 h
Shanghai → Vilnius$406$377$29 (7%)LondonShenzhen Airlines + Wizz Air12 h

Measured August 2026 on live searches (one adult, one way, ~2 months out). Each split is two separate tickets (here, two different airlines) with an unprotected self-transfer — if the first flight is late, the second airline owes you nothing. Prices move constantly; these won't reproduce exactly. 5 of 26 long-haul routes searched produced a split cheaper than the best single ticket — the win shows up at secondary cities with no cheap direct long-haul. Regenerate with tools/split-comparison.py.

The numbers above come from real searches and are reproducible: the script runs the same public search anyone can run, compares the cheapest split against the cheapest single ticket in the same result set, and writes the raw offers to split-comparison.json so any row can be checked. Routes that produced no split are reported too rather than dropped quietly — most searches never fire a split probe, and a table that hid that would misrepresent how often this happens.

✦ Starlink Wi-Fi on results

Offers tell you whether the flight has Starlink, in two honest tiers. A solid verdict (confirmed_all) means the airline has fitted every aircraft of that type. A hedged one (likely_all) means the rollout on that type is real but incomplete — as of August 2026 United was ~29% of its fleet — so it is reported as a signal, never a promise. An absent field means no information, not an absence of Wi-Fi.

python
for o in offers:    if o.get("starlink") == "confirmed_all":        print(f"{o['owner_airline']} {o['price']} — Starlink on every leg")

Full semantics: docs/api-search.md.

🏨 Hotels — new, and live

Your agent can now book hotels, not just flights. Same credential, same card on file.

Update your SDK before booking hotels. Hotel booking needs letsfg 2026.5.101 or later (Python), letsfg 2026.5.74 or later (JavaScript/TypeScript) or letsfg-mcp 2026.5.77 or later. Earlier releases send the reservation-fee fields retired on 2026-09-11 (expected_balance, no expected_cost), and the API refuses every hotel booking they make. Update with pip install -U letsfg, npm install letsfg@latest or npx -y letsfg-mcp@latest. The hosted MCP at https://letsfg.co/mcp needs no update.

python
from letsfg import LetsFGlfg = LetsFG()  # reads LETSFG_API_KEY — the SDK's hotel methods take a Developer API key
city = lfg.hotel_destinations("Warsaw")[0]stays = lfg.search_hotels(    city_id=city["Id"], city_name=city["Name"],    check_in="2026-11-10", check_out="2026-11-12", adults=2,)
hotel = stays["hotels"][0]offer = hotel["offers"][0]print(hotel["name"], offer["price"], offer["currency"],      "refundable" if offer["refundable"] else "non-refundable")
booking = lfg.book_hotel_and_wait(    session_id=offer["session_id"],    hotel_code=hotel["hotel_code"],    combination_id_v2=offer["combination_id_v2"],    expected_price=offer["price"],    expected_cost=offer["expected_cost"],    currency=offer["currency"],    fx_rate=offer["fx_rate"],    city_id=city["Id"], city_name=city["Name"],    check_in="2026-11-10", check_out="2026-11-12",    guests=[{"title": "Mr", "first_name": "Jan", "last_name": "Kowalski"},     # one entry per guest:            {"title": "Ms", "first_name": "Anna", "last_name": "Kowalska"}],   # adults=2 -> two names    email="[email protected]", phone="512345678",)print(booking["status"], booking.get("confirmation"), booking.get("total_price"), booking.get("currency"))

How you pay

Held at booking, charged when the hotel confirms. Booking holds the full price on your card — it is not taken. LetsFG books the room and pays the supplier itself, and the hold is captured only once the hotel has confirmed. If the booking fails for any reason (the rate is gone, the price moved, the supplier declined) the hold is released and nothing is charged. There is no reservation fee, no deposit and no pay link.

price is the all-in total, in the currency you searched in (USD by default). A refundable booking cancelled before its free_cancellation_until is refunded in full. The endpoint refuses a cancellation that would cost money; the hotel's own ladder ships in the booking's terms, so you can always see the cost first.

Things worth knowing before you build

  • Searching hotels needs no card; booking one does. A hotel search opens a real session at the supplier, so an account with no card on file gets a daily number of hotel searches. Booking asks for the card before anything is held: book_hotel returns a link to add it, as book_flight does. The same card that authorises flight booking authorises hotels — there is no separate hotel signup.
  • Every rate type is sold, refundable and non-refundable. Each offer carries refundable and free_cancellation_until; show them to the guest before booking a non-refundable rate.
  • Booking is asynchronous. book_hotel returns a booking_job_id, not a booking — the real thing takes minutes. Poll hotel_booking(job_id) until status is succeeded, failed or attention, or call book_hotel_and_wait. attention means a person at LetsFG is confirming the outcome with the supplier: the hold is kept, nothing is charged, and you must not book again.
  • Copy the offer back verbatim. Send expected_price, expected_cost, currency and fx_rate exactly as the offer returned them; anything else is refused as price_mismatch before anything is held.
  • Name every guest. guests needs one entry per person in the room, children included: adults first, then children in child_ages order. Fewer names than the searched party fails the booking before anything reaches the hotel, and the hold is released.
  • Do not re-book while a job is running. Poll it. A retry with the same idempotency_key returns the existing job instead of booking twice.
  • The guest hears from us either way. The guest's e-mail gets the confirmation, or a message if the booking fails or needs checking.
  • price is what the guest pays. expected_cost is the supplier's own figure, there only to be sent back — never quote it.

JavaScript

javascript
import { LetsFG } from 'letsfg';const lfg = new LetsFG({ apiKey: process.env.LETSFG_API_KEY });
const [city] = await lfg.hotelDestinations('Warsaw');const stays = await lfg.searchHotels({  cityId: city.Id, cityName: city.Name,  checkIn: '2026-11-10', checkOut: '2026-11-12', adults: 2,});
const booking = await lfg.bookHotelAndWait({ /* ...offer + guest details... */ });console.log(booking.status, booking.confirmation, booking.total_price, booking.currency);

MCP

Five new tools, in the order you call them: resolve_hotel_city → search_hotels → book_hotel → get_hotel_booking → cancel_hotel_booking.


🖥️ Omarchy desktop plugin

Search every airline in the world from the Omarchy bar. Type two airport codes and a date, press Search, click an offer to open it. The panel lives in this repo — manifest.json, BarWidget.qml, Panel.qml and Model.js at the root — and runs on the same engine as the CLI and the MCP server, ordered by the same open-source ranking algorithm in sdk/js/src/ranking.ts.

[LetsFG Flights panel in the Omarchy bar]

Install

bash
omarchy plugin add https://github.com/LetsFG/LetsFG.git --enable

Then add LetsFG Flights to a bar section in the Omarchy bar settings. The panel reads your LetsFG token from ~/.letsfg/config.json (what letsfg auth writes) and renews it itself, or connects from the panel via letsfg.co/connect — one tap, no card. See OMARCHY-PLUGIN.md.

Remove

bash
omarchy plugin remove io.github.letsfg.flights

That removes the plugin only. Your token is yours — delete ~/.letsfg/config.json yourself if you want it gone.

The plugin bundles no API keys. It authenticates with a token you create and can revoke, it never asks for card details, and it never starts a search on its own — no background poll, no price watch, no refresh timer. Every host it can contact, every file it reads or writes, and the anonymous installation id it sends so we can tell whether anyone is using it, are documented in full in OMARCHY-PLUGIN.md.

Requires the Omarchy Quattro shell. MIT, like the rest of this repo. Not affiliated with, sponsored by, or endorsed by Omarchy or 37signals.


Install

PackageCommandWhat you get
Remote MCPhttps://letsfg.co/mcpNo install. Approve the connection at letsfg.co/connect (one tap, no card), search and book
Python SDK + CLIpip install letsfgSDK + CLI (token from the connect flow in LETSFG_BEARER_TOKEN)
MCP Server (stdio)npx letsfg-mcpLocal server for clients without remote MCP support; needs LETSFG_BEARER_TOKEN
JS/TS SDKnpm install -g letsfgSDK + CLI + open-source ranking engine
Agent Skillnpx skills add LetsFG/LetsFGInstall flight search skill for any AI agent (skills.sh)
Smitherysmithery.ai/servers/letsfgOne-click MCP install
Omarchy pluginomarchy plugin add https://github.com/LetsFG/LetsFG.git --enableFlight search in the Omarchy bar (details)

CLI Commands

CommandDescription
letsfg authConnect at letsfg.co/connect (one tap, no card) and store the token (self-registers, PKCE + loopback redirect, opens a browser). --no-browser prints the URL
letsfg search <origin> <dest> <date>Search flights (free with the token from the connect flow)
letsfg register[Developer API only] Register an account for the paid, prepaid-credit product — not part of the agent flow
letsfg connect-payment[Developer API only] Print a one-time link to connect a card to the paid account; nothing is charged. letsfg setup-payment is kept as an alias — the Stripe route it once called was retired on 2026-09-08 and answers 410 Gone
letsfg recover --email <email>Recover lost API key via email
letsfg locations <query>Resolve city/airport to IATA codes
letsfg unlock <offer_id>RETIRED 2026-09-08 — the route answers 410 Gone. There is no unlock step on either lane; use letsfg book
letsfg book <offer_id>Book the flight: holds the fare on the connected card, a LetsFG agent buys the ticket, returns a booking_ref to poll
letsfg meView profile & usage stats

All commands accept --json for structured output and --api-key to override the env variable.


How it works

CLI / SDK / MCP (free, cloud-backed)

Connect the MCP (once, one tap at letsfg.co/connect) → token → Search (free) → Book (card asked for at the first booking; hold → agent → PNR)
  1. Auth — add https://letsfg.co/mcp as an MCP server and approve it. The OAuth consent step opens letsfg.co/connect: one tap, no card. The card is asked for at the first booking, in a 0.00 Revolut setup. Nothing is charged to connect. The SDKs read that token from LETSFG_BEARER_TOKEN or ~/.letsfg/config.json.
  2. Search — letsfg search LHR BCN 2026-06-15 calls POST https://letsfg.co/api/search, polls until done (8–10 s to first results), and applies the open-source ranking algorithm locally.
  3. Book — POST /api/agent-book holds the price shown on the card and starts a LetsFG booking agent; POST /api/agent-book/status reports completed with the PNR (4–11 minutes), or failed with the hold released. Nothing extra is added at booking.

Polling: completed is not the end

A search returns in 8–10 s to first results. Poll GET /api/results/<search_id> immediately and then every 2 s — a loop that sleeps first puts a floor under a search that is already faster than the sleep.

When status leaves searching, the connector fan-out is done — but the offer set may still be growing. The split-ticket probe is dispatched after the fan-out and merges its result in late, so the cheapest itinerary on the search is routinely one that does not exist yet at the moment the status turns terminal. The response says so:

FlagMeaning while true
split_ticket_pendinga split-ticket probe is still running
gf_enrich_pendingthe Google Flights enrich has not merged yet

Keep polling while either is true, and bound the wait — a flag that never clears must not hang your agent. Take whatever has landed when the bound expires.

The Python and JS SDKs and the MCP server already do this, with a 90 s ceiling — the same window the server uses to decide a result has settled. So a search that fires a split probe can take meaningfully longer than the 8–10 s to first results fast path, and it is the split offer you are waiting for. Set LETSFG_WAIT_FOR_SPLIT=0 if you would rather have the fast answer.

Most searches never fire the probe, so both flags are usually already false on the first poll and this costs nothing.

PFS — raw API (same as CLI, without the wrapper)

Connected at letsfg.co/connect -> Bearer token -> POST /api/search -> poll GET /api/results/<id> -> POST /api/agent-book -> poll POST /api/agent-book/status
  1. Get a Bearer token — connect through the MCP OAuth flow; the consent step is letsfg.co/connect (one tap, no card; the card or Revolut Pay is asked for at the first booking, 0.00, nothing charged). POST /api/agent-access/request answers 402 with add_card_url and the steps. The MPP wallet lane ($0.01 once) verifies at POST /api/agent-access/verify with Authorization: Payment.
  2. Search — POST https://letsfg.co/api/search with Authorization: Bearer <token>. Returns { search_id }. Poll GET /api/results/<search_id> immediately, then every 2 s, until status leaves searching. Then keep polling while split_ticket_pending or gf_enrich_pending is true — the split-ticket offer merges in after the status turns terminal.
  3. Book — POST /api/agent-book → booking_ref; poll POST /api/agent-book/status until completed (PNR) or failed (hold released, nothing charged).

Developer API — server-side search and booking

Register → Connect a Revolut method → Search (200 free per booking) → POST /flights/book → poll to a PNR
  1. Discover — POST /flights/discover with up to 20 destinations, get indicative prices sorted cheapest-first. 1 credit, 2–5 s. Use to rank options before committing to a full search.
  2. Full search — POST /flights/search (blocking) or /flights/search/async (non-blocking + poll). 1 credit, 8–10 s to first results.
  3. Book — each offer includes a direct airline booking_url. No LetsFG fee, no checkout step.
Virtual interlining

The server-side engine builds cross-airline round-trips by combining one-way fares from different carriers. A Ryanair outbound + Wizz Air return can save 30-50% vs booking a round-trip on either airline alone.

City-wide airport expansion

Search a city code and LetsFG automatically searches all airports in that city. LON expands to LHR, LGW, STN, LTN, SEN, LCY. NYC expands to JFK, EWR, LGA. Works for 25+ major cities worldwide.


Architecture

CLI / SDK / MCP / PFS

CLI / SDK / MCP / AI Agent        │  Connected at letsfg.co/connect (one tap) -> Bearer token        ▼POST letsfg.co/api/search  (bot-protected, token required)        │        ▼letsfg.co server-side search engine        │        ▼GET /api/results/<search_id>  (poll every 2 s; keep going while split_ticket_pending)        │        ▼Ranking applied locally (sdk/js/src/ranking.ts, open-source)        │        ▼Results + booking via POST /api/agent-book (hold on card -> LetsFG agent -> PNR)

Developer API

Product / Team / Agent        │  API key + a connected Revolut method        ▼letsfg.co/developers/api/v1  ├─ /flights/discover      (indicative prices, 20 dest, 2–5 s)  ├─ /flights/search        (full search, 8–10 s to first results)  ├─ /flights/search/async  (non-blocking + poll)  ├─ /flights/parse-query   (Gemini NL parsing, free)  ├─ /flights/book          (holds the fare on the connected method)  ├─ /flights/bookings/{id} (poll to a real PNR, 4–11 min)  └─ /sandbox/flights/*     (free: search + simulated booking, same schema)        │        ▼Real airline PNR - the hold is captured only once it exists
Airlines covered
RegionAirlines
EuropeRyanair, Wizz Air, EasyJet, Norwegian, Vueling, Eurowings, Transavia, Pegasus, Turkish Airlines, Condor, SunExpress, Volotea, Smartwings, Jet2, LOT Polish Airlines, Finnair, SAS, Aegean, Aer Lingus, ITA Airways, TAP Portugal, Icelandair, PLAY
Middle East & AfricaEmirates, Etihad, Qatar Airways, flydubai, Air Arabia, flynas, Salam Air, Air Peace, FlySafair, EgyptAir, Ethiopian Airlines, Kenya Airways, Royal Air Maroc, South African Airways
Asia-PacificAirAsia, AirAsia X, IndiGo, SpiceJet, Akasa Air, Air India, Air India Express, Alliance Air, Star Air, EaseMyTrip OTA, VietJet, Cebu Pacific, Scoot, Jetstar, Peach, Spring Airlines, Lucky Air, 9 Air, Nok Air, Batik Air, Jeju Air, T'way Air, ZIPAIR, Skymark, H.I.S. Travel OTA, Singapore Airlines, Cathay Pacific, Malaysian Airlines, Thai Airways, Korean Air, ANA, JAL, Qantas, Virgin Australia, Bangkok Airways, Air New Zealand, Garuda Indonesia, Philippine Airlines, US-Bangla, Biman Bangladesh
AmericasSouthwest, JetBlue, Frontier, Spirit, Allegiant, Avelo, Breeze, Sun Country, Flair, Porter, WestJet, Volaris, VivaAerobus, GOL, Azul, LATAM, JetSmart, Flybondi, Arajet, Wingo, Sky Airline, Copa, Avianca
OceaniaRex, Bonza, Link Airways, Air Vanuatu, Fiji Airways

Star History

[Star History Chart]

letsfg.co · API Docs · Connector Health · PyPI · npm · Smithery · Instagram · TikTok · X

Open source · MIT License · Made with ❤️ by travelers, for travelers

Want updates? Click Watch above, or follow LetsFG on Instagram, @letsfg_ on TikTok, or @LetsFG_ on X.

來源:README.md,提交 f01e291

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

1
  1. v2026.5.77最新Sep 16, 2026

評分

已滿足適用檢查項的 75%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。