ms-analysis-reports-mcp-server
Version:
PMS analysis reports server handling maintenance reports, equipment analysis, compliance tracking, and performance metrics with ERP access for data extraction
266 lines • 11.5 kB
JavaScript
import { getTypesenseClient, getDataLink, getArtifact, insertDataLinkToMongoDB, getPmsEtlDatabase, fetchQADetails } from "syia-mcp-utils";
import { logger } from "../../index.js";
// Helper function to get engine data database
async function getEngineDataDatabase() {
return await getPmsEtlDatabase();
}
// Engine names mapping
const ENGINE_NAMES_MAPPING = {
"AE1": "Auxillary Engine 1",
"AE2": "Auxillary Engine 2",
"AE3": "Auxillary Engine 3",
"AE4": "Auxillary Engine 4",
"AE5": "Auxillary Engine 5",
"ME": "Main Engine"
};
export class PerformanceToolHandler {
constructor() {
this.typesenseClient = getTypesenseClient();
}
async getLatestEnginePerformance(args) {
logger.info("getLatestEnginePerformance called", args);
const imo = args.imo;
const engineName = args.ENGINENAME;
const sessionId = args.session_id || "testing";
if (!imo) {
throw new Error("IMO number is required");
}
try {
const db = await getEngineDataDatabase();
const collection = db.collection("bluegem_performance_data");
// Build query
const query = { imo: parseInt(imo.toString()) };
// Engine names mapping
const engineNamesMapping = {
"AE1": "Auxillary Engine 1",
"AE2": "Auxillary Engine 2",
"AE3": "Auxillary Engine 3",
"AE4": "Auxillary Engine 4",
"AE5": "Auxillary Engine 5",
"ME": "Main Engine"
};
if (engineName) {
const mappedEngineName = engineNamesMapping[engineName];
if (mappedEngineName) {
query.ENGINENAME = mappedEngineName;
}
}
// Get all documents sorted by performance date
const documents = await collection
.find(query)
.project({ _id: 0 })
.toArray();
if (!documents || documents.length === 0) {
const noDataResponse = {
type: "text",
text: JSON.stringify({
message: `No engine performance data found for ${engineName || 'any engine'}`
})
};
return [noDataResponse];
}
// Process the documents based on whether engineName is specified
let processedDocuments;
if (engineName) {
// Get latest document for specific engine
processedDocuments = [documents
.sort((a, b) => new Date(b.PERFORMANCEDATE).getTime() - new Date(a.PERFORMANCEDATE).getTime())[0]
];
}
else {
// Group by engine name and get latest for each
const engineGroups = documents.reduce((groups, doc) => {
const name = doc.ENGINENAME;
if (!groups[name]) {
groups[name] = [];
}
groups[name].push(doc);
return groups;
}, {});
processedDocuments = Object.values(engineGroups)
.map((group) => group.sort((a, b) => new Date(b.PERFORMANCEDATE).getTime() - new Date(a.PERFORMANCEDATE).getTime())[0]);
}
// Get vessel name if available
const vesselName = processedDocuments[0]?.vesselName || "";
// Generate data link and store in MongoDB
const dataLink = await getDataLink(processedDocuments);
await insertDataLinkToMongoDB(dataLink, "Latest engine performance", sessionId, imo.toString(), vesselName);
// Create artifact
const artifactData = getArtifact("get_latest_engine_performance", dataLink);
const content = {
type: "text",
text: JSON.stringify(processedDocuments, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error in getLatestEnginePerformance", { error });
const errorResponse = {
type: "text",
text: `Error retrieving engine performance data: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getHistoricalEnginePerformance(args) {
logger.info("getHistoricalEnginePerformance called", args);
const imo = args.imo;
const engineName = args.ENGINENAME;
const startDate = args.start_date;
const endDate = args.end_date;
const limit = args.limit || 12;
const sessionId = args.session_id || "testing";
if (!imo) {
throw new Error("IMO number is required");
}
if (!engineName) {
throw new Error("Engine name is required");
}
if (!startDate || !endDate) {
throw new Error("Start date and end date are required");
}
try {
const db = await getEngineDataDatabase();
const collection = db.collection("bluegem_performance_data");
// Get full engine name
const fullEngineName = ENGINE_NAMES_MAPPING[engineName];
if (!fullEngineName) {
throw new Error(`Invalid engine name: ${engineName}`);
}
// Convert string dates to Date objects and adjust end date to be inclusive
const startDateTime = new Date(startDate);
const endDateTime = new Date(endDate);
endDateTime.setDate(endDateTime.getDate() + 1);
// Build query
const query = {
imo: parseInt(imo.toString()),
ENGINENAME: fullEngineName,
PERFORMANCEDATE: {
$gte: startDateTime,
$lt: endDateTime
}
};
// Fetch and sort documents
const documents = await collection
.find(query)
.sort("PERFORMANCEDATE", 1)
.limit(limit)
.toArray();
if (!documents || documents.length === 0) {
const noDataResponse = {
type: "text",
text: JSON.stringify({
message: `No historical engine performance data found for ${fullEngineName} between ${startDate} and ${endDate}`
})
};
return [noDataResponse];
}
// Sort documents by engine name and performance date
const sortedDocuments = documents.sort((a, b) => {
const engineCompare = a.ENGINENAME.localeCompare(b.ENGINENAME);
if (engineCompare !== 0)
return engineCompare;
return new Date(a.PERFORMANCEDATE).getTime() - new Date(b.PERFORMANCEDATE).getTime();
});
// Get vessel name if available
const vesselName = sortedDocuments[0]?.vesselName || "";
// Generate data link and store in MongoDB
const dataLink = await getDataLink(sortedDocuments);
await insertDataLinkToMongoDB(dataLink, "Historical engine performance", sessionId, imo.toString(), vesselName);
// Generate artifact data
const artifactData = getArtifact("get_historical_engine_performance", dataLink);
const content = {
type: "text",
text: JSON.stringify(sortedDocuments, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting historical engine performance:", error);
const errorResponse = {
type: "text",
text: `Error getting historical engine performance: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getMainEnginePerformanceReview(args) {
logger.info("getMainEnginePerformanceReview called", args);
const imo = args.imo;
if (!imo) {
throw new Error("IMO number is required");
}
try {
// Get data from QnA - Q No.67 for ME Performance Review
const result = await fetchQADetails(imo, 67);
const sessionId = args.session_id || "testing";
// Insert data link to MongoDB if available
if (result.link) {
await insertDataLinkToMongoDB(result.link, "main engine performance review", sessionId, imo.toString(), result.vesselName || "");
}
// Generate artifact data
const artifactData = getArtifact("get_main_engine_performance_review", result.link || "");
const content = {
type: "text",
text: JSON.stringify(result, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting main engine performance review:", error);
const errorResponse = {
type: "text",
text: `Error getting main engine performance review: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getAuxiliaryEnginePerformanceReview(args) {
logger.info("getAuxiliaryEnginePerformanceReview called", args);
const imo = args.imo;
if (!imo) {
throw new Error("IMO number is required");
}
try {
// Get data from QnA - Q No.71 for AE Performance Review
const result = await fetchQADetails(imo, 71);
const sessionId = args.session_id || "testing";
// Insert data link to MongoDB if available
if (result.link) {
await insertDataLinkToMongoDB(result.link, "auxiliary engine performance review", sessionId, imo.toString(), result.vesselName || "");
}
// Generate artifact data
const artifactData = getArtifact("get_auxiliary_engine_performance_review", result.link || "");
const content = {
type: "text",
text: JSON.stringify(result, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting auxiliary engine performance review:", error);
const errorResponse = {
type: "text",
text: `Error getting auxiliary engine performance review: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
}
//# sourceMappingURL=performanceTools.js.map