Skip to main content
Glama

AWS MCP Infrastructure

index.html•19.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>AWS Infrastructure Chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacMacSystemFont, 'Segoe UI', Roboto, sans-serif; /* Dark theme background */ background: linear-gradient(135deg, #121212 0%, #1a1a1a 100%); /* Darker gradient */ min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; color: #e0e0e0; /* Light text color for dark background */ } .container { width: 100%; max-width: 1200px; display: flex; gap: 20px; height: 80vh; } .chat-panel, .sidebar { flex: 1; background: #1e1e1e; /* Dark panel background */ border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); /* More prominent shadow for dark theme */ display: flex; flex-direction: column; overflow: hidden; border: 1px solid #333; /* Subtle border for definition */ } .sidebar { width: 300px; padding: 20px; overflow-y: auto; } .chat-header { background: linear-gradient(135deg, #3a005a 0%, #0a0a0a 100%); /* Darker, subtle gradient */ color: white; padding: 20px; text-align: center; } .chat-header h1 { font-size: 24px; font-weight: 600; display: flex; align-items: center; justify-content: center; gap: 10px; } .chat-messages { flex: 1; padding: 20px; overflow-y: auto; background: #242424; /* Slightly lighter dark background for messages */ } .message { margin-bottom: 20px; animation: fadeIn 0.3s ease-out; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .message.user { text-align: right; } .message.assistant { text-align: left; } .message-content { display: inline-block; padding: 12px 18px; border-radius: 18px; max-width: 70%; word-wrap: break-word; } .message.user .message-content { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); /* Keep user messages distinct */ color: white; } .message.assistant .message-content { background: #333333; /* Darker background for assistant messages */ color: #e0e0e0; /* Light text color */ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); /* Adjusted shadow for dark theme */ } .chat-input-container { padding: 20px; background: #1e1e1e; /* Match panel background */ border-top: 1px solid #333; /* Darker border */ } .chat-input-wrapper { display: flex; gap: 10px; } .chat-input { flex: 1; padding: 12px 20px; border: 2px solid #555; /* Darker border for input */ border-radius: 25px; font-size: 16px; outline: none; transition: border-color 0.3s; background: #2b2b2b; /* Dark input background */ color: #e0e0e0; /* Light text color */ } .chat-input:focus { border-color: #667eea; /* Highlight color remains */ } .send-button { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); /* Keep send button distinct */ color: white; border: none; padding: 12px 24px; border-radius: 25px; cursor: pointer; font-size: 16px; transition: transform 0.2s; } .send-button:hover { transform: scale(1.05); } .send-button:active { transform: scale(0.95); } .resource-card { background: #2b2b2b; /* Darker card background */ border-radius: 12px; padding: 15px; margin-bottom: 15px; border: 1px solid #444; /* Darker border for cards */ transition: all 0.3s; } .resource-card:hover { border-color: #667eea; box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2); /* Adjusted shadow for dark theme */ } .resource-type { font-weight: 600; color: #92b0ff; /* Lighter color for type in dark theme */ margin-bottom: 5px; } .resource-id { font-size: 14px; color: #c0c0c0; /* Lighter grey for IDs */ font-family: 'Courier New', monospace; } .resource-date { font-size: 12px; color: #888; /* Slightly darker grey for dates */ margin-top: 5px; } .delete-button { background: #a00000; /* Darker red for delete button */ color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 12px; cursor: pointer; margin-top: 10px; transition: background 0.2s; } .delete-button:hover { background: #c82333; /* Standard red on hover */ } .examples { margin-top: 30px; } .examples h3 { color: #e0e0e0; /* Light text for headings */ margin-bottom: 15px; font-size: 18px; } .example-item { background: #333333; /* Darker example item background */ padding: 10px 15px; border-radius: 8px; margin-bottom: 10px; cursor: pointer; transition: all 0.2s; font-size: 14px; color: #e0e0e0; /* Light text for example items */ } .example-item:hover { background: #444444; /* Slightly lighter on hover */ transform: translateX(5px); } .loading { display: inline-block; width: 20px; height: 20px; border: 3px solid #555; /* Darker loading spinner border */ border-top: 3px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite; margin-left: 10px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .error-message { background: #4a0000; /* Darker red background for errors */ color: #ffcccc; /* Lighter red text */ padding: 10px; border-radius: 8px; margin-top: 10px; font-size: 14px; } .success-message { background: #0a4a1a; /* Darker green background for success */ color: #ccffcc; /* Lighter green text */ padding: 10px; border-radius: 8px; margin-top: 10px; font-size: 14px; } .status-indicator { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 5px; } .status-indicator.online { background: #28a745; /* Keep online indicator visible */ animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(40, 167, 69, 0); } 100% { box-shadow: 0 0 0 0 rgba(40, 167, 69, 0); } } @media (max-width: 768px) { .container { flex-direction: column; height: 90vh; } .sidebar { width: 100%; height: 200px; } } </style> </head> <body> <div class="container"> <div class="chat-panel"> <div class="chat-header"> <h1> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M3 3h18v18H3zM12 8v8m-4-4h8"/> </svg> AWS Infrastructure Chat </h1> <p style="margin-top: 5px; opacity: 0.9; font-size: 14px;"> <span class="status-indicator online"></span> Deploy infrastructure with natural language </p> </div> <div class="chat-messages" id="chatMessages"> <div class="message assistant"> <div class="message-content"> Hello! šŸ‘‹ I'm your AWS infrastructure assistant. I can help you: <ul style="margin-top: 10px; margin-left: 20px;"> <li>Create EC2 instances</li> <li>Create S3 buckets</li> <li>Configure DynamoDB tables</li> <li>Deploy Lambda functions</li> <li>Create IAM roles</li> </ul> <br> Just tell me what you need, for example: "Create an S3 bucket named my-project" </div> </div> </div> <div class="chat-input-container"> <div class="chat-input-wrapper"> <input type="text" class="chat-input" id="chatInput" placeholder="Type your command here..." onkeypress="handleKeyPress(event)" > <button class="send-button" onclick="sendMessage()"> Send </button> </div> </div> </div> <div class="sidebar"> <h2 style="margin-bottom: 20px; color: #e0e0e0;">Deployed Resources</h2> <div id="resourcesList"> <p style="color: #999; text-align: center; padding: 20px;"> No resources deployed yet </p> </div> <div class="examples"> <h3>Quick examples:</h3> <div class="example-item" onclick="setExample('Create an S3 bucket for my application')"> šŸ’¾ Create S3 bucket </div> <div class="example-item" onclick="setExample('Deploy a t2.micro EC2 instance')"> šŸ–„ļø Create EC2 instance </div> <div class="example-item" onclick="setExample('Create a DynamoDB table for users')"> šŸ—„ļø Create DynamoDB table </div> <div class="example-item" onclick="setExample('Deploy a Lambda function')"> ⚔ Deploy Lambda function </div> <div class="example-item" onclick="setExample('Show all resources')"> šŸ“‹ List all resources </div> </div> </div> </div> <script> // API configuration const API_URL = window.location.origin + '/api'; // Application state let resources = []; let isProcessing = false; // Send message using chat endpoint async function sendMessage() { const input = document.getElementById('chatInput'); const message = input.value.trim(); if (!message || isProcessing) return; // Add user message addMessage(message, 'user'); input.value = ''; // Process command isProcessing = true; try { addMessage('Processing your request...', 'assistant'); const response = await fetch(`${API_URL}/chat/message`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message }) }); const data = await response.json(); // Remove processing message const messages = document.getElementById('chatMessages'); messages.removeChild(messages.lastChild); if (data.success) { if (data.intent === 'list') { displayResourcesList(data.data.resources); } else { const successMsg = data.intent === 'create' ? `āœ… Resource created successfully!\n\nType: ${data.resourceType}\nID: ${data.data.resourceId}` : `āœ… ${data.message}`; addMessage(successMsg, 'assistant', 'success'); } // Update resources list await updateResourcesList(); } else { addMessage(data.message || 'Could not process your request', 'assistant', data.intent === 'help' ? '' : 'error'); } } catch (error) { console.error('Error:', error); // Remove processing message if it exists const messages = document.getElementById('chatMessages'); if (messages.lastChild.textContent.includes('Processing')) { messages.removeChild(messages.lastChild); } addMessage(`āŒ Error: ${error.message}`, 'assistant', 'error'); } finally { isProcessing = false; } } // Display resources list in chat function displayResourcesList(resources) { if (resources.length > 0) { let message = 'šŸ“‹ Deployed Resources:\n\n'; resources.forEach(resource => { message += `• ${resource.type.toUpperCase()}: ${resource.id}\n`; if (resource.metadata?.awsResourceId) { message += ` AWS ID: ${resource.metadata.awsResourceId}\n`; } message += ` Created: ${new Date(resource.createdAt).toLocaleString()}\n\n`; }); addMessage(message, 'assistant'); } else { addMessage('No resources currently deployed.', 'assistant'); } } // Update resources list in sidebar async function updateResourcesList() { try { const response = await fetch(`${API_URL}/infrastructure/resources`); const data = await response.json(); const resourcesDiv = document.getElementById('resourcesList'); if (data.success && data.resources.length > 0) { resources = data.resources; resourcesDiv.innerHTML = resources.map(resource => ` <div class="resource-card"> <div class="resource-type">${resource.type.toUpperCase()}</div> <div class="resource-id">${resource.id}</div> ${resource.metadata?.awsResourceId ? `<div class="resource-id">AWS ID: ${resource.metadata.awsResourceId}</div>` : ''} <div class="resource-date">${new Date(resource.createdAt).toLocaleString()}</div> <button class="delete-button" onclick="deleteResource('${resource.id}', '${resource.type}')"> Delete </button> </div> `).join(''); } else { resourcesDiv.innerHTML = '<p style="color: #999; text-align: center; padding: 20px;">No resources deployed yet</p>'; } } catch (error) { console.error('Error updating resources:', error); } } // Delete resource async function deleteResource(resourceId, resourceType) { if (!confirm(`Are you sure you want to delete resource ${resourceId}?`)) { return; } const message = `Delete resource ${resourceId}`; // Add user message addMessage(message, 'user'); // Send delete command isProcessing = true; try { const response = await fetch(`${API_URL}/chat/message`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: `Delete resource ${resourceId}` }) }); const data = await response.json(); if (data.success) { addMessage('āœ… Resource deleted successfully', 'assistant', 'success'); await updateResourcesList(); } else { addMessage(`āŒ Error: ${data.message}`, 'assistant', 'error'); } } catch (error) { addMessage(`āŒ Error: ${error.message}`, 'assistant', 'error'); } finally { isProcessing = false; } } // Add message to chat function addMessage(content, sender, type = '') { const messagesDiv = document.getElementById('chatMessages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${sender}`; let messageContent = content; if (type === 'error') { messageContent = `<div class="error-message">${content}</div>`; } else if (type === 'success') { messageContent = `<div class="success-message">${content}</div>`; } messageDiv.innerHTML = ` <div class="message-content"> ${messageContent.replace(/\n/g, '<br>')} </div> `; messagesDiv.appendChild(messageDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; } // Handle Enter key function handleKeyPress(event) { if (event.key === 'Enter') { sendMessage(); } } // Set example function setExample(text) { document.getElementById('chatInput').value = text; document.getElementById('chatInput').focus(); } // Initialize window.onload = function() { updateResourcesList(); document.getElementById('chatInput').focus(); // Update resources every 30 seconds setInterval(updateResourcesList, 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/gesguerra-wzln/aws-mcp-infrastucture'

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