Skip to content
castella-mcp logo

Castella MCP Integration

castella-mcp

Enable AI agents to introspect and control Castella UIs via MCP. Create MCP servers, expose UI resources, handle MCP tools, and use semantic IDs.

SKILL.md

Full skill instructions

Castella MCP Integration

MCP (Model Context Protocol) enables AI agents to introspect and control Castella UIs programmatically. This provides a standard protocol for AI-UI interaction.

When to use: "enable MCP for Castella", "MCP server", "semantic ID", "MCP resources", "MCP tools", "SSE transport", "CastellaMCPServer", "control UI with MCP"

Quick Start

Create an MCP-enabled Castella app:

from castella import App, Column, Button, Input, Text
from castella.frame import Frame
from castella.mcp import CastellaMCPServer

# Build UI with semantic IDs
ui = Column(
    Text("Hello MCP!").semantic_id("greeting"),
    Input("").semantic_id("name-input"),
    Button("Submit").semantic_id("submit-btn"),
)

app = App(Frame("MCP Demo", 800, 600), ui)

# Create MCP server
mcp = CastellaMCPServer(app, name="my-castella-app")
mcp.run_in_background()  # Run MCP in background thread

app.run()  # Run UI on main thread

Installation

uv sync --extra mcp   # MCP dependencies

Semantic IDs

Assign stable, human-readable identifiers to widgets:

Button("Submit").semantic_id("submit-btn")
Input("").semantic_id("email-input")
CheckBox(state).semantic_id("newsletter-checkbox")
Text("Status").semantic_id("status-text")

Auto-generated IDs (if not specified): button_0, input_1, etc.

Best Practices for Semantic IDs

  • Use descriptive names: submit-form-btn, not btn1
  • Use kebab-case: user-name-input
  • Include widget type: email-input, save-btn
  • Match action/​purpose: login-btn, search-input

MCP Resources

Read-only data available to AI agents:

URIDescription
ui://treeComplete UI tree structure
ui://focusCurrently focused element
ui://elementsAll interactive elements
ui://element/​{id}Specific element details
a2ui://surfacesA2UI surfaces (if A2UI enabled)

Example: UI Tree Resource

{
  "type": "tree",
  "root": {
    "id": "root",
    "type": "Column",
    "children": [
      {"id": "greeting", "type": "Text", "value": "Hello MCP!"},
      {"id": "name-input", "type": "Input", "value": "", "interactive": true},
      {"id": "submit-btn", "type": "Button", "label": "Submit", "interactive": true}
    ]
  }
}

MCP Tools

Actions AI agents can perform:

ToolDescriptionParameters
clickClick/​tap elementelement_id
type_textType into inputelement_id, text, replace
focusSet focuselement_id
scrollScroll containerelement_id, direction, amount
toggleToggle checkbox/​switchelement_id
selectSelect in picker/​tabselement_id, value
list_actionableList interactive elements-
send_a2uiSend A2UI messagemessage

Tool Examples

# Click a button
click(element_id="submit-btn")

# Type into input (replace existing text)
type_text(element_id="name-input", text="Alice", replace=True)

# Type into input (append)
type_text(element_id="name-input", text=" Smith", replace=False)

# Toggle checkbox
toggle(element_id="newsletter-checkbox")

# Select tab
select(element_id="main-tabs", value="settings")

# Scroll down
scroll(element_id="message-list", direction="down", amount=100)

Transports

stdio (Default)

For MCP clients that communicate via stdin/​stdout:

mcp = CastellaMCPServer(app, name="my-app")
mcp.run_in_background()  # Uses stdio transport

SSE (HTTP)

For HTTP-based MCP clients (Claude Desktop, web clients):

mcp = CastellaMCPServer(app, name="my-app")
mcp.run_sse_in_background(host="localhost", port=8765)

SSE endpoints:

  • GET /​sse - SSE event stream
  • POST /​message - Send MCP messages
  • GET /​health - Health check

Example: MCP Client (Python)

Control a Castella app via HTTP:

import json
import urllib.request

def call_tool(name: str, **kwargs) -> dict:
    message = {
        "type": "call_tool",
        "params": {"name": name, "arguments": kwargs}
    }
    data = json.dumps(message).encode("utf-8")
    req = urllib.request.Request(
        "http://localhost:8765/​message",
        data=data,
        headers={"Content-Type": "application/​json"},
    )
    with urllib.request.urlopen(req) as response:
        return json.loads(response.read())

# Type into input
call_tool("type_text", element_id="name-input", text="Alice", replace=True)

# Click button
call_tool("click", element_id="submit-btn")

# Toggle checkbox
call_tool("toggle", element_id="newsletter-checkbox")

# List all interactive elements
result = call_tool("list_actionable")
print(result)

A2UI + MCP Integration

Combine A2UI rendering with MCP control:

from castella.a2ui import A2UIRenderer, A2UIComponent
from castella.mcp import CastellaMCPServer

renderer = A2UIRenderer(on_action=on_action)
renderer.render_json(a2ui_json)
surface = renderer.get_surface("default")

app = App(Frame("A2UI + MCP", 800, 600), A2UIComponent(surface))

# MCP with A2UI renderer for bidirectional integration
mcp = CastellaMCPServer(app, a2ui_renderer=renderer)
mcp.run_sse_in_background(port=8766)

app.run()

A2UI component IDs automatically become MCP semantic IDs.

send_a2ui Tool

When A2UI renderer is provided, the send_a2ui tool becomes available:

send_a2ui(message={
    "updateDataModel": {
        "surfaceId": "default",
        "data": {"/​counter": 42}
    }
})

API Reference

CastellaMCPServer

from castella.mcp import CastellaMCPServer

mcp = CastellaMCPServer(
    app=app,                    # Castella App instance
    name="my-app",              # MCP server name
    version="1.0.0",            # Version string
    a2ui_renderer=None,         # Optional A2UIRenderer
)

# Blocking methods
mcp.run()                       # Run stdio (blocks)
mcp.run_sse(host, port)         # Run SSE (blocks)

# Background methods
mcp.run_in_background()         # Run stdio in thread
mcp.run_sse_in_background(host, port)  # Run SSE in thread

# Management
mcp.refresh_registry()          # Refresh widget registry
mcp.stop()                      # Stop server

ElementInfo

Information about a UI element:

element = {
    "id": "submit-btn",
    "type": "Button",
    "label": "Submit",
    "value": None,
    "bounds": {"x": 10, "y": 100, "width": 80, "height": 40},
    "interactive": True,
    "focused": False,
}

Best Practices

  1. Use descriptive semantic IDs for all interactive elements
  2. Refresh registry after major UI changes: mcp.refresh_registry()
  3. Use SSE transport for remote/​HTTP clients
  4. Combine with A2UI for full agent-UI integration
  5. Handle errors in tool calls gracefully

Reference

  • references/​resources.md - Complete resource URI reference
  • references/​tools.md - Complete tool reference
  • references/​types.md - ElementInfo, UITreeNode types
  • scripts/ - Executable examples (mcp_basic.py, mcp_sse.py)

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View