Skip to main content
Glama
index.html10.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bug Bounty MCP Dashboard</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #333; min-height: 100vh; } .container { max-width: 1400px; margin: 0 auto; padding: 20px; } header { background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-radius: 15px; padding: 20px 30px; margin-bottom: 30px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); } h1 { color: #667eea; font-size: 2rem; margin-bottom: 10px; } .subtitle { color: #666; font-size: 0.9rem; } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 30px; } .stat-card { background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-radius: 15px; padding: 25px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; } .stat-card:hover { transform: translateY(-5px); } .stat-label { color: #666; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; } .stat-value { color: #333; font-size: 2.5rem; font-weight: bold; } .stat-value.critical { color: #e74c3c; } .stat-value.high { color: #f39c12; } .stat-value.medium { color: #f1c40f; } .stat-value.low { color: #3498db; } .stat-value.info { color: #95a5a6; } .main-content { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; } .panel { background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-radius: 15px; padding: 30px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); } .panel.full-width { grid-column: 1 / -1; } .panel h2 { color: #667eea; margin-bottom: 20px; font-size: 1.5rem; } .findings-list { max-height: 600px; overflow-y: auto; } .finding-item { border-left: 4px solid #ddd; padding: 15px; margin-bottom: 15px; background: #f8f9fa; border-radius: 8px; transition: all 0.3s ease; } .finding-item:hover { background: #e9ecef; transform: translateX(5px); } .finding-item.critical { border-left-color: #e74c3c; } .finding-item.high { border-left-color: #f39c12; } .finding-item.medium { border-left-color: #f1c40f; } .finding-item.low { border-left-color: #3498db; } .finding-item.info { border-left-color: #95a5a6; } .finding-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .finding-type { font-weight: bold; color: #333; } .finding-severity { padding: 5px 12px; border-radius: 20px; font-size: 0.8rem; font-weight: bold; text-transform: uppercase; } .finding-severity.critical { background: #e74c3c; color: white; } .finding-severity.high { background: #f39c12; color: white; } .finding-severity.medium { background: #f1c40f; color: white; } .finding-severity.low { background: #3498db; color: white; } .finding-severity.info { background: #95a5a6; color: white; } .finding-url { color: #667eea; font-size: 0.9rem; word-break: break-all; margin-bottom: 5px; } .finding-description { color: #666; font-size: 0.85rem; margin-top: 8px; } .loading { text-align: center; padding: 40px; color: #666; } .error { background: #fee; color: #c33; padding: 15px; border-radius: 8px; margin: 20px 0; } .refresh-btn { background: #667eea; color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 0.9rem; margin-bottom: 20px; transition: background 0.3s ease; } .refresh-btn:hover { background: #5568d3; } .refresh-btn:active { transform: scale(0.98); } @media (max-width: 768px) { .main-content { grid-template-columns: 1fr; } } </style> </head> <body> <div class="container"> <header> <h1>🐛 Bug Bounty MCP Dashboard</h1> <p class="subtitle">Real-time security findings and test results</p> </header> <div class="stats-grid" id="statsGrid"> <div class="stat-card"> <div class="stat-label">Total Findings</div> <div class="stat-value" id="totalFindings">-</div> </div> <div class="stat-card"> <div class="stat-label">Critical</div> <div class="stat-value critical" id="criticalCount">-</div> </div> <div class="stat-card"> <div class="stat-label">High</div> <div class="stat-value high" id="highCount">-</div> </div> <div class="stat-card"> <div class="stat-label">Medium</div> <div class="stat-value medium" id="mediumCount">-</div> </div> <div class="stat-card"> <div class="stat-label">Low</div> <div class="stat-value low" id="lowCount">-</div> </div> </div> <div class="main-content"> <div class="panel full-width"> <button class="refresh-btn" onclick="loadData()">🔄 Refresh Data</button> <h2>Recent Findings</h2> <div class="findings-list" id="findingsList"> <div class="loading">Loading findings...</div> </div> </div> </div> </div> <script> const API_BASE = '/api'; async function loadData() { try { // Load statistics const statsRes = await fetch(`${API_BASE}/statistics`); if (statsRes.ok) { const stats = await statsRes.json(); updateStats(stats); } // Load findings const findingsRes = await fetch(`${API_BASE}/findings`); if (findingsRes.ok) { const findings = await findingsRes.json(); displayFindings(findings.findings || []); } else { document.getElementById('findingsList').innerHTML = '<div class="error">Failed to load findings. Is the server running?</div>'; } } catch (error) { console.error('Error loading data:', error); document.getElementById('findingsList').innerHTML = '<div class="error">Error connecting to server. Please check if the dashboard server is running.</div>'; } } function updateStats(stats) { document.getElementById('totalFindings').textContent = stats.totalFindings || 0; document.getElementById('criticalCount').textContent = stats.bySeverity?.critical || 0; document.getElementById('highCount').textContent = stats.bySeverity?.high || 0; document.getElementById('mediumCount').textContent = stats.bySeverity?.medium || 0; document.getElementById('lowCount').textContent = stats.bySeverity?.low || 0; } function displayFindings(findings) { const container = document.getElementById('findingsList'); if (findings.length === 0) { container.innerHTML = '<div class="loading">No findings yet. Start testing to see results here!</div>'; return; } container.innerHTML = findings.map(finding => ` <div class="finding-item ${finding.severity}"> <div class="finding-header"> <span class="finding-type">${escapeHtml(finding.type || 'Unknown')}</span> <span class="finding-severity ${finding.severity}">${finding.severity || 'info'}</span> </div> <div class="finding-url">${escapeHtml(finding.target || 'N/A')}</div> <div class="finding-description">${escapeHtml(finding.description || 'No description')}</div> ${finding.score ? `<div style="margin-top: 5px; font-size: 0.8rem; color: #999;">Score: ${finding.score}/10</div>` : ''} </div> `).join(''); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Load data on page load loadData(); // Auto-refresh every 30 seconds setInterval(loadData, 30000); </script> </body> </html>

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/telmon95/VulneraMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server