optimizely-cms-mcp

first3things/optimizely-cms-mcp

3.3

If you are the rightful owner of optimizely-cms-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Optimizely MCP Server is a Model Context Protocol server designed to integrate with Optimizely CMS, providing AI assistants with access to Optimizely's GraphQL and Content Management APIs.

Tools
3
Resources
0
Prompts
0

Optimizely MCP Server

A Model Context Protocol (MCP) server for Optimizely CMS, providing AI assistants with comprehensive access to Optimizely's GraphQL API and Content Management API.

Features

  • GraphQL Integration: Query content using Optimizely Graph API with multiple authentication methods
  • Content Management: Full CRUD operations via Content Management API (Preview3/Experimental)
  • Intelligent Content Creation: Automatically handles null values and finds parent pages by name
  • Version Management: Create, publish, and manage content versions
  • Content Types: Explore and understand content type schemas
  • Workflow Support: Manage content approval workflows
  • Multi-language Support: Handle content in multiple languages
  • Caching: Built-in caching for improved performance
  • Type Safety: Full TypeScript support with runtime validation

Installation

# Clone the repository
git clone https://github.com/your-org/optimizely-mcp-server.git
cd optimizely-mcp-server

# Install dependencies
npm install

# Build the project
npm run build

Configuration

Create a .env file in the project root:

# Server Configuration
SERVER_NAME=optimizely-mcp-server
SERVER_VERSION=1.0.0
TRANSPORT=stdio

# Optimizely Graph Configuration
GRAPH_ENDPOINT=https://cg.optimizely.com/content/v2
GRAPH_AUTH_METHOD=single_key # Options: single_key, hmac, basic, bearer, oidc
GRAPH_SINGLE_KEY=your-single-key
# For HMAC auth:
# GRAPH_APP_KEY=your-app-key
# GRAPH_SECRET_KEY=your-secret-key

# Content Management API Configuration
CMA_BASE_URL=https://api.cms.optimizely.com/preview3
CMA_CLIENT_ID=your-client-id  # Get from Settings > API Keys in CMS
CMA_CLIENT_SECRET=your-client-secret
CMA_GRANT_TYPE=client_credentials
CMA_TOKEN_ENDPOINT=https://api.cms.optimizely.com/oauth/token
CMA_IMPERSONATE_USER=  # Optional: User email to impersonate (see Impersonation section)

# Optional Configuration
CACHE_TTL=300000 # Cache TTL in milliseconds (default: 5 minutes)
LOG_LEVEL=info # Options: debug, info, warn, error
MAX_RETRIES=3
TIMEOUT=30000

Running the Server

Development Mode

# Run with hot reloading
npm run dev

# Run with debug logging
LOG_LEVEL=debug npm run dev

Production Mode

# Build and run
npm run build
npm start

# Or run directly
node dist/index.js

Testing the Server

# Run all unit tests
npm test

# Run tests with coverage
npm run test:coverage

# Type checking
npm run typecheck

# Linting
npm run lint

How MCP Servers Work

MCP servers communicate via stdio (standard input/output), not HTTP ports:

  • No port required - The server doesn't listen on any network port
  • Process-based - Claude Desktop spawns your server as a child process
  • JSON-RPC messages - Communication happens through stdin/stdout pipes
  • Secure - No network exposure, runs only when Claude needs it

MCP Client Configuration

Claude Desktop Setup

Step 1: Find your config file

Open the configuration file in a text editor:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

For Windows, you can open it quickly with:

notepad %APPDATA%\Claude\claude_desktop_config.json
Step 2: Add the server configuration
{
  "mcpServers": {
    "optimizely": {
      "command": "node",
      "args": ["%USERPROFILE%\\path\\to\\optimizely-mcp-server\\dist\\index.js"],
      "env": {
        "LOG_LEVEL": "error",
        "GRAPH_ENDPOINT": "https://cg.optimizely.com/content/v2",
        "GRAPH_AUTH_METHOD": "single_key",
        "GRAPH_SINGLE_KEY": "your-key",
        "CMA_BASE_URL": "https://api.cms.optimizely.com/preview3/experimental",
        "CMA_CLIENT_ID": "your-client-id",
        "CMA_CLIENT_SECRET": "your-client-secret",
        "CMA_GRANT_TYPE": "client_credentials",
        "CMA_TOKEN_ENDPOINT": "https://api.cms.optimizely.com/oauth/token",
        "CMA_IMPERSONATE_USER": ""
      }
    }
  }
}

In JSON on Windows, you must use double backslashes (\). If your folder path has spaces, this still works because each argument is a separate JSON string.

  • Windows: %USERPROFILE% expands to your home directory (e.g., C:\Users\Alice). If Claude doesn’t expand it automatically, replace it with your actual path (e.g., C:\Users\Alice\path\to\optimizely-mcp-server\dist\index.js). In PowerShell, the equivalent is $env:USERPROFILE, but inside this JSON config you should keep %USERPROFILE% or use the full path.
  • macOS/Linux: the equivalent shortcut is ~ or $HOME (e.g., /Users/alice or /home/alice). If ~/$HOME isn’t expanded correctly, replace it with the full path.
Step 3: Restart Claude Desktop

After saving the config file:

  1. Completely quit Claude Desktop (not just close the window)
  2. Start Claude Desktop again
  3. The Optimizely tools should now be available
Step 4: Verify it's working

In a new Claude conversation, try:

  • "Can you list the available Optimizely tools?"
  • "Use the health-check tool to test the connection"

Troubleshooting

If the server doesn't load:

  1. Check the file path is correct and uses proper escaping (\\ for Windows)
  2. Ensure you've built the project (npm run build)
  3. Verify the dist/index.js file exists
  4. Check Claude's logs for errors

Other MCP Clients

For other MCP-compatible clients, use the stdio transport configuration:

{
  "name": "optimizely",
  "transport": {
    "type": "stdio",
    "command": "node",
    "args": ["/path/to/optimizely-mcp-server/dist/index.js"]
  },
  "env": {
    // Environment variables as above
  }
}

Available Tools (38 Total)

Utility Tools (3)

  • test_connection - Test connectivity to Optimizely APIs
  • health_check - Check server health status
  • get_config - Get current configuration (sanitized)

GraphQL Query Tools (10)

  • graph_search - Full-text content search
  • graph_autocomplete - Get autocomplete suggestions
  • graph_facet_search - Search with faceted filtering
  • graph_get_by_id - Get content by numeric ID
  • graph_get_by_guid - Get content by GUID
  • graph_get_children - Get child content items
  • graph_get_ancestors - Get ancestor hierarchy
  • graph_get_descendants - Get all descendants
  • graph_get_by_route - Get content by route segment
  • graph_get_by_url - Get content by full URL

Content Management Tools (17)

Content CRUD (7)
  • content_create - Create new content
  • content_get - Get content by ID
  • content_update - Update existing content
  • content_patch - Apply JSON Patch operations
  • content_delete - Delete content
  • content_move - Move content to new location
  • content_copy - Copy content
Version Management (5)
  • version_list - List all content versions
  • version_get - Get specific version
  • version_create - Create new version
  • version_publish - Publish a version
  • version_set_common_draft - Set as common draft
Content Types (3)
  • type_list - List available content types
  • type_get - Get content type details
  • type_get_schema - Get JSON schema for type
Workflows (2)
  • workflow_get - Get workflow status
  • workflow_transition - Change workflow state

Intelligent Content Tools (4)

These tools combine GraphQL and CMA to provide smart content creation:

  • content_find_by_name - Find content by name (e.g., "Home", "News") to get IDs and GUIDs
  • content_get_details - Get full details including GUID for a specific content
  • content_create_under - Create content under a parent by name (e.g., "create under Home")
  • content_creation_wizard - Interactive wizard for guided content creation
Smart Content Creation

The MCP server now intelligently handles content creation when Claude sends null values:

  1. Automatic Parent Finding: If no parent container is provided, it searches for common parent pages (Home, Start, Root)
  2. Content Type Mapping: Maps human-readable types like "article page" to actual types like "ArticlePage"
  3. Graceful Fallbacks: Falls back to "StandardPage" if the requested content type doesn't exist
Example: Creating content under "Home"

Instead of needing to know the Home page's GUID, you can now:

  1. Use content_find_by_name with "Home" to find the page
  2. Use content_create_under to create content directly under it
  3. Or use content_creation_wizard for a step-by-step process
  4. Even content-create now automatically handles null values intelligently!

Development

Project Structure

optimizely-mcp-server/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts          # Server entry point
β”‚   β”œβ”€β”€ register.ts       # Tool registration
β”‚   β”œβ”€β”€ config.ts         # Configuration management
β”‚   β”œβ”€β”€ clients/          # API clients
β”‚   β”‚   β”œβ”€β”€ graph-client.ts
β”‚   β”‚   └── cma-client.ts
β”‚   β”œβ”€β”€ logic/            # Tool implementations
β”‚   β”‚   β”œβ”€β”€ utility/
β”‚   β”‚   β”œβ”€β”€ graph/
β”‚   β”‚   └── content/
β”‚   β”œβ”€β”€ types/            # TypeScript types
β”‚   └── utils/            # Utilities
β”œβ”€β”€ tests/                # Test files
β”œβ”€β”€ dist/                 # Built output
└── package.json

Adding New Tools

  1. Create tool implementation in src/logic/
  2. Add tool registration in appropriate section
  3. Add TypeScript types if needed
  4. Write tests in tests/
  5. Update documentation

Testing Guidelines

  • Unit tests for all tool implementations
  • Integration tests for API clients
  • Mock external API calls
  • Test error scenarios
  • Maintain >80% coverage

Testing & Debugging

Unit Tests

Run automated tests with Vitest:

# Run unit tests
npm test

# Run with coverage report
npm run test:coverage

Unit tests are located in /tests/ and cover:

  • GraphQL client functionality
  • CMA client operations
  • Health check features

Integration Testing & Debugging

Test your setup with these npm scripts:

# Check credentials are valid
npm run check:credentials

# Test MCP tools
npm run test:tools

# Test with debug output
npm run test:tools:debug

# Test GraphQL connection
npm run debug:graph

# Validate API key format
npm run validate:key

Debugging Scripts

The scripts/ directory contains utilities for testing and debugging:

  • quick-test.js - Test MCP server tools through stdio
  • test-with-debug.js - Detailed API request/response logging
  • debug-graph.js - Direct GraphQL endpoint testing
  • debug-auth-comprehensive.js - Test all authentication methods
  • validate-key.js - Validate GraphQL key format
  • find-graphql-endpoint.js - Discover your GraphQL endpoint

For PowerShell users, set environment variables like this:

$env:LOG_LEVEL="debug"; npm run test:tools:debug

See for detailed documentation.

Troubleshooting

Common Issues

  1. Authentication Errors

    • Verify your API credentials in .env
    • For CMA: Create API keys in Settings > API Keys in your Optimizely CMS instance
    • Check token expiration for CMA (tokens expire after 5 minutes)
    • Ensure correct auth method for Graph
  2. Connection Issues

    • Verify network connectivity
    • Check firewall settings
    • Confirm API endpoints are accessible
  3. Build Errors

    • Run npm install to ensure dependencies
    • Check Node.js version (>=18 required)
    • Clear dist/ and rebuild
  4. 403 Forbidden Errors (Content Creation)

    • This typically means insufficient permissions
    • See the Impersonation section below for a solution
    • Verify the user has content creation rights
    • Check the target container allows the content type

Debug Mode

Enable debug logging for troubleshooting:

LOG_LEVEL=debug npm start

Health Check

Test server connectivity:

# Using the built tool
echo '{"method": "tools/call", "params": {"name": "health_check"}}' | node dist/index.js

User Impersonation

If you encounter 403 Forbidden errors when creating content, you can use user impersonation to execute API calls as a specific user who has the necessary permissions.

When to Use Impersonation

Use impersonation when:

  • The API client lacks content creation permissions
  • You need to test with different user permission levels
  • You want actions attributed to a specific user

Setup Instructions

  1. Enable Impersonation in Optimizely CMS:

    • Log into Optimizely CMS as an administrator
    • Navigate to Settings > API Clients
    • Find your API client
    • Enable the "Allow impersonation" option
    • Save the changes
  2. Configure the MCP Server:

    # In your .env file
    CMA_IMPERSONATE_USER=user@example.com
    
  3. Update Claude Desktop Config (if using environment variables):

    {
      "mcpServers": {
        "optimizely": {
          "env": {
            "CMA_IMPERSONATE_USER": "user@example.com",
            // ... other settings
          }
        }
      }
    }
    

How It Works

When impersonation is configured:

  • Authentication requests use JSON format with act_as field
  • All content operations execute as the impersonated user
  • Created content shows the impersonated user as the author

Testing Impersonation

Test that impersonation is working:

# Run the impersonation test script
node scripts/test-impersonation-final.js

This will create test content and show which user created it.

Security Best Practices

  • Only enable impersonation when necessary
  • Use accounts with minimal required permissions
  • Regularly review API client permissions
  • Monitor API usage logs for unusual activity

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Run npm test and npm run typecheck
  6. Submit a pull request

License

MIT