UNPKG

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