UNPKG

@equidam/mcp-server

Version:

Equidam MCP Server - Bridge between AI assistants and Equidam's company valuation API

237 lines (203 loc) 6.71 kB
/** * Equidam MCP Server Implementation * Implements the Model Context Protocol to bridge AI assistants with Equidam API */ const { Server } = require('@modelcontextprotocol/sdk/server/index.js'); const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js'); const { CallToolRequestSchema, ListToolsRequestSchema } = require('@modelcontextprotocol/sdk/types.js'); const { EquidamApiClient } = require('./api-client'); const { CLASSIFY_TOOL_DEFINITION, createClassifyHandler } = require('./tools/classify'); const { SELECT_INDUSTRY_TOOL_DEFINITION, createSelectIndustryHandler } = require('./tools/select-industry'); const { VALUATE_TOOL_DEFINITION, createValuationHandler } = require('./tools/valuate'); /** * MCP Server class for Equidam integration */ class McpServer { /** * Create a new MCP server instance * @param {object} config - Configuration object * @param {string} config.apiKey - Equidam API key * @param {string} config.baseUrl - Base URL for API requests * @param {boolean} config.debug - Enable debug logging * @param {Function} config.debugLog - Debug logging function */ constructor({ apiKey, baseUrl, debug = false, debugLog = () => {} }) { this.config = { apiKey, baseUrl, debug, debugLog }; this.debugLog = debugLog; // Initialize API client this.apiClient = new EquidamApiClient({ apiKey, baseUrl, debugLog }); // Initialize MCP server this.server = new Server( { name: '@equidam/mcp-server', version: '1.0.0' }, { capabilities: { tools: {} } } ); // Tool handlers this.classifyHandler = createClassifyHandler(this.apiClient, this.debugLog); this.selectIndustryHandler = createSelectIndustryHandler(this.apiClient, this.debugLog); this.valuationHandler = createValuationHandler(this.apiClient, this.debugLog); // Set up MCP handlers this.setupToolHandlers(); this.debugLog('MCP Server initialized with capabilities:', { tools: ['classify_company_industry', 'select_industry_classification', 'get_company_valuation'], debug: debug }); } /** * Set up MCP protocol handlers */ setupToolHandlers() { // Handle tool listing requests this.server.setRequestHandler(ListToolsRequestSchema, async () => { this.debugLog('Received tools/list request'); return { tools: [ CLASSIFY_TOOL_DEFINITION, SELECT_INDUSTRY_TOOL_DEFINITION, VALUATE_TOOL_DEFINITION ] }; }); // Handle tool execution requests this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; this.debugLog('Received tools/call request:', { tool: name, args: args ? Object.keys(args) : [] }); try { let result; switch (name) { case 'classify_company_industry': result = await this.classifyHandler(args || {}); break; case 'select_industry_classification': result = await this.selectIndustryHandler(args || {}); break; case 'get_company_valuation': result = await this.valuationHandler(args || {}); break; default: this.debugLog('Unknown tool requested:', name); return { content: [ { type: "text", text: `Unknown tool: ${name}. Available tools: classify_company_industry, select_industry_classification, get_company_valuation` } ], isError: true }; } // Handle error responses from tools if (result.isError) { this.debugLog('Tool execution error:', result.error); return { content: [ { type: "text", text: `Error: ${result.error}` } ], isError: true }; } // Return successful result this.debugLog('Tool execution successful for:', name); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { this.debugLog('Unexpected error in tool execution:', error.message); return { content: [ { type: "text", text: `Unexpected error: ${error.message}` } ], isError: true }; } }); } /** * Start the MCP server */ async start() { try { this.debugLog('Starting MCP server...'); // Create stdio transport for MCP communication const transport = new StdioServerTransport(); // Connect server to transport await this.server.connect(transport); this.debugLog('MCP server started and connected to stdio transport'); // Keep the process running process.on('SIGINT', () => { this.debugLog('Received SIGINT, shutting down MCP server...'); this.shutdown(); }); process.on('SIGTERM', () => { this.debugLog('Received SIGTERM, shutting down MCP server...'); this.shutdown(); }); } catch (error) { this.debugLog('Failed to start MCP server:', error.message); throw new Error(`Failed to start MCP server: ${error.message}`); } } /** * Shutdown the MCP server gracefully */ async shutdown() { try { this.debugLog('Shutting down MCP server...'); // Close server connection if (this.server) { await this.server.close(); } this.debugLog('MCP server shutdown complete'); process.exit(0); } catch (error) { this.debugLog('Error during server shutdown:', error.message); process.exit(1); } } /** * Get server information for debugging * @returns {object} - Server information */ getServerInfo() { return { name: '@equidam/mcp-server', version: '1.0.0', tools: ['classify_company_industry', 'select_industry_classification', 'get_company_valuation'], capabilities: { tools: true }, config: { baseUrl: this.config.baseUrl, debug: this.config.debug, apiKeyConfigured: !!this.config.apiKey } }; } } module.exports = { McpServer };