Skip to main content
Glama
index.ts18.5 kB
// Vercel API route handler // Note: @vercel/node types are provided by Vercel runtime interface VercelRequest { method?: string url?: string body?: any headers?: Record<string, string> } interface VercelResponse { statusCode?: number setHeader(name: string, value: string): void status(code: number): VercelResponse json(data: any): void send(data: any): void end(data?: any): void } export default async function handler(req: VercelRequest, res: VercelResponse) { // Set CORS headers and optimization headers res.setHeader('Access-Control-Allow-Origin', '*') res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization') res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') res.setHeader('Connection', 'keep-alive') // Handle preflight requests if (req.method === 'OPTIONS') { res.status(200).end() return } // Simple health check for ChatGPT Connector (fastest possible response) if (url === '/health' || url === '/ping') { res.setHeader('Content-Type', 'application/json') res.status(200).json({ status: 'ok', timestamp: Date.now() }) return } try { // Route handling // Landing page if (url === '/') { const html = ` <!DOCTYPE html> <html> <head> <title>🚀 AURA MCP Server</title> <meta charset="utf-8"> <style> body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2563eb; } .endpoint { background: #f8fafc; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #2563eb; } code { background: #e2e8f0; padding: 2px 6px; border-radius: 3px; } </style> </head> <body> <div class="container"> <h1>🚀 AURA MCP Server</h1> <p>Bridge LLMs with AURA API and EVM for on-chain intelligence</p> <div class="endpoint"> <h3>📡 Health Check</h3> <p><code>GET /api/health</code> - Check server status</p> </div> <div class="endpoint"> <h3>💰 Portfolio Analysis</h3> <p><code>POST /api/portfolio/balance</code> - Get wallet balance and positions</p> </div> <div class="endpoint"> <h3>🎯 Strategy Proposals</h3> <p><code>POST /api/strategy/propose</code> - Generate AI-powered trading strategies</p> </div> <div class="endpoint"> <h3>🔄 Transaction Simulation</h3> <p><code>POST /api/transaction/simulate</code> - Simulate transactions safely</p> </div> <div class="endpoint"> <h3>🛡️ Guard Management</h3> <p><code>POST /api/guard/setRules</code> - Configure risk management rules</p> </div> <div class="endpoint"> <h3>⚙️ System Health</h3> <p><code>GET /api/system/health</code> - Check system status and services</p> </div> <p><strong>Status:</strong> ✅ Server is running and ready to handle requests!</p> </div> </body> </html> ` res.setHeader('Content-Type', 'text/html') res.status(200).send(html) return } // Health check endpoint if (url === '/api/health') { const response = { success: true, data: { status: 'healthy', timestamp: new Date().toISOString(), version: '1.0.0', uptime: process.uptime(), environment: 'vercel' } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // System health endpoint if (url === '/api/system/health') { const response = { success: true, data: { status: 'operational', services: { auraApi: 'connected', guardEngine: 'active', emergencyStop: false }, timestamp: new Date().toISOString(), environment: 'vercel' } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // Portfolio balance endpoint if (url === '/api/portfolio/balance' && req.method === 'POST') { const { address } = req.body if (!address) { res.status(400).json({ success: false, error: { code: 'MISSING_ADDRESS', message: 'Address is required' } }) return } // Mock response for now (you can integrate with AURA API later) const response = { success: true, data: { address, totalValueUsd: 4897.50, positions: [ { token: 'ETH', balance: '1.234', valueUsd: 2456.75, chain: 'ethereum' }, { token: 'USDC', balance: '2440.75', valueUsd: 2440.75, chain: 'ethereum' } ], chains: ['ethereum', 'base', 'arbitrum'], lastUpdated: new Date().toISOString() } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // Strategy proposal endpoint if (url === '/api/strategy/propose' && req.method === 'POST') { const { intent, params, address } = req.body if (!intent || !address) { res.status(400).json({ success: false, error: { code: 'MISSING_PARAMS', message: 'Intent and address are required' } }) return } // Mock response for now const response = { success: true, data: { intent, strategy: { type: intent, params, recommendations: [ 'Consider DCA approach for volatile assets', 'Set stop-loss at 10% drawdown', 'Monitor gas prices before execution' ], riskScore: 7.5, expectedReturn: '12-15% annually' }, address, timestamp: new Date().toISOString() } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // Transaction simulation endpoint if (url === '/api/transaction/simulate' && req.method === 'POST') { const { intentId, txParams } = req.body if (!intentId || !txParams) { res.status(400).json({ success: false, error: { code: 'MISSING_PARAMS', message: 'IntentId and txParams are required' } }) return } // Mock response for now const response = { success: true, data: { intentId, simulation: { gasUsed: '21000', gasPrice: '20000000000', costUsd: 10.50, slippagePct: 0.5, success: true }, guards: { passed: true, triggeredGuards: [], warnings: [] }, timestamp: new Date().toISOString() } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // Guard rules endpoint if (url === '/api/guard/setRules' && req.method === 'POST') { const { rules } = req.body if (!rules) { res.status(400).json({ success: false, error: { code: 'MISSING_RULES', message: 'Rules are required' } }) return } // Mock response for now const response = { success: true, data: { success: true, rulesSet: Object.keys(rules).length, timestamp: new Date().toISOString() } } res.setHeader('Content-Type', 'application/json') res.status(200).json(response) return } // MCP Protocol endpoint for ChatGPT Connector - SSE compatible if (url === '/mcp' || url === '/mcp/') { // Set SSE headers for long-lived connection res.setHeader('Content-Type', 'text/event-stream') res.setHeader('Cache-Control', 'no-cache') res.setHeader('Connection', 'keep-alive') res.setHeader('Access-Control-Allow-Origin', '*') res.setHeader('Access-Control-Allow-Headers', '*') if (req.method === 'GET') { // Send SSE stream for MCP protocol res.status(200) // Send initial MCP handshake res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: { tools: {}, resources: {} }, serverInfo: { name: "aura-mcp-server", version: "1.0.0" } } })}\n\n`) // Keep connection alive const keepAlive = setInterval(() => { res.write(`data: ${JSON.stringify({ type: 'ping', timestamp: Date.now() })}\n\n`) }, 30000) // Clean up on connection close req.on('close', () => { clearInterval(keepAlive) }) return } if (req.method === 'POST') { // Handle MCP JSON-RPC requests with SSE const body = req.body || {} res.status(200) if (body.method === 'initialize') { res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", id: body.id, result: { protocolVersion: "2024-11-05", capabilities: { tools: {}, resources: {} }, serverInfo: { name: "aura-mcp-server", version: "1.0.0" } } })}\n\n`) } else if (body.method === 'tools/list') { res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", id: body.id, result: { tools: [ { name: "get_portfolio_balance", description: "Analyze wallet portfolio balance and positions across multiple chains", inputSchema: { type: "object", properties: { address: { type: "string", description: "Ethereum wallet address to analyze" } }, required: ["address"] } }, { name: "propose_strategy", description: "Generate AI-powered trading strategy recommendations", inputSchema: { type: "object", properties: { intent: { type: "string", description: "Strategy type" }, address: { type: "string", description: "Wallet address for strategy" } }, required: ["intent", "address"] } } ] } })}\n\n`) } else { res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", id: body.id, error: { code: -32601, message: "Method not found" } })}\n\n`) } // Keep connection alive const keepAlive = setInterval(() => { res.write(`data: ${JSON.stringify({ type: 'ping', timestamp: Date.now() })}\n\n`) }, 30000) req.on('close', () => { clearInterval(keepAlive) }) return } } // ChatGPT Connector specific endpoint if (url === '/chatgpt/mcp') { const chatgptResponse = { name: "aura-mcp-server", version: "1.0.0", protocol: "mcp", capabilities: { tools: true, resources: true }, endpoints: { initialize: "/mcp", tools: "/mcp/tools" }, status: "ready", timestamp: new Date().toISOString() } res.setHeader('Content-Type', 'application/json') res.status(200).json(chatgptResponse) return } // Alternative MCP endpoint for ChatGPT Connector if (url === '/mcp/info') { const infoResponse = { protocol: "mcp", version: "2024-11-05", name: "aura-mcp-server", capabilities: ["tools", "resources"], status: "ready" } res.setHeader('Content-Type', 'application/json') res.status(200).json(infoResponse) return } // MCP Tools list endpoint if (url === '/mcp/tools') { const toolsResponse = { jsonrpc: "2.0", id: 1, result: { tools: [ { name: "get_portfolio_balance", description: "Analyze wallet portfolio balance and positions across multiple chains", inputSchema: { type: "object", properties: { address: { type: "string", description: "Ethereum wallet address to analyze" }, chain: { type: "string", description: "Blockchain network (ethereum, base, arbitrum)", default: "ethereum" } }, required: ["address"] } }, { name: "propose_strategy", description: "Generate AI-powered trading strategy recommendations", inputSchema: { type: "object", properties: { intent: { type: "string", description: "Strategy type (dca_event_aware, liquidation_guard, basket_rotation)", enum: ["dca_event_aware", "liquidation_guard", "basket_rotation"] }, params: { type: "object", description: "Strategy parameters" }, address: { type: "string", description: "Wallet address for strategy" } }, required: ["intent", "address"] } } ] } } res.setHeader('Content-Type', 'application/json') res.status(200).json(toolsResponse) return } // ChatGPT/OpenAI compatible endpoints if (url === '/openai/functions') { const functions = { functions: [ { name: "get_portfolio_balance", description: "Analyze wallet portfolio balance and positions across multiple chains", parameters: { type: "object", properties: { address: { type: "string", description: "Ethereum wallet address to analyze" }, chain: { type: "string", description: "Blockchain network (ethereum, base, arbitrum)", default: "ethereum" } }, required: ["address"] } }, { name: "propose_strategy", description: "Generate AI-powered trading strategy recommendations", parameters: { type: "object", properties: { intent: { type: "string", description: "Strategy type (dca_event_aware, liquidation_guard, basket_rotation)", enum: ["dca_event_aware", "liquidation_guard", "basket_rotation"] }, params: { type: "object", description: "Strategy parameters" }, address: { type: "string", description: "Wallet address for strategy" } }, required: ["intent", "address"] } }, { name: "simulate_transaction", description: "Simulate transaction with risk assessment", parameters: { type: "object", properties: { intentId: { type: "string", description: "Transaction intent ID" }, txParams: { type: "object", description: "Transaction parameters" } }, required: ["intentId", "txParams"] } }, { name: "set_guard_rules", description: "Configure risk management guard rules", parameters: { type: "object", properties: { rules: { type: "object", description: "Guard rules configuration" } }, required: ["rules"] } } ] } res.setHeader('Content-Type', 'application/json') res.status(200).json(functions) return } // 404 for unknown routes res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: `Route ${url} not found` } }) } catch (error) { console.error('Handler error:', error) res.status(500).json({ success: false, error: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Internal server error' } }) } }

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/antidumpalways/MCP'

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