#!/usr/bin/env node
/**
* Ultimate Elementor MCP Server
*
* Combines the best features from WordPress Elementor MCP and Elementor MCP
* into a single, comprehensive solution for managing WordPress and Elementor
* through AI assistants.
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { getServerConfig, ServerConfig } from './config/server-config.js';
import { getWordPressConfig, validateWordPressConfig, WordPressConfig } from './config/wordpress-config.js';
import { WordPressClient } from './services/wordpress-client.js';
import { WordPressService } from './services/wordpress/wordpress-service.js';
import { ElementorService } from './services/elementor/elementor-service.js';
import { FileOperationsService } from './services/file-operations-service.js';
import { createWordPressTools } from './tools/wordpress-tools.js';
import { createElementorTools } from './tools/elementor-tools.js';
import { createFileOperationsTools } from './tools/file-operations-tools.js';
import { createConfigurationTools } from './tools/configuration-tools.js';
import { createDebuggingTools } from './tools/debugging-tools.js';
import { logger, LogLevel } from './utils/logger.js';
import { ErrorHandler, createErrorResponse } from './utils/error-handler.js';
class UltimateElementorMCP {
private server: Server;
private wordPressClient: WordPressClient | null = null;
private wordPressConfig: WordPressConfig | null = null;
private wordPressService: WordPressService | null = null;
private elementorService: ElementorService | null = null;
private fileOpsService: FileOperationsService;
private serverConfig: ServerConfig;
private tools: Map<string, any> = new Map();
constructor() {
// Initialize configuration
this.serverConfig = getServerConfig();
// Set up logger based on environment
if (process.env.DEBUG_MODE === 'true') {
logger.setLevel(LogLevel.DEBUG);
logger.setDebugMode(true);
}
logger.info('=== Ultimate Elementor MCP Server Starting ===');
logger.info(`Configuration Mode: ${this.serverConfig.mode}`);
logger.info(`Enabled Features: ${this.serverConfig.getTotalEnabledFeatures()}`);
// Initialize MCP server
this.server = new Server(
{
name: 'ultimate-elementor-mcp',
version: '1.0.0',
}
);
// Initialize File Operations Service (always available)
const dataDir = process.env.DATA_DIRECTORY || './data';
this.fileOpsService = new FileOperationsService(dataDir);
logger.info('File operations service initialized');
// Initialize WordPress connection
this.initializeWordPress();
// Set up request handlers
this.setupHandlers();
logger.info('Server initialization complete');
}
private initializeWordPress(): void {
this.wordPressConfig = getWordPressConfig();
if (this.wordPressConfig) {
try {
validateWordPressConfig(this.wordPressConfig);
this.wordPressClient = new WordPressClient(this.wordPressConfig);
// Initialize WordPress Service
this.wordPressService = new WordPressService(this.wordPressConfig);
// Initialize Elementor Service
this.elementorService = new ElementorService(this.wordPressClient.getAxiosInstance());
logger.info('WordPress and Elementor services configured successfully');
// Register tools
this.registerAllTools();
} catch (error) {
logger.error('Failed to configure WordPress connection', error);
logger.warn('Server will start without WordPress connection');
}
} else {
logger.warn('WordPress environment variables not found');
logger.warn('Required variables: WORDPRESS_BASE_URL, WORDPRESS_USERNAME, WORDPRESS_APPLICATION_PASSWORD');
logger.warn('Server will start with limited functionality');
}
}
private registerAllTools(): void {
if (!this.wordPressService || !this.elementorService) {
logger.warn('Services not initialized, skipping tool registration');
return;
}
logger.info('Registering MCP tools...');
// Register WordPress tools
if (this.serverConfig.basicWordPressOperations) {
const wpTools = createWordPressTools(this.wordPressService);
wpTools.forEach(tool => this.registerTool(tool));
logger.info(`Registered ${wpTools.length} WordPress tools`);
}
// Register Elementor tools
if (this.serverConfig.basicElementorOperations) {
const elementorTools = createElementorTools(this.elementorService);
elementorTools.forEach(tool => this.registerTool(tool));
logger.info(`Registered ${elementorTools.length} Elementor tools`);
}
// Register File Operations tools (always available)
const fileOpsTools = createFileOperationsTools(this.fileOpsService, this.elementorService);
fileOpsTools.forEach(tool => this.registerTool(tool));
logger.info(`Registered ${fileOpsTools.length} File Operations tools`);
// Register Configuration tools (always available)
const configTools = createConfigurationTools(this.serverConfig);
configTools.forEach(tool => this.registerTool(tool));
logger.info(`Registered ${configTools.length} Configuration tools`);
// Register Debugging tools (always available)
const debugTools = createDebuggingTools();
debugTools.forEach(tool => this.registerTool(tool));
logger.info(`Registered ${debugTools.length} Debugging tools`);
logger.info(`Total tools registered: ${this.tools.size}`);
}
private setupHandlers(): void {
// List tools handler
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
logger.debug('Listing available tools');
return {
tools: Array.from(this.tools.values()).map(tool => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
};
});
// Call tool handler
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
logger.info(`Tool called: ${name}`);
logger.debug(`Tool arguments:`, args);
const tool = this.tools.get(name);
if (!tool) {
logger.error(`Tool not found: ${name}`);
return createErrorResponse({
message: `Unknown tool: ${name}`,
category: 'VALIDATION' as any,
code: 'TOOL_NOT_FOUND',
} as any);
}
try {
const startTime = Date.now();
const result = await tool.handler(args);
const duration = Date.now() - startTime;
logger.performance(`Tool ${name}`, duration);
return result;
} catch (error) {
const mcpError = ErrorHandler.handle(error);
logger.error(`Tool execution failed: ${name}`, mcpError);
return createErrorResponse(mcpError);
}
});
}
public registerTool(tool: {
name: string;
description: string;
inputSchema: any;
handler: (args: any) => Promise<any>;
}): void {
logger.debug(`Registering tool: ${tool.name}`);
this.tools.set(tool.name, tool);
}
public getWordPressClient(): WordPressClient | null {
return this.wordPressClient;
}
public getServerConfig(): ServerConfig {
return this.serverConfig;
}
async start(): Promise<void> {
logger.info('Starting MCP server transport...');
const transport = new StdioServerTransport();
await this.server.connect(transport);
logger.info('=== Ultimate Elementor MCP Server Running ===');
logger.info(`Mode: ${this.serverConfig.mode}`);
logger.info(`Total Tools: ${this.tools.size}`);
logger.info('Server ready to accept connections');
}
}
// Main entry point
async function main() {
try {
const server = new UltimateElementorMCP();
await server.start();
} catch (error) {
logger.error('Fatal error starting server', error);
process.exit(1);
}
}
// Handle graceful shutdown
process.on('SIGINT', () => {
logger.info('Received SIGINT, shutting down gracefully...');
process.exit(0);
});
process.on('SIGTERM', () => {
logger.info('Received SIGTERM, shutting down gracefully...');
process.exit(0);
});
// Start the server
main();