使用说明
旅行技巧
统一的 主控程序 组合服务器 航班, 酒店, 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提要
关键设计决策
- 航班: 直接封装fli的Python API,而不是安装fli的MCP服务器(使用不兼容的FastMCP子类)。
- 酒店: 供应商已应用补丁(上游快捷酒店v0.2.1存在错误:URL中缺少位置、CSS选择器崩溃、仅限美元价格解析)。
- Airbnb 从Node.js移植到纯Python——消除了此模块对Node.js的依赖。逻辑相同:获取HTML,解析嵌入的JSON。
- 过境: 通过以下方式代理
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密钥才能获得实时数据(请参阅上面的环境变量)。
学分
该项目由几个开源工具组成:
- 飞 作者:Punit Arani——谷歌航班Python库
- 快捷酒店 作者:乔纳森·甘——谷歌酒店爬虫
- mcp服务器airbnb 通过OpenBnB——Airbnb MCP服务器(移植到Python)
- gtfs mcp 作者:Jamie McDonald——GTFS传输MCP服务器
- 快速多通道处理 --MCP服务器框架
许可证
麻省理工学院