| name | srt |
| description | Korean SRT (Super Rapid Train) search, reservation, and booking management |
| homepage | https://github.com/khj809/openclaw-srt-skill |
| user-invocable | true |
| metadata | {"openclaw":{"emoji":"๐
","requires":{"bins":["python3","uv"]},"install":[{"id":"uv","kind":"uv","package":"SRTrain","label":"Install SRTrain (uv)"}]}} |
SRT Korean Train Service Skill
OpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.
Features
- ๐ Search trains between stations with real-time seat availability
- ๐ซ Make reservations with automatic rate limiting to protect your account
- ๐ View bookings to see all active reservations
- ๐๏ธ Cancel bookings with confirmation prompts
- ๐ค AI-friendly JSON output for programmatic access
- ๐ก๏ธ Rate limiting to prevent account blocking (3s between reservations, 5s between searches)
- โ ๏ธ Retry protection with maximum 10 attempts per session
Prerequisites
- Python 3.10+ installed
- SRT account with phone number and password
- OpenClaw installed and configured
Configuration
Set your SRT credentials as environment variables:
export SRT_PHONE="010-1234-5678"
export SRT_PASSWORD="your_password"
Add these to your shell profile (~/.zshrc, ~/.bashrc, etc.) for persistence.
Security Note: Avoid committing credentials to version control.
Important: Phone number must include hyphens in the format 010-XXXX-XXXX
Usage
User-Invocable Command
Use the /srt slash command in OpenClaw:
/srt search --departure "์์" --arrival "๋ถ์ฐ" --date "20260217" --time "140000"
/srt reserve --train-id "1"
/srt reserve --retry --timeout-minutes 60
/srt reserve --retry --train-id "1,3,5" --timeout-minutes 60
/srt log -n 30
/srt list
/srt cancel --reservation-id "RES123456"
Natural Language (AI-Orchestrated)
The AI can invoke this skill based on user intent:
Examples:
- "2์ 17์ผ์ ์์์์ ๋ถ์ฐ ๊ฐ๋ ๊ธฐ์ฐจ ๊ฒ์ํด์ค" (Search trains)
- "์ ์ผ ๋น ๋ฅธ๊ฑธ๋ก ์์ฝํด์ค" (Reserve first available)
- "๋ด ์์ฝ ํ์ธํด์ค" (List bookings)
- "๋ถ์ฐ ์์ฝ ์ทจ์ํด์ค" (Cancel booking)
Direct CLI Usage
uv run --with SRTrain python3 scripts/srt_cli.py search \
--departure "์์" \
--arrival "๋ถ์ฐ" \
--date "20260217" \
--time "140000" \
--passengers "adult=2"
uv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id "1"
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
--timeout-minutes 60 \
--wait-seconds 10
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
--train-id "1,3,5" \
--timeout-minutes 60 \
--wait-seconds 10
uv run --with SRTrain python3 scripts/srt_cli.py log -n 30
uv run --with SRTrain python3 scripts/srt_cli.py list --format json
uv run --with SRTrain python3 scripts/srt_cli.py cancel \
--reservation-id "RES123456" \
--confirm
Common Korean Station Names
Main SRT Stations:
- ์์ (Suseo) - Seoul SRT station
- ๋ถ์ฐ (Busan)
- ๋๋๊ตฌ (Dongdaegu) - Daegu
- ๋์ (Daejeon)
- ์ฒ์์์ฐ (Cheonan-Asan)
- ์ค์ก (Osong)
- ๊ด์ฃผ์ก์ (Gwangju-Songjeong)
- ์ธ์ฐ (Ulsan)
- ํฌํญ (Pohang)
- ๊ฒฝ์ฃผ (Gyeongju)
- ๊น์ฒ๊ตฌ๋ฏธ (Gimcheon-Gumi)
- ์ต์ฐ (Iksan)
- ์ ์ฃผ (Jeonju)
- ๋ชฉํฌ (Mokpo)
- ์ ๊ฒฝ์ฃผ (Singyeongju)
Important: Station names MUST be in Korean (Hangul) for the SRT API to work correctly.
Date and Time Formats
- Date: YYYYMMDD (e.g.,
20260217 for February 17, 2026)
- Time: HHMMSS (e.g.,
140000 for 2:00 PM, 093000 for 9:30 AM)
Tools for AI Agent
This skill provides 5 tools for managing SRT train reservations:
1. search_trains
Search for available trains between stations.
Usage:
uv run --with SRTrain python3 scripts/srt_cli.py search \
--departure "์์" \
--arrival "๋ถ์ฐ" \
--date "20260217" \
--time "120000"
Returns: JSON array of available trains with seat availability
JSON Format:
{
"success": true,
"data": [
{
"train_id": "1",
"train_number": "301",
"train_name": "SRT301",
"departure_time": "120500",
"arrival_time": "143000",
"departure_station": "์์",
"arrival_station": "๋ถ์ฐ",
"seat_available": true,
"general_seat": "์์ฝ๊ฐ๋ฅ",
"special_seat": "์์ฝ๊ฐ๋ฅ"
}
]
}
2. make_reservation
Reserve trains with optional automatic retry support.
Usage (single attempt):
uv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id "1"
Usage (with retry):
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
--timeout-minutes 60 \
--wait-seconds 10
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
--train-id "1,3,5" \
--timeout-minutes 60 \
--wait-seconds 10
Options:
--train-id: Specific train(s) to reserve (comma-separated, e.g., "1" or "1,3,5"; omit to try all trains)
--retry: Enable automatic retry on failure
--timeout-minutes: Maximum retry duration in minutes (default: 60)
--wait-seconds: Wait time between retry attempts in seconds (default: 10)
Behavior with --retry:
- Cycles through all available trains from search results
- Waits
--wait-seconds between attempts (plus rate-limiting delays)
- Continues until success or timeout
- Logs progress to
~/.openclaw/tmp/srt/reserve.log
Returns: Reservation details with payment deadline
JSON Format:
{
"success": true,
"data": {
"reservation_id": "RES123456",
"journey_date": "20260217",
"journey_time": "120500",
"departure": "์์",
"arrival": "๋ถ์ฐ",
"train_number": "301",
"seat_number": "3A",
"payment_required": true,
"attempts": 12
}
}
Note:
- Payment must be completed manually by user via SRT app/website
- For retry mode, run in background with exec tool and periodically check logs
3. view_bookings
List all current reservations.
Usage:
uv run --with SRTrain python3 scripts/srt_cli.py list --format json
Returns: JSON array of active reservations
JSON Format:
{
"success": true,
"data": [
{
"reservation_id": "RES123456",
"journey_date": "20260217",
"journey_time": "120500",
"departure": "์์",
"arrival": "๋ถ์ฐ",
"train_number": "301",
"seat_number": "3A",
"payment_required": true
}
]
}
4. cancel_booking
Cancel a reservation by ID.
Usage:
uv run --with SRTrain python3 scripts/srt_cli.py cancel \
--reservation-id "RES123456" \
--confirm
Returns: Cancellation confirmation
JSON Format:
{
"success": true,
"data": {
"success": true,
"reservation_id": "RES123456",
"message": "Reservation cancelled successfully"
}
}
5. check_log
Check the progress of reservation attempts (especially useful for retry mode).
Usage:
uv run --with SRTrain python3 scripts/srt_cli.py log -n 30
Returns: Last N lines of reservation log file (~/.openclaw/tmp/srt/reserve.log)
Options:
-n, --lines: Number of lines to show (default: 20)
Log Format Example:
[2026-02-03 11:00:00] INFO: === SRT ์์ฝ ์์ (์ฌ์๋ ๋ชจ๋) ===
[2026-02-03 11:00:00] INFO: ํ์์์: 60๋ถ
[2026-02-03 11:00:00] INFO: ์ฌ์๋ ๊ฐ๊ฒฉ: 10์ด
[2026-02-03 11:00:00] INFO: ๋์ ์ด์ฐจ: 1,3,5 (์ด 3๊ฐ)
[2026-02-03 11:00:05] INFO: === ์๋ #1 (์ด์ฐจ 1/3) ===
[2026-02-03 11:00:05] INFO: ๐ซ ์์ฝ ์๋ ์ค... (์ด์ฐจ 301, 120500)
[2026-02-03 11:00:06] WARN: โ ์ข์ ์์ (์ด์ฐจ 301)
[2026-02-03 11:00:06] INFO: โณ 10์ด ๋๊ธฐ ํ ์ฌ์๋...
[2026-02-03 11:00:26] INFO: === ์๋ #2 (์ด์ฐจ 2/3) ===
...
[2026-02-03 11:05:00] SUCCESS: โ
์์ฝ ์ฑ๊ณต!
Error Handling
The skill provides clear, actionable error messages:
Common Errors:
-
AuthenticationFailed
- Invalid credentials
- Solution: Check phone number and password in config
-
NoSeatsAvailable
- Train is sold out
- Solution: Try next train or different time
- Exit code: 1 (retryable)
-
StationNotFound
- Invalid station name
- Solution: Use Korean station names from the list above
-
NoTrainsFound
- No trains for specified route/time
- Solution: Try different date or time
-
RateLimitExceeded
- Too many retry attempts (max 10 per session)
- Solution: Wait a few minutes before trying again
-
NetworkError
- Connection timeout or failure
- Solution: Check internet connection and retry
Exit Codes:
0 - Success
1 - Retryable error (e.g., no seats available)
2 - Fatal error (e.g., authentication failed, invalid input)
โ ๏ธ Rate Limiting and Account Protection
To protect your SRT account from being blocked by the server:
- Automatic delays between requests:
- Minimum 3 seconds between reservation attempts
- Minimum 5 seconds between search requests
- Maximum 10 retry attempts per session
- Exponential backoff after failures (3s โ 5s โ 10s โ 15s โ 20s โ 30s)
What this means for users:
- The skill will automatically wait between requests
- You'll see waiting messages like "โณ SRT ์๋ฒ ๋ณดํธ๋ฅผ ์ํด ๋๊ธฐ ์ค (3์ด)"
- If you hit the retry limit, wait a few minutes before trying again
For AI orchestration:
- The AI should inform users about delays during retries
- Example: "์ฌ์๋ ์ค์
๋๋ค. ์๋ฒ ๋ณดํธ๋ฅผ ์ํด 3์ด ๋๊ธฐํฉ๋๋ค..."
- After 10 failed attempts, suggest alternatives like different times or dates
Natural Language Handling
When users make requests in Korean, the AI should:
-
Extract parameters from natural language:
- Stations (must convert to Korean if given in English)
- Date (relative dates like "๋ด์ผ", "๋ค์์ฃผ ๊ธ์์ผ" โ YYYYMMDD)
- Time (relative times like "์คํ 2์", "12์ ์ดํ" โ HHMMSS)
- Passenger count (default to 1 if not specified)
-
Call tools in correct sequence:
- Search before reserving
- List before canceling
- Handle retry logic with rate limiting
-
Handle errors gracefully:
- If no seats available, try next train (with delays)
- If station not found, suggest correct Korean name
- Inform user about waiting times during rate limiting
-
Confirm actions in Korean:
- "์์ฝ์ด ์๋ฃ๋์์ต๋๋ค" (Reservation completed)
- "3์ด ํ ๋ค์ ์ด์ฐจ๋ฅผ ์๋ํฉ๋๋ค" (Trying next train in 3 seconds)
- "๊ฒฐ์ ๋ SRT ์ฑ์์ ์๋ฃํด์ฃผ์ธ์" (Complete payment in SRT app)
Real-World Usage Scenarios
Scenario 1: Simple Reservation
User: "2์ 17์ผ์ ์์์์ ๋๋๊ตฌ ๊ฐ๋๊ฑฐ 12์์ดํ ์ ์ผ ๋น ๋ฅธ๊ฑธ๋ก 2์ฅ ์์ฝํด์ค"
AI Actions:
- Parse: departure=์์, arrival=๋๋๊ตฌ, date=20260217, time=120000, passengers=adult:2
- Search trains
- Select first available train
- Reserve train
- Confirm with payment reminder
Scenario 2: Retry Until Success
User: "๋งค์ง์ด๋ฉด ์ฑ๊ณตํ ๋๊น์ง ๋ฐ๋ณตํด"
AI Actions:
- Search trains
- Start background retry:
exec reserve --retry --timeout-minutes 60 --wait-seconds 10 (in background)
- Create monitoring cron job (isolated session + agentTurn):
cron add --job '{
"schedule": {"kind": "every", "everyMs": 120000},
"payload": {
"kind": "agentTurn",
"message": "Check SRT retry log and report progress",
"deliver": true,
"channel": "discord"
},
"sessionTarget": "isolated",
"enabled": true
}'
cron wake --mode "now"
- Inform user: "๋ฐฑ๊ทธ๋ผ์ด๋ ์ฌ์๋ ์์. 2๋ถ๋ง๋ค ์
๋ฐ์ดํธํฉ๋๋ค."
โ ๏ธ Background Retry Monitoring
MANDATORY: Use isolated session + agentTurn cron jobs for monitoring reserve --retry.
Setup
exec reserve --retry --timeout-minutes 60 (background)
cron add --job '{
"schedule": {"kind": "every", "everyMs": 120000},
"payload": {
"kind": "agentTurn",
"message": "Check `srt_cli.py log -n 30`, parse progress, report to user. Delete cron if done.",
"deliver": true,
"channel": "discord"
},
"sessionTarget": "isolated",
"enabled": true
}'
cron wake --mode "now"
Requirements
- sessionTarget:
"isolated" (NOT "main")
- payload.kind:
"agentTurn" (NOT "systemEvent")
- payload.deliver:
true
- Schedule: Every 1-3 minutes depending on task duration
- Wake: Always call
cron wake --mode "now" after creating job
Why
systemEvent in main session doesn't trigger agent action
agentTurn in isolated session actually executes and reports
- Prevents blocking, message batching, and silent monitoring
Scenario 3: Check and Cancel
User: "๋ด ์์ฝ ํ์ธํด์ฃผ๊ณ ์ ์ผ ๋น ๋ฅธ๊ฑฐ ์ทจ์ํด์ค"
AI Actions:
- List reservations
- Parse JSON, find earliest by date/time
- Cancel reservation
- Confirm cancellation
Scenario 4: Modify Booking
User: "๋ถ์ฐ ์์ฝ ์ทจ์ํ๊ณ ๋๋๊ตฌ๋ก ๋ค์ ์์ฝํด์ค"
AI Actions:
- List reservations
- Find Busan reservation
- Cancel Busan reservation
- Search for trains to ๋๋๊ตฌ (same date/time)
- Reserve new train
- Confirm both actions
Payment Notes
IMPORTANT: This skill can search and reserve trains, but cannot process payments.
After making a reservation:
- You'll receive a reservation number
- Payment must be completed via:
- Check payment deadline (usually 20 minutes after reservation)
- Unpaid reservations will be automatically cancelled
Troubleshooting
"SRT ์ธ์ฆ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค"
- Verify
SRT_PHONE and SRT_PASSWORD environment variables are set
- Check your shell profile (
~/.zshrc, ~/.bashrc) has export keyword
- Example:
export SRT_PHONE="010-1234-5678"
"๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค"
- Run
search command before reserve
- Search results are cached in
~/.openclaw/tmp/srt/last_search.pkl
"์ฌ์๋ ํ๋ ์ด๊ณผ"
- You've made 10 reservation attempts
- Wait 5-10 minutes before trying again
- Try different trains or times
Login failures
- Verify credentials are correct
- Check if SRT service is available
- Ensure phone number format includes hyphens (010-1234-5678)
Development
Testing Locally
export SRT_PHONE="010-1234-5678"
export SRT_PASSWORD="your_password"
uv run --with SRTrain python3 scripts/srt_cli.py search --departure "์์" --arrival "๋ถ์ฐ" --date "20260203" --time "140000"
uv run --with SRTrain python3 scripts/srt_cli.py list
Publishing to ClawHub
clawhub login
clawhub publish . \
--slug srt \
--name "SRT Korean Train Service" \
--version 0.1.2 \
--tags latest
License
MIT
Support
For issues or questions:
Version History
- 0.1.3 - Retry improvements and monitoring requirements
- Unified
reserve command with --retry flag
- Added
--timeout-minutes for time-based retry limits (default: 60)
- Added
--train-id support for comma-separated multiple trains (e.g., "1,3,5")
- Changed
--wait-seconds default from 20 to 10 seconds
- Search includes sold-out trains by default (
available_only=False)
- Monitoring: Isolated session + agentTurn cron jobs required for background retry
- 0.1.2 - Add
--all flag for sold-out trains (deprecated)
- 0.1.1 - Use
uv for dependency management
- Replace venv/pip with
uv run --with SRTrain
- Environment variables only for credentials (remove config file support)
- 0.1.0 - Initial release
- Search trains
- Make reservations
- View bookings
- Cancel bookings
- Rate limiting protection
- AI-friendly JSON output