UNPKG

elasticsearch-mcp

Version:

Secure MCP server for Elasticsearch integration with comprehensive tools and Elastic Cloud support

163 lines 5.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ElasticsearchManager = void 0; const elasticsearch_1 = require("@elastic/elasticsearch"); class ElasticsearchManager { client = null; config; logger; connectionInfo; healthCheckInterval = null; constructor(config, logger) { this.config = config; this.logger = logger.child({ component: 'elasticsearch' }); this.connectionInfo = { isConnected: false, lastHealthCheck: new Date(), }; } async initialize() { try { this.logger.info('Initializing Elasticsearch client', { cloudId: this.config.cloudId ? '***' : undefined, node: this.config.node, hasApiKey: !!this.config.apiKey, hasAuth: !!this.config.auth, }); const clientOptions = { maxRetries: this.config.maxRetries, requestTimeout: this.config.requestTimeout, pingTimeout: this.config.pingTimeout, sniffOnStart: this.config.sniffOnStart, ...(this.config.sniffInterval && { sniffInterval: this.config.sniffInterval }), }; if (this.config.cloudId) { clientOptions.cloud = { id: this.config.cloudId }; if (this.config.apiKey) { clientOptions.auth = { apiKey: this.config.apiKey }; } } else if (this.config.node) { clientOptions.node = this.config.node; if (this.config.apiKey) { clientOptions.auth = { apiKey: this.config.apiKey }; } else if (this.config.auth) { clientOptions.auth = { username: this.config.auth.username, password: this.config.auth.password, }; } } if (this.config.ssl) { clientOptions.tls = { rejectUnauthorized: this.config.ssl.rejectUnauthorized, }; } this.client = new elasticsearch_1.Client(clientOptions); await this.healthCheck(); this.startHealthMonitoring(); this.logger.info('Elasticsearch client initialized successfully', { clusterName: this.connectionInfo.clusterName, version: this.connectionInfo.version, }); } catch (error) { this.logger.error('Failed to initialize Elasticsearch client', {}, error); throw error; } } async healthCheck() { if (!this.client) { this.connectionInfo = { isConnected: false, lastHealthCheck: new Date(), error: 'Client not initialized', }; return false; } try { const [pingResult, infoResult] = await Promise.all([ this.client.ping(), this.client.info(), ]); this.connectionInfo = { isConnected: pingResult === true, clusterName: infoResult.cluster_name, version: infoResult.version?.number, lastHealthCheck: new Date(), }; if (this.connectionInfo.isConnected) { this.logger.debug('Health check passed', { clusterName: this.connectionInfo.clusterName, version: this.connectionInfo.version, }); } return this.connectionInfo.isConnected; } catch (error) { this.connectionInfo = { isConnected: false, lastHealthCheck: new Date(), error: error.message, }; this.logger.warn('Health check failed', { error: error.message, }); return false; } } async reconnect() { this.logger.info('Attempting to reconnect to Elasticsearch'); if (this.client) { await this.client.close(); } await this.initialize(); } getClient() { if (!this.client) { throw new Error('Elasticsearch client not initialized'); } if (!this.connectionInfo.isConnected) { throw new Error('Elasticsearch client not connected'); } return this.client; } getConnectionInfo() { return { ...this.connectionInfo }; } startHealthMonitoring() { const HEALTH_CHECK_INTERVAL = 30000; // 30 seconds this.healthCheckInterval = setInterval(async () => { const isHealthy = await this.healthCheck(); if (!isHealthy) { this.logger.warn('Health check failed, attempting reconnection'); try { await this.reconnect(); } catch (error) { this.logger.error('Reconnection failed', {}, error); } } }, HEALTH_CHECK_INTERVAL); } async shutdown() { this.logger.info('Shutting down Elasticsearch manager'); if (this.healthCheckInterval) { clearInterval(this.healthCheckInterval); this.healthCheckInterval = null; } if (this.client) { try { await this.client.close(); this.logger.info('Elasticsearch client closed'); } catch (error) { this.logger.warn('Error closing Elasticsearch client', { error: error.message }); } } this.connectionInfo.isConnected = false; } } exports.ElasticsearchManager = ElasticsearchManager; //# sourceMappingURL=client.js.map