HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityAcademySubmit a ticketLog In
Dev Guide

MCP server for CMS 13

Set up the Model Context Protocol (MCP) server for CMS 13 to connect AI developer tools like Claude Code, Cursor, and Codex to your CMS content and configuration.

The Optimizely.Cms.Opal.Tools package includes a Model Context Protocol (MCP) server that exposes the same CMS tools available through Opal Chat to any MCP-compatible AI client. Manage CMS content, content types, and display templates from your development environment with an MCP client such as Claude Code or Cursor. The MCP server puts these tools in the editor where you write code, so you can create content types and display templates while building the templates that render them.

The MCP server shares the same tools and descriptions as the Opal protocol. See Available tools for CMS 13 for the full tool reference.

Prerequisites

Install and configure

Register the MCP server

Add the MCP server to your service collection in Startup.cs or Program.cs. Chain an authentication method to configure how MCP clients authenticate.

services.AddCmsMcpServer().WithClientSecretAuthentication();

AddCmsMcpServer() registers the MCP server with stateless HTTP transport and all CMS tools. The chained authentication method (for example, WithClientSecretAuthentication()) configures how the server validates incoming requests.

Map the MCP endpoint

Map the MCP endpoint in your application pipeline and apply the matching authorization policy.

app.UseEndpoints(endpoints =>
{
    endpoints.MapContent();
    endpoints.MapMcp("/mcp").RequireClientSecretAuthorization();
});

The convenience extension method RequireClientSecretAuthorization() applies the correct authorization policy for the authentication method.

Authentication and authorization

Every MCP tool call executes CMS operations on behalf of an authenticated user. The MCP server requires an authentication method that establishes a user identity so that all content operations respect CMS permissions.

Choose an authentication method

MethodUse caseIdentityPermissions
Client secretLocal development, secure internal environmentsApplication identity with CmsAdmins roleFull access to all tools
CustomIntegration with existing auth systemsDepends on implementationDepends on identity mapping
Optimizely IdentityComing in a future releaseIndividual Opti ID userPer-user CMS permissions

Client secret authentication is designed for local development where the network is trusted and permission scoping is not required. For production environments, implement a custom authentication handler that integrates with your existing authentication system. Optimizely Identity (Opti ID) authentication with per-user permission scoping will be available in a future release.

How tool authorization works

When the MCP server receives a request:

  1. The authentication handler validates the credentials (secret or custom token).
  2. The handler creates a ClaimsPrincipal representing the authenticated identity.
  3. Each tool impersonates this identity for all CMS API calls.
  4. CMS enforces the standard permission model (the tool can only access content the impersonated user has permission to access).

All tools require an authorized identity. Some tools, such as content type management, require the CmsAdmins role. Other tools operate under the authenticated user's own content permissions.

Optimizely Identity authentication

📘

Note

Optimizely Identity (Opti ID) authentication for the MCP server will be available in a future release. This will enable per-user authentication and permission scoping for production and multi-user environments. For now, use client secret authentication or a custom authentication handler.

Client secret authentication

Use WithClientSecretAuthentication() for local development and secure (non-public) environments. This method authenticates requests with a shared secret in the Authorization header.

services.AddCmsMcpServer().WithClientSecretAuthentication();
endpoints.MapMcp("/mcp").RequireClientSecretAuthorization();

Configure the secret in appsettings.json:

{
  "Optimizely": {
    "Cms": {
      "Mcp": {
        "Secret": "your-secret-value"
      }
    }
  }
}

Or use user secrets for local development:

dotnet user-secrets set "Optimizely:Cms:Mcp:Secret" "your-secret-value"

MCP clients send the secret as the value of the Authorization header:

Authorization: your-secret-value
🚧

Important

Client secret authentication transmits the secret in plain text. Use this method only on a trusted network, such as localhost, an internal network, or a virtual private network (VPN). Do not use client secret authentication in production environments exposed to the internet.

The client secret handler creates an identity with the CmsAdmins role, which grants full access to all CMS tools. This is suitable for development where permission scoping is not required.

Custom authentication

For scenarios where client secret authentication is not appropriate, you can implement a custom authentication handler. This is useful when you want to authenticate MCP requests with an existing authentication system such as the CMS Management API's OAuth2 flow.

A custom authentication implementation follows a three-part pattern:

  1. Authentication handler – Create a class that extends AuthenticationHandler<AuthenticationSchemeOptions> and override HandleAuthenticateAsync(). The handler validates incoming credentials (for example, a JWT or API key) and returns a ClaimsPrincipal representing an authenticated identity that CMS can resolve.
  2. IMcpServerBuilder extension method – Register the authentication handler with AddScheme<>(), define an authorization policy with AddAuthorizationBuilder().AddPolicy(), and optionally register an ISynchronizedApplicationsRepository interceptor so the MCP application identity is visible in the CMS permission system.
  3. IEndpointConventionBuilder extension method – Apply the authorization policy to the MCP endpoint with RequireAuthorization().

Register and map using the same pattern as client secret authentication:

services.AddCmsMcpServer().WithYourCustomAuthentication();

endpoints.MapMcp("/mcp").RequireYourCustomAuthorization();

The authenticated identity's CMS permissions determine which tools it can use. Some tools, such as content type management, require the CmsAdmins role. Other tools operate under the identity's own content permissions. Your authentication handler should verify the identity has the required permissions, not assign roles it does not have.

Connect an MCP client

After configuring the MCP server, connect your AI development tool by pointing it to the MCP endpoint. The configuration depends on the authentication method you chose.

Connect with client secret authentication

With client secret authentication, the MCP client sends the secret directly in the Authorization header. This works with any MCP client that supports streamable HTTP transport.

Claude Code

Add to .mcp.json or project settings:

{
  "mcpServers": {
    "optimizely-cms": {
      "type": "http",
      "url": "https://YOUR_CMS_HOST/mcp",
      "headers": {
        "Authorization": "your-secret-value"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json in your project root (or ~/.cursor/mcp.json for global configuration):

{
  "mcpServers": {
    "optimizely-cms": {
      "type": "http",
      "url": "https://YOUR_CMS_HOST/mcp",
      "headers": {
        "Authorization": "your-secret-value"
      }
    }
  }
}

Codex

Add to ~/.codex/config.toml (or .codex/config.toml in a trusted project directory):

[mcp_servers.optimizely-cms]
type = "http"
url = "https://YOUR_CMS_HOST/mcp"

[mcp_servers.optimizely-cms.headers]
Authorization = "your-secret-value"

Other MCP clients

Any MCP client that supports streamable HTTP transport can connect. Configure the client with:

  • Endpoint URL: https://YOUR_CMS_HOST/mcp
  • Transport: Streamable HTTP (stateless)
  • Authentication: The shared secret value in the Authorization header

Did this page help you?