forked from MCP-UI-Org/mcp-ui
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython_server_demo.py
More file actions
159 lines (133 loc) · 5.54 KB
/
python_server_demo.py
File metadata and controls
159 lines (133 loc) · 5.54 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
"""Python MCP server demo inspired by the TypeScript version.
This server demonstrates how to create an MCP server with UI resources
using FastMCP for both stdio and HTTP transports.
Usage:
python python_server_demo.py # stdio transport
python python_server_demo.py --http --port 3000 # HTTP transport
"""
import argparse
from mcp.server.fastmcp import FastMCP
from mcp_ui_server import create_ui_resource, UIMetadataKey
from mcp_ui_server.core import UIResource
# Create FastMCP instance
mcp = FastMCP("python-server-demo")
@mcp.tool()
def show_external_url() -> list[UIResource]:
"""Creates a UI resource displaying an external URL (example.com) with preferred frame size."""
ui_resource = create_ui_resource({
"uri": "ui://greeting",
"content": {
"type": "externalUrl",
"iframeUrl": "https://example.com"
},
"encoding": "text",
"uiMetadata": {
UIMetadataKey.PREFERRED_FRAME_SIZE: ["800px", "600px"] # CSS dimension strings (can be px, %, vh, etc.)
}
})
return [ui_resource]
@mcp.tool()
def show_raw_html() -> list[UIResource]:
"""Creates a UI resource displaying raw HTML."""
ui_resource = create_ui_resource({
"uri": "ui://raw-html-demo",
"content": {
"type": "rawHtml",
"htmlString": "<h1>Hello from Raw HTML</h1>"
},
"encoding": "text"
})
return [ui_resource]
@mcp.tool()
def show_remote_dom() -> list[UIResource]:
"""Creates a UI resource displaying a remote DOM script."""
remote_dom_script = """
const p = document.createElement('ui-text');
p.textContent = 'This is a remote DOM element from the server.';
root.appendChild(p);
"""
ui_resource = create_ui_resource({
"uri": "ui://remote-dom-demo",
"content": {
"type": "remoteDom",
"script": remote_dom_script.strip(),
"framework": "react"
},
"encoding": "text"
})
return [ui_resource]
@mcp.tool()
def show_action_html() -> list[UIResource]:
"""Creates a UI resource with interactive buttons that demonstrate intent actions."""
interactive_html = """
<div style="padding: 20px; font-family: Arial, sans-serif;">
<h2>Intent Action Demo</h2>
<p>Click the buttons below to trigger different intent actions:</p>
<div style="margin: 10px 0;">
<button onclick="sendIntent('user_profile', {userId: '123', action: 'view'})"
style="background: #007cba; color: white; padding: 8px 16px; border: none; border-radius: 4px; margin: 5px; cursor: pointer;">
View User Profile
</button>
</div>
<div style="margin: 10px 0;">
<button onclick="sendIntent('navigation', {page: 'dashboard', section: 'analytics'})"
style="background: #28a745; color: white; padding: 8px 16px; border: none; border-radius: 4px; margin: 5px; cursor: pointer;">
Navigate to Dashboard
</button>
</div>
<div style="margin: 10px 0;">
<button onclick="sendIntent('data_export', {format: 'csv', dateRange: '30days'})"
style="background: #ffc107; color: black; padding: 8px 16px; border: none; border-radius: 4px; margin: 5px; cursor: pointer;">
Export Data
</button>
</div>
<div style="margin: 10px 0;">
<button onclick="sendIntent('notification_settings', {type: 'email', enabled: true})"
style="background: #dc3545; color: white; padding: 8px 16px; border: none; border-radius: 4px; margin: 5px; cursor: pointer;">
Update Notifications
</button>
</div>
<div id="status" style="margin-top: 20px; padding: 10px; background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px;">
Click a button to see the intent action in action!
</div>
</div>
<script>
function sendIntent(intent, params) {
const status = document.getElementById('status');
status.innerHTML = `<strong>Intent Sent:</strong> ${intent}<br><strong>Parameters:</strong> ${JSON.stringify(params, null, 2)}`;
// Send the intent to the parent frame
if (window.parent) {
window.parent.postMessage({
type: 'intent',
payload: {
intent: intent,
params: params
}
}, '*');
}
}
</script>
"""
ui_resource = create_ui_resource({
"uri": "ui://action-html-demo",
"content": {
"type": "rawHtml",
"htmlString": interactive_html
},
"encoding": "text"
})
return [ui_resource]
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Python MCP Server Demo")
parser.add_argument("--http", action="store_true", help="Use HTTP transport instead of stdio")
parser.add_argument("--port", type=int, default=3000, help="Port for HTTP transport (default: 3000)")
args = parser.parse_args()
if args.http:
print("🚀 Starting Python MCP server on HTTP (SSE transport)")
print("📡 Server will use SSE transport settings")
mcp.settings.port=args.port
mcp.run(transport="sse")
else:
print("🚀 Starting Python MCP server with stdio transport")
mcp.run()