print_web_interface.pyโข13.4 kB
#!/usr/bin/env python3
"""
Web interface for the Simple Print MCP Server
"""
import asyncio
import json
import logging
import sys
from pathlib import Path
from datetime import datetime
# Add src to path
sys.path.insert(0, str(Path(__file__).parent / "src"))
from core.server import MCPServer, MCPTool
from core.testing import MCPServerTester
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class PrintWebInterface:
"""Web interface for the print server."""
def __init__(self):
self.messages = []
def generate_html(self):
"""Generate the HTML interface."""
return """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple Print MCP Server</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background: #f5f5f5;
line-height: 1.6;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.status {
padding: 15px;
margin: 20px 0;
border-radius: 6px;
font-weight: bold;
}
.status.running {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.card {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 20px;
margin: 15px 0;
}
.message-form {
background: #e9ecef;
padding: 20px;
border-radius: 6px;
margin: 20px 0;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input, .form-group select, .form-group textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.form-group textarea {
height: 80px;
resize: vertical;
}
.btn {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-right: 10px;
}
.btn:hover {
background: #0056b3;
}
.btn-success { background: #28a745; }
.btn-success:hover { background: #1e7e34; }
.btn-warning { background: #ffc107; color: #212529; }
.btn-warning:hover { background: #e0a800; }
.btn-danger { background: #dc3545; }
.btn-danger:hover { background: #c82333; }
.messages {
max-height: 400px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px;
background: white;
}
.message {
padding: 10px;
margin: 5px 0;
border-radius: 4px;
border-left: 4px solid #007bff;
}
.message.info { border-left-color: #17a2b8; background: #d1ecf1; }
.message.success { border-left-color: #28a745; background: #d4edda; }
.message.warning { border-left-color: #ffc107; background: #fff3cd; }
.message.error { border-left-color: #dc3545; background: #f8d7da; }
.message-time {
font-size: 12px;
color: #666;
margin-top: 5px;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.emoji {
font-size: 1.2em;
margin-right: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1><span class="emoji">๐จ๏ธ</span> Simple Print MCP Server</h1>
<div class="status running">
<span class="emoji">โ
</span> Print Server is running on localhost:8001
</div>
<div class="grid">
<div class="card">
<h3><span class="emoji">๐</span> Send a Message</h3>
<div class="message-form">
<div class="form-group">
<label for="message">Message:</label>
<textarea id="message" placeholder="Enter your message here..."></textarea>
</div>
<div class="form-group">
<label for="level">Level:</label>
<select id="level">
<option value="info">Info</option>
<option value="success">Success</option>
<option value="warning">Warning</option>
<option value="error">Error</option>
</select>
</div>
<button class="btn btn-success" onclick="sendMessage()">Send Message</button>
<button class="btn btn-warning" onclick="listMessages()">Refresh Messages</button>
<button class="btn btn-danger" onclick="clearMessages()">Clear All</button>
</div>
</div>
<div class="card">
<h3><span class="emoji">๐</span> Server Status</h3>
<p><strong>Host:</strong> localhost</p>
<p><strong>Port:</strong> 8001</p>
<p><strong>Status:</strong> Running</p>
<p><strong>Protocol:</strong> JSON-RPC 2.0</p>
<p><strong>Tools:</strong> print_message, list_messages, clear_messages</p>
</div>
</div>
<div class="card">
<h3><span class="emoji">๐</span> Messages</h3>
<div id="messages" class="messages">
<p>No messages yet. Send a message to see it here!</p>
</div>
</div>
<div class="card">
<h3><span class="emoji">๐งช</span> How to Test</h3>
<p>You can test this server in several ways:</p>
<ul>
<li><strong>Use this web interface:</strong> Send messages using the form above</li>
<li><strong>Connect with Claude Desktop:</strong> Add <code>localhost:8001</code> as an MCP server</li>
<li><strong>Use any MCP client:</strong> Connect to <code>localhost:8001</code></li>
<li><strong>Test with Python:</strong> Run <code>py -3 test_print_client.py</code></li>
</ul>
</div>
</div>
<script>
async function sendMessage() {
const message = document.getElementById('message').value;
const level = document.getElementById('level').value;
if (!message.trim()) {
alert('Please enter a message!');
return;
}
try {
const response = await fetch('/send_message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: message,
level: level
})
});
const result = await response.json();
if (result.success) {
document.getElementById('message').value = '';
listMessages();
} else {
alert('Error: ' + result.error);
}
} catch (error) {
alert('Error sending message: ' + error);
}
}
async function listMessages() {
try {
const response = await fetch('/list_messages');
const result = await response.json();
const messagesDiv = document.getElementById('messages');
if (result.messages && result.messages.length > 0) {
messagesDiv.innerHTML = result.messages.map(msg => `
<div class="message ${msg.level}">
<strong>${msg.message}</strong>
<div class="message-time">${new Date(msg.timestamp).toLocaleString()}</div>
</div>
`).join('');
} else {
messagesDiv.innerHTML = '<p>No messages yet.</p>';
}
} catch (error) {
console.error('Error listing messages:', error);
}
}
async function clearMessages() {
if (!confirm('Are you sure you want to clear all messages?')) {
return;
}
try {
const response = await fetch('/clear_messages', { method: 'POST' });
const result = await response.json();
if (result.success) {
alert(`Cleared ${result.count} messages`);
listMessages();
} else {
alert('Error clearing messages');
}
} catch (error) {
alert('Error clearing messages: ' + error);
}
}
// Load messages on page load
window.onload = function() {
listMessages();
};
</script>
</body>
</html>
"""
async def start_web_server(self):
"""Start a simple web server to show the interface."""
import http.server
import socketserver
class PrintHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
self.wfile.write(self.server.print_interface.generate_html().encode('utf-8'))
elif self.path == '/list_messages':
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
# For now, return empty messages
response = {"messages": []}
self.wfile.write(json.dumps(response).encode('utf-8'))
else:
super().do_GET()
def do_POST(self):
if self.path == '/send_message':
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
data = json.loads(post_data.decode('utf-8'))
# Here you would send the message to the MCP server
# For now, just return success
response = {"success": True, "message": "Message sent"}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(response).encode('utf-8'))
elif self.path == '/clear_messages':
response = {"success": True, "count": 0}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(response).encode('utf-8'))
else:
self.send_response(404)
self.end_headers()
# Create server
handler = PrintHandler
handler.server = type('Server', (), {'print_interface': self})()
with socketserver.TCPServer(("", 3002), handler) as httpd:
print("๐ Print web interface available at: http://localhost:3002")
print("๐ก Print server should be running at: localhost:8001")
print("๐ Press Ctrl+C to stop")
httpd.serve_forever()
async def main():
"""Start the print web interface."""
print("๐ Starting Print Web Interface")
print("=" * 35)
try:
interface = PrintWebInterface()
await interface.start_web_server()
except KeyboardInterrupt:
print("\n๐ Web interface stopped")
except Exception as e:
print(f"โ Error: {e}")
if __name__ == "__main__":
asyncio.run(main())