first3things/optimizely-cms-mcp
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.
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:
- Completely quit Claude Desktop (not just close the window)
- Start Claude Desktop again
- 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:
- Check the file path is correct and uses proper escaping (
\\
for Windows) - Ensure you've built the project (
npm run build
) - Verify the
dist/index.js
file exists - 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 APIshealth_check
- Check server health statusget_config
- Get current configuration (sanitized)
GraphQL Query Tools (10)
graph_search
- Full-text content searchgraph_autocomplete
- Get autocomplete suggestionsgraph_facet_search
- Search with faceted filteringgraph_get_by_id
- Get content by numeric IDgraph_get_by_guid
- Get content by GUIDgraph_get_children
- Get child content itemsgraph_get_ancestors
- Get ancestor hierarchygraph_get_descendants
- Get all descendantsgraph_get_by_route
- Get content by route segmentgraph_get_by_url
- Get content by full URL
Content Management Tools (17)
Content CRUD (7)
content_create
- Create new contentcontent_get
- Get content by IDcontent_update
- Update existing contentcontent_patch
- Apply JSON Patch operationscontent_delete
- Delete contentcontent_move
- Move content to new locationcontent_copy
- Copy content
Version Management (5)
version_list
- List all content versionsversion_get
- Get specific versionversion_create
- Create new versionversion_publish
- Publish a versionversion_set_common_draft
- Set as common draft
Content Types (3)
type_list
- List available content typestype_get
- Get content type detailstype_get_schema
- Get JSON schema for type
Workflows (2)
workflow_get
- Get workflow statusworkflow_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 GUIDscontent_get_details
- Get full details including GUID for a specific contentcontent_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:
- Automatic Parent Finding: If no parent container is provided, it searches for common parent pages (Home, Start, Root)
- Content Type Mapping: Maps human-readable types like "article page" to actual types like "ArticlePage"
- 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:
- Use
content_find_by_name
with "Home" to find the page - Use
content_create_under
to create content directly under it - Or use
content_creation_wizard
for a step-by-step process - 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
- Create tool implementation in
src/logic/
- Add tool registration in appropriate section
- Add TypeScript types if needed
- Write tests in
tests/
- 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 stdiotest-with-debug.js
- Detailed API request/response loggingdebug-graph.js
- Direct GraphQL endpoint testingdebug-auth-comprehensive.js
- Test all authentication methodsvalidate-key.js
- Validate GraphQL key formatfind-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
-
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
- Verify your API credentials in
-
Connection Issues
- Verify network connectivity
- Check firewall settings
- Confirm API endpoints are accessible
-
Build Errors
- Run
npm install
to ensure dependencies - Check Node.js version (>=18 required)
- Clear
dist/
and rebuild
- Run
-
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
-
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
-
Configure the MCP Server:
# In your .env file CMA_IMPERSONATE_USER=user@example.com
-
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
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run
npm test
andnpm run typecheck
- Submit a pull request
License
MIT