Skip to main content
Glama

Financial Data MCP Server

by j1c4b
financial_mcp_interface.html19.9 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Financial MCP Server Interface</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: rgba(255, 255, 255, 0.95); border-radius: 20px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); backdrop-filter: blur(10px); overflow: hidden; } .header { background: linear-gradient(135deg, #2c3e50, #3498db); color: white; padding: 30px; text-align: center; } .header h1 { font-size: 2.5rem; margin-bottom: 10px; font-weight: 300; } .header p { opacity: 0.9; font-size: 1.1rem; } .main-content { padding: 30px; } .controls { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-bottom: 30px; } .control-group { background: #f8f9fa; padding: 25px; border-radius: 15px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); transition: transform 0.3s ease, box-shadow 0.3s ease; } .control-group:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12); } .control-group h3 { color: #2c3e50; margin-bottom: 15px; font-size: 1.3rem; font-weight: 600; } .input-group { margin-bottom: 15px; } .input-group label { display: block; margin-bottom: 5px; color: #555; font-weight: 500; } .input-group input, .input-group select { width: 100%; padding: 12px; border: 2px solid #e1e5e9; border-radius: 8px; font-size: 1rem; transition: border-color 0.3s ease; } .input-group input:focus, .input-group select:focus { outline: none; border-color: #3498db; } .btn { background: linear-gradient(135deg, #3498db, #2980b9); color: white; border: none; padding: 12px 25px; border-radius: 8px; cursor: pointer; font-size: 1rem; font-weight: 500; transition: all 0.3s ease; width: 100%; margin-top: 10px; } .btn:hover { background: linear-gradient(135deg, #2980b9, #3498db); transform: translateY(-1px); box-shadow: 0 5px 15px rgba(52, 152, 219, 0.3); } .btn:active { transform: translateY(0); } .btn.secondary { background: linear-gradient(135deg, #95a5a6, #7f8c8d); } .btn.secondary:hover { background: linear-gradient(135deg, #7f8c8d, #95a5a6); } .quick-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; } .quick-btn { background: rgba(52, 152, 219, 0.1); color: #3498db; border: 2px solid #3498db; padding: 8px 16px; border-radius: 20px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease; } .quick-btn:hover { background: #3498db; color: white; } .results { background: #f8f9fa; border-radius: 15px; padding: 25px; margin-top: 20px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); } .results h3 { color: #2c3e50; margin-bottom: 15px; font-size: 1.4rem; } .results-content { background: white; padding: 20px; border-radius: 10px; border-left: 4px solid #3498db; font-family: 'Courier New', monospace; white-space: pre-wrap; max-height: 400px; overflow-y: auto; line-height: 1.4; } .loading { display: none; text-align: center; padding: 20px; } .loading::after { content: ''; display: inline-block; width: 20px; height: 20px; border: 3px solid #f3f3f3; border-top: 3px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .error { background: #e74c3c; color: white; padding: 15px; border-radius: 8px; margin: 10px 0; } .success { background: #27ae60; color: white; padding: 15px; border-radius: 8px; margin: 10px 0; } .status-bar { background: #2c3e50; color: white; padding: 10px 30px; font-size: 0.9rem; display: flex; justify-content: space-between; align-items: center; } .status-indicator { display: flex; align-items: center; gap: 8px; } .status-dot { width: 8px; height: 8px; border-radius: 50%; background: #27ae60; animation: pulse 2s infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } @media (max-width: 768px) { .container { margin: 10px; border-radius: 15px; } .controls { grid-template-columns: 1fr; } .header h1 { font-size: 2rem; } .quick-actions { justify-content: center; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>📈 Financial MCP Server</h1> <p>Real-time Financial Data Analysis Interface</p> </div> <div class="status-bar"> <div class="status-indicator"> <div class="status-dot"></div> <span>Server Status: Connected</span> </div> <div> <span id="serverUrl">http://localhost:3001</span> </div> </div> <div class="main-content"> <!-- Quick Actions --> <div class="quick-actions"> <button class="quick-btn" onclick="getMarketOverview()">📊 Market Overview</button> <button class="quick-btn" onclick="getEarningsCalendar()">📅 Earnings Calendar</button> <button class="quick-btn" onclick="getAnalystChanges()">🔍 Analyst Changes</button> <button class="quick-btn" onclick="loadPortfolio()">💼 Load Portfolio</button> <button class="quick-btn" onclick="testConnection()">🔧 Test Connection</button> </div> <div class="controls"> <!-- Stock Analysis --> <div class="control-group"> <h3>🔍 Stock Analysis</h3> <div class="input-group"> <label for="stockSymbol">Stock Symbol:</label> <input type="text" id="stockSymbol" placeholder="e.g., AAPL, GOOGL, MSFT" value="AAPL"> </div> <button class="btn" onclick="analyzeStock()">Get Stock Info</button> <button class="btn secondary" onclick="generateChart()">Generate MACD Chart</button> </div> <!-- Portfolio Management --> <div class="control-group"> <h3>💼 Portfolio Management</h3> <div class="input-group"> <label for="portfolioName">Portfolio Name:</label> <input type="text" id="portfolioName" placeholder="e.g., tech_stocks, dividend_portfolio"> </div> <div class="input-group"> <label for="performancePeriod">Performance Period:</label> <select id="performancePeriod"> <option value="1d">1 Day</option> <option value="5d">5 Days</option> <option value="1mo" selected>1 Month</option> <option value="3mo">3 Months</option> <option value="6mo">6 Months</option> <option value="1y">1 Year</option> </select> </div> <button class="btn" onclick="analyzePortfolio()">Analyze Portfolio</button> <button class="btn secondary" onclick="getPortfolioPerformance()">Get Performance</button> </div> <!-- Market Research --> <div class="control-group"> <h3>📈 Market Research</h3> <div class="input-group"> <label for="daysAhead">Earnings Days Ahead:</label> <select id="daysAhead"> <option value="3">3 Days</option> <option value="7" selected>7 Days</option> <option value="14">14 Days</option> <option value="30">30 Days</option> </select> </div> <div class="input-group"> <label for="daysBack">Analyst Changes Days Back:</label> <select id="daysBack"> <option value="3">3 Days</option> <option value="7" selected>7 Days</option> <option value="14">14 Days</option> <option value="30">30 Days</option> </select> </div> <button class="btn" onclick="getEarningsCalendar()">Get Earnings</button> <button class="btn secondary" onclick="getAnalystChanges()">Get Analyst Changes</button> </div> </div> <!-- Results Section --> <div class="results"> <h3>📊 Results</h3> <div class="loading" id="loading">Loading...</div> <div class="results-content" id="results"> Ready to analyze financial data! 🚀 Your MCP server is running and ready to provide real-time financial data. Click any button above to get started. ✅ Market Overview - Get current market indices ✅ Stock Analysis - Analyze individual stocks ✅ Portfolio Management - Track your investments ✅ Earnings Calendar - Upcoming earnings announcements ✅ Analyst Research - Recent analyst changes Server: http://localhost:3001 Status: Connected and Ready </div> </div> </div> </div> <script> // Configuration const MCP_SERVER_URL = 'http://localhost:3001'; // Update the server URL display document.getElementById('serverUrl').textContent = MCP_SERVER_URL; // Utility functions function showLoading() { document.getElementById('loading').style.display = 'block'; document.getElementById('results').style.opacity = '0.5'; } function hideLoading() { document.getElementById('loading').style.display = 'none'; document.getElementById('results').style.opacity = '1'; } function displayResults(data, title = 'Results') { hideLoading(); const resultsDiv = document.getElementById('results'); // Format the data nicely let formattedData; if (data.content && data.content[0] && data.content[0].text) { // Extract the actual data from MCP response format try { const parsedData = JSON.parse(data.content[0].text); formattedData = JSON.stringify(parsedData, null, 2); } catch (e) { formattedData = data.content[0].text; } } else { formattedData = JSON.stringify(data, null, 2); } resultsDiv.innerHTML = `<strong>✅ ${title}</strong>\n\n${formattedData}`; } function displayError(error) { hideLoading(); const resultsDiv = document.getElementById('results'); resultsDiv.innerHTML = `<div class="error">❌ Error: ${error.message || error}</div>`; } // API calls async function callMCPServer(tool, parameters = {}) { try { showLoading(); const response = await fetch(`${MCP_SERVER_URL}/tools/${tool}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(parameters) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { throw error; } } // Test connection async function testConnection() { try { showLoading(); const response = await fetch(`${MCP_SERVER_URL}/health`); const data = await response.json(); displayResults(data, '🔧 Connection Test'); } catch (error) { displayError(error); } } // Main functions async function getMarketOverview() { try { const data = await callMCPServer('get_market_overview'); displayResults(data, '📊 Market Overview'); } catch (error) { displayError(error); } } async function analyzeStock() { const symbol = document.getElementById('stockSymbol').value; if (!symbol) { displayError(new Error('Please enter a stock symbol')); return; } try { const data = await callMCPServer('get_stock_info', { symbol: symbol.toUpperCase() }); displayResults(data, `🔍 Analysis for ${symbol.toUpperCase()}`); } catch (error) { displayError(error); } } async function generateChart() { const symbol = document.getElementById('stockSymbol').value; if (!symbol) { displayError(new Error('Please enter a stock symbol')); return; } try { const data = await callMCPServer('generate_macd_chart', { symbol: symbol.toUpperCase(), period: '6mo' }); displayResults(data, `📈 MACD Chart for ${symbol.toUpperCase()}`); } catch (error) { displayError(error); } } async function loadPortfolio() { try { const data = await callMCPServer('load_portfolio'); displayResults(data, '💼 Portfolio Data'); } catch (error) { displayError(error); } } async function analyzePortfolio() { const portfolioName = document.getElementById('portfolioName').value; if (!portfolioName) { displayError(new Error('Please enter a portfolio name')); return; } try { const data = await callMCPServer('analyze_portfolio', { portfolio_name: portfolioName }); displayResults(data, `💼 Analysis for ${portfolioName}`); } catch (error) { displayError(error); } } async function getPortfolioPerformance() { const portfolioName = document.getElementById('portfolioName').value; const period = document.getElementById('performancePeriod').value; try { const parameters = { period }; if (portfolioName) { parameters.portfolio_name = portfolioName; } const data = await callMCPServer('portfolio_performance', parameters); displayResults(data, `📊 Portfolio Performance (${period})`); } catch (error) { displayError(error); } } async function getEarningsCalendar() { const daysAhead = document.getElementById('daysAhead').value; try { const data = await callMCPServer('get_earnings_calendar', { days_ahead: parseInt(daysAhead) }); displayResults(data, `📅 Upcoming Earnings (${daysAhead} days)`); } catch (error) { displayError(error); } } async function getAnalystChanges() { const daysBack = document.getElementById('daysBack').value; const symbol = document.getElementById('stockSymbol').value; try { const parameters = { days_back: parseInt(daysBack) }; if (symbol) { parameters.symbol = symbol.toUpperCase(); } const data = await callMCPServer('get_analyst_changes', parameters); displayResults(data, `🔍 Analyst Changes (${daysBack} days back)`); } catch (error) { displayError(error); } } // Initialize document.addEventListener('DOMContentLoaded', function() { // Add enter key support document.getElementById('stockSymbol').addEventListener('keypress', function(e) { if (e.key === 'Enter') { analyzeStock(); } }); document.getElementById('portfolioName').addEventListener('keypress', function(e) { if (e.key === 'Enter') { analyzePortfolio(); } }); console.log('🚀 Financial MCP Interface loaded successfully!'); console.log(`📡 Server: ${MCP_SERVER_URL}`); // Test connection on load setTimeout(testConnection, 1000); }); </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/j1c4b/finance_mcp_server'

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