Loading...
Loading...
MCP server for querying China Railway 12306 train tickets, stations, transfers, and schedules in real-time
npx skill4agent add aradotso/mcp-skills mcp-server-12306Skill by ara.so — MCP Skills collection.
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json{
"mcpServers": {
"12306": {
"command": "uvx",
"args": ["mcp-server-12306"]
}
}
}{
"mcpServers": {
"12306": {
"command": "pipx",
"args": ["run", "--no-cache", "mcp-server-12306"]
}
}
}{
"mcpServers": {
"12306": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_12306.cli"],
"cwd": "/path/to/mcp-server-12306"
}
}
}git clone https://github.com/drfccv/mcp-server-12306.git
cd mcp-server-12306
uv sync
uv run python scripts/start_server.py{
"mcpServers": {
"12306": {
"url": "http://localhost:8000/mcp"
}
}
}docker run -d -p 8000:8000 --name mcp-server-12306 drfccv/mcp-server-12306:latestfrom_stationto_stationtrain_datepurpose_codes# Search 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"
})train_nofrom_station_noto_station_noseat_typestrain_date# Get prices for train 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"
})keyword# Search stations containing "beijing"
result = await mcp_client.call_tool("search_stations", {
"keyword": "beijing"
})
# Also works with Chinese
result = await mcp_client.call_tool("search_stations", {
"keyword": "北京"
})station_nameresult = await mcp_client.call_tool("get_station_info", {
"station_name": "北京南"
})from_stationto_stationtrain_datepurpose_codes# Find 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"
})train_nofrom_station_telecodeto_station_telecodedepart_dateresult = 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"
})timezoneresult = await mcp_client.call_tool("get_current_time", {
"timezone": "Asia/Shanghai"
})# 1. Get current time to determine valid booking dates
time_info = await client.call_tool("get_current_time", {})
travel_date = time_info["dates"]["tomorrow"]
# 2. Search for station codes if needed
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
tickets = await client.call_tool("query_tickets", {
"from_station": "北京",
"to_station": "上海",
"train_date": travel_date,
"purpose_codes": "ADULT"
})
# 4. Get price for specific train
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
})# When 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"
})
# 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']}")# Get 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"
})
# Shows all stops with arrival/departure times
for stop in route["stations"]:
print(f"{stop['station_name']}: {stop['arrive_time']} - {stop['start_time']}")PORTget_current_timecd scripts
uv run python update_station_data.pysrc/mcp_12306/data/station_names.jsonsrc/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 updatersearch_stations# Search before querying
results = await client.call_tool("search_stations", {
"keyword": "beijing"
})
# Use the exact name from results
station_name = results[0]["name"]get_current_timequery_transferuv run python scripts/start_server.py-p 8000:8000uvxpipxuvx --versioncwdget_current_timesearch_stationsquery_ticketsquery_transferget_station_info