JSPM

@myea/aem-mcp-handler

1.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q44979F
  • License MIT

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

Package Exports

  • @myea/aem-mcp-handler
  • @myea/aem-mcp-handler/aem-connector

Readme

AEM MCP Handler

Advanced Adobe Experience Manager (AEM) request handler with intelligent search, multi-locale support, and comprehensive content management capabilities for AI integrations.

๐Ÿš€ Features

  • Intelligent Search: Advanced fuzzy matching and cross-section path generation
  • Multi-Locale Support: Automatic discovery and search across language variants
  • Comprehensive AEM Operations: Full CRUD operations for pages, components, and assets
  • Smart Path Resolution: Automatic site structure discovery and path suggestions
  • Validation & Feedback Loops: Built-in result validation and search optimization
  • Enterprise Ready: Supports complex AEM architectures and workflows

๐Ÿš€ Quick Setup for Claude Desktop

Connect Claude AI directly to your AEM instance!

Step 1: Install the Handler

npm install -g @myea/aem-mcp-handler

Step 2: Configure Claude Desktop

On Mac:

  1. Open Claude Desktop
  2. Go to Settings (Claude Desktop โ†’ Settings)
  3. Click Developer tab
  4. Edit the MCP servers configuration file, or create it at:
    ~/Library/Application Support/Claude/claude_desktop_config.json

On Windows:

  1. Open Claude Desktop
  2. Go to Settings (File โ†’ Settings or Ctrl+Comma)
  3. Click Developer tab
  4. Edit the MCP servers configuration file, or create it at:
    %APPDATA%\Claude\claude_desktop_config.json

Step 3: Add Configuration

Add this configuration to your claude_desktop_config.json:

{
  "mcpServers": {
    "aem-mcp-handler": {
      "command": "aem-mcp-server",
      "env": {
        "AEM_HOST": "http://localhost:4502",
        "AEM_SERVICE_USER": "admin",
        "AEM_SERVICE_PASSWORD": "admin",
        "AEM_TIMEOUT": "30000"
      }
    }
  }
}

Step 4: Restart Claude Desktop

Important: Completely quit and restart Claude Desktop for the changes to take effect.

Step 5: Test the Connection

Ask Claude: "Can you search for pages in my AEM instance?"

Claude should now be able to:

  • ๐Ÿ” Search your AEM content
  • ๐Ÿ“„ List pages and components
  • ๐Ÿ“ Get page properties and content
  • ๐Ÿ”ง Update component properties
  • ๐Ÿ“Š Provide detailed content analysis

๐Ÿ› Troubleshooting & Logs

Where to Find Logs

Mac Logs Location:

~/Library/Logs/Claude/mcp.log

Windows Logs Location:

%LOCALAPPDATA%\Claude\logs\mcp.log

View Live Logs

Mac:

tail -f ~/Library/Logs/Claude/mcp.log

Windows (PowerShell):

Get-Content "$env:LOCALAPPDATA\Claude\logs\mcp.log" -Wait -Tail 10

Common Issues

โŒ "Cannot connect to AEM"

  • Check if your AEM instance is running at the specified host
  • Verify credentials are correct
  • Ensure firewall/network allows connection

โŒ "Command not found: aem-mcp-server"

# Reinstall globally
npm uninstall -g @myea/aem-mcp-handler
npm install -g @myea/aem-mcp-handler

โŒ "Environment variables not working"

  • Restart Claude Desktop completely
  • Check JSON syntax in config file
  • Verify file permissions

โŒ "No results found"

  • Check AEM content exists at specified paths
  • Try broader search terms
  • Verify user permissions in AEM

Test AEM Connection Manually

# Test if AEM is accessible
curl -u admin:admin http://localhost:4502/libs/granite/core/content/login.html -I

# Test content access
curl -u admin:admin "http://localhost:4502/content.1.json"

๐Ÿ“ฆ Installation

npm install @venkatesh/aem-mcp-handler

๐Ÿ”ง Quick Setup

1. Environment Configuration

Create a .env file in your project:

# AEM Instance Configuration
AEM_HOST=http://localhost:4502
AEM_USERNAME=admin
AEM_PASSWORD=admin

# Optional: Timeout settings
AEM_TIMEOUT=30000

2. Basic Usage

import { MCPRequestHandler } from '@venkatesh/aem-mcp-handler';
import { AEMConnector } from '@venkatesh/aem-mcp-handler/aem-connector';

// Initialize the connector
const aemConnector = new AEMConnector({
  host: process.env.AEM_HOST || 'http://localhost:4502',
  username: process.env.AEM_USERNAME,
  password: process.env.AEM_PASSWORD,
  timeout: parseInt(process.env.AEM_TIMEOUT || '30000')
});

// Initialize the MCP handler
const mcpHandler = new MCPRequestHandler(aemConnector);

// Example: Search for content
const searchResults = await mcpHandler.handleRequest('search', {
  searchTerm: 'homepage',
  basePath: '/content/mysite'
});

console.log('Search Results:', searchResults);

๐Ÿ“‹ Available Methods

Content Search & Discovery

// Comprehensive content search with intelligent path discovery
await mcpHandler.handleRequest('search', {
  searchTerm: 'product page',
  basePath: '/content/mysite',
  limit: 10
});

// Enhanced page search with fuzzy matching
await mcpHandler.handleRequest('searchPages', {
  searchTerm: 'about us',
  basePath: '/content/mysite'
});

// List all pages in a site
await mcpHandler.handleRequest('listPages', {
  siteRoot: '/content/mysite',
  depth: 2,
  limit: 50
});

Content Management

// Get page or component content
await mcpHandler.handleRequest('getContent', {
  path: '/content/mysite/en/homepage',
  depth: 2
});

// Update component properties
await mcpHandler.handleRequest('updateComponent', {
  path: '/content/mysite/en/homepage/jcr:content/hero',
  properties: {
    title: 'New Hero Title',
    description: 'Updated description'
  }
});

// Validate component before update
await mcpHandler.handleRequest('validateComponent', {
  path: '/content/mysite/en/homepage/jcr:content/hero',
  properties: {
    title: 'New Title'
  }
});

Asset Management

// Search for assets
await mcpHandler.handleRequest('searchAssets', {
  searchTerm: 'logo',
  basePath: '/content/dam'
});

// Get asset metadata
await mcpHandler.handleRequest('getAssetMetadata', {
  assetPath: '/content/dam/images/logo.png'
});

Workflow & Publishing

// Get workflow status
await mcpHandler.handleRequest('getWorkflowStatus', {
  workflowId: 'workflow-123'
});

// Check page activation status
await mcpHandler.handleRequest('getActivationStatus', {
  pagePath: '/content/mysite/en/homepage'
});

๐ŸŽฏ Use Cases

1. Chatbot Integration

import { MCPRequestHandler } from '@venkatesh/aem-mcp-handler';

class AEMChatbot {
  constructor(private mcpHandler: MCPRequestHandler) {}

  async handleUserQuery(userMessage: string) {
    // Extract intent and parameters from user message
    const intent = this.extractIntent(userMessage);
    
    switch (intent.type) {
      case 'search':
        return await this.mcpHandler.handleRequest('search', {
          searchTerm: intent.searchTerm,
          basePath: intent.basePath || '/content'
        });
        
      case 'update':
        return await this.mcpHandler.handleRequest('updateComponent', {
          path: intent.componentPath,
          properties: intent.properties
        });
        
      default:
        return { error: 'Intent not recognized' };
    }
  }
}

2. Content Migration Tool

async function migrateContent(sourceInstance: MCPRequestHandler, targetInstance: MCPRequestHandler) {
  // Get all pages from source
  const pages = await sourceInstance.handleRequest('listPages', {
    siteRoot: '/content/oldsite',
    depth: 5
  });

  for (const page of pages.results) {
    // Get content from source
    const content = await sourceInstance.handleRequest('getContent', {
      path: page.path,
      depth: 3
    });

    // Create/update in target
    await targetInstance.handleRequest('updateComponent', {
      path: page.path.replace('/oldsite/', '/newsite/'),
      properties: content.properties
    });
  }
}

3. Multi-Locale Content Sync

async function syncContentAcrossLocales(handler: MCPRequestHandler) {
  const masterContent = await handler.handleRequest('getContent', {
    path: '/content/mysite/language-masters/en/homepage'
  });

  const locales = ['de', 'fr', 'es', 'it'];
  
  for (const locale of locales) {
    await handler.handleRequest('updateComponent', {
      path: `/content/mysite/language-masters/${locale}/homepage`,
      properties: {
        ...masterContent.properties,
        // Keep locale-specific fields
        title: await translateTitle(masterContent.properties.title, locale)
      }
    });
  }
}

๐Ÿ” Advanced Search Features

The handler includes sophisticated search capabilities:

Cross-Section Path Generation

Automatically discovers and searches across:

  • Language masters (/language-masters/en, /language-masters/de)
  • Country/locale combinations (/us/en, /de/de, /ca/fr)
  • Direct locale paths (/en, /fr, /es)

Fuzzy Matching

  • Levenshtein distance calculation
  • Term variation generation (camelCase, kebab-case, etc.)
  • Similarity scoring and ranking

Validation & Feedback

  • Result validation with confidence scoring
  • Automatic retry logic for low-confidence results
  • Comprehensive search reporting

๐Ÿ› ๏ธ Configuration Options

AEM Connector Options

const connector = new AEMConnector({
  host: 'https://author.mysite.com',
  username: 'service-user',
  password: 'secure-password',
  timeout: 30000,
  retryAttempts: 3,
  retryDelay: 1000
});

Search Configuration

await mcpHandler.handleRequest('search', {
  searchTerm: 'product',
  basePath: '/content/mysite',
  limit: 20,
  includeInactive: false,
  searchDepth: 5,
  fuzzyThreshold: 0.7
});

๐Ÿ“Š Response Formats

Search Response

{
  success: true,
  results: [
    {
      path: '/content/mysite/en/products',
      title: 'Products Page',
      lastModified: '2024-01-15T10:30:00Z',
      score: 0.95
    }
  ],
  searchReport: {
    strategiesUsed: ['enhanced', 'fuzzy', 'cross-section'],
    pathsExplored: ['/content/mysite/en', '/content/mysite/de'],
    totalAttempts: 3,
    confidence: 0.89,
    coverage: 'comprehensive'
  },
  total: 1
}

Content Response

{
  success: true,
  content: {
    'jcr:primaryType': 'cq:Page',
    'jcr:content': {
      'jcr:title': 'Homepage',
      'sling:resourceType': 'mysite/components/page',
      // ... other properties
    }
  },
  metadata: {
    lastModified: '2024-01-15T10:30:00Z',
    lastModifiedBy: 'admin'
  }
}

๐Ÿ”’ Security Considerations

  • Use service users with minimal required permissions
  • Store credentials securely (environment variables, vault systems)
  • Implement proper authentication for production instances
  • Validate all input parameters to prevent injection attacks

๐Ÿงช Testing

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Run specific test suites
npm run test:unit
npm run test:integration

๐Ÿ“ˆ Performance Tips

  1. Use specific base paths: Narrow down search scope for better performance
  2. Set appropriate limits: Avoid large result sets that may timeout
  3. Cache frequently accessed content: Implement caching layer for repeated queries
  4. Use batch operations: Group multiple updates when possible

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Commit changes: git commit -am 'Add new feature'
  4. Push to branch: git push origin feature/new-feature
  5. Submit a Pull Request

๐Ÿ“„ License

MIT License - see LICENSE file for details.

๐Ÿ†˜ Support

๐Ÿ”„ Migration Guide

From Direct AEM API Calls

Replace direct axios calls:

// Before
const response = await axios.get(`${aemHost}/content/mysite.2.json`);

// After  
const response = await mcpHandler.handleRequest('getContent', {
  path: '/content/mysite',
  depth: 2
});

From Other AEM Libraries

The MCP Handler provides enhanced search and multi-locale support not available in basic AEM connectors, making it ideal for AI-powered applications and complex content management scenarios.