UNPKG

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

148 lines 6.38 kB
/** * PMS Analysis Reports MCP Server * A low-level server implementation using Model Context Protocol */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourceTemplatesRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { ToolHandler } from "./tools/index.js"; import { config } from "./utils/config.js"; import { logger } from "./utils/logger.js"; import { toolDefinitions } from "./tools/schema.js"; import { promptList, handleGetPrompt } from "./prompts/index.js"; import { initializeCompanyDatabase, fetchCompanyImoNumbers, setCompanyImoNumbers, shouldBypassImoFiltering, closeCompanyDatabase } from "./utils/imoUtils.js"; async function main() { logger.info("Starting PMS Analysis Reports MCP server... version 1.0.19"); // ✅ Step 1: Validate company name configuration if (!config.companyName) { logger.error("Company name is required for IMO filtering. Please provide it via --company-name option or COMPANY_NAME environment variable."); process.exit(1); } logger.info(`Starting server for company: ${config.companyName}`); // ✅ Step 2: Initialize company database and fetch IMO numbers try { // Initialize company database connection await initializeCompanyDatabase(); // Skip IMO fetching for admin companies if (shouldBypassImoFiltering(config.companyName)) { logger.info(`Admin company detected: ${config.companyName}. Skipping IMO filtering.`); setCompanyImoNumbers([]); } else { logger.info(`Fetching IMO numbers for company: ${config.companyName}`); const imoNumbers = await fetchCompanyImoNumbers(config.companyName); setCompanyImoNumbers(imoNumbers); logger.info(`Successfully fetched and cached ${imoNumbers.length} IMO numbers for company: ${config.companyName}`); } } catch (error) { logger.error("Failed to initialize IMO filtering system:", error); logger.warn("IMO filtering may be limited. Server will continue with reduced functionality."); // Continue server startup even if IMO fetching fails setCompanyImoNumbers([]); } const server = new Server({ name: "pms-analysis-reports-mcp-server", version: "1.0.19" }, { capabilities: { resources: { read: true, list: true, templates: true }, tools: { list: true, call: true }, prompts: { list: true, get: true } } }); const toolHandler = new ToolHandler(server); // Empty resource list server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [] }; }); // Empty resource read server.setRequestHandler(ReadResourceRequestSchema, async (request) => { throw new Error("Resource reading not implemented"); }); // Empty resource templates server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => { return { templates: [] }; }); // Tools list server.setRequestHandler(ListToolsRequestSchema, async (request) => { logger.info("Handling ListToolsRequest", { request }); let tools = [...toolDefinitions]; const params = request.params || {}; const category = params.category; const search = params.search; const includeDeprecated = params.include_deprecated; // Apply category filter if provided if (category) { tools = tools.filter(tool => { const toolName = tool.name.toLowerCase(); return toolName.includes(category.toLowerCase()); }); } // Apply search filter if provided if (search) { const searchTerm = search.toLowerCase(); tools = tools.filter(tool => tool.name.toLowerCase().includes(searchTerm) || (tool.description?.toLowerCase() || '').includes(searchTerm)); } // Filter out deprecated tools unless explicitly requested if (!includeDeprecated) { tools = tools.filter(tool => !tool.name.includes('deprecated')); } return { tools }; }); // Tool call server.setRequestHandler(CallToolRequestSchema, async (request) => { const result = await toolHandler.handleCallTool(request.params.name, request.params.arguments || {}); // Ensure content is always an array as expected by MCP protocol const content = Array.isArray(result) ? result : [result]; return { content }; }); // Prompts list server.setRequestHandler(ListPromptsRequestSchema, async () => { logger.info("Handling ListPromptsRequest"); return { prompts: promptList }; }); // Prompt get server.setRequestHandler(GetPromptRequestSchema, async (request) => { logger.info("Handling GetPromptRequest", { request }); const params = request.params || {}; const name = params.name; const args = params.arguments || {}; const result = handleGetPrompt(name, args); return result; }); // ✅ Step 3: Setup graceful shutdown handling const gracefulShutdown = async () => { logger.info("Shutting down server gracefully..."); try { await closeCompanyDatabase(); logger.info("Company database connection closed successfully"); } catch (error) { logger.error("Error during graceful shutdown:", error); } process.exit(0); }; process.on('SIGINT', gracefulShutdown); process.on('SIGTERM', gracefulShutdown); // Connect to transport and start server const transport = new StdioServerTransport(); await server.connect(transport); logger.info("Server started successfully with IMO filtering enabled"); } main().catch((error) => { logger.error("Fatal error:", error); process.exit(1); }); //# sourceMappingURL=index.js.map