mcp-server-12306
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMCP Server 12306
MCP Server 12306
Skill by ara.so — MCP Skills collection.
MCP Server 12306 is a Model Context Protocol server that provides real-time access to China Railway 12306 data including train tickets, station information, transfers, prices, and schedules. Built with FastAPI for high-performance async operations.
由 ara.so 开发的Skill — MCP Skills 合集。
MCP Server 12306是一个基于Model Context Protocol的服务器,可实时获取中国铁路12306的各类数据,包括火车票、车站信息、中转方案、票价及时刻表。它采用FastAPI构建,支持高性能异步操作。
What It Does
功能介绍
This MCP server exposes tools for:
- Real-time ticket queries: Search available tickets with seat types, departure/arrival times
- Station search: Fuzzy search for stations by Chinese name, pinyin, or abbreviation
- Transfer planning: Find one-transfer routes between cities
- Price queries: Get real-time ticket prices for trains
- Route information: Query train stops and schedules
- Time utilities: Get current time and relative dates for booking
本MCP服务器提供以下工具:
- 实时车票查询:搜索包含座位类型、出发/到达时间的可用车票
- 车站搜索:通过中文名称、拼音或简称模糊搜索车站
- 中转规划:查询城市间的一次中转路线
- 票价查询:获取列车的实时票价
- 路线信息:查询列车经停站及时刻表
- 时间工具:获取当前时间及可用于购票的相对日期
Installation
安装方法
For Claude Desktop (Stdio Mode - Recommended)
适用于Claude Desktop(标准输入输出模式 - 推荐)
Add to your Claude Desktop configuration file:
macOS:
Windows:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json将以下内容添加到你的Claude Desktop配置文件中:
macOS:
Windows:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonUsing uvx (fastest):
使用uvx(最快方式):
json
{
"mcpServers": {
"12306": {
"command": "uvx",
"args": ["mcp-server-12306"]
}
}
}json
{
"mcpServers": {
"12306": {
"command": "uvx",
"args": ["mcp-server-12306"]
}
}
}Using pipx:
使用pipx:
json
{
"mcpServers": {
"12306": {
"command": "pipx",
"args": ["run", "--no-cache", "mcp-server-12306"]
}
}
}json
{
"mcpServers": {
"12306": {
"command": "pipx",
"args": ["run", "--no-cache", "mcp-server-12306"]
}
}
}From source (for development):
从源码安装(适用于开发):
json
{
"mcpServers": {
"12306": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_12306.cli"],
"cwd": "/path/to/mcp-server-12306"
}
}
}json
{
"mcpServers": {
"12306": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_12306.cli"],
"cwd": "/path/to/mcp-server-12306"
}
}
}For Remote/HTTP Mode (Streamable HTTP)
远程/HTTP模式(支持流式HTTP)
Local development:
本地开发:
bash
git clone https://github.com/drfccv/mcp-server-12306.git
cd mcp-server-12306
uv sync
uv run python scripts/start_server.pyThen configure your MCP client:
json
{
"mcpServers": {
"12306": {
"url": "http://localhost:8000/mcp"
}
}
}bash
git clone https://github.com/drfccv/mcp-server-12306.git
cd mcp-server-12306
uv sync
uv run python scripts/start_server.py然后配置你的MCP客户端:
json
{
"mcpServers": {
"12306": {
"url": "http://localhost:8000/mcp"
}
}
}Docker deployment:
Docker部署:
bash
docker run -d -p 8000:8000 --name mcp-server-12306 drfccv/mcp-server-12306:latestbash
docker run -d -p 8000:8000 --name mcp-server-12306 drfccv/mcp-server-12306:latestAvailable Tools
可用工具
1. query_tickets
1. query_tickets
Search for available train tickets between stations.
Parameters:
- (string, required): Departure station name (Chinese or pinyin)
from_station - (string, required): Arrival station name (Chinese or pinyin)
to_station - (string, required): Travel date in YYYY-MM-DD format
train_date - (string, optional): "ADULT" (default) or "0X00" for student tickets
purpose_codes
Example usage:
python
undefined查询两站之间的可用火车票。
参数:
- (字符串,必填):出发站名称(中文或拼音)
from_station - (字符串,必填):到达站名称(中文或拼音)
to_station - (字符串,必填):出行日期,格式为YYYY-MM-DD
train_date - (字符串,可选):"ADULT"(默认)或"0X00"(学生票)
purpose_codes
使用示例:
python
undefinedSearch tickets from Beijing to Shanghai on a specific date
查询指定日期从北京到上海的车票
result = await mcp_client.call_tool("query_tickets", {
"from_station": "北京",
"to_station": "上海",
"train_date": "2025-06-15",
"purpose_codes": "ADULT"
})
**Response includes:**
- Train number, type (G/D/K/T/Z)
- Departure/arrival times and duration
- Seat availability and types
- Station codesresult = await mcp_client.call_tool("query_tickets", {
"from_station": "北京",
"to_station": "上海",
"train_date": "2025-06-15",
"purpose_codes": "ADULT"
})
**返回内容包括:**
- 车次、车型(G/D/K/T/Z)
- 出发/到达时间及行程时长
- 座位可用性及类型
- 车站代码2. query_ticket_price
2. query_ticket_price
Get real-time ticket prices for a specific train.
Parameters:
- (string, required): Train number (e.g., "G101")
train_no - (string, required): Departure station code
from_station_no - (string, required): Arrival station code
to_station_no - (string, required): Comma-separated seat type codes
seat_types - (string, required): Travel date in YYYY-MM-DD format
train_date
Example usage:
python
undefined获取指定列车的实时票价。
参数:
- (字符串,必填):车次(例如:"G101")
train_no - (字符串,必填):出发站代码
from_station_no - (字符串,必填):到达站代码
to_station_no - (字符串,必填):逗号分隔的座位类型代码
seat_types - (字符串,必填):出行日期,格式为YYYY-MM-DD
train_date
使用示例:
python
undefinedGet prices for train G101
获取G101次列车的票价
result = await mcp_client.call_tool("query_ticket_price", {
"train_no": "G101",
"from_station_no": "BJP",
"to_station_no": "SHH",
"seat_types": "9,M,O",
"train_date": "2025-06-15"
})
**Response includes:**
- Price for each seat type
- Seat type codes and names
- Currency (CNY)result = await mcp_client.call_tool("query_ticket_price", {
"train_no": "G101",
"from_station_no": "BJP",
"to_station_no": "SHH",
"seat_types": "9,M,O",
"train_date": "2025-06-15"
})
**返回内容包括:**
- 各座位类型的票价
- 座位类型代码及名称
- 货币单位(CNY)3. search_stations
3. search_stations
Search for railway stations by name, pinyin, or abbreviation.
Parameters:
- (string, required): Search term (Chinese, pinyin, or abbreviation)
keyword
Example usage:
python
undefined通过名称、拼音或简称搜索火车站。
参数:
- (字符串,必填):搜索关键词(中文、拼音或简称)
keyword
使用示例:
python
undefinedSearch stations containing "beijing"
搜索包含"beijing"的车站
result = await mcp_client.call_tool("search_stations", {
"keyword": "beijing"
})
result = await mcp_client.call_tool("search_stations", {
"keyword": "beijing"
})
Also works with Chinese
中文关键词同样适用
result = await mcp_client.call_tool("search_stations", {
"keyword": "北京"
})
**Response includes:**
- Station name (Chinese)
- Station code
- Pinyin and abbreviation
- Match scoreresult = await mcp_client.call_tool("search_stations", {
"keyword": "北京"
})
**返回内容包括:**
- 车站名称(中文)
- 车站代码
- 拼音及简称
- 匹配得分4. get_station_info
4. get_station_info
Get detailed information about a specific station.
Parameters:
- (string, required): Exact station name or code
station_name
Example usage:
python
result = await mcp_client.call_tool("get_station_info", {
"station_name": "北京南"
})获取指定车站的详细信息。
参数:
- (字符串,必填):准确的车站名称或代码
station_name
使用示例:
python
result = await mcp_client.call_tool("get_station_info", {
"station_name": "北京南"
})5. query_transfer
5. query_transfer
Find one-transfer routes between cities (when no direct train available).
Parameters:
- (string, required): Departure station
from_station - (string, required): Arrival station
to_station - (string, required): Travel date in YYYY-MM-DD format
train_date - (string, optional): Ticket type
purpose_codes
Example usage:
python
undefined查询城市间的一次中转路线(无直达列车时使用)。
参数:
- (字符串,必填):出发站
from_station - (字符串,必填):到达站
to_station - (字符串,必填):出行日期,格式为YYYY-MM-DD
train_date - (字符串,可选):车票类型
purpose_codes
使用示例:
python
undefinedFind transfer routes from Beijing to Guilin
查询从北京到桂林的中转路线
result = await mcp_client.call_tool("query_transfer", {
"from_station": "北京",
"to_station": "桂林",
"train_date": "2025-06-20",
"purpose_codes": "ADULT"
})
**Response includes:**
- First leg train details
- Transfer station
- Second leg train details
- Total duration
- Layover time at transfer stationresult = await mcp_client.call_tool("query_transfer", {
"from_station": "北京",
"to_station": "桂林",
"train_date": "2025-06-20",
"purpose_codes": "ADULT"
})
**返回内容包括:**
- 第一段列车详情
- 中转车站
- 第二段列车详情
- 总行程时长
- 中转停留时间6. get_train_route_stations
6. get_train_route_stations
Query all stops and schedule for a specific train.
Parameters:
- (string, required): Train number
train_no - (string, required): Origin station code
from_station_telecode - (string, required): Destination station code
to_station_telecode - (string, required): Departure date in YYYY-MM-DD format
depart_date
Example usage:
python
result = await mcp_client.call_tool("get_train_route_stations", {
"train_no": "G101",
"from_station_telecode": "BJP",
"to_station_telecode": "SHH",
"depart_date": "2025-06-15"
})Response includes:
- Station sequence
- Arrival/departure times
- Stop duration
- Running distance
查询指定列车的所有经停站及时刻表。
参数:
- (字符串,必填):车次
train_no - (字符串,必填):始发站代码
from_station_telecode - (字符串,必填):终点站代码
to_station_telecode - (字符串,必填):出发日期,格式为YYYY-MM-DD
depart_date
使用示例:
python
result = await mcp_client.call_tool("get_train_route_stations", {
"train_no": "G101",
"from_station_telecode": "BJP",
"to_station_telecode": "SHH",
"depart_date": "2025-06-15"
})返回内容包括:
- 车站顺序
- 到达/出发时间
- 停留时长
- 行驶距离
7. get_current_time
7. get_current_time
Get current time and calculate relative dates for booking.
Parameters:
- (string, optional): Timezone (default: "Asia/Shanghai")
timezone
Example usage:
python
result = await mcp_client.call_tool("get_current_time", {
"timezone": "Asia/Shanghai"
})Response includes:
- Current time
- ISO format timestamp
- Unix timestamp
- Formatted date strings
- Relative dates (today, tomorrow, next week)
获取当前时间并计算可用于购票的相对日期。
参数:
- (字符串,可选):时区(默认:"Asia/Shanghai")
timezone
使用示例:
python
result = await mcp_client.call_tool("get_current_time", {
"timezone": "Asia/Shanghai"
})返回内容包括:
- 当前时间
- ISO格式时间戳
- Unix时间戳
- 格式化日期字符串
- 相对日期(今天、明天、下周)
Common Patterns
常用使用流程
Complete ticket search workflow:
完整车票查询流程:
python
undefinedpython
undefined1. Get current time to determine valid booking dates
1. 获取当前时间以确定有效的购票日期
time_info = await client.call_tool("get_current_time", {})
travel_date = time_info["dates"]["tomorrow"]
time_info = await client.call_tool("get_current_time", {})
travel_date = time_info["dates"]["tomorrow"]
2. Search for station codes if needed
2. 如需车站代码,先搜索车站
stations = await client.call_tool("search_stations", {
"keyword": "beijing"
})
from_code = stations[0]["code"]
stations = await client.call_tool("search_stations", {
"keyword": "shanghai"
})
to_code = stations[0]["code"]
stations = await client.call_tool("search_stations", {
"keyword": "beijing"
})
from_code = stations[0]["code"]
stations = await client.call_tool("search_stations", {
"keyword": "shanghai"
})
to_code = stations[0]["code"]
3. Query available tickets
3. 查询可用车票
tickets = await client.call_tool("query_tickets", {
"from_station": "北京",
"to_station": "上海",
"train_date": travel_date,
"purpose_codes": "ADULT"
})
tickets = await client.call_tool("query_tickets", {
"from_station": "北京",
"to_station": "上海",
"train_date": travel_date,
"purpose_codes": "ADULT"
})
4. Get price for specific train
4. 获取指定列车的票价
if tickets["trains"]:
train = tickets["trains"][0]
prices = await client.call_tool("query_ticket_price", {
"train_no": train["station_train_code"],
"from_station_no": train["from_station_telecode"],
"to_station_no": train["to_station_telecode"],
"seat_types": train["seat_types"],
"train_date": travel_date
})
undefinedif tickets["trains"]:
train = tickets["trains"][0]
prices = await client.call_tool("query_ticket_price", {
"train_no": train["station_train_code"],
"from_station_no": train["from_station_telecode"],
"to_station_no": train["to_station_telecode"],
"seat_types": train["seat_types"],
"train_date": travel_date
})
undefinedFinding transfer routes:
查询中转路线:
python
undefinedpython
undefinedWhen no direct trains available, query transfers
无直达列车时,查询中转方案
transfers = await client.call_tool("query_transfer", {
"from_station": "拉萨",
"to_station": "厦门",
"train_date": "2025-07-01",
"purpose_codes": "ADULT"
})
transfers = await client.call_tool("query_transfer", {
"from_station": "拉萨",
"to_station": "厦门",
"train_date": "2025-07-01",
"purpose_codes": "ADULT"
})
Each result shows:
每个结果包含:
- First train to transfer city
- 前往中转城市的第一趟列车
- Layover duration
- 中转停留时长
- Second train to final destination
- 前往最终目的地的第二趟列车
for route in transfers["transfer_routes"]:
print(f"Transfer at: {route['transfer_station']}")
print(f"Layover: {route['layover_minutes']} minutes")
print(f"Total duration: {route['total_duration']}")
undefinedfor route in transfers["transfer_routes"]:
print(f"中转车站: {route['transfer_station']}")
print(f"停留时长: {route['layover_minutes']} 分钟")
print(f"总行程时长: {route['total_duration']}")
undefinedChecking train route details:
查询列车路线详情:
python
undefinedpython
undefinedGet complete route for a train
获取列车的完整路线
route = await client.call_tool("get_train_route_stations", {
"train_no": "G7",
"from_station_telecode": "BJP",
"to_station_telecode": "SHH",
"depart_date": "2025-06-15"
})
route = await client.call_tool("get_train_route_stations", {
"train_no": "G7",
"from_station_telecode": "BJP",
"to_station_telecode": "SHH",
"depart_date": "2025-06-15"
})
Shows all stops with arrival/departure times
显示所有经停站的到达/出发时间
for stop in route["stations"]:
print(f"{stop['station_name']}: {stop['arrive_time']} - {stop['start_time']}")
undefinedfor stop in route["stations"]:
print(f"{stop['station_name']}: {stop['arrive_time']} - {stop['start_time']}")
undefinedConfiguration
配置说明
Environment Variables
环境变量
The server uses default 12306 public APIs and doesn't require API keys. However, you can configure:
- Port (HTTP mode only): Set via environment variable (default: 8000)
PORT - Timezone: Pass to tool (default: "Asia/Shanghai")
get_current_time
服务器默认使用12306公开API,无需API密钥。不过你可以配置:
- 端口(仅HTTP模式):通过环境变量设置(默认:8000)
PORT - 时区:传递给工具(默认:"Asia/Shanghai")
get_current_time
Station Data
车站数据
The server includes a pre-built station database. To update:
bash
cd scripts
uv run python update_station_data.pyThis fetches the latest station list from 12306 and updates .
src/mcp_12306/data/station_names.json服务器包含预构建的车站数据库。如需更新:
bash
cd scripts
uv run python update_station_data.py该脚本会从12306获取最新车站列表并更新。
src/mcp_12306/data/station_names.jsonProject Structure
项目结构
src/mcp_12306/
├── server.py # FastAPI main entry point
├── services/
│ ├── ticket_service.py # Ticket query logic
│ ├── station_service.py # Station search logic
│ └── http_service.py # 12306 API client
├── utils/
│ ├── config.py # Configuration
│ └── logger.py # Logging
├── data/
│ └── station_names.json # Station database
scripts/
├── start_server.py # HTTP mode launcher
└── update_station_data.py # Station data updatersrc/mcp_12306/
├── server.py # FastAPI主入口
├── services/
│ ├── ticket_service.py # 车票查询逻辑
│ ├── station_service.py # 车站搜索逻辑
│ └── http_service.py # 12306 API客户端
├── utils/
│ ├── config.py # 配置文件
│ └── logger.py # 日志工具
├── data/
│ └── station_names.json # 车站数据库
scripts/
├── start_server.py # HTTP模式启动脚本
└── update_station_data.py # 车站数据更新脚本Troubleshooting
故障排查
"Station not found" errors
"车站未找到"错误
The station database uses exact matching. Use first to find the correct station name:
search_stationspython
undefined车站数据库使用精确匹配。请先使用工具找到正确的车站名称:
search_stationspython
undefinedSearch before querying
查询前先搜索
results = await client.call_tool("search_stations", {
"keyword": "beijing"
})
results = await client.call_tool("search_stations", {
"keyword": "beijing"
})
Use the exact name from results
使用结果中的准确名称
station_name = results[0]["name"]
undefinedstation_name = results[0]["name"]
undefinedNo tickets available
无可用车票
- Check date format is YYYY-MM-DD
- 12306 typically allows booking 15-30 days in advance
- Use to get valid booking dates
get_current_time - Try different dates or use for indirect routes
query_transfer
- 检查日期格式是否为YYYY-MM-DD
- 12306通常允许提前15-30天购票
- 使用获取有效的购票日期
get_current_time - 尝试不同日期或使用查询中转路线
query_transfer
HTTP connection errors
HTTP连接错误
- Ensure the server is running ()
uv run python scripts/start_server.py - Check port 8000 is not in use
- For Docker, verify port mapping:
-p 8000:8000 - In China, direct 12306 API access may require proper network access
- 确保服务器正在运行(执行)
uv run python scripts/start_server.py - 检查8000端口是否被占用
- 若使用Docker,验证端口映射是否正确:
-p 8000:8000 - 在国内,直接访问12306 API可能需要合适的网络环境
Stdio mode not working in Claude Desktop
Claude Desktop标准输入输出模式无法工作
- Restart Claude Desktop after configuration changes
- Verify JSON syntax in config file
- Check or
uvxis installed:pipxuvx --version - For source mode, ensure points to correct directory
cwd
- 修改配置后重启Claude Desktop
- 验证配置文件的JSON语法是否正确
- 检查或
uvx是否已安装:执行pipxuvx --version - 若使用源码模式,确保指向正确的目录
cwd
Rate limiting
请求频率限制
The 12306 API may rate-limit requests. The server includes basic retry logic, but for production use:
- Add delays between requests
- Cache frequently accessed data (stations, routes)
- Use transfer queries sparingly (they make multiple API calls)
12306 API可能会限制请求频率。服务器已包含基础重试逻辑,但生产环境使用时:
- 在请求之间添加延迟
- 缓存频繁访问的数据(车站、路线)
- 谨慎使用中转查询(会发起多个API请求)
Best Practices
最佳实践
- Always get current time first: Use to determine valid booking dates
get_current_time - Search stations before querying: Verify exact station names with
search_stations - Check direct routes first: Try before
query_ticketsquery_transfer - Cache station data: Station codes rarely change, cache results
get_station_info - Handle no-results gracefully: Not all routes have direct or one-transfer options
- Use appropriate date formats: Always use YYYY-MM-DD for dates
- 先获取当前时间:使用确定有效的购票日期
get_current_time - 查询前先搜索车站:使用验证准确的车站名称
search_stations - 先查直达路线:先尝试再使用
query_ticketsquery_transfer - 缓存车站数据:车站代码很少变化,缓存的结果
get_station_info - 优雅处理无结果情况:并非所有路线都有直达或一次中转方案
- 使用正确的日期格式:日期始终使用YYYY-MM-DD格式
Legal Notice
法律声明
This project is for educational and research purposes only. It queries publicly available 12306 APIs and does not store, modify, or distribute official data. Users must comply with Chinese laws and 12306 terms of service. The authors assume no liability for misuse.
本项目仅用于教育和研究目的。它查询12306公开API,不存储、修改或分发官方数据。用户必须遵守中国法律及12306服务条款。作者对 misuse 不承担任何责任。