mcp_dashboard.html•15.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCP System Dashboard</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
text-align: center;
color: white;
margin-bottom: 30px;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
font-size: 1.2em;
opacity: 0.9;
}
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0,0,0,0.15);
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.card-icon {
font-size: 2em;
margin-right: 15px;
}
.card-title {
font-size: 1.3em;
font-weight: 600;
color: #333;
}
.status-indicator {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
}
.status-online {
background-color: #4CAF50;
box-shadow: 0 0 10px rgba(76, 175, 80, 0.5);
}
.status-offline {
background-color: #f44336;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
font-size: 1em;
margin: 5px;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
text-align: center;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn-secondary {
background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);
}
.btn-success {
background: linear-gradient(135deg, #55efc4 0%, #00b894 100%);
}
.btn-warning {
background: linear-gradient(135deg, #fdcb6e 0%, #e17055 100%);
}
.agent-list {
max-height: 200px;
overflow-y: auto;
}
.agent-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
margin: 5px 0;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #667eea;
}
.quick-actions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 20px;
}
.action-card {
background: white;
border-radius: 10px;
padding: 20px;
text-align: center;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.action-card:hover {
transform: translateY(-3px);
}
.action-icon {
font-size: 2.5em;
margin-bottom: 10px;
}
.footer {
text-align: center;
color: white;
margin-top: 40px;
opacity: 0.8;
}
.command-input {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 1em;
margin-bottom: 10px;
}
.command-input:focus {
outline: none;
border-color: #667eea;
}
.response-area {
background: #f8f9fa;
border-radius: 8px;
padding: 15px;
min-height: 100px;
max-height: 200px;
overflow-y: auto;
font-family: monospace;
font-size: 0.9em;
white-space: pre-wrap;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🤖 MCP System Dashboard</h1>
<p>Enhanced Model Context Protocol - Complete Local Interface</p>
</div>
<div class="dashboard-grid">
<!-- Server Status Card -->
<div class="card">
<div class="card-header">
<span class="card-icon">🖥️</span>
<div>
<div class="card-title">Server Status</div>
<div id="server-status">
<span class="status-indicator status-offline"></span>
Checking...
</div>
</div>
</div>
<div>
<button class="btn" onclick="checkServerStatus()">🔄 Refresh Status</button>
<a href="http://localhost:8000" target="_blank" class="btn btn-secondary">🌐 Open Server</a>
<a href="http://localhost:8000/docs" target="_blank" class="btn btn-success">📚 API Docs</a>
</div>
</div>
<!-- Agents Card -->
<div class="card">
<div class="card-header">
<span class="card-icon">🤖</span>
<div class="card-title">Active Agents</div>
</div>
<div id="agents-list" class="agent-list">
<div>Loading agents...</div>
</div>
<button class="btn" onclick="loadAgents()">🔄 Refresh Agents</button>
</div>
<!-- Command Interface Card -->
<div class="card">
<div class="card-header">
<span class="card-icon">💬</span>
<div class="card-title">Command Interface</div>
</div>
<div>
<input type="text" id="command-input" class="command-input" placeholder="Enter command (e.g., 'hello', 'get gmail status', 'analyze document')">
<button class="btn" onclick="sendCommand()">📤 Send Command</button>
<button class="btn btn-warning" onclick="clearResponse()">🗑️ Clear</button>
</div>
<div id="command-response" class="response-area">
Ready to receive commands...
</div>
</div>
<!-- System Info Card -->
<div class="card">
<div class="card-header">
<span class="card-icon">📊</span>
<div class="card-title">System Information</div>
</div>
<div id="system-info">
<div><strong>Server URL:</strong> http://localhost:8000</div>
<div><strong>Client Interface:</strong> mcp_client/web_client.html</div>
<div><strong>Agent Folders:</strong> agents/core/, agents/specialized/, agents/custom/</div>
<div><strong>Last Updated:</strong> <span id="last-updated">Never</span></div>
</div>
<button class="btn" onclick="updateSystemInfo()">🔄 Update Info</button>
</div>
</div>
<!-- Quick Actions -->
<div class="quick-actions">
<div class="action-card">
<div class="action-icon">🌐</div>
<h3>Web Client</h3>
<p>Visual interface for MCP</p>
<button class="btn" onclick="openWebClient()">Open Client</button>
</div>
<div class="action-card">
<div class="action-icon">💻</div>
<h3>CLI Client</h3>
<p>Command line interface</p>
<button class="btn" onclick="openCLI()">Launch CLI</button>
</div>
<div class="action-card">
<div class="action-icon">🧪</div>
<h3>System Test</h3>
<p>Test all functionality</p>
<button class="btn" onclick="runTest()">Run Test</button>
</div>
<div class="action-card">
<div class="action-icon">📧</div>
<h3>Gmail Agent</h3>
<p>Email functionality</p>
<button class="btn" onclick="testGmail()">Test Gmail</button>
</div>
<div class="action-card">
<div class="action-icon">📄</div>
<h3>Document Analysis</h3>
<p>Process documents</p>
<button class="btn" onclick="testDocuments()">Test Analysis</button>
</div>
<div class="action-card">
<div class="action-icon">🔄</div>
<h3>Hot Reload</h3>
<p>Reload agents</p>
<button class="btn" onclick="reloadAgents()">Reload Agents</button>
</div>
</div>
<div class="footer">
<p>🎯 MCP System - Drop agents in folders and they auto-connect!</p>
<p>📁 Enhanced Model Context Protocol with modular agent architecture</p>
</div>
</div>
<script>
const SERVER_URL = 'http://localhost:8000';
async function checkServerStatus() {
const statusElement = document.getElementById('server-status');
try {
const response = await fetch(`${SERVER_URL}/api/health`);
if (response.ok) {
const data = await response.json();
statusElement.innerHTML = `
<span class="status-indicator status-online"></span>
Online - ${data.status}
`;
} else {
throw new Error('Server not responding');
}
} catch (error) {
statusElement.innerHTML = `
<span class="status-indicator status-offline"></span>
Offline
`;
}
}
async function loadAgents() {
const agentsElement = document.getElementById('agents-list');
try {
const response = await fetch(`${SERVER_URL}/api/mcp/agents`);
if (response.ok) {
const data = await response.json();
const agents = data.agents || {};
if (Object.keys(agents).length === 0) {
agentsElement.innerHTML = '<div>No agents loaded</div>';
} else {
agentsElement.innerHTML = Object.entries(agents).map(([id, info]) => `
<div class="agent-item">
<div>
<strong>${info.name || id}</strong>
<div style="font-size: 0.9em; color: #666;">${info.description || 'No description'}</div>
</div>
<span class="status-indicator status-online"></span>
</div>
`).join('');
}
} else {
throw new Error('Failed to load agents');
}
} catch (error) {
agentsElement.innerHTML = '<div>Error loading agents</div>';
}
}
async function sendCommand() {
const input = document.getElementById('command-input');
const response = document.getElementById('command-response');
const command = input.value.trim();
if (!command) return;
response.textContent = 'Sending command...';
try {
const result = await fetch(`${SERVER_URL}/api/mcp/command`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ command: command })
});
if (result.ok) {
const data = await result.json();
response.textContent = JSON.stringify(data, null, 2);
} else {
response.textContent = `Error: ${result.status} ${result.statusText}`;
}
} catch (error) {
response.textContent = `Error: ${error.message}`;
}
input.value = '';
}
function clearResponse() {
document.getElementById('command-response').textContent = 'Ready to receive commands...';
}
function updateSystemInfo() {
document.getElementById('last-updated').textContent = new Date().toLocaleString();
}
function openWebClient() {
window.open('mcp_client/web_client.html', '_blank');
}
function openCLI() {
alert('To use CLI: Open terminal and run "python mcp_client/cli_client.py interactive"');
}
function runTest() {
alert('To run test: Open terminal and run "python test_mcp_system.py"');
}
async function testGmail() {
await sendCommandQuick('get gmail status');
}
async function testDocuments() {
await sendCommandQuick('test document analysis');
}
async function reloadAgents() {
await sendCommandQuick('reload agents');
}
async function sendCommandQuick(command) {
document.getElementById('command-input').value = command;
await sendCommand();
}
// Auto-refresh on page load
window.addEventListener('load', () => {
checkServerStatus();
loadAgents();
updateSystemInfo();
// Auto-refresh every 30 seconds
setInterval(() => {
checkServerStatus();
loadAgents();
}, 30000);
});
// Enter key support for command input
document.getElementById('command-input').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendCommand();
}
});
</script>
</body>
</html>