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
758 lines • 30.8 kB
JavaScript
import { getTypesenseClient, fetchQADetails, getArtifact, insertDataLinkToMongoDB } from "syia-mcp-utils";
import { logger } from "../../index.js";
export class LubeOilToolHandler {
constructor() {
this.typesenseClient = getTypesenseClient();
}
async getLubeOilShoreAnalysis(args) {
logger.info("getLubeOilShoreAnalysis called", args);
const imo = args.imo;
if (!imo) {
throw new Error("IMO number is required");
}
try {
// Get data from QnA
const result = await fetchQADetails(imo, 103);
const sessionId = args.session_id || "testing";
// Insert data link to MongoDB if available
if (result.link) {
await insertDataLinkToMongoDB(result.link, "lube oil shore analysis status", sessionId, imo.toString(), result.vesselName);
}
// Generate artifact data
const artifactData = getArtifact("get_lube_oil_shore_analysis", result.link || "");
const content = {
type: "text",
text: JSON.stringify(result, null, 2),
title: `Lube Oil Shore Analysis Status for vessel ${imo}`,
format: "json"
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2),
title: `Lube Oil Shore Analysis Status for vessel ${imo}`,
format: "json"
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting lube oil analysis status:", error);
const errorResponse = {
type: "text",
text: `Error getting lube oil analysis status: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getOnboardLubeAnalysisForm(args) {
logger.info("getOnboardLubeAnalysisForm called", args);
try {
const imo = args.imo;
const sessionId = args.session_id || "testing";
if (!imo) {
throw new Error("IMO number is required");
}
// Fetch QA details for question 72 (TE-57 Onboard Weekly Lube Analysis Review)
let result;
try {
result = await fetchQADetails(imo.toString(), 72);
}
catch (error) {
const noDataResponse = {
type: "text",
text: "No onboard lube analysis form found for this vessel."
};
return [noDataResponse];
}
// Get link and vessel name for MongoDB
const dataLink = result.Artifactlink ?? "";
const vesselName = result.vesselName || "";
// Insert the data link to mongodb collection
await insertDataLinkToMongoDB(dataLink, "onboard lube analysis form", sessionId, imo.toString(), vesselName);
// Format results as JSON
const formattedText = JSON.stringify(result, null, 2);
// Create artifact
const artifactData = getArtifact("get_onboard_lube_analysis_form", dataLink);
const content = {
type: "text",
text: formattedText
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error in getOnboardLubeAnalysisForm", { error });
const errorResponse = {
type: "text",
text: `Error retrieving onboard lube analysis form: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getLubeOilTankDistribution(args) {
logger.info("getLubeOilTankDistribution called", args);
try {
const imo = args.imo;
const sessionId = args.session_id || "testing";
if (!imo) {
throw new Error("IMO number is required");
}
// Fetch QA details for question 104 (Lube Oil Tank Distribution & Capacities)
let result;
try {
result = await fetchQADetails(imo.toString(), 104);
}
catch (error) {
const noDataResponse = {
type: "text",
text: "No lube oil tank distribution data found for this vessel."
};
return [noDataResponse];
}
// Get link and vessel name for MongoDB
const dataLink = result.Artifactlink ?? "";
const vesselName = result.vesselName || "";
// Insert the data link to mongodb collection
await insertDataLinkToMongoDB(dataLink, "lube oil tank distribution", sessionId, imo.toString(), vesselName);
// Format results as JSON
const formattedText = JSON.stringify(result, null, 2);
// Create artifact
const artifactData = getArtifact("get_lube_oil_tank_distribution", dataLink);
const content = {
type: "text",
text: formattedText
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error in getLubeOilTankDistribution", { error });
const errorResponse = {
type: "text",
text: `Error retrieving lube oil tank distribution: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
async getLubeOilRob(args) {
logger.info("getLubeOilRob called", args);
try {
const imo = args.imo;
const sessionId = args.session_id || "testing";
if (!imo) {
throw new Error("IMO number is required");
}
// Fetch QA details for question 74 (TE-56 Monthly Lube Oil Consumption Review)
let result;
try {
result = await fetchQADetails(imo.toString(), 74);
}
catch (error) {
const noDataResponse = {
type: "text",
text: "No lube oil ROB data found for this vessel."
};
return [noDataResponse];
}
// Get link and vessel name for MongoDB
const dataLink = result.Artifactlink ?? "";
const vesselName = result.vesselName || "";
// Insert the data link to mongodb collection
await insertDataLinkToMongoDB(dataLink, "lube oil ROB consumption review", sessionId, imo.toString(), vesselName);
// Format results as JSON
const formattedText = JSON.stringify(result, null, 2);
// Create artifact
const artifactData = getArtifact("get_lube_oil_rob", dataLink);
const content = {
type: "text",
text: formattedText
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error in getLubeOilRob", { error });
const errorResponse = {
type: "text",
text: `Error retrieving lube oil ROB data: ${error instanceof Error ? error.message : String(error)}`
};
return [errorResponse];
}
}
}
// ============================================================================
// INDIVIDUAL LUBE OIL HANDLERS - REPLACED BY universalLubeOilSearchHandler
// ============================================================================
// The following individual lube oil handler functions have been consolidated
// into the universalLubeOilSearchHandler in universalTools.ts. They are
// commented out but kept for reference and potential future use if needed.
// ============================================================================
// Typesense tool implementations
// export async function lubeReportTableQuery(args: LubeReportTableQueryArgs): Promise<ToolResponse> {
// logger.info("Executing lube_report_table_query", { args });
//
// try {
// const collection = args.collection;
// const query = args.query || {};
//
// if (!collection) {
// throw new Error("Missing required parameter: 'collection'.");
// }
//
// // Validate required query fields
// const requiredQueryFields = ["q", "query_by"];
// for (const field of requiredQueryFields) {
// if (!query[field] || !query[field]) {
// throw new Error(`Missing required query field: '${field}'.`);
// }
// }
//
// logger.debug(`Querying Typesense collection '${collection}' with:`, query);
//
// // Use the existing typesense client to search
// const results = await getTypesenseClient().collections(collection).documents().search(query);
//
// const hits = results.hits || [];
// const formattedHits = [];
//
// for (const hit of hits as any[]) {
// let formattedDoc = hit.document || {};
// if (collection === "pms") {
// formattedDoc = convertUnixDates(formattedDoc);
// }
// formattedHits.push(formattedDoc);
// }
//
// const formattedResults = {
// found: results.found || 0,
// out_of: results.out_of || 0,
// page: results.page || 1,
// hits: formattedHits
// };
//
// // Generate link and artifact data
// const link = await getDataLink(formattedHits) || '';
// const artifactData = getArtifact("typesense_query", link);
//
// const content: TextContent = {
// type: "text",
// text: JSON.stringify(formattedResults, null, 2)
// };
//
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
//
// return [content, artifact];
// } catch (error) {
// logger.error("Error in lubeReportTableQuery", { error });
// throw new Error(`Typesense query failed: ${error instanceof Error ? error.message : String(error)}`);
// }
// }
// export async function listOverdueLubeOilSamples(args: OverdueLubeOilSamplesArgs): Promise<ToolResponse> {
// logger.info("Executing list_overdue_lube_oil_samples", { args });
//
// try {
// const imo = args.imo;
// const sessionId = args.session_id || "testing";
//
// if (!imo) {
// throw new Error("IMO number is required");
// }
//
// // Build filter_by string
// let filterBy = `imo:${imo} && dueStatus:"OVERDUE"`;
//
// // Add optional machinery name filter
// if (args.machineryName) {
// filterBy += ` && machineryName:${args.machineryName}`;
// }
//
// // Execute search
// const searchParameters = {
// q: "*",
// filter_by: filterBy,
// sort_by: "nextDue:asc",
// per_page: args.per_page || 30,
// include_fields: "imo,vesselName,machineryName,reportStatus,sampleDate,nextDue,frequency,dueStatus,testLab,report"
// };
//
// const searchResult = await getTypesenseClient().collections("lube_oil_reports").documents().search(searchParameters);
//
// if (!searchResult || !searchResult.hits) {
// const noDataResponse: TextContent = {
// type: "text",
// text: "No overdue lube oil samples found for the specified criteria."
// };
// return [noDataResponse];
// }
//
// // Process results
// const hits = searchResult.hits || [];
// const samples = [];
//
// for (const hit of hits as any[]) {
// let documentData = hit.document || {};
// // Convert dates if needed
// documentData = convertUnixDates(documentData);
// samples.push({
// imo: documentData.imo,
// vesselName: documentData.vesselName,
// machineryName: documentData.machineryName,
// reportStatus: documentData.reportStatus,
// sampleDate: documentData.sampleDate,
// nextDue: documentData.nextDue,
// frequency: documentData.frequency,
// dueStatus: documentData.dueStatus,
// testLab: documentData.testLab,
// report: documentData.report
// });
// }
//
// // Get documents for data link
// const documents = hits.map((hit: any) => hit.document);
//
// // Get data link
// const dataLink = await getDataLink(documents);
//
// // Get vessel name from hits
// let vesselName = "";
// try {
// vesselName = (hits[0]?.document as any)?.vesselName || "";
// } catch (error) {
// vesselName = "";
// }
//
// // Insert the data link to mongodb collection
// const machineryName = args.machineryName || "all machinery";
// const linkHeader = `overdue lube oil samples for ${machineryName}`;
// await insertDataLinkToMongoDB(dataLink || "", linkHeader, sessionId, imo, vesselName);
//
// // Format results
// const formattedText = JSON.stringify(samples, null, 2);
//
// // Create artifact
// const artifactData = getArtifact("list_overdue_lube_oil_samples", dataLink || "no_link");
//
// const content: TextContent = {
// type: "text",
// text: formattedText
// };
//
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
//
// return [content, artifact];
//
// } catch (error) {
// logger.error("Error in listOverdueLubeOilSamples", { error });
// const errorResponse: TextContent = {
// type: "text",
// text: `Error retrieving overdue lube oil samples: ${error instanceof Error ? error.message : String(error)}`
// };
// return [errorResponse];
// }
// }
//
// export async function machineryWithWarningLubeOilAnalysis(args: MachineryWarningLubeOilArgs): Promise<ToolResponse> {
// logger.info("Executing machinery_with_warning_lube_oil_analysis", { args });
//
// try {
// const imo = args.imo;
// const sessionId = args.session_id || "testing";
//
// if (!imo) {
// throw new Error("IMO number is required");
// }
//
// // Build filter_by string
// let filterBy = `imo:${imo} && reportStatus:"WARNING"`;
//
// // Add optional machinery name filter
// if (args.machineryName) {
// filterBy += ` && machineryName:${args.machineryName}`;
// }
//
// // Execute search
// const searchParameters = {
// q: "*",
// filter_by: filterBy,
// sort_by: "sampleDate:desc",
// per_page: args.per_page || 30,
// include_fields: "imo,vesselName,machineryName,reportStatus,sampleDate,nextDue,frequency,dueStatus,testLab,report"
// };
//
// const searchResult = await getTypesenseClient().collections("lube_oil_reports").documents().search(searchParameters);
//
// if (!searchResult || !searchResult.hits) {
// const noDataResponse: TextContent = {
// type: "text",
// text: "No warning status oil analysis reports found for the specified criteria."
// };
// return [noDataResponse];
// }
//
// // Process results
// const hits = searchResult.hits || [];
// const reports = [];
//
// for (const hit of hits as any[]) {
// let documentData = hit.document || {};
// // Convert dates if needed
// documentData = convertUnixDates(documentData);
// reports.push({
// imo: documentData.imo,
// vesselName: documentData.vesselName,
// machineryName: documentData.machineryName,
// reportStatus: documentData.reportStatus,
// sampleDate: documentData.sampleDate,
// nextDue: documentData.nextDue,
// frequency: documentData.frequency,
// dueStatus: documentData.dueStatus,
// testLab: documentData.testLab,
// report: documentData.report
// });
// }
//
// // Get documents for data link
// const documents = hits.map((hit: any) => hit.document);
//
// // Get data link
// const dataLink = await getDataLink(documents);
//
// // Get vessel name from hits
// let vesselName = "";
// try {
// vesselName = (hits[0]?.document as any)?.vesselName || "";
// } catch (error) {
// vesselName = "";
// }
//
// // Insert the data link to mongodb collection
// const machineryName = args.machineryName || "all machinery";
// const linkHeader = `warning oil analysis reports for ${machineryName}`;
// await insertDataLinkToMongoDB(dataLink || "", linkHeader, sessionId, imo, vesselName);
//
// // Format results
// const formattedText = JSON.stringify(reports, null, 2);
//
// // Create artifact
// const artifactData = getArtifact("machinery_with_warning_lube_oil_analysis", dataLink || "no_link");
//
// const content: TextContent = {
// type: "text",
// text: formattedText
// };
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
// return [content, artifact];
//
// } catch (error) {
// logger.error("Error in machineryWithWarningLubeOilAnalysis", { error });
// const errorResponse: TextContent = {
// type: "text",
// text: `Error retrieving warning status oil analysis reports: ${error instanceof Error ? error.message : String(error)}`
// };
// return [errorResponse];
// }
// }
//
//
// export async function getLatestLubeOilAnalysisForMachinery(args: LatestLubeOilAnalysisForMachineryArgs): Promise<ToolResponse> {
// logger.info("Executing get_latest_lube_oil_analysis_for_machinery", { args });
//
// try {
// const imo = args.imo;
// const machineryName = args.machineryName;
// const sessionId = args.session_id || "testing";
//
// if (!imo || !machineryName) {
// throw new Error("IMO number and machinery name are required");
// }
//
// // Build filter_by string
// const filterBy = `imo:${imo} && machineryName:${machineryName}`;
//
// // Execute search
// const searchParameters = {
// q: "*",
// filter_by: filterBy,
// sort_by: "sampleDate:desc",
// per_page: args.per_page || 10,
// include_fields: "imo,vesselName,machineryName,reportStatus,sampleDate,nextDue,frequency,dueStatus,testLab,report"
// };
//
// const searchResult = await getTypesenseClient().collections("lube_oil_reports").documents().search(searchParameters);
//
// if (!searchResult || !searchResult.hits || searchResult.hits.length === 0) {
// const noDataResponse: TextContent = {
// type: "text",
// text: `No oil analysis records found for ${machineryName} on vessel ${imo}.`
// };
// return [noDataResponse];
// }
//
// // Get the latest record
// const hits = searchResult.hits;
// let document = hits[0].document as any;
// // Convert date fields to human readable format
// document = convertUnixDates(document);
// const result = {
// imo: document.imo,
// vesselName: document.vesselName,
// machineryName: document.machineryName,
// reportStatus: document.reportStatus,
// sampleDate: document.sampleDate,
// nextDue: document.nextDue,
// frequency: document.frequency,
// dueStatus: document.dueStatus,
// testLab: document.testLab,
// report: document.report
// };
//
// // Get documents for data link
// const documents = hits.map((hit: any) => hit.document);
//
// // Get data link
// const dataLink = await getDataLink(documents);
//
// // Get vessel name from document
// const vesselName = document.vesselName || "";
//
// // Insert the data link to mongodb collection
// const linkHeader = `latest oil analysis for ${machineryName}`;
// await insertDataLinkToMongoDB(dataLink || "", linkHeader, sessionId, imo, vesselName);
//
// // Format results
// const formattedText = JSON.stringify(result, null, 2);
//
// // Create artifact
// const artifactData = getArtifact("get_latest_oil_analysis_for_machinery", dataLink || "no_link");
//
// const content: TextContent = {
// type: "text",
// text: formattedText
// };
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
// return [content, artifact];
//
// } catch (error) {
// logger.error("Error in getLatestLubeOilAnalysisForMachinery", { error });
// const errorResponse: TextContent = {
// type: "text",
// text: `Error retrieving latest oil analysis: ${error instanceof Error ? error.message : String(error)}`
// };
// return [errorResponse];
// }
// }
//
//
// export async function listLubeOilSamplesByFrequency(args: LubeOilSamplesByFrequencyArgs): Promise<ToolResponse> {
// logger.info("Executing list_lube_oil_samples_by_frequency", { args });
//
// try {
// const imo = args.imo;
// const frequency = args.frequency;
// const sessionId = args.session_id || "testing";
//
// if (!imo || !frequency) {
// throw new Error("IMO number and frequency are required");
// }
//
// // Build filter_by string
// const filterBy = `imo:${imo} && frequency:"${frequency}"`;
//
// // Execute search
// const searchParameters = {
// q: "*",
// filter_by: filterBy,
// sort_by: "nextDue:asc",
// per_page: args.per_page || 30,
// include_fields: "imo,vesselName,machineryName,reportStatus,sampleDate,nextDue,frequency,dueStatus,testLab,report"
// };
//
// const searchResult = await getTypesenseClient().collections("lube_oil_reports").documents().search(searchParameters);
//
// if (!searchResult || !searchResult.hits || searchResult.hits.length === 0) {
// const noDataResponse: TextContent = {
// type: "text",
// text: `No ${frequency} frequency lube oil samples found for vessel ${imo}.`
// };
// return [noDataResponse];
// }
//
// // Process results
// const hits = searchResult.hits;
// const samples = [];
//
// for (const hit of hits as any[]) {
// let sampleData = hit.document || {};
// // Convert dates if needed
// sampleData = convertUnixDates(sampleData);
// samples.push({
// imo: sampleData.imo,
// vesselName: sampleData.vesselName,
// machineryName: sampleData.machineryName,
// reportStatus: sampleData.reportStatus,
// sampleDate: sampleData.sampleDate,
// nextDue: sampleData.nextDue,
// frequency: sampleData.frequency,
// dueStatus: sampleData.dueStatus,
// testLab: sampleData.testLab,
// report: sampleData.report
// });
// }
//
// // Get documents for data link
// const documents = hits.map((hit: any) => hit.document);
//
// // Get data link
// const dataLink = await getDataLink(documents);
//
// // Get vessel name from hits
// let vesselName = "";
// try {
// vesselName = (hits[0]?.document as any)?.vesselName || "";
// } catch (error) {
// vesselName = "";
// }
//
// // Insert the data link to mongodb collection
// const linkHeader = `${frequency} frequency lube oil samples`;
// await insertDataLinkToMongoDB(dataLink || "", linkHeader, sessionId, imo, vesselName);
//
// // Format results
// const formattedText = JSON.stringify(samples, null, 2);
//
// // Create artifact
// const artifactData = getArtifact("list_lube_oil_samples_by_frequency", dataLink || "no_link");
//
// const content: TextContent = {
// type: "text",
// text: formattedText
// };
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
// return [content, artifact];
//
// } catch (error) {
// logger.error("Error in listLubeOilSamplesByFrequency", { error });
// const errorResponse: TextContent = {
// type: "text",
// text: `Error retrieving lube oil samples: ${error instanceof Error ? error.message : String(error)}`
// };
// return [errorResponse];
// }
// }
//
// export async function fetchLubeOilAnalysisWithLink(args: FetchLubeOilAnalysisWithLinkArgs): Promise<ToolResponse> {
// logger.info("Executing fetch_lube_oil_analysis_with_link", { args });
//
// try {
// const imo = args.imo;
// const sessionId = args.session_id || "testing";
//
// if (!imo) {
// throw new Error("IMO number is required");
// }
//
// // Build filter_by string
// let filterBy = `imo:${imo}`;
//
// // Add optional machinery name filter
// if (args.machineryName) {
// filterBy += ` && machineryName:${args.machineryName}`;
// }
//
// // Execute search
// const searchParameters = {
// q: "*",
// filter_by: filterBy,
// sort_by: "sampleDate:desc",
// per_page: args.per_page || 10,
// include_fields: "imo,vesselName,machineryName,reportStatus,sampleDate,nextDue,frequency,dueStatus,testLab,report"
// };
//
// const searchResult = await getTypesenseClient().collections("lube_oil_reports").documents().search(searchParameters);
//
// if (!searchResult || !searchResult.hits || searchResult.hits.length === 0) {
// const noDataResponse: TextContent = {
// type: "text",
// text: `No oil analysis reports found for vessel ${imo}.`
// };
// return [noDataResponse];
// }
//
// // Get the latest record
// const hits = searchResult.hits;
// let latest = hits[0].document as any;
// // Convert date fields to human readable format
// latest = convertUnixDates(latest);
//
// const reportLink = latest?.report || null;
// // const report = await parseDocumentLink({ document_link: reportLink }) : null;
//
// const result = {
// machineryName: latest.machineryName,
// sampleDate: latest.sampleDate,
// // report: report,
// reportLink: reportLink
// };
//
// // Get documents for data link
// const documents = hits.map((hit: any) => hit.document);
//
// // Get data link
// const dataLink = await getDataLink(documents);
//
// // Get machinery name for the header
// const machineryName = args.machineryName || latest.machineryName || "machinery";
//
// // Insert the data link to mongodb collection
// const linkHeader = `latest oil analysis report link for ${machineryName}`;
// await insertDataLinkToMongoDB(dataLink || "", linkHeader, sessionId, imo, latest.vesselName || "");
//
// // Format results
// const formattedText = JSON.stringify(result, null, 2);
//
// // Create artifact
// const artifactData = getArtifact("fetch_lube_oil_analysis_with_link", dataLink || "no_link");
//
// const content: TextContent = {
// type: "text",
// text: formattedText
// };
//
// const artifact: TextContent = {
// type: "text",
// text: JSON.stringify(artifactData, null, 2)
// };
// return [content, artifact];
// } catch (error) {
// logger.error("Error in fetchLubeOilAnalysisWithLink", { error });
// const errorResponse: TextContent = {
// type: "text",
// text: `Error retrieving latest oil analysis report link: ${error instanceof Error ? error.message : String(error)}`
// };
// return [errorResponse];
// }
// }
//# sourceMappingURL=lubeOilTools.js.map