@equidam/mcp-server
Version:
Equidam MCP Server - Bridge between AI assistants and Equidam's company valuation API
237 lines (203 loc) • 6.71 kB
JavaScript
/**
* 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
};