旅行规划服务

一个整合航班、酒店、Airbnb和公共交通的统一MCP服务器,专为AI助手提供端到端的旅行规划服务。

  • by JMMonte
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 JMMonte/travel-skill

使用说明

旅行技巧

统一的 主控程序 组合服务器 航班, 酒店, Airbnb,以及 公共交通 进入一个单一的界面。专为人工智能助手(Claude Desktop、Claude Code、Cursor等)设计,用于端到端规划行程。

15个工具。一台服务器。四个数据来源。37个城市。

模块 源 工具 数据
航班 飞 (谷歌航班API) search_flights, search_dates 所有航空公司的实时价格
酒店 快捷酒店 (谷歌酒店) search_hotels 价格、评级、设施
Airbnb 纯Python移植 openbnb MCP airbnb_search, airbnb_listing_details 列表、价格、评论、设施
过境 gtfs mcp (GTFS提要) 10个工具(见下文) 时间表、实时到达、44个系统

快速开始

1.安装

git clone https://github.com/JMMonte/travel-skill.git
cd travel-skill
pip install -e .

2.安装Playwright浏览器(用于酒店搜索)

playwright install chromium

3.(可选)设置中转

./scripts/setup-gtfs.sh

4.跑步

travel-mcp

这将在STDIO上启动MCP服务器。将其连接到您的AI客户端(请参阅 配置 在......下面


配置

克劳德桌面版

添加 claude_desktop_config.json:

{
  "mcpServers": {
    "travel": {
      "command": "travel-mcp"
    }
  }
}

克劳德代码

添加 .claude/settings.json 或使用MCP设置:

{
  "mcpServers": {
    "travel": {
      "command": "travel-mcp"
    }
  }
}

游标/其他MCP客户端

{
  "mcpServers": {
    "travel": {
      "command": "travel-mcp"
    }
  }
}

工具参考

航班

search_flights

搜索特定日期两个机场之间的航班。

参数 类型 必填 说明
origin string 是 出发机场IATA代码(例如。, LIS)
destination string 是 到达机场IATA代码(例如。, BCN)
departure_date string 是 旅行日期(YYYY-MM-DD)
return_date string 否 往返返回日期
departure_window string 否 中的时间窗口 HH-HH 格式(例如。, 6-20)
airlines list[str] 否 按航空公司IATA代码筛选(例如。, ["TP", "BA"])
cabin_class string 否 ECONOMY (默认), PREMIUM_ECONOMY, BUSINESS, FIRST
max_stops string 否 ANY (默认), NON_STOP, ONE_STOP, TWO_PLUS_STOPS
sort_by string 否 CHEAPEST (默认), DURATION, DEPARTURE_TIME, ARRIVAL_TIME
adults int 否 成年乘客(默认值:1)
children int 否 儿童乘客(默认值:0)
infants_in_seat int 否 坐在座位上的婴儿(默认值:0)
infants_on_lap int 否 腿上的婴儿(默认值:0)
max_price int 否 最高价格(美元)
max_duration int 否 最大总飞行时间(分钟)
layover_airports list[str] 否 限制在这些机场的转机
max_layover_duration int 否 最长停留时间(分钟)
top_n int 否 往返搜索深度(默认值:5)

退货: 航班列表,包括价格、持续时间、停靠站和每条航段的详细信息(航空公司、航班号、机场、时间)。

search_dates

在日期范围内查找最便宜的旅行日期。

参数 类型 必填 说明
origin string 是 出发机场IATA代码
destination string 是 到达机场IATA代码
start_date string 是 日期范围的开始(YYYY-MM-DD)
end_date string 是 日期范围结束(YYYY-MM-DD)
trip_duration int 否 行程长度(以天为单位)(默认值:3)
is_round_trip bool 否 往返搜索(默认值:false)
airlines list[str] 否 按航空公司IATA代码筛选
cabin_class string 否 客舱类别(默认值: ECONOMY)
max_stops string 否 最大停止次数(默认值: ANY)
departure_window string 否 中的时间窗口 HH-HH 格式
sort_by_price bool 否 按价格从低到高排序(默认值:true)
adults int 否 成年乘客(默认值:1)
children int 否 儿童乘客(默认值:0)
infants_in_seat int 否 坐在座位上的婴儿(默认值:0)
infants_on_lap int 否 腿上的婴儿(默认值:0)
days_of_week list[str] 否 按出发日期筛选(例如。, ["friday", "saturday"])

退货: 日期和价格列表,按最便宜的排序。


酒店

search_hotels

使用谷歌酒店数据搜索酒店。

参数 类型 必填 说明
location string 是 城市名称或IATA代码(例如。, Marrakech, BCN)
checkin string 是 入住日期(YYYY-MM-DD)
checkout string 是 退房日期(YYYY-MM-DD)
adults int 否 成人人数(默认值:1)
children int 否 子项数量(默认值:0)
infants int 否 婴儿数量(默认值:0)
room_type string 否 standard (默认), deluxe, suite
sort_by string 否 price (默认), rating,或值比率为空
limit int 否 最大结果(默认值:20)

退货: 酒店列表,包括名称、每晚价格、评级、设施和谷歌酒店URL。

注: 酒店搜索使用Playwright(无头Chromium)绕过谷歌的同意墙。第一次运行下载浏览器(~160MB)。搜索需要5-15秒。


Airbnb

airbnb_search

使用过滤器和分页搜索Airbnb房源。

参数 类型 必填 说明
location string 是 位置(例如。, Marrakech, Morocco)
place_id string 否 用于精确定位的谷歌地图地点ID
checkin string 否 入住日期(YYYY-MM-DD)
checkout string 否 退房日期(YYYY-MM-DD)
adults int 否 成人人数(默认值:1)
children int 否 子项数量(默认值:0)
infants int 否 婴儿数量(默认值:0)
pets int 否 宠物数量(默认值:0)
min_price int 否 住宿的最低总价
max_price int 否 住宿的最高总价
cursor string 否 来自上一个响应的分页光标

退货: 包含姓名、价格(住宿总额)、评级、评论、徽章(超级房东/客人最喜欢的)、坐标和直接Airbnb网址的房源列表。每页18个结果,带分页光标。

注: Airbnb的价格 住宿总计不是每晚。除以住宿天数,与酒店价格进行比较。

airbnb_listing_details

获取有关特定Airbnb房源的完整详细信息。

参数 类型 必填 说明
id string 是 列表ID(来自搜索结果)
checkin string 否 入住日期(YYYY-MM-DD)
checkout string 否 退房日期(YYYY-MM-DD)
adults int 否 成人人数(默认值:1)
children int 否 子项数量(默认值:0)
infants int 否 婴儿数量(默认值:0)
pets int 否 宠物数量(默认值:0)

退货: 位置坐标、房屋规则(入住/退房时间、最多客人)、亮点、完整描述和分组设施(浴室、厨房、停车场等)。


中转

交通工具通过查询GTFS公共交通数据 gtfs mcp 代理。已预先配置 37个城市和44个交通系统 横跨欧洲、亚洲和美洲。

所有运输工具都需要 system 参数——配置中的系统ID(例如。, lisbon-carris, rome, tokyo-metro).

工具 说明 关键参数
list_systems 列出所有44个已配置的交通系统 --
search_stops 按名称查找站点 system, query, limit?
get_stop 站点详细信息+服务路线 system, stop_id
get_arrivals 即将到达(可用时实时) system, stop_id, route_id?, limit?
list_routes 所有路线,可按类型筛选 system, route_type?
get_route 路线详细信息及有序停车清单 system, route_id, direction_id?
get_alerts 活动服务警报 system, route_id?, stop_id?
get_vehicles 带电车辆位置 system, route_id?
get_trip 带延迟的跳闸-停止顺序 system, trip_id
get_system_status 路线/站点计数、警报计数、饲料健康状况 system

路线类型: 0=有轨电车,1=地铁/地铁,2=铁路,3=公共汽车,4=渡轮,5=缆车,6=缆车,7=缆车。

城市覆盖范围

Europe — 21 cities, 21 systems
城市 系统ID 模式 实时 身份验证
阿姆斯特丹 ovapi-netherlands 所有荷兰交通工具(公共汽车/电车/地铁/火车) 否 无
巴塞罗那 barcelona-bus 大都会巴士 否 无
柏林 vbb U-Bahn、S-Bahn、有轨电车、公共汽车 否 无
布鲁塞尔 stib-mivb 地铁、电车、公共汽车 否 无
布达佩斯 bkk 地铁、有轨电车、无轨电车、公共汽车 是 API键
哥本哈根 rejseplanen 所有丹麦过境 否 无
都柏林 nta 巴士、Luas、铁路(全爱尔兰) 是 API密钥
赫尔辛基 hsl 地铁、电车、公共汽车、铁路、渡轮 是 无
以色列 israel-transit 全国公共汽车、铁路、轻轨 否 无
里斯本 lisbon-carris Carris Metropolitana公共汽车/电车 是 无
伦敦 london-bus 所有伦敦公交车(TfL/BODS) 否 无
马德里 crtm-metro 马德里地铁 否 无
米兰 atm-milan 地铁、电车、公共汽车 否 无
慕尼黑 mvv U-Bahn、S-Bahn、有轨电车、公共汽车、区域 否 无
奥斯陆 entur-norway 所有挪威中转站(60家运营商) 是 无
巴黎 idfm 地铁、RER、电车、公共汽车(全部为法兰西岛) 否 无
波尔图 stcp 公共汽车、电车 否 无
布拉格 pid 地铁、有轨电车、公共汽车、缆车、渡轮 是 API密钥(仅限RT)
罗马 rome 地铁、公共汽车、电车 是 无
维也纳 wiener-linien 地铁、电车、公共汽车 否 无
华沙 ztm-warsaw 地铁、电车、公共汽车 是 无
Asia — 9 cities, 13 systems
城市 系统ID 模式 实时 身份验证
迪拜 dubai-rta 地铁、电车、公共汽车 否 无
香港 hk-transport 港铁、巴士、电车、渡轮 否 无
雅加达 transjakarta 快速公交系统,支线 否 无
高知 kochi-metro 地铁(单线) 否 无
吉隆坡 kl-rail 轻轨、地铁、单轨 否 无
kl-bus 快速巴士 是 无
kl-ktmb KTMB Komuter+ETS轨道 是 无
马尼拉 manila-transit 轻轨、地铁、PNR、巴士 否 无
新加坡 sg-transit 公共汽车+地铁/轻轨(社区) 否 无
台北 taipei-metro 地铁MRT 否 API密钥
东京 toei-rail 都营地铁、有轨电车、Liner 是 API密钥
toei-bus 都营市公交车 有 无(静态)
tokyo-metro 9条地铁线路 是 API密钥
Americas — 7 cities, 10 systems
城市 系统ID 模式 实时 身份验证
芝加哥 cta L火车、公共汽车 没有 没有
洛杉矶 la-metro-bus 地铁巴士 否 无
la-metro-rail 地铁 否 无
墨西哥城 cdmx-semovi 地铁、Metrobus、有轨电车、公共汽车、有线电视 否 无
纽约 nyc-subway 地铁(MTA) 是 无
旧金山 bart BART快速交通 否 无
muni 穆尼巴士、轻轨、缆车 否 无
多伦多 ttc 地铁、公共汽车、有轨电车 是 无
华盛顿特区 wmata-bus Metrobus 是 API密钥
wmata-rail Metrorail 是 API密钥

添加更多城市

在中创建新文件 cities/<city-name>.json:

{
  "city": "City Name",
  "country": "XX",
  "systems": [
    {
      "id": "city-system",
      "name": "System Name (modes)",
      "schedule_url": "https://example.com/gtfs.zip",
      "realtime": {
        "trip_updates": [],
        "vehicle_positions": ["https://example.com/vehicles.pb"],
        "alerts": []
      },
      "auth": null
    }
  ]
}

所有城市配置在启动时都会自动合并。 无需更改代码 --只需添加JSON文件并重新启动。

在以下网址查找GTFS订阅源 移动数据库, Transitland,或城市开放数据门户。

对于需要API密钥的提要:

"auth": { "type": "query_param", "param_name": "api_key", "key_env": "MY_API_KEY" }

看 cities/README.md 获取完整的贡献指南。


建筑

travel-mcp (FastMCP server)
├── flights_mcp      ← wraps fli Python API directly
├── hotels_mcp       ← vendored + patched fast-hotels (Playwright)
├── airbnb_mcp       ← pure Python port (requests + HTML parsing)
└── transit_proxy     ← FastMCP proxy → gtfs-mcp Node.js subprocess
                       ↑ auto-merges cities/*.json at startup

每个模块都通过以下方式安装到根服务器中 FastMCP.mount().Modules优雅地失败了——如果缺少依赖关系,其他模块仍然可以工作。

数据流

  • 航班和日期: python→ fli → 谷歌航班内部API(protobuf)→ 结构化结果
  • 酒店: python→ 剧作家(无头Chrome)→ 谷歌酒店HTML→ 解析结果
  • Airbnb python→ HTTP请求→ Airbnb HTML→ 嵌入式JSON(#data-deferred-state-0) → 结构化结果
  • 过境: python→ FastMCP代理→ Node.js gtfs mcp子进程→ GTFS SQLite+实时protobuf提要

关键设计决策

  1. 航班: 直接封装fli的Python API,而不是安装fli的MCP服务器(使用不兼容的FastMCP子类)。
  2. 酒店: 供应商已应用补丁(上游快捷酒店v0.2.1存在错误:URL中缺少位置、CSS选择器崩溃、仅限美元价格解析)。
  3. Airbnb 从Node.js移植到纯Python——消除了此模块对Node.js的依赖。逻辑相同:获取HTML,解析嵌入的JSON。
  4. 过境: 通过以下方式代理 fastmcp.server.create_proxy() + NodeStdioTransport --gtfs-mcp很复杂(SQLite+protobuf),最好保持原样 cities/ 在启动时自动合并到单个gtfs-mcp配置中。

依赖项

必需

包装 用途
flights (fli) 谷歌航班搜索
fastmcp MCP服务器框架(可通过fli传输)
requests Airbnb的HTTP客户端
selectolax Airbnb和酒店的HTML解析
playwright 酒店无头浏览器

可选的

包装 用途
primp Chrome模拟酒店“常用”模式(已阻止,不需要)
Node.js 18+ 仅在传输时需要(gtfs-mcp子进程)

环境变量

变量 默认值 描述
GTFS_MCP_DIR ~/Development/gtfs-mcp gtfs mcp安装路径
TRAVEL_MCP_DATA_DIR ~/Development/gtfs-mcp/data 缓存GTFS SQLite数据库的位置
ODPT_CONSUMER_KEY -- 东京地铁/都营实时(免费) developer.odpt.org)
BKK_API_KEY -- 布达佩斯BKK实时(免费) opendata.bkk.hu)
NTA_API_KEY -- 都柏林NTA实时(免费) 开发商.国家运输公司.ie)
WMATA_API_KEY -- 华盛顿特区WMATA(免费网址: developer.wmata.com)
TDX_ACCESS_TOKEN -- 台北捷运(免费) tdx.transportaldata.tw)
GOLEMIO_API_KEY -- 布拉格实时(免费) api.golemio.cn)

API密钥仅用于那些特定城市的实时数据。静态计划在没有任何键的情况下工作。


局限性

  • 酒店 搜索需要5-15秒(Playwright浏览器启动)。
  • Airbnb 如果Airbnb更改页面结构,HTML解析可能会中断。
  • 中转 需要Node.js和单独的gtfs-mcp安装。
  • 酒店 价格可能以当地货币表示,具体取决于谷歌的地理检测。
  • Airbnb 价格是住宿的总价,而不是每晚的价格。
  • 中转 每个城市首次使用时下载GTFS数据(5-90MB)。缓存在SQLite中。
  • 一些城市不可用:首尔、曼谷、大阪、北京/上海、胡志明市(未发布GTFS)。
  • 某些提要可能需要免费的API密钥才能获得实时数据(请参阅上面的环境变量)。

学分

该项目由几个开源工具组成:

许可证

麻省理工学院