Skip to main content
Glama
auth-portal.html11 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Umbrella MCP Authentication Portal</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .container { background: white; border-radius: 20px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); max-width: 500px; width: 100%; padding: 40px; } h1 { color: #333; margin-bottom: 10px; font-size: 28px; } .subtitle { color: #666; margin-bottom: 30px; font-size: 14px; } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 8px; color: #555; font-weight: 500; } input { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; transition: border-color 0.3s; } input:focus { outline: none; border-color: #667eea; } button { width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: transform 0.2s; } button:hover { transform: translateY(-2px); } button:disabled { opacity: 0.5; cursor: not-allowed; } .error { background: #fee; color: #c33; padding: 12px; border-radius: 8px; margin-bottom: 20px; display: none; } .success { background: #e8f5e9; border: 2px solid #4caf50; padding: 20px; border-radius: 8px; margin-top: 20px; display: none; } .success h3 { color: #2e7d32; margin-bottom: 15px; } .config-box { background: #f5f5f5; padding: 15px; border-radius: 8px; margin: 15px 0; font-family: 'Courier New', monospace; font-size: 12px; white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; } .copy-btn { background: #4caf50; padding: 8px 16px; font-size: 14px; margin-top: 10px; } .instructions { color: #555; font-size: 14px; line-height: 1.6; } .instructions ol { margin-left: 20px; margin-top: 10px; } .session-info { background: #fff3cd; border: 1px solid #ffc107; padding: 10px; border-radius: 8px; margin-top: 15px; font-size: 14px; color: #856404; } .server-status { text-align: center; padding: 10px; background: #f0f0f0; border-radius: 8px; margin-bottom: 20px; font-size: 14px; } .status-online { color: #4caf50; } .status-offline { color: #f44336; } </style> </head> <body> <div class="container"> <div class="server-status" id="serverStatus"> Checking server status... </div> <h1>🔐 Umbrella MCP Portal</h1> <p class="subtitle">Authenticate to get your Claude Desktop configuration</p> <div class="error" id="error"></div> <form id="authForm"> <div class="form-group"> <label for="username">Email / Username</label> <input type="text" id="username" name="username" placeholder="your-email@domain.com" required > </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" name="password" placeholder="Your password" required > </div> <button type="submit" id="submitBtn">Authenticate</button> </form> <div class="success" id="success"> <h3>✅ Authentication Successful!</h3> <div class="instructions"> <strong>Your Session Token:</strong> <div class="config-box" id="sessionToken"></div> <button class="copy-btn" onclick="copyToken()">📋 Copy Token</button> </div> <div class="instructions" style="margin-top: 20px;"> <strong>Claude Desktop Configuration:</strong> <div class="config-box" id="claudeConfig"></div> <button class="copy-btn" onclick="copyConfig()">📋 Copy Configuration</button> </div> <div class="instructions" style="margin-top: 20px;"> <strong>How to use:</strong> <ol> <li>Copy the configuration above</li> <li>Open Claude Desktop Settings</li> <li>Go to Developer → Edit Config</li> <li>Add the configuration to your MCP servers</li> <li>Restart Claude Desktop</li> </ol> </div> <div class="session-info"> ⏱️ Session expires in 30 minutes of inactivity </div> </div> </div> <script> const SERVER_URL = 'http://localhost:3000'; let currentToken = ''; let currentConfig = ''; // Check server status async function checkServerStatus() { try { const response = await fetch(`${SERVER_URL}/health`); if (response.ok) { const data = await response.json(); document.getElementById('serverStatus').innerHTML = `<span class="status-online">✅ Server Online | ${data.activeSessions || 0} active sessions</span>`; } else { document.getElementById('serverStatus').innerHTML = `<span class="status-offline">❌ Server Offline</span>`; } } catch (error) { document.getElementById('serverStatus').innerHTML = `<span class="status-offline">❌ Cannot connect to server at ${SERVER_URL}</span>`; } } // Check status on load checkServerStatus(); setInterval(checkServerStatus, 10000); // Handle form submission document.getElementById('authForm').addEventListener('submit', async (e) => { e.preventDefault(); const username = document.getElementById('username').value; const password = document.getElementById('password').value; const submitBtn = document.getElementById('submitBtn'); const errorDiv = document.getElementById('error'); const successDiv = document.getElementById('success'); // Reset displays errorDiv.style.display = 'none'; successDiv.style.display = 'none'; // Disable button submitBtn.disabled = true; submitBtn.textContent = 'Authenticating...'; try { const response = await fetch(`${SERVER_URL}/auth`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); if (response.ok && data.success) { // Show success currentToken = data.sessionToken; currentConfig = JSON.stringify({ "mcpServers": { "umbrella-cost": { "command": "npx", "args": [ "mcp-remote", `${SERVER_URL}/sse?token=${data.sessionToken}` ] } } }, null, 2); document.getElementById('sessionToken').textContent = currentToken; document.getElementById('claudeConfig').textContent = currentConfig; successDiv.style.display = 'block'; // Clear form document.getElementById('authForm').reset(); } else { // Show error errorDiv.textContent = data.error || 'Authentication failed'; errorDiv.style.display = 'block'; } } catch (error) { errorDiv.textContent = `Connection error: ${error.message}`; errorDiv.style.display = 'block'; } finally { submitBtn.disabled = false; submitBtn.textContent = 'Authenticate'; } }); // Copy functions function copyToken() { navigator.clipboard.writeText(currentToken); alert('Session token copied to clipboard!'); } function copyConfig() { navigator.clipboard.writeText(currentConfig); alert('Configuration copied to clipboard!'); } </script> </body> </html>

Latest Blog Posts

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/daviddraiumbrella/invoice-monitoring'

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