TDX Rail Metro CLI is a command-line tool for accessing Taiwan Metro (MRT) data via the TDX API. It supports multiple metro systems including:
- TRTC - Taipei Metro (台北捷運)
- KRTC - Kaohsiung Metro (高雄捷運)
- TYMC - Taoyuan Airport MRT (桃園機場捷運)
- TMRT - Taichung Metro (台中捷運)
- KLRT - Kaohsiung Light Rail (高雄輕軌)
- NTDLRT - Danhai Light Rail (淡海輕軌)
- NTMC - New Taipei Circular Line (新北環狀線)
- NTALRT - Ankeng Light Rail (安坑輕軌)
- TRTCMG - Maokong Gondola (貓空纜車)
Using TDD (Test-Driven Development):
- Research API endpoints and document response formats
- Write tests based on expected behavior
- Implement functionality to pass tests
- Commit after each feature completion
Based on TDX API v2, the following endpoints are available for each metro operator:
| # | Endpoint | Description | Status |
|---|---|---|---|
| 1 | Station | 車站資料 | ✅ Done |
| 2 | Line | 路線資料 | ✅ Done |
| 3 | Route | 營運路線資料 | ✅ Done |
| 4 | StationOfLine | 路線車站順序資料 | ✅ Done |
| 5 | S2STravelTime | 站間運行時間資料 | ✅ Done |
| 6 | Frequency | 班距資料 | ✅ Done |
| 7 | FirstLastTimetable | 首末班車時刻資料 | ✅ Done |
| 8 | ODFare | 起訖站票價資料 | ✅ Done |
| 9 | StationExit | 車站出口資料 | ✅ Done |
| 10 | StationFacility | 車站設施資料 | ✅ Done |
| 11 | Shape | 路線幾何線型資料 | ✅ Done |
| # | Endpoint | Description | Status |
|---|---|---|---|
| 12 | LiveBoard | 車站即時到站資料 | ✅ Done |
| 13 | Alert | 營運警報資料 | ✅ Done |
| 14 | News | 最新消息資料 | ✅ Done |
{
"StationUID": "TRTC-BL01",
"StationID": "BL01",
"StationName": {
"Zh_tw": "頂埔",
"En": "Dingpu"
},
"StationAddress": "236040新北市土城區中央路4段51之6號B3",
"BikeAllowOnHoliday": true,
"StationPosition": {
"PositionLon": 121.418744,
"PositionLat": 24.959351,
"GeoHash": "wsqmfzwqv"
},
"LocationCity": "新北市",
"LocationCityCode": "NWT",
"LocationTown": "土城區",
"LocationTownCode": "65000130",
"UpdateTime": "2023-10-17T00:00:00+08:00",
"VersionID": 6
}{
"LineNo": "BL",
"LineID": "BL",
"LineName": {
"Zh_tw": "板南線",
"En": "Bannan Line"
},
"LineSectionName": {},
"LineColor": "#0a59ae",
"IsBranch": false,
"UpdateTime": "2020-05-20T12:00:00+08:00",
"VersionID": 2
}{
"OriginStationID": "BL01",
"OriginStationName": {
"Zh_tw": "頂埔",
"En": "Dingpu"
},
"DestinationStationID": "BL02",
"DestinationStationName": {
"Zh_tw": "永寧",
"En": "Yongning"
},
"TrainType": 0,
"Fares": [
{
"TicketType": 1,
"FareClass": 1,
"Price": 20
}
],
"TravelDistance": 1.95
}{
"UpdateTime": "2025-12-29T01:41:38+08:00",
"Alerts": [
{
"AlertID": "0",
"Title": "正常營運",
"Description": "正常營運",
"Status": 1,
"Scope": {
"Network": {},
"Stations": [],
"Lines": [],
"Routes": [],
"Trains": [],
"LineSections": []
},
"PublishTime": "2025-12-29T01:41:38+08:00",
"UpdateTime": "2025-12-29T01:41:38+08:00"
}
]
}{
"LineNo": "BL",
"LineID": "BL",
"StationID": "BL01",
"StationName": {
"Zh_tw": "頂埔",
"En": "Dingpu"
},
"TripHeadSign": "往南港展覽館",
"DestinationStaionID": "BL23",
"DestinationStationName": {
"Zh_tw": "南港展覽館",
"En": "Taipei Nangang Exhibition Center"
},
"TrainType": 0,
"FirstTrainTime": "06:00",
"LastTrainTime": "00:00",
"ServiceDay": {
"Monday": true,
"Tuesday": true,
"Wednesday": true,
"Thursday": true,
"Friday": true,
"Saturday": true,
"Sunday": true,
"NationalHolidays": true
}
}tdx-rail-metro-cli/
├── .env # API credentials
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── PRD.md # This file
├── README.md
├── src/
│ ├── index.ts # CLI entry point
│ ├── cli.ts # Command definitions
│ ├── types/
│ │ ├── api.ts # API response types
│ │ ├── config.ts # Config types
│ │ └── auth.ts # Auth types
│ ├── services/
│ │ ├── api.ts # TDX API client
│ │ ├── auth.ts # OAuth2 authentication
│ │ ├── cache.ts # Caching service
│ │ └── config.ts # Configuration management
│ ├── lib/
│ │ ├── output-formatter.ts
│ │ ├── station-resolver.ts
│ │ └── ...
│ └── commands/
│ ├── stations.ts
│ ├── lines.ts
│ ├── fare.ts
│ └── ...
└── tests/
├── services/
│ ├── api.test.ts
│ └── auth.test.ts
└── commands/
└── ...
- Project setup (package.json, tsconfig.json, vitest.config.ts)
- Type definitions
- Auth service with tests (9 tests passing)
- API client with tests (23 tests passing)
- Cache service with tests (15 tests passing)
- Station API
- Line API
- Route API
- StationOfLine API
- S2STravelTime API
- Frequency API
- FirstLastTimetable API
- ODFare API
- StationExit API
- StationFacility API
- Shape API
- LiveBoard API
- Alert API
- News API
- metro stations list/search/info
- metro lines list/info/stations
- metro fare list/query
- metro timetable first-last/frequency/travel-time
- metro live board
- metro alerts list/news
- metro operators
- Command tests: stations (9), alerts (8), live (8), fare (9), lines (10), timetable (15)
- Output utility tests: formatStation/formatLine/formatFare/formatAlert (14)
- API client tests expanded to 23 (getLiveBoard, getFrequency, getFirstLastTimetable, getS2STravelTime, getStationOfLine, getNews)
- Fix TDX null date sentinel (year=1 → shown as '-') in alerts news
- Fix empty result messages for live board and stations search
- Fix --no-cache wiring across all subcommands (was missing on most)
- Fix process.exit(1) + return guard in fare query and lines stations
- Global uncaughtException/unhandledRejection handler in index.ts
- Fix MSW server lifecycle in api.test.ts (beforeAll/afterAll)
| Date | Change | Commit |
|---|---|---|
| 2025-12-29 | Initial PRD created with API research | 318e4ed |
| 2025-12-29 | Project structure setup | b1fbb52 |
| 2025-12-29 | Auth service implemented with TDD (9 tests) | 04f0429 |
| 2025-12-29 | Cache service implemented with TDD (15 tests) | 752ca2f |
| 2025-12-29 | Metro API client implemented with TDD (9 tests) | 0eedd2e |
| 2025-12-29 | CLI commands implemented (all endpoints) | 068c835 |
| 2026-04-29 | Comprehensive test suite + bug fixes (120 tests, v0.1.1) | f965c63 |