UNPKG

@myea/aem-mcp-handler

Version:

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

146 lines (145 loc) • 4.98 kB
#!/usr/bin/env node import express from 'express'; import cors from 'cors'; import { AEMConnector } from './aem-connector.js'; import { MCPRequestHandler } from './mcp-handler.js'; import dotenv from 'dotenv'; dotenv.config(); const app = express(); const PORT = parseInt(process.env.MCP_PORT || '8080', 10); // Middleware app.use(cors()); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Basic auth middleware for security 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', timestamp: new Date().toISOString(), version: process.env.npm_package_version || '1.0.0' }); } 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 }); } }); // Start server async function startServer() { console.error('šŸš€ Starting AEM MCP HTTP Server...'); // Test AEM connection first console.log('šŸ” Testing AEM connectivity...'); const isConnected = await aemConnector.testConnection(); if (!isConnected) { console.log('āŒ AEM connection failed! Server will start but AEM operations may not work.'); console.log(' Check your AEM instance and credentials.'); } else { console.log('āœ… AEM connection successful!'); } app.listen(PORT, () => { console.error('🌐 AEM MCP HTTP Server'); console.error('================================'); console.error(`šŸš€ Server running at: http://localhost:${PORT}`); console.error(`šŸ“‹ Health check: http://localhost:${PORT}/health`); console.error(`šŸ”§ MCP Methods: http://localhost:${PORT}/mcp/methods`); console.error(`šŸ“” MCP Endpoint: http://localhost:${PORT}/mcp`); console.error('================================'); }); } // Handle graceful shutdown process.on('SIGINT', () => { console.error('\nšŸ›‘ Shutting down AEM MCP server...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('\nšŸ›‘ Shutting down AEM MCP server...'); process.exit(0); }); // Start the server startServer().catch((error) => { console.error('Failed to start server:', error); process.exit(1); });