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
JavaScript
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