The lifecycle of a digital product often hits a specific wall: the dependency of business teams on engineering capacity. Marketing managers wait days for simple layout changes, while developers spend valuable time moving pixels instead of solving complex backend problems.

At Spyrosoft BSG, we addressed this by building an architecture where an authorized CMS user modifies the frontend using natural language. We demonstrate how to move beyond simple chat interfaces by connecting AI assistants directly to your infrastructure using the Model Context Protocol (MCP).

The core concept here is declarative UI composition. Generative AI should not write frontend code (HTML/CSS/JS) in production, as it is prone to errors. Instead, the AI systems intelligently assemble predefined, styled components. This article outlines the MCP architecture, code implementation, and the specific engineering challenges we solved.

The Bottleneck: Engineering Dependency in Content Management

In a standard OTT platform workflow, a request to add a new “Oscar Winners” row to the homepage initiates a Jira ticket, development sprint planning, coding, QA, and deployment.

Our goal is to enable a manager to implement this change via a command in the CMS:

“Create an ‘Oscar Winners’ carousel on the homepage with 5 movies from our catalog that won this award.”

The Solution: Declarative UI Composition vs. Code Generation

Many AI applications focus on Large Language Models (LLMs) writing React or Vue code on the fly. In an enterprise environment, this approach introduces risks:

  • Inconsistency: The model might invent classes that do not match the brand book.
  • Security threats: Injecting generated code creates vulnerabilities.
  • Fragility: The output is non-deterministic.


We use AI-driven UI composition. The LLM acts as the logic layer that decides which block to pick and what data to put inside it.

Architecture: The Model Context Protocol (MCP) as the “USB-C Port” for AI

To interact with the CMS, the Agent needs a standardized way to call functions and access external data sources. This is where the Model Context Protocol (MCP) comes in.

Think of MCP as a USB-C port for AI models. Just as USB-C provides a standardized connector for peripherals, MCP provides an open standard for connecting LLMs to external tools and content repositories. It eliminates the need to build custom integrations for every new model.

The MCP architecture consists of three parts:

  1. MCP Host: The application where the AI agents live (e.g., our CMS interface or an IDE like Cursor).
  2. MCP Clients: The connector maintaining the 1:1 connection with the server.
  3. MCP Servers: Lightweight services that expose tools and resources to the client.

Below is a simplified, functional code snippet of an MCP server built with Python. This server acts as the bridge, allowing function calling to search content and modify the layout.

# mcp_server.py
from typing import List, Literal, Dict, Any
from fastmcp import FastMcp
 
# [cite_start]In a real implementation, you would import your internal SDK here [cite: 38]
# import our_ott_cms_sdk as cms
 
# --- MOCK (for the article's purpose, to ensure code readability) ---
class MockCMS:
    def search(self, query, limit): return []
    class Layouts:
        def create_component(self, title, type, content): return "comp_123"
        def add_to_page(self, page_id, component_id, position): return True
        def delete_component(self, component_id): return True
    layouts = Layouts()
 
cms = MockCMS() 
# --------------------------------------------------------------------
 
# [cite_start]Initialize the server which will expose capabilities to MCP Clients [cite: 39]
mcp = FastMcp("OTTCmsAgent")
 
# --- Toolset for layout and content manipulation ---
 
@mcp.tool()
async def find_content_by_query(query: str, limit: int = 5) -> List[Dict[str, Any]]:
    """
    [cite_start]Searches for content in the catalog based on a query[cite: 43].
    """
    # [cite_start]Accessing external data sources (OTT Catalog) [cite: 44]
    content_items = cms.search(query=query, limit=limit)
    # Assuming content_items have a to_dict() method
    return [item.to_dict() for item in content_items] if content_items else []
 
@mcp.tool()
async def create_ui_component(
    title: str, 
    component_type: Literal["carousel", "grid", "hero"], 
    content_ids: List[str]
) -> Dict[str, str]:
    """
    Creates a new, abstract UI component definition in the system.
    [cite_start]Note: We do not generate HTML here. We create a structured data object [cite: 53-54].
    """
    # [cite_start][Fixed syntax error from original: arguments are now correctly inside parentheses] [cite: 55-57]
    component_id = cms.layouts.create_component(
        title=title, 
        type=component_type, 
        content=content_ids
    )
    return {"component_id": component_id}
 
@mcp.tool()
async def add_component_to_page(
    component_id: str, 
    page_id: str, 
    position: int = -1
) -> Dict[str, str]:
    """
    Adds an existing component to a page.
    [cite_start]Defaults to adding at the end (position=-1) [cite: 61-62].
    """
    # [cite_start]Backend function call to update the layout [cite: 63]
    success = cms.layouts.add_to_page(
        page_id=page_id, 
        component_id=component_id, 
        position=position
    )
    return {"status": "success" if success else "failure"}
 
@mcp.tool()
async def delete_ui_component(component_id: str) -> Dict[str, str]:
    """
    [cite_start]Removes a UI component. Key for the rollback mechanism[cite: 69].
    """
    # Compensating operation for transaction rollback
    success = cms.layouts.delete_component(component_id=component_id)
    return {"status": "success" if success else "failure"}
 
if __name__ == "__main__":
    # Run the MCP server
    mcp.run()

    Execution: How the Agent Translates Intent into Action

    When a user types a prompt, the AI tool decomposes it into a plan and a sequence of tool usage. The Model Context Protocol handles the transport layer, ensuring the model receives relevant information about available tools.

    1. Prompt:
    “Create an ‘Oscar Winners’ carousel on the homepage with 5 movies from our catalog that won this award.”

    2. Agent Plan (Internal Reasoning):

    • “I must identify the content first from the data sources.”
    • “With the obtained IDs, I will configure a carousel.”
    • “I will place the component on the homepage.”

    3. Execution (Sequence of MCP Tool Calls):

    • findContentByQuery -> Returns ID list from the content repository.
    • createUiComponent -> Creates the object.
    • addComponentToPage -> Updates the layout.

    4. User Response (in CMS):
    “Done. The ‘Oscar Winners’ section has been added to the homepage.”

    Engineering Challenges for Production Deployment

    This approach is powerful, but a naive implementation will fail in production. At Spyrosoft BSG, we identified five critical issues.

    1. Idempotency and Deduplication

    LLM applications can be unpredictable. To prevent duplicate components, the createUiComponent tool uses a deduplication key (e.g., hash of parameters). If the key matches an existing draft, the agent reuses it instead of creating a copy.

    2. Validation and Human-in-the-Loop

    The agent cannot act blindly. If the information retrieval from the catalog is imprecise, the system must pause. The agent asks: “I found 3 movies matching ‘Oscar Winners’. Should I continue?” This keeps the human in control.

    3. Security and Tool Permissions

    Standard integrations often overlook tool permissions. In our architecture, every request via the context protocol is authorized. Our SDK verifies if the user has the rights to modify the homepage before executing a write action.

    4. Sandbox and Versioning

    We never allow AI models to touch production directly. The Agent operates on a “draft version”. Only after review does a publishChanges tool push modifications to the live external systems.

    5. Transactionality and Rollback

    We treat the sequence of actions as a transaction. If adding to the page fails, the creation step must be reversed. We implement an undo stack, using compensating operations (like delete_ui_component) to ensure data integrity.

    Conclusion: Engineering Over Models

    We are moving from an era where AI helps write code to an era where AI uses code written by experts.

    The real value lies in designing atomic, idempotent tools and using an industry standard like MCP. It allows developers to build production-grade AI that safely interacts with remote resources. At Spyrosoft BSG, we focus on these architectural foundations to deliver real business value in the OTT space.

    Ready to build the future of streaming?

    Explore our work in Media and Entertainment and let’s discuss how we can can elevate your platform.

    FAQ

    No. In this solution, AI does not generate HTML, CSS, or JavaScript. Instead, it assembles predefined and approved UI components into structured layouts. This ensures brand consistency, security, and production stability.

    Every AI-driven action goes through authorization, validation, and versioning layers. Changes are first applied in a draft environment and require human approval before publishing. In addition, rollback and deduplication mechanisms protect the system from errors and duplicate components.

    Yes. The architecture based on the Model Context Protocol is designed for enterprise environments. It supports permission management, transactional workflows, integration with existing systems, and scalability. This makes it suitable for high-traffic, production-grade OTT platforms with complex infrastructures.

    About the author

    Damian Maicher

    Business Researcher