UNPKG

voyage-and-consumption-mcp-server

Version:

Voyage and consumption management server handling vessel voyages, fuel consumption, performance monitoring, and operational data with ERP access for data extraction

137 lines 5.74 kB
/** * Voyage & Consumption 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, getPrompt } from './prompts/index.js'; import { registerResources } from './resources/index.js'; import { ConnectionManager } from './database/connection-manager.js'; import { DatabaseService } from './database/database-service.js'; import { initializeCompanyImoNumbers } from './utils/imoUtils.js'; async function main() { logger.info("Starting Voyage & Consumption MCP server..."); // Validate critical configuration if (!config.siyaApiKey) { logger.error("SIYA_API_KEY is required but not provided. Please set the --siya-api-key argument or SIYA_API_KEY environment variable."); process.exit(1); } // Validate company configuration for IMO filtering 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); } // Initialize connection pooling logger.info("Initializing database connection pooling..."); const connectionManager = new ConnectionManager({ uri: config.mongoUri, dbName: config.dbName }, { uri: config.secondaryMongoUri, dbName: config.secondaryDbName }); await connectionManager.initializeConnections(); const databaseService = new DatabaseService(connectionManager); // Initialize company IMO numbers for filtering logger.info("Initializing company IMO numbers for filtering..."); await initializeCompanyImoNumbers(); const server = new Server({ name: "voyage-and-consumption-mcp-server", version: "1.1.4" }, { capabilities: { resources: { read: true, list: true, templates: true }, tools: { list: true, call: true }, prompts: { list: true, get: true } } }); const toolHandler = new ToolHandler(server, databaseService); // Register resources const { handleListResources, handleReadResource } = await registerResources(); // Register handlers server.setRequestHandler(ListResourcesRequestSchema, async (request) => { return handleListResources(request); }); server.setRequestHandler(ReadResourceRequestSchema, async (request) => { return handleReadResource(request); }); // 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 || {}); return { content: result }; }); // List prompts server.setRequestHandler(ListPromptsRequestSchema, async () => { return { prompts: promptList }; }); // Get prompt server.setRequestHandler(GetPromptRequestSchema, async (request) => { return getPrompt(request.params.name, request.params.arguments); }); // Set up graceful shutdown process.on('SIGINT', async () => { logger.info('Received SIGINT, shutting down gracefully...'); await databaseService.close(); process.exit(0); }); process.on('SIGTERM', async () => { logger.info('Received SIGTERM, shutting down gracefully...'); await databaseService.close(); process.exit(0); }); // Connect to transport and start server const transport = new StdioServerTransport(); await server.connect(transport); logger.info("MCP server connected and running with connection pooling"); } main().catch((error) => { logger.error("Fatal error:", error); process.exit(1); }); //# sourceMappingURL=index.js.map