mcp-ui-server Usage & Examples
This page provides practical examples for using the mcp-ui-server
package.
For a complete example, see the python-server-demo
.
Basic Setup
First, ensure you have mcp-ui-server
available in your project:
bash
pip install mcp-ui-server
1
Or with uv:
bash
uv add mcp-ui-server
1
Basic Usage
The core function is create_ui_resource
.
python
from mcp_ui_server import create_ui_resource
# Example 1: Direct HTML, delivered as text
resource1 = create_ui_resource({
"uri": "ui://my-component/instance-1",
"content": {
"type": "rawHtml",
"htmlString": "<p>Hello World</p>"
},
"encoding": "text"
})
print("Resource 1:", resource1.model_dump_json(indent=2))
# Output for Resource 1:
# {
# "type": "resource",
# "resource": {
# "uri": "ui://my-component/instance-1",
# "mimeType": "text/html",
# "text": "<p>Hello World</p>"
# }
# }
# Example 2: Direct HTML, delivered as a Base64 blob
resource2 = create_ui_resource({
"uri": "ui://my-component/instance-2",
"content": {
"type": "rawHtml",
"htmlString": "<h1>Complex HTML</h1>"
},
"encoding": "blob"
})
print("Resource 2 (blob will be Base64):", resource2.model_dump_json(indent=2))
# Output for Resource 2:
# {
# "type": "resource",
# "resource": {
# "uri": "ui://my-component/instance-2",
# "mimeType": "text/html",
# "blob": "PGgxPkNvbXBsZXggSFRNTDwvaDE+"
# }
# }
# Example 3: External URL, text encoding
dashboard_url = "https://my.analytics.com/dashboard/123"
resource3 = create_ui_resource({
"uri": "ui://analytics-dashboard/main",
"content": {
"type": "externalUrl",
"iframeUrl": dashboard_url
},
"encoding": "text"
})
print("Resource 3:", resource3.model_dump_json(indent=2))
# Output for Resource 3:
# {
# "type": "resource",
# "resource": {
# "uri": "ui://analytics-dashboard/main",
# "mimeType": "text/uri-list",
# "text": "https://my.analytics.com/dashboard/123"
# }
# }
# Example 4: External URL, blob encoding (URL is Base64 encoded)
chart_api_url = "https://charts.example.com/api?type=pie&data=1,2,3"
resource4 = create_ui_resource({
"uri": "ui://live-chart/session-xyz",
"content": {
"type": "externalUrl",
"iframeUrl": chart_api_url
},
"encoding": "blob"
})
print("Resource 4 (blob will be Base64 of URL):", resource4.model_dump_json(indent=2))
# Output for Resource 4:
# {
# "type": "resource",
# "resource": {
# "uri": "ui://live-chart/session-xyz",
# "mimeType": "text/uri-list",
# "blob": "aHR0cHM6Ly9jaGFydHMuZXhhbXBsZS5jb20vYXBpP3R5cGU9cGllJmRhdGE9MSwyLDM="
# }
# }
# Example 5: Remote DOM script, text encoding
remote_dom_script = """
const button = document.createElement('ui-button');
button.setAttribute('label', 'Click me for a tool call!');
button.addEventListener('press', () => {
window.parent.postMessage({
type: 'tool',
payload: {
toolName: 'uiInteraction',
params: { action: 'button-click', from: 'remote-dom' }
}
}, '*');
});
root.appendChild(button);
"""
resource5 = create_ui_resource({
"uri": "ui://remote-component/action-button",
"content": {
"type": "remoteDom",
"script": remote_dom_script.strip(),
"framework": "react" # or "webcomponents"
},
"encoding": "text"
})
print("Resource 5:", resource5.model_dump_json(indent=2))
# Output for Resource 5:
# {
# "type": "resource",
# "resource": {
# "uri": "ui://remote-component/action-button",
# "mimeType": "application/vnd.mcp-ui.remote-dom+javascript; framework=react",
# "text": "\\nconst button = document.createElement('ui-button');\\n..."
# }
# }
# These resource objects would then be included in the 'content' array
# of a toolResult in an MCP interaction.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
Using with FastMCP
Here's how to use create_ui_resource
with the FastMCP framework:
python
import argparse
from mcp.server.fastmcp import FastMCP
from mcp_ui_server import create_ui_resource
from mcp_ui_server.core import UIResource
# Create FastMCP instance
mcp = FastMCP("my-server")
@mcp.tool()
def show_dashboard() -> list[UIResource]:
"""Display an analytics dashboard."""
ui_resource = create_ui_resource({
"uri": "ui://dashboard/analytics",
"content": {
"type": "externalUrl",
"iframeUrl": "https://my.analytics.com/dashboard"
},
"encoding": "text"
})
return [ui_resource]
@mcp.tool()
def show_welcome() -> list[UIResource]:
"""Display a welcome message."""
ui_resource = create_ui_resource({
"uri": "ui://welcome/main",
"content": {
"type": "rawHtml",
"htmlString": "<h1>Welcome to My MCP Server!</h1><p>How can I help you today?</p>"
},
"encoding": "text"
})
return [ui_resource]
if __name__ == "__main__":
mcp.run()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Advanced URI List Example
You can provide multiple URLs in the text/uri-list
format for fallback purposes. However, MCP-UI requires a single URL and will only use the first valid URL found:
python
# Example 6: Multiple URLs with fallbacks (MCP-UI uses only the first)
multi_url_content = """# Primary dashboard
https://dashboard.example.com/main
# Backup dashboard (will be logged but not used)
https://backup.dashboard.example.com/main
# Emergency fallback (will be logged but not used)
https://emergency.dashboard.example.com/main"""
resource6 = create_ui_resource({
"uri": "ui://dashboard-with-fallbacks/session-123",
"content": {
"type": "externalUrl",
"iframeUrl": multi_url_content
},
"encoding": "text"
})
# The client will:
# 1. Use https://dashboard.example.com/main for rendering
# 2. Log a warning about the ignored backup URLs
# This allows you to specify fallback URLs in the standard format
# while MCP-UI focuses on the primary URL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Error Handling
The create_ui_resource
function will raise exceptions if invalid combinations are provided, for example:
- URI not starting with
ui://
for any content type - Invalid content type specified
python
from mcp_ui_server.exceptions import InvalidURIError
try:
create_ui_resource({
"uri": "invalid://should-be-ui",
"content": {
"type": "externalUrl",
"iframeUrl": "https://example.com"
},
"encoding": "text"
})
except InvalidURIError as e:
print(f"Caught expected error: {e}")
# URI must start with 'ui://' but got: invalid://should-be-ui
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14