# π οΈ 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!** π