An MCP server for Indian Railways IRCTC data access, providing tools to query PNR status, train schedules, live train information, fare enquiry, seat availability, and journey planning.
Nine tools with decent naming and descriptions, but significant gaps in schema completeness, parameter documentation, and error handling guidance. All tools follow verb_noun pattern (get_*, search_, plan_*, check_*, resolve_*) which is positive. However, most tools lack explicit enum constraints, default values, and clear error recovery guidance. Output schemas are mostly undocumented, we see what the code returns but no explicit schema contracts in tool definitions. Parameter descriptions are present but often lack format specifications (e.g., 'DD-MM-YYYY' format is mentioned only in one tool). Error handling is minimal: most errors return dict with 'error' key but no actionable recovery hints. This is a C-grade server: noticeable gaps in parameter rigor, output documentation, and error guidance that would confuse agents in production.
Check seat availability for a specific train, date, and class.
Get ticket prices for different classes between two stations on a specific date.
Fetch trains running between two stations in the next N hours. Requires Station CODES (e.g., 'NDLS', 'CNB').
Track current location and delay of a running train. Provide train number and journey date.
Fetch detailed PNR status including train time, number, stations, and passenger status.
Get complete schedule/route of a train with all station stops and timings. Use this to find all stations a train passes through.
Output schemas completely undocumented. No explicit contract defined for what fields tools return or their types. Code shows return dicts with nested objects (e.g., train_info, journey_details, passengers in get_pnr_status), but tool definitions have no schema property. Agents cannot plan downstream tool calls or validate response structure.
Date format documentation scattered. get_fare, get_live_train_status, search_trains, and plan_journey all require 'DD-MM-YYYY' format but only get_fare explicitly states it in description. Agents may pass ISO 8601 or Unix timestamps, breaking queries. Parameter descriptions lack format constraints.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 47 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 43 | - | v1 |
Plan a journey with direct trains AND connecting options via major junctions.
Find the station code for a city name (e.g., 'Delhi' -> 'NDLS'). Always use this BEFORE searching for trains if you don't know the code.
Find all trains between two stations on a specific date.
No enum constraints for class parameter in check_seat_availability. Description says 'e.g., 1A, 2A, 3A, SL, CC' but does not use an enum schema. Agents can hallucinate invalid class codes (e.g., '5X', 'BUSINESS'). Should declare as enum with valid values.
Error responses are generic dict with 'error' key, but provide no recovery guidance. E.g., 'No station found for "Delhi"' does not suggest calling search_users or retrying with alternate names. 'PNR might be invalid' is passive, should guide agent: 'Try resolve_station_code() first to confirm station codes.' Pattern:recovery-guide not followed.
No default values for optional parameters. get_live_station_trains has hours=4 default (good), but other tools like search_trains lack defaults. If agent omits 'date', should it use today, tomorrow, or fail? Unclear defaults force agents to pass all params explicitly, wasting tokens.
No pagination support on tools returning lists. get_live_station_trains returns 'trains' array with no limit or pagination. If a route has 50 trains, all are returned. Large responses blow context window. Should add limit and offset/cursor params and return total_count.
Station code parameter documented as 'station code (uppercase)' but accepts lowercase in requests (e.g., .upper() called on input). Inconsistent. Should clarify: accepts any case, normalized internally, OR requires uppercase. Current behavior unclear to LLM.
No explicit permission/risk declarations. All tools are READ_ONLY (safe), but tool definitions lack readOnlyHint annotation. Modern MCP servers should declare via toolAnnotations. Agents cannot infer tool safety without explicit metadata.