UNPKG

@myea/aem-mcp-handler

Version:

Advanced AEM MCP request handler with intelligent search, multi-locale support, and comprehensive content management capabilities

241 lines (240 loc) • 8.97 kB
#!/usr/bin/env node import express from 'express'; import cors from 'cors'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { AEMConnector } from './aem-connector.js'; import { MCPRequestHandler } from './mcp-handler.js'; import llmRouter from './llm-integration.js'; import telegramIntegration from './telegram-integration.js'; import dotenv from 'dotenv'; dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const app = express(); const MCP_PORT = parseInt(process.env.MCP_PORT || '8080', 10); const GATEWAY_PORT = parseInt(process.env.GATEWAY_PORT || '3000', 10); // Middleware app.use(cors()); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Serve static files from public directory app.use(express.static(join(__dirname, '../public'))); // Basic auth middleware for MCP endpoints if credentials are configured const basicAuth = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Basic ')) { res.status(401).json({ error: 'Authentication required' }); return; } const credentials = Buffer.from(authHeader.slice(6), 'base64').toString(); const [username, password] = credentials.split(':'); const validUsername = process.env.MCP_USERNAME || 'admin'; const validPassword = process.env.MCP_PASSWORD || 'admin'; if (username !== validUsername || password !== validPassword) { res.status(401).json({ error: 'Invalid credentials' }); return; } next(); }; // Apply auth to MCP endpoints if credentials are configured if (process.env.MCP_USERNAME && process.env.MCP_PASSWORD) { app.use('/mcp', basicAuth); } // Initialize AEM connector and MCP handler const aemConnector = new AEMConnector(); const mcpHandler = new MCPRequestHandler(aemConnector); // Health check endpoint app.get('/health', async (req, res) => { try { const aemConnected = await aemConnector.testConnection(); res.json({ status: 'healthy', aem: aemConnected ? 'connected' : 'disconnected', mcp: 'ready', chatgpt: !!process.env.OPENAI_API_KEY, timestamp: new Date().toISOString(), version: process.env.npm_package_version || '1.0.0', ports: { gateway: GATEWAY_PORT, mcp: MCP_PORT } }); } catch (error) { res.status(500).json({ status: 'unhealthy', error: error.message, timestamp: new Date().toISOString() }); } }); // MCP JSON-RPC endpoint app.post('/mcp', async (req, res) => { try { const { jsonrpc, id, method, params } = req.body; // Validate JSON-RPC format if (jsonrpc !== '2.0' || !method) { res.status(400).json({ jsonrpc: '2.0', id: id || null, error: { code: -32600, message: 'Invalid Request', data: 'Must be valid JSON-RPC 2.0' } }); return; } console.error(`[MCP] ${method}:`, params ? JSON.stringify(params).substring(0, 100) + '...' : 'no params'); const result = await mcpHandler.handleRequest(method, params || {}); res.json({ jsonrpc: '2.0', id: id || null, result }); } catch (error) { console.error(`[MCP] Error:`, error); res.json({ jsonrpc: '2.0', id: req.body?.id || null, error: { code: -32000, message: error.message || 'Internal error', data: error.stack } }); } }); // List available MCP methods app.get('/mcp/methods', async (req, res) => { try { const methods = mcpHandler.getAvailableMethods(); res.json({ methods, total: methods.length, timestamp: new Date().toISOString() }); } catch (error) { res.status(500).json({ error: error.message }); } }); // LLM Integration endpoints app.use('/api', llmRouter); // Telegram Integration endpoints app.use('/webhook', telegramIntegration); // Root endpoint with API documentation app.get('/', (req, res) => { res.json({ name: 'AEM MCP Gateway Server', description: 'A Model Context Protocol server for Adobe Experience Manager with ChatGPT and Telegram Bot integration', version: process.env.npm_package_version || '1.0.0', endpoints: { health: { method: 'GET', path: '/health', description: 'Health check for all services' }, mcp: { method: 'POST', path: '/mcp', description: 'JSON-RPC endpoint for MCP calls', example: { jsonrpc: '2.0', id: 1, method: 'fetchSites', params: {} } }, mcpMethods: { method: 'GET', path: '/mcp/methods', description: 'List all available MCP methods' }, chatgpt: { method: 'POST', path: '/api/chat', description: 'Natural language interface to AEM via ChatGPT', example: { message: 'What sites are available in AEM?', conversationHistory: [] } }, chatgptHealth: { method: 'GET', path: '/api/health', description: 'Health check for ChatGPT integration' }, telegram: { method: 'POST', path: '/webhook/telegram', description: 'Telegram bot webhook endpoint' }, telegramStatus: { method: 'GET', path: '/webhook/telegram/status', description: 'Telegram bot status endpoint' }, telegramWebhook: { method: 'POST', path: '/webhook/telegram/webhook', description: 'Setup Telegram webhook' } }, architecture: 'Telegram Bot + ChatGPT + MCP integration', timestamp: new Date().toISOString() }); }); // Start server async function startGateway() { console.error('šŸš€ Starting AEM MCP Gateway Server...'); console.error('Architecture: Telegram Bot + ChatGPT + MCP integration'); console.error('================================'); // Test AEM connection first console.error('šŸ” Testing AEM connectivity...'); // const isConnected = await aemConnector.testConnection(); // if (!isConnected) { // console.error('āŒ AEM connection failed! Server will start but AEM operations may not work.'); // console.error(' Check your AEM instance and credentials.'); // } else { // console.error('āœ… AEM connection successful!'); // } // Check ChatGPT configuration if (process.env.OPENAI_API_KEY) { console.error('āœ… OpenAI API key configured'); } else { console.error('āš ļø OpenAI API key not configured - ChatGPT features disabled'); } app.listen(GATEWAY_PORT, () => { console.error('🌐 AEM MCP Gateway Server'); console.error('================================'); console.error(`šŸš€ Gateway Server: http://localhost:${GATEWAY_PORT}`); console.error(`šŸ“‹ Health Check: http://localhost:${GATEWAY_PORT}/health`); console.error(`šŸ“” MCP Endpoint: http://localhost:${GATEWAY_PORT}/mcp`); console.error(`šŸ”§ MCP Methods: http://localhost:${GATEWAY_PORT}/mcp/methods`); console.error(`šŸ’¬ ChatGPT API: http://localhost:${GATEWAY_PORT}/api/chat`); console.error(`šŸ¤– Telegram Webhook: http://localhost:${GATEWAY_PORT}/webhook/telegram`); console.error(`šŸŽÆ API Health: http://localhost:${GATEWAY_PORT}/api/health`); console.error(`šŸ“Š Telegram Status: http://localhost:${GATEWAY_PORT}/webhook/telegram/status`); console.error('================================'); console.error(`šŸ“– API Documentation: http://localhost:${GATEWAY_PORT}`); console.error('�� Ready for ChatGPT, Telegram Bot and MCP clients!'); }); } // Handle graceful shutdown process.on('SIGINT', () => { console.error('\nšŸ›‘ Shutting down AEM MCP Gateway...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('\nšŸ›‘ Shutting down AEM MCP Gateway...'); process.exit(0); }); // Start the gateway startGateway().catch((error) => { console.error('Failed to start gateway:', error); process.exit(1); });