UNPKG

@memory-bank/mcp

Version:

Memory-enabled Co-Pilot (MCP) server for managing project documentation and context

173 lines 7.94 kB
import { setupContainer } from './di/providers.js'; import { Constants } from './config/constants.js'; import { logger } from '../shared/utils/logger.js'; // パスエイリアスを相対パスに修正 import { LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js'; // Keep the correct import /** * Application main class * Initializes and manages the application lifecycle */ export class Application { // Changed options visibility for debugging options; container; globalController; branchController; contextController; documentController; // Expose configProvider for tools to check project mode get configProvider() { if (!this.container) { throw new Error('Application not initialized. Call initialize() first.'); } return this.container.get('configProvider'); } /** * Constructor * @param options Minimal application options */ constructor(options) { this.options = options || {}; logger.info(`Starting ${Constants.APP_NAME} v${Constants.VERSION}`); } /** * Initialize the application */ async initialize() { try { logger.info('Initializing application..'); this.container = await setupContainer(this.options); this.globalController = await this.container.get('globalController'); this.branchController = await this.container.get('branchController'); this.contextController = await this.container.get('contextController'); this.documentController = await this.container.get('documentController'); logger.info('Application initialized successfully'); } catch (error) { logger.error('Failed to initialize application:', error); throw error; } } /** * Get global controller * @returns Global controller */ getGlobalController() { if (!this.globalController) { throw new Error('Application not initialized. Call initialize() first.'); } return this.globalController; } /** * Get branch controller * @returns Branch controller */ getBranchController() { if (!this.branchController) { throw new Error('Application not initialized. Call initialize() first.'); } return this.branchController; } /** * Get context controller * @returns Context controller */ getContextController() { if (!this.contextController) { throw new Error('Application not initialized. Call initialize() first.'); } return this.contextController; } /** * Get document controller * @returns Document controller */ getDocumentController() { if (!this.documentController) { throw new Error('Application not initialized. Call initialize() first.'); } return this.documentController; } /** * Handles incoming connections from a client transport. * @param transport The server-side transport for communication. */ async handleConnection(transport) { logger.info('[Application.handleConnection] Handling new connection...'); transport.onmessage = async (message) => { let response = null; // Use 'any' for JSONRPCResponse type initially try { // TODO: Implement message routing based on message.method // e.g., call appropriate controller method (global, branch, context) if (!message || typeof message.method !== 'string') { throw new Error('Invalid JSON-RPC message received'); } const method = message.method; if (method === 'initialize') { // Handle initialize method // Respond with basic server info (can be expanded later) response = { jsonrpc: '2.0', id: message.id, result: { protocolVersion: LATEST_PROTOCOL_VERSION, serverInfo: { name: Constants.APP_NAME, version: Constants.VERSION, }, capabilities: {} } }; } else if (method === 'read_context' && this.contextController) { logger.debug(`Routing to contextController.${method}`); const params = message.params || {}; const controllerResult = await this.contextController.readContext(params); response = { jsonrpc: '2.0', id: message.id, result: controllerResult }; // Return the controller result directly } else if (method.startsWith('read_global') && this.globalController) { logger.debug(`Routing to globalController.${method}`); // TODO: Implement actual controller call response = { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not implemented yet: ${method}` } }; } else if (method.startsWith('write_branch') && this.branchController) { logger.debug(`Routing to branchController.${method}`); // TODO: Implement actual controller call response = { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not implemented yet: ${method}` } }; } else if (method.startsWith('read_branch') && this.branchController) { logger.debug(`Routing to branchController.${method}`); // TODO: Implement actual controller call response = { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not implemented yet: ${method}` } }; } else if (method.startsWith('search_documents') && (this.globalController || this.branchController)) { logger.debug(`Routing to searchDocumentsByTagsUseCase via controller`); // TODO: Implement actual controller call response = { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not implemented yet: ${method}` } }; } else { logger.warn(`Method not found or controller not available: ${method}`); response = { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not found: ${method}` } }; } } catch (error) { // Keep error log, but maybe simplify context if needed logger.error('[Application.handleConnection] Error processing message:', { error: error.message }); response = { jsonrpc: '2.0', id: message?.id ?? null, // Use null id if message.id is missing error: { code: -32000, message: error.message || 'Internal server error' }, }; } if (response) { await transport.send(response); } }; transport.onclose = () => { logger.info('[Application.handleConnection] Connection closed.'); // Restore info log // Perform any necessary cleanup for this connection }; // Start the transport if it's not already started (optional, depends on transport impl) // await transport.start(); // Assuming transport starts automatically or is started elsewhere logger.info('[Application.handleConnection] Connection handler set up.'); // Restore info log } } //# sourceMappingURL=Application.js.map