UNPKG

@siva-sub/mcp-public-transport

Version:

A Model Context Protocol server for Singapore transport data with real-time information and routing

96 lines (95 loc) 3.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BusArrivalTool = void 0; const zod_1 = require("zod"); const base_js_1 = require("../base.js"); const validation_js_1 = require("../../utils/validation.js"); const logger_js_1 = require("../../utils/logger.js"); const BusArrivalInputSchema = zod_1.z.object({ busStopCode: validation_js_1.BusStopCodeSchema, serviceNo: zod_1.z.string().optional(), format: zod_1.z.enum(['detailed', 'user_friendly']).default('detailed'), }); class BusArrivalTool extends base_js_1.BaseTool { constructor(ltaService) { super(); this.ltaService = ltaService; } getDefinitions() { return [ { name: 'get_bus_arrival', description: 'Get real-time bus arrival times and information for a specific bus stop', inputSchema: this.createSchema({ busStopCode: { type: 'string', description: '5-digit bus stop code (e.g., "83139")', pattern: '^[0-9]{5}$', }, serviceNo: { type: 'string', description: 'Optional specific bus service number (e.g., "15")', }, format: { type: 'string', enum: ['detailed', 'user_friendly'], default: 'detailed', description: 'Response format preference', }, }, ['busStopCode']), }, ]; } canHandle(toolName) { return toolName === 'get_bus_arrival'; } async execute(toolName, args) { try { const { busStopCode, serviceNo, format } = (0, validation_js_1.validateInput)(BusArrivalInputSchema, args); logger_js_1.logger.info(`Getting bus arrivals for stop ${busStopCode}`, { serviceNo, format }); const services = await this.ltaService.getBusArrival(busStopCode, serviceNo); if (format === 'user_friendly') { return this.formatUserFriendly(services, busStopCode); } return { busStopCode, services, totalServices: services.length, timestamp: new Date().toISOString(), }; } catch (error) { logger_js_1.logger.error(`Bus arrival tool failed: ${toolName}`, error); return this.formatError(error, toolName); } } formatUserFriendly(services, busStopCode) { if (services.length === 0) { return { message: `No buses arriving soon at stop ${busStopCode}`, busStopCode, timestamp: new Date().toISOString(), }; } const summaries = services.map(service => { const nextBus = service.nextBuses[0]; if (!nextBus) return null; const timeMsg = nextBus.minutesAway === 0 ? 'Arriving now' : nextBus.minutesAway === 1 ? '1 minute' : `${nextBus.minutesAway} minutes`; const wheelchairIcon = nextBus.wheelchairAccessible ? ' ♿' : ''; return `Bus ${service.serviceNo}: ${timeMsg} (${nextBus.loadDescription})${wheelchairIcon}`; }).filter(Boolean); return { busStopCode, summary: summaries.join(' • '), nextArrivals: summaries, services, timestamp: new Date().toISOString(), }; } } exports.BusArrivalTool = BusArrivalTool;