Skip to main content
Glama
SatoshiInoue

AEM Assets MCP Server

by SatoshiInoue

AEM Assets Server for AI Integrations

A dual-implementation server for Adobe Experience Manager (AEM) Assets API:

  • REST API (rest-api/) - For ChatGPT Custom GPTs via Actions (FastAPI)

  • MCP Server (mcp-server/) - For ChatGPT Custom GPTs with MCP support (FastMCP)

Both implementations share the same core AEM client logic and provide identical functionality.

πŸ—οΈ Architecture

aem-assets-mcp-server/
β”œβ”€β”€ rest-api/              ← REST API implementation (Vercel)
β”‚   β”œβ”€β”€ app/              - FastAPI application
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── vercel.json
β”œβ”€β”€ mcp-server/            ← MCP Server implementation (Cloud Run)
β”‚   β”œβ”€β”€ app/              - FastMCP application
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── requirements.txt
β”œβ”€β”€ shared/                ← Common AEM client logic
β”‚   β”œβ”€β”€ aem_client.py     - AEM API client
β”‚   β”œβ”€β”€ jwt_auth.py       - JWT authentication
β”‚   β”œβ”€β”€ models.py         - Data models
β”‚   └── constants.py      - Configuration constants
└── .github/workflows/    - CI/CD pipelines

πŸš€ Features

Both implementations provide identical tools to interact with AEM Assets:

  • List folders - Browse folders in your AEM Assets repository

  • List assets by folder - Get all assets within a specific folder

  • Get asset details - Retrieve detailed information about a specific asset including metadata

  • Update asset metadata - Update metadata fields for individual assets

  • Bulk update metadata - Update metadata for all assets in a folder

🎯 Which Implementation Should I Use?

Feature

REST API (Vercel)

MCP Server (Cloud Run)

Target Platform

ChatGPT Actions

ChatGPT with MCP support

Protocol

HTTP REST

JSON-RPC over SSE

Deployment

Vercel (serverless)

Google Cloud Run (containers)

Schema

OpenAPI 3.0

MCP Protocol

Best For

Standard ChatGPT integrations

Native MCP clients (ChatGPT, Claude Desktop)

Recommendation:

  • Use REST API if you're integrating with ChatGPT Custom GPTs via Actions (most common)

  • Use MCP Server if your ChatGPT supports native MCP protocol connections

πŸ“‹ Prerequisites

AEM Access

  1. Adobe Experience Manager Assets Author API Access

    • AEM base URL (e.g., https://author-pXXXXXX-eXXXXXXX.adobeaemcloud.com)

    • OAuth Server-to-Server credentials (for modern /adobe/* APIs):

      • Client ID

      • Client Secret

    • JWT Service Account credentials (for classic /api/assets API):

      • Service Account JSON file with private key

    • See GET_CREDENTIALS.md for detailed setup

REST API Requirements

  • Python 3.12+

  • Vercel account (for deployment)

  • ChatGPT Plus/Pro with Custom GPTs

MCP Server Requirements

  • Python 3.12+

  • Docker

  • Google Cloud Platform account

  • gcloud CLI

  • GitHub account (for CI/CD)

πŸ› οΈ Tech Stack

Shared Components

  • Python 3.12 - Core language

  • HTTPX - Async HTTP client

  • Pydantic - Data validation

  • Dual Authentication:

    • OAuth Server-to-Server (modern AEM APIs)

    • JWT Service Account (classic AEM APIs)

REST API Stack

  • FastAPI - Modern async web framework

  • Vercel - Serverless deployment

MCP Server Stack

  • FastMCP - MCP protocol implementation

  • Docker - Containerization

  • Google Cloud Run - Container hosting

  • Terraform - Infrastructure as Code

  • GitHub Actions - CI/CD

πŸ“ Project Structure

.
β”œβ”€β”€ rest-api/                     # REST API Implementation (Vercel)
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   └── main.py              # FastAPI application
β”‚   β”œβ”€β”€ requirements.txt
β”‚   β”œβ”€β”€ vercel.json              # Vercel deployment config
β”‚   └── openapi-schema.json      # ChatGPT Actions schema
β”œβ”€β”€ mcp-server/                   # MCP Server Implementation (Cloud Run)
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   └── main.py              # FastMCP application
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── Dockerfile               # Container configuration
β”œβ”€β”€ shared/                       # Shared AEM Client Logic
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ aem_client.py            # AEM API client (OAuth + JWT)
β”‚   β”œβ”€β”€ jwt_auth.py              # JWT Service Account auth
β”‚   β”œβ”€β”€ models.py                # Pydantic data models
β”‚   └── constants.py             # Configuration constants
β”œβ”€β”€ terraform/                    # Infrastructure as Code
β”‚   β”œβ”€β”€ main.tf
β”‚   β”œβ”€β”€ variables.tf
β”‚   └── terraform.tfvars.example
β”œβ”€β”€ .github/workflows/            # CI/CD Pipelines
β”‚   β”œβ”€β”€ deploy-cloud-run.yml     # MCP Server β†’ Cloud Run
β”‚   β”œβ”€β”€ terraform-apply.yml      # Terraform deployment
β”‚   └── test.yml                 # Testing workflow
β”œβ”€β”€ vercel.json                  # Root Vercel config (points to rest-api/)
└── README.md

πŸš€ Quick Start

Choose your implementation path:

Option A: REST API for ChatGPT Actions

Local Development

  1. Clone the repository:

cd "SC Practice 20260130 - Assets MCP"
  1. Create virtual environment:

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install dependencies:

pip install -r rest-api/requirements.txt
  1. Configure environment:

# Copy example env
cp rest-api/env.example .env

# Edit with your AEM credentials
# Required:
# - AEM_BASE_URL
# - AEM_CLIENT_ID
# - AEM_CLIENT_SECRET
# - AEM_SERVICE_ACCOUNT_JSON (path to service-account.json)
nano .env

See GET_CREDENTIALS.md for how to get your credentials.

  1. Run REST API locally:

cd rest-api
uvicorn app.main:app --reload

Visit http://localhost:8000 to see the server info.

Deploy to Vercel

See DEPLOYMENT_VERCEL.md for detailed instructions.

Option A: Local Deployment (Fastest)

# Install Vercel CLI
npm i -g vercel

# Deploy (from project root)
vercel

# Add environment variables via Vercel dashboard:
# - AEM_BASE_URL
# - AEM_CLIENT_ID  
# - AEM_CLIENT_SECRET
# - AEM_SERVICE_ACCOUNT_JSON (paste JSON content)

# Deploy to production
vercel --prod

Option B: GitHub Actions (Automated CI/CD)

Set up once, then automatically deploy on every push to main:

  1. Get Vercel credentials (see DEPLOYMENT_VERCEL.md)

  2. Add GitHub Secrets:

    • VERCEL_TOKEN

    • VERCEL_ORG_ID

    • VERCEL_PROJECT_ID

  3. Push to main or manually trigger workflow

Your API will be available at: https://your-project.vercel.app/api/mcp

Use the OpenAPI schema at rest-api/openapi-schema.json to configure ChatGPT Actions.


Option B: MCP Server for Native MCP Support

Local Development

  1. Install MCP server dependencies:

pip install -r mcp-server/requirements.txt
  1. Configure environment (same as REST API):

cp rest-api/env.example .env
nano .env  # Add your AEM credentials
  1. Run MCP server locally:

cd mcp-server
python -m app.main

The MCP server will start with SSE transport on port 8080.

Deploy to Google Cloud Run

See DEPLOYMENT_CLOUDRUN.md for detailed instructions.

Quick steps using GitHub Actions:

  1. Set up GCP project and enable APIs

  2. Configure Workload Identity Federation (see CLOUD_RUN_SETUP_GUIDE.md)

  3. Add GitHub Secrets:

    • GCP_PROJECT_ID

    • GCP_REGION

    • GCP_WORKLOAD_IDENTITY_PROVIDER

    • GCP_SERVICE_ACCOUNT

    • AEM_BASE_URL

    • AEM_CLIENT_ID

  4. Create GCP secrets:

    echo -n "your_client_secret" | gcloud secrets create aem-client-secret --data-file=-
    echo -n "$(cat service-account.json)" | gcloud secrets create aem-service-account-json --data-file=-
  5. Trigger deployment:

    • Go to GitHub Actions β†’ "Deploy to Google Cloud Run" β†’ "Run workflow"

Your MCP server will be available at: https://aem-assets-mcp-server-xxxxx.run.app

Connect from ChatGPT using the MCP server URL.


πŸ§ͺ Testing

Test REST API

# List folders
curl -X POST http://localhost:8000/api/mcp \
  -H "Content-Type: application/json" \
  -d '{"tool": "list_folders", "arguments": {"path": "/"}}'

# List assets in a folder
curl -X POST http://localhost:8000/api/mcp \
  -H "Content-Type: application/json" \
  -d '{"tool": "list_assets_by_folder", "arguments": {"folderPath": "/MyFolder"}}'

Test MCP Server

See TESTING.md for comprehensive testing guide including:

  • Direct AEM API testing

  • JWT token generation

  • MCP Inspector usage


πŸ”§ Configuration

Both implementations use the same environment variables:

Variable

Description

Required

Example

AEM_BASE_URL

AEM Author instance URL

βœ…

https://author-pXXXXXX.adobeaemcloud.com

AEM_CLIENT_ID

OAuth Client ID

βœ…

a41e805f8c3042d3bba66ff1c05f1e94

AEM_CLIENT_SECRET

OAuth Client Secret

βœ…

p8e-xxx...

AEM_SERVICE_ACCOUNT_JSON

JWT Service Account (file path or JSON string)

βœ…

./service-account.json

API endpoints and scopes are configured in shared/constants.py:

  • Modern API: /adobe/assets, /adobe/folders (OAuth)

  • Classic API: /api/assets (JWT)

  • IMS Token: https://ims-na1.adobelogin.com/ims/token/v3

  • Scopes: openid,AdobeID,aem.assets.author,aem.folders


πŸ“š Documentation


🀝 ChatGPT Integration

For REST API (ChatGPT Actions)

  1. Create a Custom GPT in ChatGPT

  2. Go to "Configure" β†’ "Actions"

  3. Import the schema from rest-api/openapi-schema.json

  4. Set the server URL to your Vercel deployment

  5. Test with prompts like:

    • "List all folders in /content/dam/"

    • "Show me assets in the MyFolder folder"

    • "Update the description for asset XYZ"

For MCP Server (Native MCP)

  1. Create a Custom GPT in ChatGPT with MCP support

  2. Configure MCP connection with your Cloud Run URL

  3. The MCP server will automatically expose all tools

  4. Test with the same natural language prompts


πŸ” Security Notes

  • Never commit .env files or service-account.json

  • Use GitHub Secrets for CI/CD

  • Use GCP Secret Manager for Cloud Run

  • Use Vercel environment variables for Vercel deployment

  • Rotate credentials regularly

  • Review AEM user permissions


πŸ› Troubleshooting

Common Issues

Issue: JWT authentication not working in Cloud Run

  • Cause: AEM_SERVICE_ACCOUNT_JSON must contain JSON string, not file path

  • Fix: Create secret with JSON content: gcloud secrets create aem-service-account-json --data-file=service-account.json

Issue: Permission denied on Secret Manager

  • Cause: Cloud Run service account lacks permissions

  • Fix: Grant roles/secretmanager.secretAccessor:

    gcloud secrets add-iam-policy-binding aem-client-secret \
      --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
      --role="roles/secretmanager.secretAccessor"

Issue: 403 Forbidden from AEM

  • Cause: Incorrect authentication or insufficient permissions

  • Fix: Verify credentials, check AEM user has correct Product Profile (AEM Administrators)

Issue: Vercel deployment fails

  • Cause: Path issues after restructure

  • Fix: Ensure vercel.json points to rest-api/app/main.py

See TESTING.md for more troubleshooting steps.


πŸ“ License

MIT License - See LICENSE file for details


πŸ™ Acknowledgments

  • Adobe Experience Manager Assets API

  • FastAPI and FastMCP teams

  • Model Context Protocol specification


Option 2: Using Terraform

cd terraform

# Copy and edit variables
cp terraform.tfvars.example terraform.tfvars
nano terraform.tfvars

# Initialize Terraform
terraform init

# Preview changes
terraform plan

# Deploy infrastructure
terraform apply

Option 3: Manual Docker Deployment

# Build and tag
docker build -t gcr.io/YOUR_PROJECT/aem-mcp-server .

---

Made with ❀️ for AEM + AI Integration
-
security - not tested
F
license - not found
-
quality - not tested

Resources

Looking for Admin?

Admins can modify the Dockerfile, update the server description, and track usage metrics. If you are the server author, to authenticate as an admin.

Latest Blog Posts

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/SatoshiInoue/aem-assets-mcp-server'

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