Developer Demo

CMS MCP Server

The Optimizely SaaS CMS ships a native Model Context Protocol server. Connect any MCP-compatible AI assistant to your CMS and interact with content, schemas, and navigation through natural language - no GraphQL or REST knowledge required.

Zero boilerplate setupWorks with Claude, Cursor, CopilotReads Graph, writes Management APIOAuth-authenticated

Setup #

Add one entry to your project's .mcp.json file. The MCP server is hosted by Optimizely - there is nothing to deploy or maintain on your side. Your AI assistant discovers available tools automatically on first connection.

.mcp.json
{
  "mcpServers": {
    "cms": {
      "type": "http",
      "url": "https://cms.mcp.opal.optimizely.com/mcp"
    }
  }
}

What the server exposes

list_content_types

Returns all registered content types with their property schemas and base types

get_content

Fetches a content item by key, URL, or Graph reference - supports draft and published modes

create_content

Creates a new content item via the Management API with typed property validation

update_content

Patches an existing content item - accepts partial property updates

query_content

Issues a Graph query described in plain language and returns the matching items

publish_content

Moves a draft to published status and triggers ISR revalidation

How a prompt becomes a CMS operation

Developer prompt

natural language

MCP client

Claude / Cursor / Copilot

MCP server

cms.mcp.opal.optimizely.com

Graph / Mgmt API

authenticated request

CMS updated

draft or published

Content Type Exploration #

Auditing content types in the CMS UI means navigating menus for each type individually. With MCP it is a single natural-language query. Useful when onboarding to an existing project, debugging a Graph query that returns unexpected fields, or figuring out what properties are available before writing a seed script.

Example

Inspect a content type

Developer prompt

What properties does ArticlePage expose? Which ones are searchable and which are content references?

  1. 1MCP calls list_content_types and filters to ArticlePage
  2. 2Returns property names, types (string, richText, contentReference, array), and indexing flags
  3. 3Searchable fields are highlighted - these are what Graph full-text search covers
  4. 4Content reference fields include their allowedTypes so you know what can be linked

Example

Find all types that extend a base type

Developer prompt

Which content types use _page as their base type, and which ones support display template variants?

  1. 1MCP calls list_content_types and groups results by baseType
  2. 2Types with registered display templates are flagged
  3. 3Useful when deciding whether a new page type should extend _page or _experience
  4. 4Returns the compositionBehaviors for each type (elementEnabled vs sectionEnabled)

Example

Check allowed types in a content area

Developer prompt

What blocks are allowed inside the sections content area on DynamicExperience pages?

  1. 1MCP fetches the DynamicExperience content type definition
  2. 2Returns the allowedTypes array for the sections property
  3. 3Lists each allowed block type with its own property schema
  4. 4Useful before building a composition script to know what block types are valid

Example

Understand a property constraint

Developer prompt

Does HeroBlock use elementEnabled or sectionEnabled? Can it contain child content areas?

  1. 1MCP fetches HeroBlock from the content type registry
  2. 2Returns compositionBehaviors: elementEnabled means it is a leaf node
  3. 3Confirms that adding a content area property to it would be silently ignored by the CMS
  4. 4Saves a round-trip of deploying a broken schema to find this out at runtime

Content Authoring & Seeding #

Create and update content items through conversation instead of writing seed scripts or using the CMS UI. The MCP server handles the Management API authentication, content reference format ( cms://content/key ), and property validation on your behalf.

Example

Create a draft article

Developer prompt

Create an ArticlePage titled 'Five tax-efficient savings strategies for 2026' under /en/insights/articles. Set the category to personal-finance and tag it with savings, tax, and ISA.

  1. 1MCP resolves ArticlePage schema to know the required property shape
  2. 2Calls create_content with title, slug, category enum, and tags array
  3. 3Content is created as a draft - no accidental publishes
  4. 4Returns the new content key and CMS edit link for immediate review

Example

Link a content reference

Developer prompt

Set the author on the article we just created to Sarah Chen.

  1. 1MCP calls query_content to find the AuthorBlock for Sarah Chen by display name
  2. 2Resolves the author's content key and forms the cms://content/{key} reference
  3. 3Calls update_content to patch the author field on the target article
  4. 4Handles the single reference format the Management API expects automatically

Example

Seed a batch of FAQ items

Developer prompt

Create five FaqItemBlock entries covering common questions about Mosey Bank's savings accounts. Link them all to the /en/faqs page's faqItems content area.

  1. 1MCP creates each FaqItemBlock individually and collects their keys
  2. 2Fetches the target FaqContainerBlock to read its current faqItems array
  3. 3Appends the new items using the { reference: 'cms://content/key' } array format
  4. 4Patches the container block in one update_content call with the merged array

Example

Publish a reviewed draft

Developer prompt

The article looks good. Publish it and make sure the nav cache is cleared.

  1. 1MCP calls publish_content with the article's content key
  2. 2Management API moves the draft to published status
  3. 3The configured publish webhook fires, triggering Next.js ISR revalidation
  4. 4The page tag and navigation tag are both invalidated so visitors see fresh content

Querying & Auditing #

Ask questions about your content library in plain language. The MCP server translates them into Graph queries with the correct filters, pagination, and locale scope - useful for audits, debugging, and ad hoc content checks during development.

Example

Find stale content

Developer prompt

Which ArticlePages in the investments category haven't been updated in the last 60 days? Show me their titles and last-modified dates.

  1. 1MCP builds a Graph query filtering by category='investments' and publishDate
  2. 2Sorts results by publishDate ascending to surface the most stale items first
  3. 3Returns titles, slugs, publishDate, and Management API edit links
  4. 4Can be followed up with: 'Flag all of them for review' to batch-patch their status

Example

Debug a missing content item

Developer prompt

The page at /en/insights/articles/mortgage-rates-explained isn't rendering. Is it published? Does it have an author set?

  1. 1MCP calls get_content with the URL to fetch the item regardless of publish state
  2. 2Checks _metadata.status to confirm whether it is draft, published, or deleted
  3. 3Inspects the author field - single content references return only base metadata
  4. 4Reports missing fields and suggests the next fix (set author, publish draft, etc.)

Example

Count content by type

Developer prompt

How many ArticlePages exist per category? I want to know if any category is underpopulated before we launch.

  1. 1MCP queries ArticlePages with a facet on the category field
  2. 2Graph returns facet counts without fetching all items - efficient for large libraries
  3. 3Results show each category label alongside its article count
  4. 4Immediately actionable: 'Create two more articles in the business-banking category'

Example

Inspect navigation structure

Developer prompt

Show me the full nav tree. I want to see every node, its URL, and how many levels deep it goes.

  1. 1MCP calls query_content with the @recursive directive on the navigation type
  2. 2Returns the full tree with node labels, hrefs, and nesting depth
  3. 3Useful before running a seed script that modifies nav to understand the current shape
  4. 4Can be followed up with: 'Add a node under Insights for the new Savings hub'

Example

Plan a type deprecation

Developer prompt

We are deprecating LegacyBannerBlock. Find every page that still has it in a content area and give me a list of URLs and edit links.

  1. 1MCP queries Graph for all content items whose composition includes LegacyBannerBlock
  2. 2Returns parent page keys, titles, and CMS edit links for each affected item
  3. 3Surfaces draft and published pages separately so the migration can be phased
  4. 4Immediately actionable - follow up with 'Replace each one with HeroBlock using the same heading and image'

Developer Workflow Integration #

The MCP server fits into common development tasks - not just one-off content operations. These examples show how it speeds up the feedback loop when building new content types, writing seed scripts, or debugging Graph query issues. It also helps when onboarding new developers - instead of learning the CMS UI to understand the content model, they can ask the MCP server directly.

Example

Validate a new content type before pushing

Developer prompt

I'm about to push a new PressReleasePage type. Check whether anything in the existing schema conflicts with the property names I've defined.

  1. 1MCP lists all registered content types and their property key namespaces
  2. 2Cross-references against the new type's property list for collisions
  3. 3Flags any property key that already exists on a parent or sibling type
  4. 4Saves a round-trip of running opti:push only to hit a schema validation error

Example

Generate a seed script from an existing item

Developer prompt

Look at the case study at /en/insights/case-studies/local-bakery-growth and generate a seed script stub that creates a similar item.

  1. 1MCP calls get_content on the case study URL to fetch its full property shape
  2. 2Reads referenced OutcomeItemBlock and TestimonialBlock keys from the composition
  3. 3Outputs a TypeScript snippet following the scripts/seed-modeling.ts pattern
  4. 4Includes the cms://content/{key} reference format for all content area items

Example

Reproduce a Graph query result locally

Developer prompt

The GetArticles query is returning no results for the 'market-insights' category. Run it against the live CMS and tell me what's coming back.

  1. 1MCP executes the query against the Graph delivery API with the given filter
  2. 2Returns the raw response including any empty arrays or null fields
  3. 3Reports whether the category enum value matches what is stored on published items
  4. 4Surfaces whether the articles exist as drafts but haven't been published yet

Example

Clean up after a seed run

Developer prompt

The seed script created duplicate FAQ items. Find all FaqItemBlocks whose question starts with 'What is' and delete the extras, keeping only the most recently created one.

  1. 1MCP queries FaqItemBlocks matching the question prefix filter
  2. 2Sorts by _metadata.created descending to identify the newest item
  3. 3Calls the Management API delete endpoint for each duplicate key
  4. 4Confirms deletion by re-querying and returning the remaining item count

Example

Scaffold a block component from a content type

Developer prompt

Read the PricingTierBlock content type and generate a TypeScript React component that renders all its properties with the correct data-component attribute and preview utils.

  1. 1MCP calls list_content_types and returns PricingTierBlock's full property schema
  2. 2AI maps each property type to its rendering pattern - string to <p>, richText to <RichText />, contentReference to <Image />
  3. 3Generates the component with correct TypeScript types, pa() preview attributes, and data-component
  4. 4No need to open the CMS UI, copy field names by hand, or guess at property shapes

Supported MCP clients

Any tool implementing the Model Context Protocol can connect to the same server endpoint. No per-client integration is needed on the Optimizely side.

Claude DesktopClaude CodeCursorGitHub CopilotWindsurfZedAny MCP-compatible client
Auth is handled once at connection time. The MCP server uses the same OAuth credentials as the Management API ( OPTIMIZELY_CMS_CLIENT_ID and OPTIMIZELY_CMS_CLIENT_SECRET ). Set them once in your environment and every tool call in the session is automatically authenticated - no token management in prompts.