index.ts•12.7 kB
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError,
} from '@modelcontextprotocol/sdk/types.js';
import { AEMClient } from './aem-client.js';
import { AEMTools } from './aem-tools.js';
class AEMServer {
private server: Server;
private aemClient: AEMClient;
private aemTools: AEMTools;
constructor() {
this.server = new Server(
{
name: 'aem-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
this.aemClient = new AEMClient();
this.aemTools = new AEMTools(this.aemClient);
this.setupToolHandlers();
// Error handling
this.server.onerror = (error) => console.error('[MCP Error]', error);
process.on('SIGINT', async () => {
await this.server.close();
process.exit(0);
});
}
private setupToolHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'aem_status',
description: 'Check the status of AEM instance',
inputSchema: {
type: 'object',
properties: {
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
}
}
},
{
name: 'aem_install_package',
description: 'Install a package in AEM',
inputSchema: {
type: 'object',
properties: {
packagePath: {
type: 'string',
description: 'Path to the package file (.zip)'
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
},
force: {
type: 'boolean',
description: 'Force installation (default: false)',
default: false
}
},
required: ['packagePath']
}
},
{
name: 'aem_list_packages',
description: 'List installed packages in AEM',
inputSchema: {
type: 'object',
properties: {
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
}
}
},
{
name: 'aem_create_page',
description: 'Create a new page in AEM',
inputSchema: {
type: 'object',
properties: {
parentPath: {
type: 'string',
description: 'Parent path where to create the page'
},
pageName: {
type: 'string',
description: 'Name of the new page'
},
pageTitle: {
type: 'string',
description: 'Title of the new page'
},
template: {
type: 'string',
description: 'Template path for the page'
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
},
required: ['parentPath', 'pageName', 'pageTitle', 'template']
}
},
{
name: 'aem_replicate_content',
description: 'Replicate content to publish instance',
inputSchema: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'Content path to replicate'
},
action: {
type: 'string',
description: 'Replication action (activate/deactivate)',
enum: ['activate', 'deactivate'],
default: 'activate'
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
},
required: ['path']
}
},
{
name: 'aem_query_content',
description: 'Query content using JCR-SQL2 or XPath',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Query string (JCR-SQL2 or XPath)'
},
type: {
type: 'string',
description: 'Query type',
enum: ['JCR-SQL2', 'xpath'],
default: 'JCR-SQL2'
},
limit: {
type: 'number',
description: 'Maximum number of results (default: 20)',
default: 20
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
},
required: ['query']
}
},
{
name: 'aem_bundle_status',
description: 'Check OSGi bundle status',
inputSchema: {
type: 'object',
properties: {
bundleId: {
type: 'string',
description: 'Specific bundle ID or symbolic name (optional)'
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
}
}
},
{
name: 'aem_clear_cache',
description: 'Clear various AEM caches',
inputSchema: {
type: 'object',
properties: {
cacheType: {
type: 'string',
description: 'Type of cache to clear',
enum: ['dispatcher', 'clientlibs', 'all'],
default: 'all'
},
host: {
type: 'string',
description: 'AEM host (default: localhost)',
default: 'localhost'
},
port: {
type: 'number',
description: 'AEM port (default: 4502)',
default: 4502
},
username: {
type: 'string',
description: 'AEM username (default: admin)',
default: 'admin'
},
password: {
type: 'string',
description: 'AEM password (default: admin)',
default: 'admin'
}
}
}
}
]
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'aem_status':
return await this.aemTools.checkStatus(args);
case 'aem_install_package':
return await this.aemTools.installPackage(args);
case 'aem_list_packages':
return await this.aemTools.listPackages(args);
case 'aem_create_page':
return await this.aemTools.createPage(args);
case 'aem_replicate_content':
return await this.aemTools.replicateContent(args);
case 'aem_query_content':
return await this.aemTools.queryContent(args);
case 'aem_bundle_status':
return await this.aemTools.getBundleStatus(args);
case 'aem_clear_cache':
return await this.aemTools.clearCache(args);
default:
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${name}`
);
}
} catch (error) {
throw new McpError(
ErrorCode.InternalError,
`Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`
);
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('AEM MCP server running on stdio');
}
}
const server = new AEMServer();
server.run().catch(console.error);