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 withuri,content, andencoding
Returns:
UIResourceinstance ready for use in MCP tool results
Action Result Functions
ui_action_result_tool_call(tool_name: str, params: dict) -> UIActionResultToolCallui_action_result_prompt(prompt: str) -> UIActionResultPromptui_action_result_link(url: str) -> UIActionResultLinkui_action_result_intent(intent: str, params: dict) -> UIActionResultIntentui_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 resultsadvanced_features.py: Advanced patterns and integrationsmcp_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)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_ui_server-1.0.0.tar.gz | 78.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|