Skip to main content
Glama

CTS MCP Server

by EricA1019
hop_dashboard_output.htmlโ€ข11.1 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hop Dashboard - CTS Compliance Tracker</title> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1e1e1e; color: #d4d4d4; padding: 20px; } .hop-dashboard { max-width: 1400px; margin: 0 auto; } .dashboard-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; background: #252526; border-radius: 8px; border: 1px solid #007acc; margin-bottom: 20px; } .dashboard-header h1 { margin: 0; color: #007acc; font-size: 24px; } .filter-controls { display: flex; gap: 10px; align-items: center; } .filter-controls label { font-size: 14px; color: #858585; } .filter-controls select { background: #1e1e1e; color: #d4d4d4; border: 1px solid #007acc; padding: 8px 12px; border-radius: 4px; font-size: 14px; cursor: pointer; } .stats-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 20px; } .stat-card { background: #252526; padding: 20px; border-radius: 8px; border-left: 4px solid #007acc; } .stat-label { font-size: 12px; color: #858585; margin-bottom: 8px; } .stat-value { font-size: 28px; font-weight: bold; color: #d4d4d4; } .stat-card.compliance .stat-value { color: #16825d; } .stat-card.completion .stat-value { color: #007acc; } .hop-list { display: grid; gap: 15px; } .hop-card { background: #252526; border-radius: 8px; padding: 20px; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; border-left: 4px solid #858585; } .hop-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } .hop-card.planned { border-left-color: #ffa500; } .hop-card.in_progress { border-left-color: #007acc; } .hop-card.completed { border-left-color: #16825d; } .hop-card.violation { border-left-color: #f48771; background: #2d2020; } .hop-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; } .hop-title { display: flex; align-items: center; gap: 10px; } .hop-status-icon { font-size: 20px; } .hop-title h3 { margin: 0; font-size: 18px; color: #d4d4d4; } .hop-meta { text-align: right; } .hop-loc { font-size: 14px; font-weight: bold; } .hop-loc.compliant { color: #16825d; } .hop-loc.violation { color: #f48771; } .hop-description { color: #858585; font-size: 14px; margin-bottom: 12px; line-height: 1.5; } .hop-details { display: flex; gap: 20px; font-size: 12px; color: #858585; } .hop-detail-item { display: flex; align-items: center; gap: 5px; } .phase-label { display: inline-block; background: #007acc; color: #fff; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: bold; } .empty-state { text-align: center; padding: 60px 20px; color: #858585; } .empty-state h3 { margin-bottom: 10px; color: #d4d4d4; } </style> </head> <body> <div id="root"></div> <script type="text/babel"> const { useState } = React; const HopDashboard = ({ data }) => { const [statusFilter, setStatusFilter] = useState('all'); // Flatten all hops from all phases const allHops = data.phases.flatMap(phase => phase.hops.map(hop => ({ ...hop, phase: phase.name })) ); // Filter hops by status const filteredHops = statusFilter === 'all' ? allHops : allHops.filter(hop => hop.status === statusFilter); const handleHopClick = (hop) => { if (window.parent !== window) { window.parent.postMessage({ type: 'artifact_interaction', action: 'hop_details', payload: { hopId: hop.id, name: hop.name } }, '*'); } console.log('[Hop Dashboard] Hop clicked:', hop.id); }; const getStatusIcon = (status) => { switch (status) { case 'completed': return 'โœ…'; case 'in_progress': return '๐Ÿ”„'; case 'planned': return 'โณ'; default: return 'โ“'; } }; return ( <div className="hop-dashboard"> <div className="dashboard-header"> <h1>๐Ÿ“Š Hop Dashboard - {data.currentPhase}</h1> <div className="filter-controls"> <label htmlFor="status-filter">Filter by Status:</label> <select id="status-filter" value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} > <option value="all">All ({allHops.length})</option> <option value="completed">Completed ({allHops.filter(h => h.status === 'completed').length})</option> <option value="in_progress">In Progress ({allHops.filter(h => h.status === 'in_progress').length})</option> <option value="planned">Planned ({allHops.filter(h => h.status === 'planned').length})</option> </select> </div> </div> <div className="stats-panel"> <div className="stat-card"> <div className="stat-label">Total LOC</div> <div className="stat-value">{data.stats.totalLOC.toLocaleString()}</div> <div className="stat-label">of {data.stats.plannedLOC.toLocaleString()} planned</div> </div> <div className="stat-card compliance"> <div className="stat-label">CTS Compliance</div> <div className="stat-value">{data.stats.ctsComplianceRate}%</div> <div className="stat-label">{allHops.filter(h => h.ctsCompliant).length}/{allHops.length} hops</div> </div> <div className="stat-card completion"> <div className="stat-label">Completion Rate</div> <div className="stat-value">{data.stats.completionRate}%</div> <div className="stat-label">{allHops.filter(h => h.status === 'completed').length}/{allHops.length} completed</div> </div> </div> <div className="hop-list"> {filteredHops.length === 0 ? ( <div className="empty-state"> <h3>No hops match the current filter</h3> <p>Try selecting a different status filter</p> </div> ) : ( filteredHops.map(hop => ( <div key={hop.id} className={`hop-card ${hop.status} ${hop.ctsCompliant ? '' : 'violation'}`} onClick={() => handleHopClick(hop)} > <div className="hop-header"> <div className="hop-title"> <span className="hop-status-icon">{getStatusIcon(hop.status)}</span> <h3>{hop.id}: {hop.name}</h3> </div> <div className="hop-meta"> <div className={`hop-loc ${hop.ctsCompliant ? 'compliant' : 'violation'}`}> {hop.actualLOC || 0}/{hop.estimatedLOC} LOC {hop.ctsCompliant ? ' โœ…' : ' โŒ'} </div> </div> </div> <div className="hop-description"> {hop.description} </div> <div className="hop-details"> <span className="phase-label">{hop.phase}</span> <div className="hop-detail-item"> <span>๐Ÿ“ฆ Dependencies:</span> {hop.dependencies.length} </div> {hop.tests && ( <div className="hop-detail-item"> <span>๐Ÿงช Tests:</span> {hop.tests.passing}/{hop.tests.total} ({hop.tests.coverage}%) </div> )} </div> </div> )) )} </div> </div> ); }; // Data passed from server const dashboardData = {"currentPhase":"Phase CTS_MCP_1","phases":[{"name":"Phase 1: Foundation","hops":[{"id":"5.1a","name":"Core MCP Server & Shrimp Integration","status":"completed","description":"MCP server boilerplate with stdio transport and automated Shrimp task creation","estimatedLOC":400,"actualLOC":395,"ctsCompliant":true,"phase":"Phase 1","dependencies":[],"tests":{"total":15,"passing":15,"coverage":85}},{"id":"5.1b","name":"Signal Map & Hop Dashboard","status":"in_progress","description":"D3.js force-directed graph for signals and React dashboard for hops","estimatedLOC":350,"actualLOC":320,"ctsCompliant":true,"phase":"Phase 1","dependencies":["5.1a"],"tests":{"total":20,"passing":18,"coverage":75}}]},{"name":"Phase 2: Advanced Features","hops":[{"id":"5.2a","name":"Dependency Graph Renderer","status":"planned","description":"Visualize hop dependencies and critical path","estimatedLOC":250,"actualLOC":0,"ctsCompliant":true,"phase":"Phase 2","dependencies":["5.1b"]},{"id":"5.2b","name":"Performance Charts","status":"planned","description":"Track LOC growth, test coverage trends over time","estimatedLOC":300,"actualLOC":0,"ctsCompliant":true,"phase":"Phase 2","dependencies":["5.1b"]}]}],"stats":{"totalLOC":715,"plannedLOC":1300,"ctsComplianceRate":100,"completionRate":50}}; // Render React component const root = ReactDOM.createRoot(document.getElementById('root')); root.render(React.createElement(HopDashboard, { data: dashboardData })); // Send ready message console.log('[Hop Dashboard] React renderer loaded'); console.log('[Hop Dashboard] Data:', dashboardData); if (window.parent !== window) { window.parent.postMessage({ type: 'artifact_ready', artifactType: 'hop_dashboard' }, '*'); } </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/EricA1019/CTS_MCP'

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