Browser-Bound MCP 機票查詢工具 研究筆記¶
資料來源¶
| 項目 | 連結 |
|---|---|
| 架構截圖 | 7 張截圖拆解(Claude Code / Kiro CLI chat session) |
| 相關概念:WebMCP | Chrome for Developers Blog |
| 相關專案:Google Flights MCP (Fli) | punitarani/fli |
| 相關專案:Rust Browser MCP | EmilLindfors/rust-browser-mcp |
| ITA Matrix | matrix.itasoftware.com |
專案概述¶
這是一個自建的 Browser-Bound MCP 工具,讓 AI Agent(Kiro、Claude 等)能透過 MCP 協議呼叫 Google Flights 搜尋機票。不是公開的 GitHub repo,而是從截圖中拆解出的架構模式研究。
核心創新在於 「Browser-Bound MCP」架構:不用 headless browser 或逆向 API,而是直接操控真實瀏覽器(Brave)的 DOM——帶著使用者的 cookies、登入狀態、語言偏好,結果與人工操作完全一致。
使用場景:在 Kiro CLI chat(persona「諸葛亮」)中,一句話查詢多段機票,Agent 自動拆解需求、組合最便宜的航線。
技術架構¶
四層架構圖¶
┌──────────────────────────────────────────────┐
│ AI Agent (任何 Tailnet 上的裝置) │
│ e.g. Kiro CLI, Claude Code, etc. │
└──────────────┬───────────────────────────────┘
│ HTTP SSE (MCP protocol)
│ http://100.115.238.40:3000/sse
▼
┌──────────────────────────────────────────────┐
│ Rust Bridge (0.0.0.0:3000) │
│ ┌──────────┐ ┌────────────┐ ┌────────────┐ │
│ │SSE Server│↔│MCP Handler │↔│WS Forwarder│ │
│ │ (axum) │ │ │ │ │ │
│ └──────────┘ │search_flts │ └─────┬──────┘ │
│ │scrape_res │ │ │
│ └────────────┘ │ │
└────────────────────────────────────┼────────┘
│ WebSocket ws://127.0.0.1:9222
│ (localhost only!)
▼
┌──────────────────────────────────────────────┐
│ Chrome Extension (MV3, in Brave) │
│ ┌──────────────┐ ┌────────────────────┐ │
│ │background.js │───→│content.js │ │
│ │• WS client │chrome│(Google Flights tab)│ │
│ │• keep-alive │.tabs │• buildFlightsUrl()│ │
│ │ (25s alarm) │.send │• scrapeResults() │ │
│ │• auto-reconn │Msg │• CAPTCHA detect │ │
│ └──────────────┘ └─────────┬──────────┘ │
└────────────────────────────────┼──────────────┘
│ DOM scraping
▼
┌──────────────────────────────────────────────┐
│ google.com/travel/flights │
│ (真實 Brave session, cookies/login) │
└──────────────────────────────────────────────┘
安全設計要點¶
| 設計 | 說明 |
|---|---|
| WebSocket localhost-only | Extension 只在 127.0.0.1:9222 監聽,永不暴露到網路 |
| SSE 走 Tailnet | MCP endpoint 100.115.238.40:3000 只在 Tailscale VPN 內可達 |
| Browser 不離開本機 | 只有結構化的 MCP tool call 跨網路傳輸,瀏覽器操作完全在本地 |
| 故障隔離 | Extension keep-alive (25s alarm) + auto-reconnect,斷線自動恢復 |
MCP 暴露的 Tools¶
1. search_flights — 導航 Google Flights 並爬取結果
├── origin (required) — 機場代碼或城市名
├── destination (required) — 機場代碼或城市名
├── departure_date (required) — YYYY-MM-DD
├── return_date (optional) — YYYY-MM-DD, 省略 = 單程
└── passengers (optional) — 預設 1
2. scrape_results — 重新爬取當前 Google Flights 頁面(不重新導航)
實戰 Demo:台北→首爾→東京→台北¶
截圖展示了一次多段機票查詢的完整流程:
Round-trip 查詢(Agent 自動分段)¶
| 段 | 航線 | 日期 | 航空公司 | 時間 | 票價 |
|---|---|---|---|---|---|
| 1 | TPE→ICN | 4/6 | Scoot | 6:10→9:45 PM | NT$7,257 |
| 2 | ICN→NRT | 4/8 | Jeju Air | 1:20→3:50 PM | NT$9,671 |
| 3 | NRT→TPE | 4/11 | Scoot | 12:30→3:05 PM | NT$11,270 |
| 三段最低總價 | NT$28,198 |
單程改查(Agent 發現價差洞察)¶
Agent 發現上述「單程」其實查的是 round-trip 價格,改用真正的 one-way 搜尋後:
| 段 | 航空公司 | 時間 | 單程價 |
|---|---|---|---|
| TPE→ICN 4/6 | Scoot | 6:10→9:45 PM | NT$3,891 |
| ICN→NRT 4/8 | ZIPAIR | 12:55→3:30 PM | NT$4,153 |
| NRT→TPE 4/11 | Thai Lion Air | 5:40→8:20 PM | NT$6,464 |
| 三段總計 | NT$14,508 |
關鍵洞察
Round-trip 查 NT$28,198 vs. 真正 one-way 組合 NT$14,508 = 省 NT$13,690(近一半)。 這是 Agent 自己發現的,人工操作很難想到逐段改查 one-way。
機票搜尋策略(ITA Matrix + Google Flights)¶
┌─────────────────────┐ ┌──────────────────────┐
│ ITA Matrix │ │ Google Flights │
│ = Discovery │ ──→ │ = Validation │
│ (理論最低價) │ │ (實際可訂) │
│ │ │ │
│ • 搜所有 fare class │ │ • 確認是否可買 │
│ • hidden city combo │ │ • 取得預訂連結 │
│ • open jaw 組合 │ │ • 台灣在地支援好 │
└─────────────────────┘ └──────────────────────┘
架構的通用性¶
截圖明確指出:架構本身是通用的。目前只為 Google Flights 寫了 content script,但 bridge ↔ WebSocket ↔ extension ↔ content script ↔ DOM 這個模式可以適用於任何網站。
新增一個網站只需要:
- 新的
content.js(該網站的 DOM 爬取邏輯) background.js加新的 message type- Rust Bridge 加新的 MCP tool
Bridge 和 WebSocket 管線完全不用改。
目前限制 / 注意事項¶
- 非公開專案:沒有 GitHub repo,無法直接使用,僅供架構參考
- Google Flights DOM 脆弱性:DOM 結構隨時可能改版,content.js 需持續維護
- CAPTCHA 風險:雖有偵測邏輯,但高頻率查詢仍可能觸發 Google 反爬
- 單機限制:需要在本機跑 Brave + Extension + Rust Bridge,不能 serverless 部署
- Tailscale 依賴:跨裝置使用需要 Tailscale VPN,增加一層基礎建設
- 手動維護成本:Rust Bridge + Chrome Extension MV3 + content script 三個元件需同步維護
研究價值與啟示¶
關鍵洞察¶
-
「真實瀏覽器」是最被低估的 AI 工具連接策略:大多數 Google Flights MCP 工具(如 Fli、SerpApi)選擇逆向 API 或 headless browser,但這個專案選擇操控真實瀏覽器 session。好處是:帶著使用者的 cookies/語言/幣別設定、結果與人工操作一致、不觸發 headless 偵測。這個 tradeoff 在「查機票」這種高價值低頻率場景特別合理。
-
「Browser-Bound MCP」是一個可複製的架構模式:
Rust Bridge (SSE/MCP) ↔ WebSocket ↔ Chrome Extension ↔ DOM這個四層架構是通用的。只要替換 content script,就能讓 AI Agent 操作任何網站——銀行、政府網站、需要登入的服務。這比 Playwright/Puppeteer 更適合需要「帶身份操作」的場景。 -
AI Agent 的「價差發現」能力:最有價值的 demo 不是查機票本身,而是 Agent 自己發現 round-trip vs. one-way 的價差(省 NT$13,690)。人類查機票通常只查一種方式,但 Agent 能平行查多種組合、自動比較。這暗示 AI Agent 在消費者決策場景的真正價值不是自動化,是發現人類看不到的選項。
-
Tailscale 作為 Agent 網路層的巧妙用法:用 Tailscale 讓遠端 Agent(在任何裝置上)透過 VPN 存取本機的 MCP server,解決了「瀏覽器必須在本機」和「Agent 可能在遠端」的矛盾。這個模式值得在其他 browser-bound 工具中複製。
-
ITA Matrix + Google Flights 雙引擎策略:截圖揭示了旅遊高手的進階策略——ITA Matrix 當 discovery(理論最低價、hidden city combo、open jaw),Google Flights 當 validation(可訂性確認)。如果把這個 MCP 工具擴展到也支援 ITA Matrix 爬取,就能實現完整的自動化機票搜尋漏斗。
與其他專案的關聯¶
- MCPorter(
docs/mcporter.md):MCPorter 管理 MCP server 的 discovery 和呼叫,Browser-Bound MCP 則是一種特化的 MCP server 實現。兩者可以組合——用 MCPorter 管理多個 browser-bound tool - Lightpanda Browser(
docs/lightpanda-browser.md):Lightpanda 是為 AI Agent 設計的 headless browser(快 11x、省 9x 記憶體)。但 Browser-Bound MCP 走的是相反路線——不用 headless,而是操控真實瀏覽器。兩者的取捨在於:headless 適合大規模 stateless 爬取,real browser 適合需要登入/cookies 的高價值場景 - Page Agent(
docs/page-agent.md):阿里巴巴的 GUI Agent 用視覺理解操控網頁,Browser-Bound MCP 用 DOM selector 操控。視覺方式更通用但更慢,DOM 方式更快但需要為每個網站寫 content script