Skip to main content
Glama
DEVELOPER_GUIDE.mdβ€’17.2 kB
# πŸ› οΈ Ultimate Elementor MCP - Developer Guide Technical documentation for developers extending or customizing the MCP. --- ## πŸ“‹ **Table of Contents** - [Architecture Overview](#architecture-overview) - [Project Structure](#project-structure) - [Core Components](#core-components) - [Adding New Tools](#adding-new-tools) - [Extending Services](#extending-services) - [Custom Configuration](#custom-configuration) - [Error Handling](#error-handling) - [Testing](#testing) - [Building and Deployment](#building-and-deployment) --- ## πŸ—οΈ **Architecture Overview** The Ultimate Elementor MCP follows a modular, service-oriented architecture: ``` MCP Client (Cursor, Claude Desktop, etc.) ↓ MCP Server (index.ts) ↓ Tool Handlers (tools/*.ts) ↓ Services (services/*.ts) ↓ WordPress REST API / File System ``` ### **Key Design Principles** 1. **Separation of Concerns** - Each service has a single responsibility 2. **Modularity** - Features can be enabled/disabled via configuration 3. **Type Safety** - Full TypeScript coverage 4. **Error Handling** - Comprehensive error management 5. **Testability** - Services and tools are independently testable --- ## πŸ“ **Project Structure** ``` ultimate-elementor-mcp/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ config/ β”‚ β”‚ β”œβ”€β”€ server-config.ts # MCP configuration modes β”‚ β”‚ └── wordpress-config.ts # WordPress connection config β”‚ β”œβ”€β”€ services/ β”‚ β”‚ β”œβ”€β”€ wordpress-client.ts # Axios HTTP client β”‚ β”‚ β”œβ”€β”€ wordpress/ β”‚ β”‚ β”‚ β”œβ”€β”€ posts-service.ts # Posts CRUD β”‚ β”‚ β”‚ β”œβ”€β”€ pages-service.ts # Pages CRUD β”‚ β”‚ β”‚ β”œβ”€β”€ media-service.ts # Media management β”‚ β”‚ β”‚ β”œβ”€β”€ users-service.ts # User management β”‚ β”‚ β”‚ β”œβ”€β”€ taxonomy-service.ts # Categories/Tags β”‚ β”‚ β”‚ └── wordpress-service.ts # Unified WordPress service β”‚ β”‚ β”œβ”€β”€ elementor/ β”‚ β”‚ β”‚ β”œβ”€β”€ elementor-data-service.ts # Data operations β”‚ β”‚ β”‚ β”œβ”€β”€ element-builder-service.ts # Element creation β”‚ β”‚ β”‚ β”œβ”€β”€ element-manipulation-service.ts # Element manipulation β”‚ β”‚ β”‚ β”œβ”€β”€ template-service.ts # Templates β”‚ β”‚ β”‚ β”œβ”€β”€ global-settings-service.ts # Global settings β”‚ β”‚ β”‚ └── elementor-service.ts # Unified Elementor service β”‚ β”‚ └── file-operations-service.ts # File management β”‚ β”œβ”€β”€ tools/ β”‚ β”‚ β”œβ”€β”€ wordpress-tools.ts # WordPress MCP tools β”‚ β”‚ β”œβ”€β”€ elementor-tools.ts # Elementor MCP tools β”‚ β”‚ β”œβ”€β”€ file-operations-tools.ts # File operation tools β”‚ β”‚ β”œβ”€β”€ configuration-tools.ts # Configuration tools β”‚ β”‚ └── debugging-tools.ts # Debugging tools β”‚ β”œβ”€β”€ types/ β”‚ β”‚ β”œβ”€β”€ index.ts # Core types β”‚ β”‚ β”œβ”€β”€ wordpress.ts # WordPress types β”‚ β”‚ β”œβ”€β”€ elementor.ts # Elementor types β”‚ β”‚ └── file-operations.ts # File operation types β”‚ β”œβ”€β”€ utils/ β”‚ β”‚ β”œβ”€β”€ logger.ts # Logging utility β”‚ β”‚ β”œβ”€β”€ error-handler.ts # Error management β”‚ β”‚ └── security.ts # Security utilities β”‚ └── index.ts # Main server entry point β”œβ”€β”€ test/ β”‚ β”œβ”€β”€ unit/ # Unit tests β”‚ β”œβ”€β”€ integration/ # Integration tests β”‚ └── ... β”œβ”€β”€ docs/ # Documentation β”œβ”€β”€ dist/ # Compiled JavaScript (generated) └── data/ # File operations data ``` --- ## 🧩 **Core Components** ### **1. MCP Server (index.ts)** Main entry point that: - Initializes configuration - Sets up services - Registers tools - Handles MCP protocol requests ```typescript class UltimateElementorMCP { private server: Server; private wordPressService: WordPressService; private elementorService: ElementorService; private fileOpsService: FileOperationsService; constructor() { // Initialize components } async start() { // Start MCP server } } ``` ### **2. Services** Services encapsulate business logic and API interactions: ```typescript // WordPress Service Example class PostsService { constructor(private axios: AxiosInstance) {} async createPost(data: any): Promise<any> { return await this.axios.post('/wp-json/wp/v2/posts', data); } } ``` ### **3. Tools** Tools are MCP protocol wrappers around services: ```typescript { name: 'create_post', description: 'Create a new WordPress post', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Post title' }, content: { type: 'string', description: 'Post content' } }, required: ['title'] }, handler: async (args) => { const result = await wpService.posts.createPost(args); return { content: [{ type: 'text', text: JSON.stringify(result) }] }; } } ``` --- ## βž• **Adding New Tools** ### **Step 1: Add Service Method** ```typescript // src/services/wordpress/posts-service.ts export class PostsService { // ... existing methods ... async getPostsByCategory(categoryId: number): Promise<any[]> { const response = await this.axios.get('/wp-json/wp/v2/posts', { params: { categories: categoryId } }); return response.data; } } ``` ### **Step 2: Create Tool Definition** ```typescript // src/tools/wordpress-tools.ts export function createWordPressTools(wpService: WordPressService) { const tools = []; // ... existing tools ... tools.push({ name: 'get_posts_by_category', description: 'Get posts filtered by category ID', inputSchema: { type: 'object', properties: { category_id: { type: 'number', description: 'Category ID to filter by' } }, required: ['category_id'] }, handler: async (args: any) => { const result = await wpService.posts.getPostsByCategory(args.category_id); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } }); return tools; } ``` ### **Step 3: Register Tool** Tools are automatically registered in `src/index.ts`: ```typescript const wpTools = createWordPressTools(this.wordPressService); wpTools.forEach(tool => this.registerTool(tool)); ``` ### **Step 4: Add to Documentation** Update `docs/TOOLS_REFERENCE.md` with your new tool. --- ## πŸ”§ **Extending Services** ### **Create a New Service** ```typescript // src/services/wordpress/comments-service.ts import { AxiosInstance } from 'axios'; export class CommentsService { constructor(private axios: AxiosInstance) {} async listComments(params: any = {}): Promise<any[]> { const response = await this.axios.get('/wp-json/wp/v2/comments', { params: { per_page: params.per_page || 10, post: params.post, status: params.status || 'approve' } }); return response.data; } async createComment(data: any): Promise<any> { const response = await this.axios.post('/wp-json/wp/v2/comments', data); return response.data; } } ``` ### **Integrate with WordPress Service** ```typescript // src/services/wordpress/wordpress-service.ts import { CommentsService } from './comments-service.js'; export class WordPressService { public posts: PostsService; public pages: PagesService; public comments: CommentsService; // Add new service constructor(config: WordPressConfig) { const client = new WordPressClient(config); const axios = client.getAxiosInstance(); this.posts = new PostsService(axios); this.pages = new PagesService(axios); this.comments = new CommentsService(axios); // Initialize } } ``` --- ## βš™οΈ **Custom Configuration** ### **Add New Configuration Mode** ```typescript // src/config/server-config.ts export const CONFIGURATION_MODES = { // ... existing modes ... custom: { mode: 'custom' as const, basicWordPressOperations: true, basicElementorOperations: true, sectionContainerCreation: true, widgetAddition: false, // ... configure as needed } }; ``` ### **Add New Feature Flag** ```typescript export interface ServerConfig { // ... existing flags ... customFeature: boolean; } // Update modes to include new flag export const CONFIGURATION_MODES = { full: { // ... existing settings ... customFeature: true } }; ``` ### **Add Environment Variable Support** ```typescript // src/config/server-config.ts export function getServerConfig(): ServerConfig { // ... existing code ... if (process.env.ENABLE_CUSTOM_FEATURE === 'true') { config.customFeature = true; } return config; } ``` --- ## πŸ› **Error Handling** ### **Create Custom Error** ```typescript import { MCPError, ErrorCategory } from '../utils/error-handler.js'; throw new MCPError( 'Custom error message', ErrorCategory.VALIDATION, 'CUSTOM_ERROR_CODE', { additionalInfo: 'details' }, 400 ); ``` ### **Handle Errors in Tools** ```typescript handler: async (args: any) => { try { const result = await service.someOperation(args); return { content: [{ type: 'text', text: JSON.stringify(result) }] }; } catch (error) { const mcpError = ErrorHandler.handle(error); logger.error('Operation failed', mcpError); throw mcpError; } } ``` ### **Add Error Recovery** ```typescript import { ErrorHandler } from '../utils/error-handler.js'; try { await riskyOperation(); } catch (error) { const mcpError = ErrorHandler.handle(error); if (ErrorHandler.isRecoverableError(mcpError)) { // Retry logic logger.warn('Retrying operation...'); await retryOperation(); } else { throw mcpError; } } ``` --- ## πŸ§ͺ **Testing** ### **Write Unit Tests** ```typescript // test/services/my-service.test.ts import { MyService } from '../../src/services/my-service.js'; describe('MyService', () => { let service: MyService; let mockAxios: any; beforeEach(() => { mockAxios = { get: jest.fn(), post: jest.fn() }; service = new MyService(mockAxios); }); it('should perform operation', async () => { mockAxios.get.mockResolvedValue({ data: { id: 1 } }); const result = await service.myOperation(); expect(result.id).toBe(1); expect(mockAxios.get).toHaveBeenCalled(); }); }); ``` ### **Write Integration Tests** ```typescript // test/integration/my-feature.test.ts describe('My Feature Integration', () => { it('should work end-to-end', async () => { // Test with real services const result = await myFeature.execute(); expect(result).toBeDefined(); }); }); ``` ### **Run Tests** ```bash # All tests npm test # Specific test file npm test -- my-service.test.ts # With coverage npm test -- --coverage ``` --- ## πŸ—οΈ **Building and Deployment** ### **Development Build** ```bash npm run dev # Watch mode with auto-rebuild ``` ### **Production Build** ```bash npm run build # Compile TypeScript to JavaScript ``` ### **Type Checking** ```bash npx tsc --noEmit # Check types without building ``` ### **Linting** ```bash npm run lint # Check code quality ``` --- ## πŸ“¦ **Packaging** ### **Prepare for Distribution** 1. **Build the project** ```bash npm run build ``` 2. **Update version** ```bash npm version patch # or minor, or major ``` 3. **Create distribution package** ```bash npm pack ``` --- ## πŸ” **Security Considerations** ### **Input Validation** Always validate user inputs: ```typescript import { InputValidator } from '../utils/security.js'; const validator = new InputValidator(); if (!validator.validateUrl(url)) { throw new MCPError('Invalid URL', ErrorCategory.VALIDATION, 'INVALID_URL'); } ``` ### **Rate Limiting** Protect against abuse: ```typescript import { RateLimiter } from '../utils/security.js'; const limiter = new RateLimiter(10, 60000); // 10 requests per minute if (!limiter.checkLimit(userId)) { throw new MCPError('Rate limit exceeded', ErrorCategory.VALIDATION, 'RATE_LIMIT'); } ``` ### **File Operations Security** ```typescript import { SecureFileOperations } from '../utils/security.js'; const secureOps = new SecureFileOperations(baseDir); if (!secureOps.isPathSafe(filePath)) { throw new MCPError('Invalid file path', ErrorCategory.FILE_OPERATION, 'INVALID_PATH'); } ``` --- ## πŸ“Š **Performance Optimization** ### **Caching** ```typescript private cache = new Map<string, any>(); async getCachedData(key: string): Promise<any> { if (this.cache.has(key)) { return this.cache.get(key); } const data = await this.fetchData(key); this.cache.set(key, data); return data; } ``` ### **Chunked Operations** For large datasets: ```typescript async processInChunks(items: any[], chunkSize: number = 10) { const chunks = []; for (let i = 0; i < items.length; i += chunkSize) { chunks.push(items.slice(i, i + chunkSize)); } for (const chunk of chunks) { await this.processChunk(chunk); } } ``` --- ## πŸ” **Debugging** ### **Enable Debug Logging** ```typescript import { logger, LogLevel } from './utils/logger.js'; logger.setLevel(LogLevel.DEBUG); logger.setDebugMode(true); logger.debug('Detailed debug information', { data: value }); ``` ### **Track Performance** ```typescript const startTime = Date.now(); await operation(); const duration = Date.now() - startTime; logger.performance('Operation name', duration); ``` ### **Error Statistics** ```typescript import { ErrorStatistics } from './utils/error-handler.js'; const stats = ErrorStatistics.getStatistics(); console.log('Total errors:', stats.totalErrors); console.log('By category:', stats.byCategory); ``` --- ## πŸ“š **API Reference** ### **WordPress Service** ```typescript interface WordPressService { posts: PostsService; pages: PagesService; media: MediaService; users: UsersService; taxonomies: TaxonomyService; } ``` ### **Elementor Service** ```typescript interface ElementorService { data: ElementorDataService; builder: ElementBuilderService; manipulation: ElementManipulationService; templates: TemplateService; globalSettings: GlobalSettingsService; } ``` ### **File Operations Service** ```typescript interface FileOperationsService { exportElementorData(postId: number, data: any, options?: ExportOptions): Promise<FileOperationResult>; importElementorData(filePath: string, options?: ImportOptions): Promise<ImportResult>; backupPageData(postId: number, data: any, label?: string): Promise<BackupResult>; restorePageData(backupId: string): Promise<RestoreResult>; listBackups(): Promise<BackupMetadata[]>; cleanupOldBackups(daysOld: number): Promise<CleanupResult>; } ``` --- ## πŸŽ“ **Advanced Topics** ### **Custom WordPress Endpoints** ```typescript async callCustomEndpoint(endpoint: string, data: any): Promise<any> { const response = await this.axios.post( `/wp-json/custom/v1/${endpoint}`, data ); return response.data; } ``` ### **Elementor Custom Widgets** ```typescript createCustomWidget(widgetType: string, settings: any): ElementorWidget { return { id: this.generateId(), elType: 'widget', widgetType: widgetType, settings: settings }; } ``` ### **Batch Operations** ```typescript async batchUpdate(operations: BatchOperation[]): Promise<BatchResult[]> { const results = []; for (const operation of operations) { try { const result = await this.executeOperation(operation); results.push({ success: true, data: result }); } catch (error) { results.push({ success: false, error: error.message }); } } return results; } ``` --- ## 🀝 **Contributing** ### **Development Workflow** 1. **Fork the repository** from https://github.com/mbrown1837/Ultimate-Elementor-MCP 2. **Create feature branch** ```bash git checkout -b feature/my-new-feature ``` 3. **Make changes** - Follow TypeScript best practices - Add comprehensive error handling - Write tests for new features 4. **Test thoroughly** ```bash npm test npm run build ``` 5. **Submit Pull Request** - Describe changes clearly - Include test results - Update documentation ### **Code Style** - Use TypeScript strict mode - Follow existing code patterns - Add JSDoc comments for public APIs - Use meaningful variable names - Handle all error cases --- ## πŸ“– **Resources** - [MCP Protocol Specification](https://modelcontextprotocol.io/) - [WordPress REST API Handbook](https://developer.wordpress.org/rest-api/) - [Elementor Developer Documentation](https://developers.elementor.com/) - [TypeScript Documentation](https://www.typescriptlang.org/docs/) --- **πŸ”§ Happy coding!** πŸš€

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mbrown1837/Ultimate-Elementor-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server