Dutch rail travel helper for NS Reisinformatie via the ovNlGateway server tool.
Use this for stations, departures, arrivals, trips, journey details, and disruptions.
Dutch rail travel helper for NS Reisinformatie via the ovNlGateway server tool.
Use this for stations, departures, arrivals, trips, journey details, and disruptions.
license
MIT
compatibility
Requires the RemcoChat ovNlGateway tool to be enabled and configured with a valid NS subscription key.
intent.soft.rankBy (ranking hints): one or more of fastest, fewest_transfers, earliest_departure, earliest_arrival, realtime_first, least_walking.
Use hard constraints for wording like must/only/without/no/geen/alleen/zonder/niet.
Use soft ranking for wording like prefer/liefst/best/bij voorkeur.
If hard constraints produce no matches, ask one concise clarification to relax a single hard constraint.
Detail endpoints (important)
For trips.detail, journey.detail, and disruptions.detail, omit args.intent (it is ignored/stripped).
Date/time guidance
Prefer ISO-8601 strings for dateTime, fromDateTime, toDateTime when you can.
Natural language like "today" is accepted for trips.search.dateTime.
For departures.window with date + fromTime/toTime, interpret the date/time in Europe/Amsterdam.
Action mapping
stations.search: station lookup by name.
stations.nearest: nearest stations by coordinates.
departures.list: upcoming departures for a station.
departures.window: departures for a station within a requested time window (use fromDateTime/toDateTime or date + fromTime/toTime).
arrivals.list: upcoming arrivals for a station.
trips.search: trip options from A to B (with optional via + time).
trips.detail: full details for one trip from ctxRecon.
journey.detail: train/journey detail with stops and status.
disruptions.list: active disruptions overview.
disruptions.by_station: disruptions for a specific station.
disruptions.detail: one disruption detail by type + id.
Output handling (disambiguation + errors)
Most actions return a matching kind (e.g. kind: "trips.search"). Two special cases:
kind: "disambiguation": the tool could not uniquely resolve a station name.
Show the candidates[] succinctly (label + station code/UIC).
Ask the user to pick one (or restate with city/“Centraal”/etc.).
Re-run the original action using the chosen candidate’s station code/UIC where possible:
trips: use from/to station codes
boards: use stationCode or uicCode
disruptions.by_station: use the chosen candidate’s displayed name (args only supports station text)
kind: "error": surface the error message; if actionable, suggest the smallest next step.
access_denied / tool disabled: explain the local access limitation.
config_error: explain that an NS subscription key/config is missing.
station_not_found: ask for a more specific station name or nearby city.
upstream_*: suggest retrying and/or broadening time window.
UX guidelines
Keep answers concise and practical.
Highlight delays, cancellations, platform changes, and transfer counts.
When multiple trip options exist, reason first about what option is the 'best option' to match the user prompt or the user known preferences and highlight that best option.
Suggested call flows (recipes)
“Next train from X” → resolve station (if needed) → departures.list (or departures.window if user gives a time window).
“Geef het vertrektijdenbord/vertrekbord van X” → resolve station (if needed) → departures.list.
“Departures between 17:00 and 18:00” → departures.window with date + fromTime/toTime.
“Best route from A to B (via C)” → trips.search → summarize top 2–3 → if user picks one, trips.detail for richer leg detail.
“What’s going on with this train?” → if you have a journeyDetailRef from a board item, call journey.detail with id.
“Disruptions near station X” → disruptions.by_station (station text) or disruptions.list for a broad overview.