Skip to main content

MCP UI Server SDK for Python

A Python SDK for creating MCP UI resources on the server side, enabling rich interactive experiences in MCP applications.

Installation

pip install mcp-ui-server

Quick Start

from mcp_ui_server import create_ui_resource

# Create an HTML resource
resource = create_ui_resource({
    "uri": "ui://my-component",
    "content": {
        "type": "rawHtml",
        "htmlString": "<h1>Hello MCP UI!</h1>"
    },
    "encoding": "text"
})

# Use in MCP tool result
tool_result = {
    "content": [resource.to_dict()]
}

Features

Resource Types

The SDK supports three main content types:

1. Raw HTML

Direct HTML content for embedding in the UI:

html_resource = create_ui_resource({
    "uri": "ui://html-example",
    "content": {
        "type": "rawHtml", 
        "htmlString": "<div><h1>Dynamic Content</h1><p>Generated server-side</p></div>"
    },
    "encoding": "text"  # or "blob" for base64 encoding
})

2. External URLs

Embed external websites via iframe:

url_resource = create_ui_resource({
    "uri": "ui://external-site",
    "content": {
        "type": "externalUrl",
        "iframeUrl": "https://example.com"
    },
    "encoding": "text"
})

3. Remote DOM Components

Interactive components using React or Web Components:

# React component
react_resource = create_ui_resource({
    "uri": "ui://react-component",
    "content": {
        "type": "remoteDom",
        "script": """
            function WeatherWidget({ location }) {
                return (
                    <div>
                        <h3>Weather for {location}</h3>
                        <p>Temperature: 72°F</p>
                    </div>
                );
            }
        """,
        "framework": "react"
    },
    "encoding": "text"
})

# Web Components
wc_resource = create_ui_resource({
    "uri": "ui://web-component", 
    "content": {
        "type": "remoteDom",
        "script": """
            class StatusIndicator extends HTMLElement {
                connectedCallback() {
                    this.innerHTML = `
                        <div style="color: green;">
                            ✅ System Online
                        </div>
                    `;
                }
            }
            customElements.define('status-indicator', StatusIndicator);
        """,
        "framework": "webcomponents"
    },
    "encoding": "blob"
})

Encoding Options

Choose between text and blob encoding:

  • text: Direct string content (recommended for development)
  • blob: Base64-encoded content (recommended for production)
# Text encoding - content stored as plain text
text_resource = create_ui_resource({
    "uri": "ui://text-example",
    "content": {"type": "rawHtml", "htmlString": "<p>Text content</p>"},
    "encoding": "text"
})

# Blob encoding - content base64 encoded
blob_resource = create_ui_resource({
    "uri": "ui://blob-example", 
    "content": {"type": "rawHtml", "htmlString": "<p>Blob content</p>"},
    "encoding": "blob"
})

UI Metadata

Enhance resources with metadata for client-side handling. The SDK automatically prefixes UI-specific metadata with mcpui.dev/ui- to distinguish it from custom metadata.

Preferred Frame Size

Specify preferred dimensions for UI rendering:

resource = create_ui_resource({
    "uri": "ui://chart",
    "content": {
        "type": "externalUrl",
        "iframeUrl": "https://charts.example.com/widget"
    },
    "encoding": "text",
    "uiMetadata": {
        "preferred-frame-size": [800, 600]  # width, height in pixels or css units
    }
})

Initial Render Data

Provide data to components at initialization:

resource = create_ui_resource({
    "uri": "ui://dashboard",
    "content": {
        "type": "remoteDom",
        "script": """
            function Dashboard({ theme, userId }) {
                // Component receives initial data
                return <div>Dashboard for user {userId}</div>;
            }
        """,
        "framework": "react"
    },
    "encoding": "text",
    "uiMetadata": {
        "initial-render-data": {
            "theme": "dark",
            "userId": "123"
        }
    }
})

Multiple Metadata Fields

Combine multiple metadata fields:

resource = create_ui_resource({
    "uri": "ui://data-viz",
    "content": {
        "type": "rawHtml",
        "htmlString": "<canvas id='chart'></canvas>"
    },
    "encoding": "text",
    "uiMetadata": {
        "preferred-frame-size": ["800px", "600px"],
        "initial-render-data": {
            "chartType": "bar",
            "dataSet": "quarterly-sales"
        }
    }
})

Custom Metadata

Add custom metadata alongside UI metadata:

resource = create_ui_resource({
    "uri": "ui://custom-widget",
    "content": {
        "type": "rawHtml",
        "htmlString": "<div>Widget</div>"
    },
    "encoding": "text",
    "uiMetadata": {
        "preferred-frame-size": [640, 480]
    },
    "metadata": {
        "customKey": "customValue",
        "version": "1.0.0"
    }
})

# Result includes both prefixed UI metadata and custom metadata:
# {
#   "resource": {
#     "meta": {
#       "mcpui.dev/ui-preferred-frame-size": [640, 480],
#       "customKey": "customValue",
#       "version": "1.0.0"
#     }
#   }
# }

UI Actions

Create action results for user interactions:

from mcp_ui_server import (
    ui_action_result_tool_call,
    ui_action_result_prompt,
    ui_action_result_link,
    ui_action_result_intent,
    ui_action_result_notification
)

# Tool execution
tool_action = ui_action_result_tool_call("search_database", {
    "query": "user input",
    "limit": 10
})

# User prompt
prompt_action = ui_action_result_prompt("Enter search query:")

# External link
link_action = ui_action_result_link("https://docs.example.com")

# Intent trigger
intent_action = ui_action_result_intent("show_details", {
    "item_id": "123"
})

# Notification
notify_action = ui_action_result_notification("Search completed!")

Advanced Usage

MCP Integration

Convert UI resources for MCP tool results:

from mcp_ui_server.utils import create_mcp_tool_result_content

# Create resource
resource = create_ui_resource({...})

# Convert to MCP format
mcp_content = create_mcp_tool_result_content(resource)

# Use in tool result
return {
    "content": [mcp_content],
    "isError": False
}

HTML Enhancement

Automatically enhance HTML with communication capabilities:

from mcp_ui_server.utils import wrap_html_with_communication

# Basic HTML
html = "<div>My content</div>"

# Enhanced with MCP UI communication
enhanced_html = wrap_html_with_communication(html)

# Use in resource
resource = create_ui_resource({
    "uri": "ui://enhanced-html",
    "content": {"type": "rawHtml", "htmlString": enhanced_html},
    "encoding": "text"
})

Error Handling

The SDK provides specific exception types:

from mcp_ui_server.exceptions import (
    MCPUIServerError,
    InvalidURIError,
    InvalidContentError,
    EncodingError
)

try:
    resource = create_ui_resource({
        "uri": "invalid://test",  # Must start with ui://
        "content": {"type": "rawHtml", "htmlString": "<p>Test</p>"},
        "encoding": "text"
    })
except InvalidURIError as e:
    print(f"URI validation failed: {e}")
except InvalidContentError as e:
    print(f"Content validation failed: {e}")
except MCPUIServerError as e:
    print(f"General SDK error: {e}")

API Reference

Core Functions

create_ui_resource(options: CreateUIResourceOptions) -> UIResource

Creates a UI resource from the given options.

Parameters:

  • options: Configuration dictionary with uri, content, and encoding

Returns:

  • UIResource instance ready for use in MCP tool results

Action Result Functions

  • ui_action_result_tool_call(tool_name: str, params: dict) -> UIActionResultToolCall
  • ui_action_result_prompt(prompt: str) -> UIActionResultPrompt
  • ui_action_result_link(url: str) -> UIActionResultLink
  • ui_action_result_intent(intent: str, params: dict) -> UIActionResultIntent
  • ui_action_result_notification(message: str) -> UIActionResultNotification

Types

CreateUIResourceOptions

{
    "uri": str,  # Must start with "ui://"
    "content": Union[RawHtmlPayload, ExternalUrlPayload, RemoteDomPayload],
    "encoding": Literal["text", "blob"],
    "uiMetadata": Optional[dict[str, Any]],  # UI-specific metadata (auto-prefixed)
    "metadata": Optional[dict[str, Any]]     # Custom metadata
}

Content Payloads

# Raw HTML
{
    "type": "rawHtml",
    "htmlString": str
}

# External URL
{
    "type": "externalUrl", 
    "iframeUrl": str
}

# Remote DOM
{
    "type": "remoteDom",
    "script": str,
    "framework": Literal["react", "webcomponents"]
}

Examples

See the examples/ directory for complete usage examples:

  • basic_server_usage.py: Basic resource creation and action results
  • advanced_features.py: Advanced patterns and integrations
  • mcp_tool_integration.py: Complete MCP tool implementation

Development

Setup

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linting
ruff check .
black .

# Type checking
mypy src/

Project Structure

src/mcp_ui_server/
├── __init__.py          # Main exports
├── types.py             # Type definitions
├── core.py              # Core functionality
├── utils.py             # Utility functions
└── exceptions.py        # Custom exceptions

License

Apache 2.0

Contributing

See CONTRIBUTING.md for contribution guidelines.

Release files for mcp-ui-server 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-ui-server 1.0.0
File Size Uploaded
mcp_ui_server-1.0.0.tar.gz 78.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-ui-server 1.0.0
File Interpreter ABI Platform
mcp_ui_server-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 89.9 kB

Release files / mcp_ui_server-1.0.0.tar.gz

Download URL mcp_ui_server-1.0.0.tar.gz
Size 78.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5ab8f17b93bf794966af7c35e9a575e4f21a9ba2bab3d316cfc107a15f88a3c9
BLAKE2b-256 checksum
How to use checksums
f7ed80b21fb515be72baa7fbb55326ee36bad55aa3080519827431599b003989
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.11.14

Release files / mcp_ui_server-1.0.0-py3-none-any.whl

Download URL mcp_ui_server-1.0.0-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
85f53b2e4300fbd175f1fbb7c40f2566b1f4a4ad03a1f33647867c82a3159dcc
BLAKE2b-256 checksum
How to use checksums
4b8a4c1b2b5708e2f8bf3f3d2ebc130f5bb2a1805cd648b6eda8e5e4bdc039bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.11.14

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page