Skip to main content
Glama

MCP Ethereum Address Info Server

by doronaviguy
sse-demo.html13.6 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>MCP SSE Demo</title> <style> body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; line-height: 1.6; } h1, h2, h3 { color: #333; } .container { display: flex; gap: 20px; } .panel { flex: 1; border: 1px solid #ddd; border-radius: 5px; padding: 15px; background-color: #f9f9f9; } .events { height: 400px; overflow-y: auto; background-color: #f5f5f5; border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin-top: 10px; font-family: monospace; } .event { margin-bottom: 10px; padding: 8px; border-radius: 4px; } .event-connection { background-color: #d4edda; border: 1px solid #c3e6cb; } .event-heartbeat { background-color: #f8f9fa; border: 1px solid #e9ecef; } .event-tool-call { background-color: #cce5ff; border: 1px solid #b8daff; } .event-address-update { background-color: #fff3cd; border: 1px solid #ffeeba; } .event-subscription-update { background-color: #d1ecf1; border: 1px solid #bee5eb; } button { background-color: #4CAF50; color: white; border: none; padding: 10px 15px; text-align: center; text-decoration: none; display: inline-block; font-size: 14px; margin: 4px 2px; cursor: pointer; border-radius: 4px; } button:hover { background-color: #45a049; } button:disabled { background-color: #cccccc; cursor: not-allowed; } input[type="text"] { width: 100%; padding: 8px; margin: 5px 0 15px 0; display: inline-block; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .status { font-weight: bold; margin-bottom: 10px; } .connected { color: green; } .disconnected { color: red; } </style> </head> <body> <h1>MCP Server-Sent Events (SSE) Demo</h1> <p>This page demonstrates how to use the SSE endpoint of the MCP server to receive real-time updates.</p> <div class="container"> <div class="panel"> <h2>Connection</h2> <div class="status disconnected" id="connection-status">Disconnected</div> <button id="connect-btn">Connect to SSE</button> <button id="disconnect-btn" disabled>Disconnect</button> <h3>Client Information</h3> <div id="client-info">Not connected</div> <h2>Address Subscription</h2> <label for="address-input">Ethereum Address:</label> <input type="text" id="address-input" placeholder="0x742d35Cc6634C0532925a3b844Bc454e4438f44e" value="0x742d35Cc6634C0532925a3b844Bc454e4438f44e"> <button id="subscribe-btn" disabled>Subscribe</button> <button id="unsubscribe-btn" disabled>Unsubscribe</button> <h3>Subscribed Addresses</h3> <div id="subscribed-addresses">None</div> <h2>Tools</h2> <button id="get-address-info-btn" disabled>Call get-address-info</button> <button id="ping-btn" disabled>Call ping</button> </div> <div class="panel"> <h2>Events</h2> <button id="clear-events-btn">Clear Events</button> <div class="events" id="events-container"></div> </div> </div> <script> // DOM Elements const connectBtn = document.getElementById('connect-btn'); const disconnectBtn = document.getElementById('disconnect-btn'); const subscribeBtn = document.getElementById('subscribe-btn'); const unsubscribeBtn = document.getElementById('unsubscribe-btn'); const getAddressInfoBtn = document.getElementById('get-address-info-btn'); const pingBtn = document.getElementById('ping-btn'); const clearEventsBtn = document.getElementById('clear-events-btn'); const eventsContainer = document.getElementById('events-container'); const connectionStatus = document.getElementById('connection-status'); const clientInfo = document.getElementById('client-info'); const subscribedAddresses = document.getElementById('subscribed-addresses'); const addressInput = document.getElementById('address-input'); // State let eventSource = null; let clientId = null; let subscribedAddressList = []; // Functions function addEvent(event) { const eventData = JSON.parse(event.data); const eventType = eventData.type; const eventElement = document.createElement('div'); eventElement.className = `event event-${eventType}`; const timestamp = new Date(eventData.timestamp).toLocaleTimeString(); const header = document.createElement('div'); header.innerHTML = `<strong>${eventType}</strong> (${timestamp})`; eventElement.appendChild(header); const content = document.createElement('pre'); content.textContent = JSON.stringify(eventData, null, 2); eventElement.appendChild(content); eventsContainer.appendChild(eventElement); eventsContainer.scrollTop = eventsContainer.scrollHeight; // Handle specific event types if (eventType === 'connection') { clientId = eventData.clientId; clientInfo.innerHTML = `Client ID: ${clientId}<br>Connected at: ${timestamp}`; } else if (eventType === 'subscription-update') { subscribedAddressList = eventData.subscribedAddresses; updateSubscribedAddresses(); } } function updateSubscribedAddresses() { if (subscribedAddressList.length === 0) { subscribedAddresses.textContent = 'None'; } else { subscribedAddresses.innerHTML = subscribedAddressList.map(addr => `<div>${addr}</div>` ).join(''); } } function connectSSE() { if (eventSource) { eventSource.close(); } eventSource = new EventSource('http://localhost:3002/sse'); eventSource.onopen = () => { connectionStatus.textContent = 'Connected'; connectionStatus.className = 'status connected'; connectBtn.disabled = true; disconnectBtn.disabled = false; subscribeBtn.disabled = false; unsubscribeBtn.disabled = false; getAddressInfoBtn.disabled = false; pingBtn.disabled = false; }; eventSource.onmessage = (event) => { addEvent(event); }; eventSource.onerror = () => { disconnectSSE(); connectionStatus.textContent = 'Connection failed. Retry?'; connectionStatus.className = 'status disconnected'; }; } function disconnectSSE() { if (eventSource) { eventSource.close(); eventSource = null; } connectionStatus.textContent = 'Disconnected'; connectionStatus.className = 'status disconnected'; connectBtn.disabled = false; disconnectBtn.disabled = true; subscribeBtn.disabled = true; unsubscribeBtn.disabled = true; getAddressInfoBtn.disabled = true; pingBtn.disabled = true; clientId = null; clientInfo.textContent = 'Not connected'; } function subscribeToAddress() { const address = addressInput.value.trim(); if (!address || !address.match(/^0x[a-fA-F0-9]{40}$/)) { alert('Please enter a valid Ethereum address'); return; } if (!clientId) { alert('Not connected to SSE. Please connect first.'); return; } fetch(`http://localhost:3002/sse/subscribe/${clientId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ addresses: [address] }) }) .then(response => response.json()) .then(data => { console.log('Subscription response:', data); }) .catch(error => { console.error('Error subscribing to address:', error); alert('Error subscribing to address. See console for details.'); }); } function unsubscribeFromAddress() { const address = addressInput.value.trim(); if (!address) { alert('Please enter an address to unsubscribe from'); return; } if (!clientId) { alert('Not connected to SSE. Please connect first.'); return; } fetch(`http://localhost:3002/sse/unsubscribe/${clientId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ addresses: [address] }) }) .then(response => response.json()) .then(data => { console.log('Unsubscription response:', data); }) .catch(error => { console.error('Error unsubscribing from address:', error); alert('Error unsubscribing from address. See console for details.'); }); } function callGetAddressInfo() { const address = addressInput.value.trim(); if (!address || !address.match(/^0x[a-fA-F0-9]{40}$/)) { alert('Please enter a valid Ethereum address'); return; } fetch('http://localhost:3002/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'get-address-info', arguments: { address: address } } }) }) .then(response => response.json()) .then(data => { console.log('get-address-info response:', data); }) .catch(error => { console.error('Error calling get-address-info:', error); alert('Error calling get-address-info. See console for details.'); }); } function callPing() { fetch('http://localhost:3002/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'ping', arguments: {} } }) }) .then(response => response.json()) .then(data => { console.log('ping response:', data); }) .catch(error => { console.error('Error calling ping:', error); alert('Error calling ping. See console for details.'); }); } function clearEvents() { eventsContainer.innerHTML = ''; } // Event Listeners connectBtn.addEventListener('click', connectSSE); disconnectBtn.addEventListener('click', disconnectSSE); subscribeBtn.addEventListener('click', subscribeToAddress); unsubscribeBtn.addEventListener('click', unsubscribeFromAddress); getAddressInfoBtn.addEventListener('click', callGetAddressInfo); pingBtn.addEventListener('click', callPing); clearEventsBtn.addEventListener('click', clearEvents); </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/doronaviguy/mpc-0x'

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