Skip to main content
Glama

NS Travel Information MCP Server

by r-huijts
types.ts15 kB
export interface Coordinate { lat: number; lng: number; } export interface Station { coordinate: Coordinate; countryCode: string; name: string; stationCode: string; uicCode: string; } export interface TitleSection { type: string; value: string; } export interface Phase { id: string; label: string; } export interface Impact { value: number; } export interface ExpectedDuration { description: string; endTime: string; } export interface Section { stations: Station[]; direction: string; } export interface Consequence { section: Section; description: string; level: string; } export interface PublicationSection { section: Section; consequence: Consequence; sectionType: string; } export interface AdditionalTravelTime { label: string; shortLabel: string; minimumDurationInMinutes?: number; maximumDurationInMinutes: number; } export interface Situation { label: string; } export interface Cause { label: string; } export interface Timespan { start: string; end: string; period: string; situation: Situation; cause: Cause; additionalTravelTime?: AdditionalTravelTime; alternativeTransport?: { label: string; shortLabel: string; }; advices: string[]; } export interface AlternativeTransportLocation { station: Station; description: string; } export interface AlternativeTransport { location: AlternativeTransportLocation[]; label: string; shortLabel: string; } export interface AlternativeTransportTimespan { start: string; end: string; alternativeTransport: AlternativeTransport; } export interface Disruption { type: string; id: string; title: string; isActive: boolean; topic?: string; local: boolean; description?: string; titleSections?: TitleSection[][]; registrationTime: string; releaseTime: string; start: string; end: string; phase?: Phase; impact: Impact; expectedDuration?: ExpectedDuration; publicationSections: PublicationSection[]; summaryAdditionalTravelTime?: AdditionalTravelTime; timespans: Timespan[]; alternativeTransportTimespans: AlternativeTransportTimespan[]; } export interface ApiResponse { contents: { uri: string; mimeType: string; text: string; }[]; } export type DisruptionType = "MAINTENANCE" | "DISRUPTION"; /** * Arguments for getting disruptions */ export interface GetDisruptionsArgs { isActive?: boolean; // Filter for active disruptions only type?: DisruptionType; // Type of disruption to filter for } /** * Type guard for disruption arguments */ export function isValidDisruptionsArgs(args: unknown): args is GetDisruptionsArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; // Check isActive: should be undefined or boolean if (typedArgs.isActive !== undefined && typeof typedArgs.isActive !== "boolean") { return false; } // Check type: should be undefined or one of the allowed values if (typedArgs.type !== undefined && (typeof typedArgs.type !== "string" || !["MAINTENANCE", "DISRUPTION"].includes(typedArgs.type))) { return false; } return true; } /** * Station information in travel advice */ export interface TravelAdviceStation { name: string; lng: number; lat: number; countryCode?: string; uicCode?: string; plannedDateTime: string; actualDateTime?: string; plannedTrack?: string; actualTrack?: string; } /** * Single leg of a journey (one train/segment) */ export interface TravelAdviceLeg { idx: string; name: string; direction?: string; // Final destination of the train cancelled: boolean; origin: TravelAdviceStation; destination: TravelAdviceStation; product: { displayName: string; // e.g. "Intercity" type: string; number: string; // Train number operatorName: string; // e.g. "NS" }; stops?: TravelAdviceStation[]; // Intermediate stops } /** * Complete trip from origin to destination */ export interface TravelAdviceTrip { uid: string; plannedDurationInMinutes: number; actualDurationInMinutes: number; status: string; legs: TravelAdviceLeg[]; crowdForecast?: string; optimal: boolean; } /** * Complete travel advice response */ export interface TravelAdvice { source: string; trips: TravelAdviceTrip[]; } /** * Arguments for getting travel advice */ export interface GetTravelAdviceArgs { fromStation: string; // Departure station toStation: string; // Destination station dateTime?: string; // Optional departure/arrival time searchForArrival?: boolean; // If true, dateTime is treated as arrival time } /** * Type guard for travel advice arguments */ export function isValidTravelAdviceArgs(args: unknown): args is GetTravelAdviceArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; // Required fields if (typeof typedArgs.fromStation !== "string" || typeof typedArgs.toStation !== "string") { return false; } // Optional fields if (typedArgs.dateTime !== undefined && typeof typedArgs.dateTime !== "string") { return false; } if (typedArgs.searchForArrival !== undefined && typeof typedArgs.searchForArrival !== "boolean") { return false; } return true; } // Add these new types for the track map feature export interface TrackMapFeature { type: "Feature"; geometry: { type: "LineString"; coordinates: [number, number][]; }; properties: { stations: string[]; }; } export interface TrackMapResponse { type: "FeatureCollection"; features: TrackMapFeature[]; } export interface GetTrackMapArgs { stations: string[]; } export function isValidTrackMapArgs(args: any): args is GetTrackMapArgs { return ( typeof args === "object" && args !== null && Array.isArray(args.stations) && args.stations.length > 0 && args.stations.every((station: any) => typeof station === "string") ); } // Add these new interfaces after the existing ones export interface DepartureProduct { number: string; categoryCode: string; shortCategoryName: string; longCategoryName: string; operatorName: string; operatorCode: string; type: string; } export interface RouteStation { uicCode: string; mediumName: string; } export interface Departure { direction: string; name: string; plannedDateTime: string; plannedTimeZoneOffset: number; actualDateTime: string; actualTimeZoneOffset: number; plannedTrack?: string; actualTrack?: string; product: DepartureProduct; trainCategory: string; cancelled: boolean; routeStations: RouteStation[]; messages: string[]; departureStatus: string; } export interface DeparturesResponse { payload: { source: string; departures: Departure[]; }; } export interface GetDeparturesArgs { station: string; dateTime?: string; maxJourneys?: number; lang?: string; } export function isValidDeparturesArgs(args: unknown): args is GetDeparturesArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; // Required station field if (typeof typedArgs.station !== "string") { return false; } // Optional fields if (typedArgs.dateTime !== undefined && typeof typedArgs.dateTime !== "string") { return false; } if (typedArgs.maxJourneys !== undefined && typeof typedArgs.maxJourneys !== "number") { return false; } if (typedArgs.lang !== undefined && typeof typedArgs.lang !== "string") { return false; } return true; } export interface OpeningHours { dayOfWeek: number; startTime: string; endTime: string; closesNextDay: boolean; } export interface OVFietsLocation { distance?: number; name: string; stationCode: string; lat: number; lng: number; open: string; description: string; openingHours: OpeningHours[]; extra: { serviceType: string; rentalBikes: string; locationCode: string; type: string; }; street: string; houseNumber: string; postalCode: string; city: string; } export interface OVFietsResponse { payload: { locations: OVFietsLocation[]; }[]; } export interface GetOVFietsArgs { stationCode: string; } export function isValidOVFietsArgs(args: unknown): args is GetOVFietsArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; return typeof typedArgs.stationCode === "string"; } export interface StationInfoArgs { query: string; includeNonPlannableStations?: boolean; limit?: number; } export function isValidStationInfoArgs(args: any): args is StationInfoArgs { return ( typeof args === 'object' && typeof args.query === 'string' && (args.includeNonPlannableStations === undefined || typeof args.includeNonPlannableStations === 'boolean') && (args.limit === undefined || (typeof args.limit === 'number' && args.limit >= 1 && args.limit <= 50)) ); } export interface StationId { uicCode: string; evaCode: string; cdCode: number; code: string; } export interface StationNames { long: string; medium: string; short: string; synonyms: string[]; } export interface StationLocation { lat: number; lng: number; } export interface NearbyMeLocationId { value: string; type: string; } export interface Station { id: StationId; stationType: string; names: StationNames; location: StationLocation; tracks: string[]; hasKnownFacilities: boolean; availableForAccessibleTravel: boolean; hasTravelAssistance: boolean; areTracksIndependentlyAccessible: boolean; isBorderStop: boolean; country: string; radius: number; approachingRadius: number; startDate: string; nearbyMeLocationId: NearbyMeLocationId; } export interface StationInfoResponse { payload: Station[]; } export interface RecognizableDestination { code: string; name: string; } export interface ArrivalProduct { number: string; categoryCode: string; shortCategoryName: string; longCategoryName: string; operatorName: string; operatorCode: string; type: string; } export interface ArrivalMessage { message: string; style: string; } export interface Arrival { origin: string; recognizableDestination?: RecognizableDestination; name: string; plannedDateTime: string; plannedTimeZoneOffset: number; actualDateTime: string; actualTimeZoneOffset: number; plannedTrack?: string; actualTrack?: string; product: ArrivalProduct; trainCategory: string; cancelled: boolean; messages: ArrivalMessage[]; arrivalStatus: string; } export interface ArrivalsResponse { payload: { source: string; arrivals: Arrival[]; }; } export interface GetArrivalsArgs { station?: string; uicCode?: string; dateTime?: string; maxJourneys?: number; lang?: string; } export function isValidArrivalsArgs(args: unknown): args is GetArrivalsArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; // Either station or uicCode must be provided if (!typedArgs.station && !typedArgs.uicCode) { return false; } // Check station: should be undefined or string if (typedArgs.station !== undefined && typeof typedArgs.station !== "string") { return false; } // Check uicCode: should be undefined or string if (typedArgs.uicCode !== undefined && typeof typedArgs.uicCode !== "string") { return false; } // Check dateTime: should be undefined or string if (typedArgs.dateTime !== undefined && typeof typedArgs.dateTime !== "string") { return false; } // Check maxJourneys: should be undefined or number between 1 and 100 if (typedArgs.maxJourneys !== undefined) { if (typeof typedArgs.maxJourneys !== "number" || typedArgs.maxJourneys < 1 || typedArgs.maxJourneys > 100) { return false; } } // Check lang: should be undefined or 'nl' or 'en' if (typedArgs.lang !== undefined) { if (typeof typedArgs.lang !== "string" || !["nl", "en"].includes(typedArgs.lang)) { return false; } } return true; } export interface PriceValidity { label: string; value: string; } export interface Price { totalPriceInCents: number; pricePerAdultInCents: number; discountInCents: number; operatorName: string; discountType: string; travelClass: 'FIRST_CLASS' | 'SECOND_CLASS'; displayName: string; conditionsHeader: string; productId: string; isBestOption: boolean; pricePerChildInCents: number; validity: PriceValidity; conditionsList: string[]; } export interface PricesResponse { payload: { prices: Price[]; }; } export interface GetPricesArgs { fromStation?: string; toStation?: string; travelClass?: 'FIRST_CLASS' | 'SECOND_CLASS'; travelType?: 'single' | 'return'; isJointJourney?: boolean; adults?: number; children?: number; routeId?: string; plannedDepartureTime?: string; plannedArrivalTime?: string; } export function isValidPricesArgs(args: unknown): args is GetPricesArgs { if (!args || typeof args !== "object") { return false; } const typedArgs = args as Record<string, unknown>; // Check station fields: should be undefined or string if (typedArgs.fromStation !== undefined && typeof typedArgs.fromStation !== "string") { return false; } if (typedArgs.toStation !== undefined && typeof typedArgs.toStation !== "string") { return false; } // Check travelClass: should be undefined or one of the allowed values if (typedArgs.travelClass !== undefined && !["FIRST_CLASS", "SECOND_CLASS"].includes(typedArgs.travelClass as string)) { return false; } // Check travelType: should be undefined or one of the allowed values if (typedArgs.travelType !== undefined && !["single", "return"].includes(typedArgs.travelType as string)) { return false; } // Check isJointJourney: should be undefined or boolean if (typedArgs.isJointJourney !== undefined && typeof typedArgs.isJointJourney !== "boolean") { return false; } // Check adults: should be undefined or integer if (typedArgs.adults !== undefined && (typeof typedArgs.adults !== "number" || !Number.isInteger(typedArgs.adults))) { return false; } // Check children: should be undefined or integer if (typedArgs.children !== undefined && (typeof typedArgs.children !== "number" || !Number.isInteger(typedArgs.children))) { return false; } // Check routeId: should be undefined or string if (typedArgs.routeId !== undefined && typeof typedArgs.routeId !== "string") { return false; } // Check time fields: should be undefined or string if (typedArgs.plannedDepartureTime !== undefined && typeof typedArgs.plannedDepartureTime !== "string") { return false; } if (typedArgs.plannedArrivalTime !== undefined && typeof typedArgs.plannedArrivalTime !== "string") { return false; } return true; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/r-huijts/ns-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server