返回市场
aem内容管理服务器

aem内容管理服务器

作者:indrasishbanerjee7 星标更新:2025-10-19

项目介绍

请通过LinkedInEmail Me与我联系以讨论定制化内容!

💡 对于对AEM作为云服务的MCP服务器感兴趣的用户,请查看我的另一个GitHub项目: AEMaaCS MCP Server - 一个专门为AEM作为云服务设计的全面读写MCP服务器,具有高级功能和企业级能力。

许可证更新:此项目现在采用AGPL-V3许可。对于在企业环境中进行商业使用,需要付费许可。

AEM MCP Server (aem-mcp-server)

Node.js CI AEM 兼容 TypeScript MCP 协议

AEM MCP Server 是一个全面、生产就绪的模型上下文协议(MCP)服务器,适用于Adobe Experience Manager(AEM)。它提供了超过35种强大的REST/JSON-RPC API方法,用于完全的内容、组件、资产和模板管理,并具备AI、聊天机器人和自动化工作流的高级集成。该项目专为希望以编程方式或通过自然语言接口管理AEM的AEM开发者、内容团队和自动化工程师设计。


目录


概述

  • 现代、基于TypeScript的AEM MCP服务器
  • REST/JSON-RPC API 用于AEM内容、组件和资产操作
  • AI/LLM集成 (OpenAI,Anthropic,Ollama,自定义HTTP API)
  • Telegram机器人 用于对话式AEM管理
  • 生产就绪、模块化且可扩展

特性

🚀 核心能力(35+方法)

页面操作(10个方法)

  • 页面生命周期:创建、删除、激活/停用页面,正确集成模板
  • 内容管理:获取页面内容、属性、文本提取和图像管理
  • 页面发现:分层控制、分页和过滤列表页面
  • 发布:激活/停用页面,树形操作

组件操作(7个方法)

  • 组件CRUD:创建、更新、删除和验证组件
  • 批量操作:更新多个组件,支持验证和回滚
  • 组件发现:扫描页面以发现所有组件及其属性
  • 图像管理:更新图像路径并验证

资产操作(4个方法)

  • DAM管理:上传、更新、删除AEM DAM中的资产
  • 元数据操作:获取和更新资产元数据
  • 文件处理:支持多种文件类型,检测MIME类型

搜索及查询操作(3个方法)

  • 高级搜索:QueryBuilder集成,全文搜索
  • JCR查询:执行JCR SQL2风格查询,带安全验证
  • 增强页面搜索:智能搜索,带有回退策略

模板操作(2个方法)

  • 模板发现:获取站点和路径可用的模板
  • 模板分析:详细模板结构和元数据提取

站点及本地化(3个方法)

  • 多站点管理:获取站点、语言主站和可用区域
  • 本地化支持:跨不同语言和地区管理内容

复制及发布(2个方法)

  • 内容复制:将内容复制到选定区域
  • 取消发布:从发布环境移除内容

遗留及实用操作(5个方法)

  • JCR节点访问:直接节点内容访问和子节点列表
  • 系统实用工具:方法列表、状态检查和工作流管理

🔧 技术特性

  • REST & JSON-RPC API:双API支持,最大兼容性
  • 交互式仪表盘:基于Web的界面,用于API探索和测试
  • 全面测试:内置测试套件,自动问题跟踪
  • 增强错误处理:结构化错误响应,带有重试机制
  • 安全性:认证、路径验证和安全操作默认设置
  • 性能:连接池、缓存和优化查询

快速开始

前提条件

  • Node.js 18+
  • 访问AEM实例(本地或远程)

安装

cd clone
npm install

构建

npm run build

运行(生产)

npm start

运行(开发,热重载)

npm run dev

使用示例

JSON-RPC API示例

1. 列出路径下的所有页面

curl -u admin:admin \
  -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "listPages",
    "params": {
      "siteRoot": "/content/mysite",
      "depth": 2,
      "limit": 10
    }
  }'

2. 使用模板创建新页面

curl -u admin:admin \
  -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "createPage",
    "params": {
      "parentPath": "/content/mysite/en",
      "title": "新产品页面",
      "template": "/conf/mysite/settings/wcm/templates/page-template"
    }
  }'

3. 更新组件属性

curl -u admin:admin \
  -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "updateComponent",
    "params": {
      "componentPath": "/content/mysite/en/home/jcr:content/root/container/text",
      "properties": {
        "text": "更新的内容",
        "textIsRich": true
      }
    }
  }'

4. 搜索内容

curl -u admin:admin \
  -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "searchContent",
    "params": {
      "type": "cq:Page",
      "fulltext": "产品",
      "path": "/content/mysite",
      "limit": 20
    }
  }'

5. 将资产上传到DAM

curl -u admin:admin \
  -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 5,
    "method": "uploadAsset",
    "params": {
      "parentPath": "/content/dam/mysite/images",
      "fileName": "hero-image.jpg",
      "fileContent": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...",
      "mimeType": "image/jpeg",
      "metadata": {
        "dc:title": "英雄图片",
        "dc:description": "首页的主要英雄图片"
      }
    }
  }'

REST API示例

1. 获取所有可用的方法

curl -u admin:admin http://localhost:3001/api/methods

2. 获取方法详情

curl -u admin:admin http://localhost:3001/api/methods/createPage

3. 通过REST执行方法

curl -u admin:admin \
  -X POST http://localhost:3001/api/methods/listPages \
  -H 'Content-Type: application/json' \
  -d '{
    "siteRoot": "/content/mysite",
    "depth": 1,
    "limit": 10
  }'

方法类别和示例

页面操作

  • createPage - 创建页面,正确集成模板
  • deletePage - 删除页面,带强制选项
  • listPages - 列出页面,带深度和分页
  • getPageContent - 提取完整页面内容
  • getPageProperties - 获取页面元数据和属性
  • activatePage / deactivatePage - 发布/取消发布页面
  • getAllTextContent / getPageTextContent - 提取文本内容
  • getPageImages - 提取图像引用

组件操作

  • validateComponent - 在应用之前验证组件更改
  • updateComponent - 更新组件属性并验证
  • scanPageComponents - 发现页面上的所有组件
  • createComponent - 向页面添加新组件
  • deleteComponent - 删除组件
  • updateImagePath - 更新图像组件引用
  • bulkUpdateComponents - 原子地更新多个组件

资产操作

  • uploadAsset - 将文件上传到DAM,附带元数据
  • updateAsset - 更新资产元数据和内容
  • deleteAsset - 从DAM中删除资产
  • getAssetMetadata - 检索资产元数据

搜索操作

  • searchContent - 查询构建器搜索,带灵活参数
  • executeJCRQuery - 执行JCR查询(查询构建器包装器)
  • enhancedPageSearch - 智能页面搜索,带有回退策略

模板操作

  • getTemplates - 列出站点可用的模板
  • getTemplateStructure - 获取详细的模板结构

站点及本地化

  • fetchSites - 获取所有可用站点
  • fetchLanguageMasters - 获取站点的语言主站
  • fetchAvailableLocales - 获取可用区域

交互式仪表盘

访问位于http://localhost:3001/dashboard的web仪表盘,以:

  • 交互式方法测试
  • 参数验证
  • 响应可视化
  • API文档
  • 批量测试能力

配置

环境变量

在项目根目录创建一个.env文件,包含以下内容(根据需要编辑):

AEM_HOST=http://localhost:4502
AEM_SERVICE_USER=admin
AEM_SERVICE_PASSWORD=admin
MCP_PORT=8080
GATEWAY_PORT=3001
MCP_USERNAME=admin
MCP_PASSWORD=admin

MCP客户端配置

示例如下,用于AI代码编辑器或自定义客户端:

{
  "mcpServers": {
    "aem-mcp": {
      "command": "node",
      "args": [
        "绝对路径到dist/mcp-server.js"
      ]
    }
  }
}

高级配置选项

# 可选:高级AEM配置
AEM_SITES_ROOT=/content
AEM_ASSETS_ROOT=/content/dam
AEM_TEMPLATES_ROOT=/conf
AEM_XF_ROOT=/content/experience-fragments
AEM_PUBLISHER_URLS=http://localhost:4503
AEM_DEFAULT_AGENT=publish
AEM_ALLOWED_COMPONENTS=text,image,hero,button,list,teaser,carousel
AEM_QUERY_MAX_LIMIT=100
AEM_QUERY_DEFAULT_LIMIT=20
AEM_QUERY_TIMEOUT=30000
AEM_MAX_DEPTH=5

# 可选:AI集成(如有需要)
# OPENAI_API_KEY=your-openai-key
# TELEGRAM_BOT_TOKEN=your-telegram-bot-token

API及客户端使用

  • REST/JSON-RPC:通过HTTP端点暴露所有AEM操作
  • 支持的操作:页面/资产CRUD,组件验证/更新,搜索,部署,发布,文本/图像提取等
  • AI/LLM:向服务器发送自然语言命令(通过API或Telegram)
  • Telegram机器人:使用TELEGRAM_BOT_TOKEN连接您的机器人并与您的AEM实例聊天

AI IDE集成(Cursor,Cline等)

AEM MCP服务器与支持MCP协议的现代AI IDE和代码编辑器兼容,如CursorCline

如何连接:

  1. 安装并运行AEM MCP服务器,如上所述。
  2. 配置您的IDE以连接到MCP服务器。例如,对于Cursor/Cline:
    • 打开IDE的MCP服务器设置。
    • 添加一个新的服务器,如下所示:
      • 类型:自定义MCP
      • 命令node
      • 参数["/绝对路径/to/dist/mcp-server.js"]
      • 端口8080(或按配置)
      • 认证:使用.env中的MCP_USERNAME/MCP_PASSWORD
  3. 重启您的IDE并连接。IDE现在可以:
    • 列表、搜索和管理AEM内容
    • 运行MCP方法(CRUD、搜索、部署等)
    • 如果启用,则使用AI/LLM功能

自定义MCP客户端

  • 您可以在任何支持HTTP/JSON-RPC的语言中构建自己的MCP客户端。
  • 查看使用示例以了解API调用模式。
  • 使用基本认证(MCP_USERNAME/MCP_PASSWORD)进行身份验证。
  • 所有MCP方法都可通过/api端点访问。

安全

  • 所有操作都需要认证(参见MCP_USERNAME/MCP_PASSWORD
  • 基于环境的配置,确保安全部署
  • 所有破坏性操作都需要明确参数和验证

项目结构

  • src/ — TypeScript源代码
  • dist/ — 编译后的JS输出

集成

  • AI/LLM:OpenAI,Anthropic,Ollama,自定义HTTP API
  • Telegram:基于对话的AEM管理

贡献

欢迎贡献!请打开问题或拉请求以修复错误、添加功能或改进文档。


故障排除

常见问题

连接问题

# 测试AEM连接
curl -u admin:admin http://localhost:4502/libs/granite/core/content/login.html

# 检查服务器健康状况
curl http://localhost:3001/health

认证问题

  • 验证.env文件中的AEM凭据
  • 检查MCP_USERNAME和MCP_PASSWORD以访问API
  • 确保AEM用户有足够的权限

页面创建问题

  • 没有jcr:content的空页面:使用正确的模板参数
  • 作者中不可见的页面:确保模板存在且有效
  • 找不到模板:验证模板路径和权限

组件更新失败

  • 找不到组件:验证组件路径是否存在
  • 更新失败:检查组件属性和验证
  • 权限被拒绝:确保用户具有写入权限

性能优化

  • 使用limit参数进行大结果集的分页
  • 设置适当的depth值以列出页面
  • 配置AEM_QUERY_TIMEOUT以处理慢查询
  • 使用批量操作更新多个组件

调试

# 启用调试日志
DEBUG=aem-mcp:* npm run dev

# 检查详细健康状态
curl http://localhost:3001/health

# 列出所有可用的方法
curl -u admin:admin http://localhost:3001/api/methods

常见用例

内容迁移

// 1. 列出源页面
const pages = await listPages({ siteRoot: '/content/source', depth: 3 });

// 2. 使用模板创建目标页面
for (const page of pages.data.pages) {
  await createPage({
    parentPath: '/content/target',
    title: page.title,
    template: '/conf/target/settings/wcm/templates/page'
  });
}

// 3. 复制组件
const components = await scanPageComponents({ pagePath: sourcePage });
for (const component of components.data.components) {
  await createComponent({
    pagePath: targetPage,
    componentType: component.resourceType,
    properties: component.properties
  });
}

批量内容更新

// 更新多个文本组件
const updates = [
  {
    componentPath: '/content/site/page1/jcr:content/text1',
    properties: { text: '更新的内容1' }
  },
  {
    componentPath: '/content/site/page2/jcr:content/text2',
    properties: { text: '更新的内容2'