UNPKG

voyage-and-consumption-mcp-server

Version:

Voyage and consumption management server handling vessel position tracking, ETA monitoring, fuel consumption, lube oil consumption, fresh water production and weather data

136 lines 7.43 kB
import { logger } from "../index.js"; import { config } from "../config/index.js"; import { VoyageCargoToolHandler } from "./handlers/voyageCargoTools.js"; // import { FuelConsumptionToolHandler } from "./handlers/fuelConsumptionTools.js"; import { LubricantOilToolHandler } from "./handlers/lubricantOilTools.js"; import { FreshWaterToolHandler } from "./handlers/freshWaterTools.js"; import { ComplianceToolHandler } from "./handlers/complianceTools.js"; import { VesselPositionToolHandler } from "./handlers/vesselPositionTools.js"; import { UniversalToolHandler } from "./handlers/universalTools.js"; // TODO: Replace with syia-mcp-utils import when imoCache is moved there import { getCompanyImosWithFallback, shouldSkipImoValidation } from "../utils/index.js"; import { MongodbToolsHandler } from "./handlers/mongofetchTools.js"; /** * Main tool handler that coordinates different categories of tools */ export class ToolHandler { constructor(server) { this.voyageCargoToolHandler = new VoyageCargoToolHandler(); // this.fuelConsumptionToolHandler = new FuelConsumptionToolHandler(); this.lubricantOilToolHandler = new LubricantOilToolHandler(); this.freshWaterToolHandler = new FreshWaterToolHandler(); this.complianceToolHandler = new ComplianceToolHandler(); this.vesselPositionToolHandler = new VesselPositionToolHandler(); this.universalToolHandler = new UniversalToolHandler(); this.mongodbToolsHandler = new MongodbToolsHandler(); } /** * Get company IMO numbers for validation */ getCompanyImos() { return getCompanyImosWithFallback(); } /** * Validate IMO numbers against company IMO list */ validateImoNumber(imo) { // Skip validation for companies that don't require IMO validation if (shouldSkipImoValidation(config.companyName)) { logger.debug(`Skipping IMO validation for company: "${config.companyName}"`); return null; } const companyImos = this.getCompanyImos(); if (companyImos.length === 0) { logger.warn('No company IMOs available for validation, allowing request to proceed'); return null; } const imoNum = Number(imo); const companyImosNum = companyImos.map(imo => Number(imo)); if (!companyImosNum.includes(imoNum)) { return [{ type: "text", text: `Error: IMO number ${imo} is not associated with the current company. Please provide a valid IMO number. Available IMO numbers: ${companyImos.join(", ")}`, title: "Invalid IMO Number", format: "json" }]; } return null; } /** * Handles tool calls by routing them to appropriate specialized handlers * @param name - The name of the tool to call * @param arguments_ - The arguments for the tool * @returns Promise resolving to the tool response */ async handleCallTool(name, arguments_) { try { // 🔒 AUTHORIZATION: Validate company IMO access before any tool execution if (arguments_.imo) { const error = this.validateImoNumber(arguments_.imo); if (error) return error; } if (arguments_.filters?.imo) { const error = this.validateImoNumber(arguments_.filters.imo); if (error) return error; } switch (name) { // Voyage and Cargo Tools // case "get_vessel_eta_cargo_activity": // return await this.voyageCargoToolHandler.getVesselEtaCargoActivity(arguments_ as any); // case "get_voyage_details_from_shippalm": // return await this.voyageCargoToolHandler.getVoyageDetailsFromShippalm(arguments_ as any); case "get_fleet_eta_cargo_activity": return await this.voyageCargoToolHandler.getFleetEtaCargoActivity(arguments_); // Fuel Consumption Tools // case "get_vessel_fuel_consumption_rob": // return await this.fuelConsumptionToolHandler.getVesselFuelConsumptionRob(arguments_ as any); // case "get_vessel_fuel_consumption_history": // return await this.fuelConsumptionToolHandler.getVesselFuelConsumptionHistory(arguments_ as any); // case "get_mecc_aecc_consumption_and_rob": // return await this.fuelConsumptionToolHandler.getMeccAeccConsumptionAndRob(arguments_ as any); // Lubricant Oil Tools // case "get_me_cylinder_oil_consumption_and_rob": // return await this.lubricantOilToolHandler.getMeCylinderOilConsumptionAndRob(arguments_ as any); case "get_vessel_mecc_history": return await this.lubricantOilToolHandler.handleGetVesselMeccHistory(arguments_); case "meclo_historical_data": return await this.lubricantOilToolHandler.handleMecloHistoricalData(arguments_); case "get_vessel_aecc_history": return await this.lubricantOilToolHandler.handleGetVesselAeccHistory(arguments_); // Fresh Water Tools // case "get_fresh_water_status": // return await this.freshWaterToolHandler.getFreshWaterStatus(arguments_ as any); case "get_vessel_fresh_water_history": return await this.freshWaterToolHandler.handleGetVesselFreshWaterHistory(arguments_); // Compliance Tools // case "get_charter_party_compliance_status": // return await this.complianceToolHandler.getCharterPartyComplianceStatus(arguments_ as any); case "get_fleet_vessels_cii_rating": return await this.complianceToolHandler.getFleetVesselsCiiRating(arguments_); case "get_fleet_charter_party_compliance_status": return await this.complianceToolHandler.getFleetCharterPartyComplianceStatus(arguments_); // Vessel Position Tools case "get_live_position_from_navtor": return await this.vesselPositionToolHandler.handleGetVesselLivePositionAndEta(arguments_); case "get_live_weather_by_coordinates": return await this.vesselPositionToolHandler.handleGetLiveWeatherByCoordinates(arguments_); // Universal Search Tools case "universal_voyage_search": return await this.universalToolHandler.universalVoyageSearchHandler(arguments_); case "get_vessel_voyage_operations_information": return await this.mongodbToolsHandler.getVesselVoyageOperationsInformation(arguments_); // case "get_tank_distribution_information": // return await this.mongodbToolsHandler.getTankDistributionInformation(arguments_ as any); default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { logger.error(`Error calling tool ${name}:`, error); throw error; } } } //# sourceMappingURL=index.js.map