Skip to main content
Glama

AEM MCP Server

aem-client.ts11.6 kB
import axios, { AxiosInstance } from 'axios'; import FormData from 'form-data'; import * as fs from 'fs'; import { promisify } from 'util'; export interface AEMConfig { host: string; port: number; username: string; password: string; protocol?: string; } export class AEMClient { private axiosInstance: AxiosInstance; constructor() { this.axiosInstance = axios.create({ timeout: 30000, validateStatus: () => true, // Don't throw on HTTP error status codes }); } private getBaseUrl(config: AEMConfig): string { const protocol = config.protocol || 'http'; return `${protocol}://${config.host}:${config.port}`; } private getAuthHeader(config: AEMConfig): string { const credentials = Buffer.from(`${config.username}:${config.password}`).toString('base64'); return `Basic ${credentials}`; } async checkStatus(config: AEMConfig): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); try { const response = await this.axiosInstance.get(`${baseUrl}/system/console/bundles.json`, { headers: { 'Authorization': authHeader, }, }); if (response.status === 200) { const data = response.data; console.log('AEM Status Data:', data); return { status: 'running', totalBundles: data.s?.length || 0, activeBundles: data.s?.filter((bundle: any) => bundle.state === 'Active').length || 0, version: await this.getAEMVersion(config), }; } else { return { status: 'error', message: `HTTP ${response.status}: ${response.statusText}`, }; } } catch (error) { return { status: 'offline', message: error instanceof Error ? error.message : 'Unknown error', }; } } async getAEMVersion(config: AEMConfig): Promise<string> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); try { const response = await this.axiosInstance.get(`${baseUrl}/system/console/status-productinfo.json`, { headers: { 'Authorization': authHeader, }, }); if (response.status === 200 && response.data) { return response.data.productVersion || 'Unknown'; } } catch (error) { // Fallback method try { const response = await this.axiosInstance.get(`${baseUrl}/libs/granite/core/content/login.html`, { headers: { 'Authorization': authHeader, }, }); if (response.status === 200) { const versionMatch = response.data.match(/Adobe Experience Manager (\d+\.\d+)/); return versionMatch ? versionMatch[1] : 'Unknown'; } } catch (fallbackError) { // Ignore fallback errors } } return 'Unknown'; } async installPackage(config: AEMConfig, packagePath: string, force: boolean = false): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); const readFile = promisify(fs.readFile); const access = promisify(fs.access); try { // Check if file exists await access(packagePath, fs.constants.F_OK); } catch (error) { throw new Error(`Package file not found: ${packagePath}`); } try { // Read the file as buffer instead of using createReadStream const fileBuffer = await readFile(packagePath); const formData = new FormData(); formData.append('file', fileBuffer, { filename: packagePath.split(/[/\\]/).pop() || 'package.zip', contentType: 'application/zip' }); formData.append('force', force.toString()); formData.append('install', 'true'); const response = await this.axiosInstance.post( `${baseUrl}/crx/packmgr/service.jsp`, formData, { headers: { 'Authorization': authHeader, ...formData.getHeaders(), }, } ); if (response.status === 200) { return { success: true, message: 'Package installed successfully', response: response.data, }; } else { return { success: false, message: `Installation failed: HTTP ${response.status}`, response: response.data, }; } } catch (error) { throw new Error(`Package installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async listPackages(config: AEMConfig): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); try { const response = await this.axiosInstance.get(`${baseUrl}/crx/packmgr/list.jsp`, { headers: { 'Authorization': authHeader, }, }); if (response.status === 200) { return { success: true, packages: response.data, }; } else { return { success: false, message: `Failed to list packages: HTTP ${response.status}`, }; } } catch (error) { throw new Error(`Failed to list packages: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async createPage(config: AEMConfig, parentPath: string, pageName: string, pageTitle: string, template: string): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); const formData = new FormData(); formData.append('cmd', 'createPage'); formData.append('parentPath', parentPath); formData.append('title', pageTitle); formData.append('label', pageName); formData.append('template', template); try { const response = await this.axiosInstance.post( `${baseUrl}/bin/wcmcommand`, formData, { headers: { 'Authorization': authHeader, ...formData.getHeaders(), }, } ); if (response.status === 200 || response.status === 201) { return { success: true, message: `Page created successfully at ${parentPath}/${pageName}`, path: `${parentPath}/${pageName}`, }; } else { return { success: false, message: `Page creation failed: HTTP ${response.status}`, response: response.data, }; } } catch (error) { throw new Error(`Page creation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async replicateContent(config: AEMConfig, contentPath: string, action: string = 'activate'): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); const formData = new FormData(); formData.append('cmd', action); formData.append('path', contentPath); try { const response = await this.axiosInstance.post( `${baseUrl}/bin/replicate.json`, formData, { headers: { 'Authorization': authHeader, ...formData.getHeaders(), }, } ); if (response.status === 200) { return { success: true, message: `Content ${action}d successfully: ${contentPath}`, response: response.data, }; } else { return { success: false, message: `Replication failed: HTTP ${response.status}`, response: response.data, }; } } catch (error) { throw new Error(`Replication failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async queryContent(config: AEMConfig, query: string, type: string = 'JCR-SQL2', limit: number = 20): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); const params = new URLSearchParams(); params.append('query', query); params.append('type', type); params.append('p.limit', limit.toString()); try { const response = await this.axiosInstance.get( `${baseUrl}/bin/querybuilder.json?${params.toString()}`, { headers: { 'Authorization': authHeader, }, } ); if (response.status === 200) { return { success: true, results: response.data, }; } else { return { success: false, message: `Query failed: HTTP ${response.status}`, }; } } catch (error) { throw new Error(`Query failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async getBundleStatus(config: AEMConfig, bundleId?: string): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); try { const url = bundleId ? `${baseUrl}/system/console/bundles/${bundleId}.json` : `${baseUrl}/system/console/bundles.json`; const response = await this.axiosInstance.get(url, { headers: { 'Authorization': authHeader, }, }); if (response.status === 200) { return { success: true, bundles: response.data, }; } else { return { success: false, message: `Failed to get bundle status: HTTP ${response.status}`, }; } } catch (error) { throw new Error(`Failed to get bundle status: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async clearCache(config: AEMConfig, cacheType: string = 'all'): Promise<any> { const baseUrl = this.getBaseUrl(config); const authHeader = this.getAuthHeader(config); const results: any[] = []; try { if (cacheType === 'clientlibs' || cacheType === 'all') { // Clear client libraries cache const clientlibsResponse = await this.axiosInstance.post( `${baseUrl}/libs/granite/ui/content/dumplibs.rebuild.html`, {}, { headers: { 'Authorization': authHeader, }, } ); results.push({ type: 'clientlibs', success: clientlibsResponse.status === 200, message: clientlibsResponse.status === 200 ? 'Client libraries cache cleared' : 'Failed to clear client libraries cache', }); } if (cacheType === 'dispatcher' || cacheType === 'all') { // Invalidate dispatcher cache (if available) try { const dispatcherResponse = await this.axiosInstance.post( `${baseUrl}/dispatcher/invalidate.cache`, {}, { headers: { 'Authorization': authHeader, }, } ); results.push({ type: 'dispatcher', success: dispatcherResponse.status === 200, message: dispatcherResponse.status === 200 ? 'Dispatcher cache invalidated' : 'Failed to invalidate dispatcher cache', }); } catch (error) { results.push({ type: 'dispatcher', success: false, message: 'Dispatcher cache invalidation not available or failed', }); } } return { success: true, results: results, }; } catch (error) { throw new Error(`Cache clearing failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } }

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/pradeep-moolemane/aem-mcp'

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