Skip to main content
Glama

get-interline-tickets

Find available interline train tickets on China's 12306 railway system by specifying departure, destination, and optional transfer stations. This tool displays up to 10 results for planning multi-leg journeys.

Instructions

查询12306中转余票信息。尚且只支持查询前十条。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dateYes查询日期,格式为 "yyyy-MM-dd"。如果用户提供的是相对日期(如“明天”),请务必先调用 `get-current-date` 接口获取当前日期,并计算出目标日期。
fromStationYes出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。
toStationYes出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。
middleStationNo中转地的 `station_code` ,可选。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。
showWZNo是否显示无座车,默认不显示无座车。
trainFilterFlagsNo车次筛选条件,默认为空。从以下标志中选取多个条件组合[G(高铁/城际),D(动车),Z(直达特快),T(特快),K(快速),O(其他),F(复兴号),S(智能动车组)]

Implementation Reference

  • The main handler function for 'get-interline-tickets' tool. It validates input, fetches data from 12306 interline API (/lcquery/queryG), handles errors, parses the response using parseInterlinesInfo, applies train filters, and formats the output using formatInterlinesInfo.
    async ({ date, fromStation, toStation, middleStation, showWZ, trainFilterFlags, }) => { // 检查日期是否早于当前日期 if (!checkDate(date)) { return { content: [ { type: 'text', text: 'Error: The date cannot be earlier than today.', }, ], }; } if ( !Object.keys(STATIONS).includes(fromStation) || !Object.keys(STATIONS).includes(toStation) ) { return { content: [{ type: 'text', text: 'Error: Station not found. ' }], }; } const queryUrl = `${API_BASE}/lcquery/queryG`; const queryParams = new URLSearchParams({ train_date: date, from_station_telecode: fromStation, to_station_telecode: toStation, middle_station: middleStation, result_index: '0', can_query: 'Y', isShowWZ: showWZ ? 'Y' : 'N', purpose_codes: '00', // 00: 成人票 0X: 学生票 channel: 'E', // 没搞清楚什么用 }); const cookies = await getCookie(API_BASE); if (cookies == null) { return { content: [ { type: 'text', text: 'Error: get cookie failed. Check your network.', }, ], }; } const queryResponse = await make12306Request<InterlineQueryResponse>( queryUrl, queryParams, { Cookie: formatCookies(cookies) } ); // 处理请求错误 if (queryResponse === null || queryResponse === undefined) { return { content: [ { type: 'text', text: 'Error: request interline tickets data failed. ', }, ], }; } // 请求成功,但查询有误 if (typeof queryResponse.data == 'string') { return { content: [{ type: 'text', text: queryResponse.errorMsg }], }; } // 请求和查询都没问题 let interlineTicketsInfo: InterlineInfo[]; try { interlineTicketsInfo = parseInterlinesInfo(queryResponse.data.middleList); } catch (error) { return { content: [ { type: 'text', text: `Error: parse tickets info failed. ${error}` }, ], }; } const filteredInterlineTicketsInfo = filterTicketsInfo<InterlineInfo>( interlineTicketsInfo, trainFilterFlags ); return { content: [ { type: 'text', text: formatInterlinesInfo(filteredInterlineTicketsInfo), }, ], }; }
  • Zod schema defining the input parameters for the 'get-interline-tickets' tool, including date, stations, middle station, showWZ flag, and train filters.
    date: z .string() .length(10) .describe( '查询日期,格式为 "yyyy-MM-dd"。如果用户提供的是相对日期(如“明天”),请务必先调用 `get-current-date` 接口获取当前日期,并计算出目标日期。' ), fromStation: z .string() .describe( '出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), toStation: z .string() .describe( '出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), middleStation: z .string() .optional() .default('') .describe( '中转地的 `station_code` ,可选。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), showWZ: z .boolean() .optional() .default(false) .describe('是否显示无座车,默认不显示无座车。'), trainFilterFlags: z .string() .regex(/^[GDZTKOFS]*$/) .max(8) .optional() .default('') .describe( '车次筛选条件,默认为空。从以下标志中选取多个条件组合[G(高铁/城际),D(动车),Z(直达特快),T(特快),K(快速),O(其他),F(复兴号),S(智能动车组)]' ), },
  • src/index.ts:809-947 (registration)
    Registration of the 'get-interline-tickets' tool using server.tool, including name, description, input schema, and handler function.
    server.tool( 'get-interline-tickets', '查询12306中转余票信息。尚且只支持查询前十条。', { date: z .string() .length(10) .describe( '查询日期,格式为 "yyyy-MM-dd"。如果用户提供的是相对日期(如“明天”),请务必先调用 `get-current-date` 接口获取当前日期,并计算出目标日期。' ), fromStation: z .string() .describe( '出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), toStation: z .string() .describe( '出发地的 `station_code` 。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), middleStation: z .string() .optional() .default('') .describe( '中转地的 `station_code` ,可选。必须是通过 `get-station-code-by-name` 或 `get-station-code-of-city` 接口查询得到的编码,严禁直接使用中文地名。' ), showWZ: z .boolean() .optional() .default(false) .describe('是否显示无座车,默认不显示无座车。'), trainFilterFlags: z .string() .regex(/^[GDZTKOFS]*$/) .max(8) .optional() .default('') .describe( '车次筛选条件,默认为空。从以下标志中选取多个条件组合[G(高铁/城际),D(动车),Z(直达特快),T(特快),K(快速),O(其他),F(复兴号),S(智能动车组)]' ), }, async ({ date, fromStation, toStation, middleStation, showWZ, trainFilterFlags, }) => { // 检查日期是否早于当前日期 if (!checkDate(date)) { return { content: [ { type: 'text', text: 'Error: The date cannot be earlier than today.', }, ], }; } if ( !Object.keys(STATIONS).includes(fromStation) || !Object.keys(STATIONS).includes(toStation) ) { return { content: [{ type: 'text', text: 'Error: Station not found. ' }], }; } const queryUrl = `${API_BASE}/lcquery/queryG`; const queryParams = new URLSearchParams({ train_date: date, from_station_telecode: fromStation, to_station_telecode: toStation, middle_station: middleStation, result_index: '0', can_query: 'Y', isShowWZ: showWZ ? 'Y' : 'N', purpose_codes: '00', // 00: 成人票 0X: 学生票 channel: 'E', // 没搞清楚什么用 }); const cookies = await getCookie(API_BASE); if (cookies == null) { return { content: [ { type: 'text', text: 'Error: get cookie failed. Check your network.', }, ], }; } const queryResponse = await make12306Request<InterlineQueryResponse>( queryUrl, queryParams, { Cookie: formatCookies(cookies) } ); // 处理请求错误 if (queryResponse === null || queryResponse === undefined) { return { content: [ { type: 'text', text: 'Error: request interline tickets data failed. ', }, ], }; } // 请求成功,但查询有误 if (typeof queryResponse.data == 'string') { return { content: [{ type: 'text', text: queryResponse.errorMsg }], }; } // 请求和查询都没问题 let interlineTicketsInfo: InterlineInfo[]; try { interlineTicketsInfo = parseInterlinesInfo(queryResponse.data.middleList); } catch (error) { return { content: [ { type: 'text', text: `Error: parse tickets info failed. ${error}` }, ], }; } const filteredInterlineTicketsInfo = filterTicketsInfo<InterlineInfo>( interlineTicketsInfo, trainFilterFlags ); return { content: [ { type: 'text', text: formatInterlinesInfo(filteredInterlineTicketsInfo), }, ], }; } );
  • Helper function to parse raw InterlineData from API into structured InterlineInfo array, used in the handler.
    function parseInterlinesInfo(interlineData: InterlineData[]): InterlineInfo[] { const result: InterlineInfo[] = []; for (const ticket of interlineData) { const interlineTickets = parseInterlinesTicketInfo(ticket.fullList); result.push({ all_lishi: ticket.all_lishi, start_time: ticket.start_time, start_date: ticket.train_date, middle_date: ticket.middle_date, arrive_date: ticket.arrive_date, arrive_time: ticket.arrive_time, from_station_code: ticket.from_station_code, from_station_name: ticket.from_station_name, middle_station_code: ticket.middle_station_code, middle_station_name: ticket.middle_station_name, end_station_code: ticket.end_station_code, end_station_name: ticket.end_station_name, start_train_code: interlineTickets[0].start_train_code, first_train_no: ticket.first_train_no, second_train_no: ticket.second_train_no, train_count: ticket.train_count, ticketList: interlineTickets, same_station: ticket.same_station == '0' ? true : false, same_train: ticket.same_train == 'Y' ? true : false, wait_time: ticket.wait_time, }); } return result; }
  • Helper function to format InterlineInfo array into a readable text summary for the tool response.
    function formatInterlinesInfo(interlinesInfo: InterlineInfo[]): string { let result = '出发时间 -> 到达时间 | 出发车站 -> 中转车站 -> 到达车站 | 换乘标志 |换乘等待时间| 总历时\n\n'; interlinesInfo.forEach((interlineInfo) => { result += `${interlineInfo.start_date} ${interlineInfo.start_time} -> ${interlineInfo.arrive_date} ${interlineInfo.arrive_time} | `; result += `${interlineInfo.from_station_name} -> ${interlineInfo.middle_station_name} -> ${interlineInfo.end_station_name} | `; result += `${ interlineInfo.same_train ? '同车换乘' : interlineInfo.same_station ? '同站换乘' : '换站换乘' } | ${interlineInfo.wait_time} | ${interlineInfo.all_lishi}\n\n`; result += '\t' + formatTicketsInfo(interlineInfo.ticketList).replace(/\n/g, '\n\t'); result += '\n'; }); return result; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/freestylefly/12306-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server