机票
概述
途牛机票 MCP 服务提供基于 MCP 协议的国内航班搜索、舱位查询和在线预订功能,支持集成到 AI 助手、智能客服等应用中。
服务地址: https://openapi.tuniu.cn/mcp/flight
核心特性:
- 🚀 无状态设计,无需维护会话
- 🔐 基于 API Key 认证
- 💾 智能缓存,提升响应速度
- 📦 完整的预订流程(搜索→舱位→下单)
- 支持 6 种查询模式(低价、时间范围、价格区间、周边出发、周边到达、中转)
一、快速开始
1.1 获取认证凭证
访问 途牛开放平台 注册并创建应用,获取:
- API Key: 应用密钥(用于
apiKey请求头)
1.2 第一个 API 调用
搜索北京到上海的航班:
curl -X POST "https://openapi.tuniu.cn/mcp/flight" \
-H "Content-Type: application/json" \
-H "apiKey: YOUR_API_KEY" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15"
}
}
}'响应解析:
const response = await fetch(...);
const result = await response.json();
// ⚠️ 重要:result.content[0].text 是 JSON 字符串,需要再次解析
const data = JSON.parse(result.result.content[0].text);
console.log('航班列表:', data.data);客户端配置(Cursor、OpenClaw、CoPaw 等)请参考 常用 Client 配置。
二、Tools 列表
2.1 searchLowestPriceFlight(航班搜索)
功能:根据出发城市、到达城市和日期搜索航班,支持 6 种查询模式,支持分页查询。
请求说明
查询模式说明:
| searchType | 说明 | 额外参数 |
|---|---|---|
| 不传/空 | 默认低价查询 | 无 |
| TIME | 按出发/到达时间范围查询 | departureTime 或 arrivalTime |
| PRICE | 按价格区间查询 | priceRange |
| NEAR_GO | 周边机场出发查询 | 无 |
| NEAR_BACK | 周边机场到达查询 | 无 |
| TRANSFER | 中转航班查询 | 无 |
参数表:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
departureCityName | string | ✅ | 出发城市名称 |
arrivalCityName | string | ✅ | 到达城市名称 |
departureDate | string | ✅ | 出发日期 YYYY-MM-DD |
searchType | string | ❌ | 查询模式:TIME/PRICE/NEAR_GO/NEAR_BACK/TRANSFER |
departureTime | string | ❌ | 出发时间范围,如"06:00-10:00",仅 TIME 模式使用 |
arrivalTime | string | ❌ | 到达时间范围,如"14:00-18:00",仅 TIME 模式使用 |
priceRange | string | ❌ | 价格区间,如"500-800",仅 PRICE 模式使用 |
pageNum | number | ❌ | 页码(分页时传递,从 2 开始) |
响应说明
| 参数 | 类型 | 说明 |
|---|---|---|
successCode | boolean | 是否成功 |
queryId | string | 用于翻页的查询 ID |
totalPageNum | number | 总页数 |
data | array | 航班列表 |
data 数组元素
| 参数 | 类型 | 说明 |
|---|---|---|
flightNumber | string | 航班号 |
airlineCompany | string | 航空公司 |
departureTime | string | 出发时间 |
arrivalTime | string | 到达时间 |
departureAirport | string | 出发机场 |
arrivalAirport | string | 到达机场 |
departureTerminal | string | 出发航站楼 |
arrivalTerminal | string | 到达航站楼 |
basePrice | string | 基准价格(元) |
cabinClass | string | 舱位等级 |
remainingSeats | string | 剩余座位数 |
totalDuration | string | 总时长 |
flyTime | string | 飞行时长 |
type | string | 航班类型(直飞/经停) |
craftType | string | 机型 |
shareFlightNo | string | 共享航班号 |
请求示例
// 默认低价查询
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15"
}
}
// TIME 模式:按时间范围查询(早班机)
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"searchType": "TIME",
"departureTime": "06:00-10:00"
}
}
// PRICE 模式:按价格区间查询
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"searchType": "PRICE",
"priceRange": "500-800"
}
}
// NEAR_GO 模式:周边机场出发查询
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"searchType": "NEAR_GO"
}
}
// NEAR_BACK 模式:周边机场到达查询
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"searchType": "NEAR_BACK"
}
}
// TRANSFER 模式:中转航班查询
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"searchType": "TRANSFER"
}
}
// 分页查询(第 2 页)
{
"name": "searchLowestPriceFlight",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"pageNum": 2
}
}响应示例
{
"successCode": true,
"queryId": "Y2l0eUtleXM9TktHLUNUVS...",
"totalPageNum": 1,
"data": [
{
"flightNumber": "ZH9561",
"airlineCompany": "深航",
"departureTime": "2026-04-11 07:20",
"arrivalTime": "2026-04-11 09:55",
"departureAirport": "禄口",
"arrivalAirport": "天府",
"basePrice": "710",
"cabinClass": "经济舱",
"remainingSeats": "9",
"totalDuration": "2h35m",
"type": "直飞"
}
]
}2.2 multiCabinDetails(舱位价格查询)
功能:查询指定航班的舱位价格详情,返回下单所需的关键字段。
请求说明
前置条件:需先调用 searchLowestPriceFlight 搜索航班,系统会自动关联查询上下文。
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
departureCityName | string | ✅ | 出发城市名称(从搜索结果获取) |
arrivalCityName | string | ✅ | 到达城市名称(从搜索结果获取) |
departureDate | string | ✅ | 出发日期 YYYY-MM-DD(从搜索结果获取) |
flightNo | string | ✅ | 航班号(从搜索结果获取) |
响应说明
| 参数 | 类型 | 说明 |
|---|---|---|
successCode | boolean | 是否成功 |
flightInfo | array | 航班详细信息 |
cabinInfo | array | 舱位信息(下单必需) |
flightInfo 数组元素
| 参数 | 类型 | 说明 |
|---|---|---|
flightNumber | string | 航班号 |
airlineCompany | string | 航空公司 |
departureTime | string | 出发时间 |
arrivalTime | string | 到达时间 |
departureAirport | string | 出发机场 |
arrivalAirport | string | 到达机场 |
departureTerminal | string | 出发航站楼 |
arrivalTerminal | string | 到达航站楼 |
totalDuration | string | 总时长 |
flyTime | string | 飞行时长 |
type | string | 航班类型(直飞/经停) |
craftType | string | 机型 |
punctualityRate | string | 准点率 |
cabinInfo 数组元素
| 参数 | 类型 | 说明 |
|---|---|---|
cabinPriceId | string | ⚠️ 舱位价格 ID(下单必需) |
basePrice | string | 票面价格 |
cabinClass | string | 舱等 |
cabinClassCodes | string | 舱位代码 |
buyCondition | string | 购买条件 |
refundChangeRule | string | 退改签规则 |
baggageInfo | string | 行李信息 |
mealCode | string | 餐食信息 |
reimbursementProof | string | 报销凭证 |
remainingSeats | string | 剩余座位数 |
请求示例
{
"name": "multiCabinDetails",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"flightNo": "MU5101"
}
}响应示例
{
"successCode": true,
"flightInfo": [
{
"flightNumber": "ZH9565",
"airlineCompany": "深航",
"departureTime": "2026-04-11 20:25",
"arrivalTime": "2026-04-11 23:10",
"departureAirport": "禄口",
"arrivalAirport": "天府",
"punctualityRate": "96%"
}
],
"cabinInfo": [
{
"cabinPriceId": "OQ8jBCEcPxsVVFsIEw==",
"basePrice": "680",
"cabinClass": "经济舱",
"cabinClassCodes": "Y",
"refundChangeRule": "退改¥34 起",
"baggageInfo": "免费托运行李额 20 公斤",
"mealCode": "点心餐",
"remainingSeats": "9"
}
]
}重要提示:cabinPriceId 是下单时的必需参数。
2.3 getBookingRequiredInfo(获取预订信息)
功能:获取机票预订所需填写的字段信息,下单前必须先调用此接口了解必填字段。
请求说明
无参数,arguments 传空对象即可。
响应说明
返回纯文本(非 JSON),内容位于 result.content[0].text,包含:
| 内容模块 | 说明 |
|---|---|
| 预定所需信息 | 乘客信息(姓名、证件类型、证件号码、乘客类型)、联系信息(姓名、手机、邮箱) |
| 填写样例 | 身份证乘客、护照乘客、联系人信息的填写示例 |
| 注意事项 | 证件格式判断、儿童/婴儿出生日期等 |
| 预定须知 | 相关声明与协议链接 |
请求示例
{
"name": "getBookingRequiredInfo",
"arguments": {
}
}响应示例
返回预订所需的字段说明列表。
2.4 saveOrder(创建订单)
功能:创建机票预订订单。
请求说明
前置条件:
- 必须先调用
searchLowestPriceFlight获取航班信息 - 必须调用
multiCabinDetails获取cabinPriceId - 建议先调用
getBookingRequiredInfo了解必填字段
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
departureCityName | string | ✅ | 出发城市名称(从搜索结果获取) |
arrivalCityName | string | ✅ | 到达城市名称(从搜索结果获取) |
departureDate | string | ✅ | 出发日期 YYYY-MM-DD(从搜索结果获取) |
flightNo | string | ✅ | 航班号(从搜索结果获取) |
cabinPriceId | string | ✅ | 舱位价格 ID(来自舱位详情) |
tourists | array | ✅ | 乘机人信息列表 |
contactTourist | object | ✅ | 联系人信息 |
tourists 数组元素
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 姓名(必填) |
idType | string | 证件类型(必填):身份证、护照、户口簿、出生证明、军人证、台胞证、回乡证、港澳居民居住证、台湾居民居住证、外国人永久居留身份证 |
idNumber | string | 证件号码(必填) |
mobile | string | 手机号(必填) |
type | string | 乘客类型(可选):成人/儿童/婴儿,不填则根据生日自动判断 |
psptEndDate | string | 证件有效期,格式 yyyy-MM-dd,非身份证必填(可选) |
sex | number | 性别,1 男 0 女 9 未知,非身份证必填(可选) |
birthday | string | 生日,格式 yyyy-MM-dd,非身份证必填(可选) |
contactTourist 对象
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 联系人姓名(可选,不填则使用第一个乘机人姓名) |
mobile | string | 联系人手机号(可选,不填则使用第一个乘机人电话) |
email | string | 联系人邮箱(可选) |
响应说明
| 参数 | 类型 | 说明 |
|---|---|---|
successCode | boolean | 是否成功 |
orderId | string | 订单号 |
payUrl | string | 支付链接 |
请求示例
{
"name": "saveOrder",
"arguments": {
"departureCityName": "北京",
"arrivalCityName": "上海",
"departureDate": "2026-03-15",
"flightNo": "MU5101",
"cabinPriceId": "OQ8jBCEcPxsVVFsIEw==",
"tourists": [
{
"name": "张三",
"idType": "身份证",
"idNumber": "310101199001011234",
"mobile": "13800138000"
}
],
"contactTourist": {
"name": "张三",
"mobile": "13800138000",
"email": "zhangsan@example.com"
}
}
}响应示例
{
"successCode": true,
"orderId": "1260278419",
"payUrl": "https://m.tuniu.com/flight/domestic/orderDetail/1260278419?orderType=37"
}重要提示:下单成功后 必须提醒用户点击 payUrl 完成支付。
2.5 cancelOrder(取消订单)
功能:取消已下单未支付的订单。
请求说明
前置条件:必须是 saveOrder 下单成功且未支付的订单。
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
orderId | string | ✅ | 下单返回的订单号 |
响应说明
| 参数 | 类型 | 说明 |
|---|---|---|
successCode | boolean | 是否成功 |
msg | string | 取消成功/失败提示 |
errorCode | number | 错误码 |
请求示例
{
"name": "cancelOrder",
"arguments": {
"orderId": "1260278419"
}
}响应示例
{
"successCode": true,
"msg": "订单取消成功!",
"errorCode": 170000
}三、完整预订流程
3.1 流程图
搜索航班 → 选择航班 → 查看舱位 → 选择舱位 → 创建订单 → 支付
↓ ↓ ↓ ↓ ↓ ↓
flightNo flightNo cabinPriceId cabinPriceId orderId 取消订单3.2 代码示例
// 步骤 1: 搜索航班
const searchResult = await callTool('searchLowestPriceFlight', {
departureCityName: '北京',
arrivalCityName: '上海',
departureDate: '2026-03-15',
});
const flight = searchResult.data[0];
// 步骤 2: 查看舱位详情(传入相同的城市和日期)
const cabinResult = await callTool('multiCabinDetails', {
departureCityName: '北京',
arrivalCityName: '上海',
departureDate: '2026-03-15',
flightNo: flight.flightNumber,
});
const cabin = cabinResult.cabinInfo[0];
// 步骤 3: 创建订单
const orderResult = await callTool('saveOrder', {
departureCityName: '北京',
arrivalCityName: '上海',
departureDate: '2026-03-15',
flightNo: flight.flightNumber,
cabinPriceId: cabin.cabinPriceId,
tourists: [
{
name: '张三',
idType: '身份证',
idNumber: '310101199001011234',
mobile: '13800138000'
}
],
contactTourist: {
name: '张三',
mobile: '13800138000',
email: 'zhangsan@example.com'
}
});
console.log('订单号:', orderResult.orderId);
console.log('支付链接:', orderResult.payUrl);
// 必须提醒用户点击 payUrl 完成支付
// 步骤 4: 取消订单(如需取消)
const cancelResult = await callTool('cancelOrder', {
orderId: orderResult.orderId
});
console.log('取消结果:', cancelResult.msg);四、常见问题
Q1: 是否需要先调用 initialize?
A: 不需要。本服务采用无状态设计,可以直接调用工具。
Q2: cabinPriceId 从哪里获取?
A: 需要先调用 multiCabinDetails 接口,从返回的 cabinInfo 中获取 cabinPriceId。
Q3: 如何分页查询航班?
A: 分页时传入相同的城市、日期参数和 pageNum(从 2 开始)即可,系统会自动关联查询上下文。
Q4: 有哪些查询模式可用?
A: 支持 6 种查询模式:
- 默认低价查询(不传 searchType)
- TIME:按出发/到达时间范围查询
- PRICE:按价格区间查询
- NEAR_GO:周边机场出发查询
- NEAR_BACK:周边机场到达查询
- TRANSFER:中转航班查询
Q5: 支付流程是怎样的?
A: 下单成功后会返回 payUrl,用户需访问该链接在途牛官网完成支付。
Q6: 如何处理"舱位信息已失效"错误?
A: 说明缓存已过期,需要重新调用 multiCabinDetails 获取最新的舱位信息。
