npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@myea/aem-mcp-handler

v1.0.2

Published

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

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.