Skip to main content
Glama

MCP Firebird

// simple-proxy-cjs.js // Proxy simple para manejar conexiones SSE con el servidor MCP Firebird const express = require('express'); const cors = require('cors'); const http = require('http'); const https = require('https'); const url = require('url'); // Configuración const PORT = process.env.PORT || 3005; const MCP_SERVER_URL = process.env.MCP_SERVER_URL || 'http://localhost:3003'; // Crear la aplicación Express const app = express(); // Habilitar CORS app.use(cors()); // Parsear JSON app.use(express.json()); // Almacenar las sesiones activas const sessions = new Map(); // Endpoint SSE app.get('/', async (req, res) => { try { console.log('Nueva conexión SSE recibida'); // Configurar la respuesta para SSE res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache, no-transform'); res.setHeader('Connection', 'keep-alive'); res.flushHeaders(); // Establecer una conexión SSE con el servidor MCP para obtener un ID de sesión válido let mcpSessionId = null; try { // Conectar al servidor MCP como cliente SSE console.log('Estableciendo conexión SSE con el servidor MCP para obtener un ID de sesión válido...'); // Hacer una solicitud GET al servidor MCP const mcpResponse = await new Promise((resolve, reject) => { const parsedUrl = new URL(MCP_SERVER_URL); const requestOptions = { hostname: parsedUrl.hostname, port: parsedUrl.port, path: parsedUrl.pathname, method: 'GET', headers: { 'Accept': 'text/event-stream' } }; const request = http.request(requestOptions, (response) => { if (response.statusCode !== 200) { reject(new Error(`Error al conectar con el servidor MCP: ${response.statusCode} ${response.statusMessage}`)); return; } let buffer = ''; let sessionIdFound = false; response.on('data', (chunk) => { buffer += chunk.toString(); console.log(`Recibido del servidor MCP: ${chunk.toString()}`); // Buscar el evento endpoint en el buffer const endpointMatch = buffer.match(/event: endpoint\ndata: ([^\n]+)/); if (endpointMatch && !sessionIdFound) { const endpointUrl = endpointMatch[1]; console.log(`Evento endpoint recibido: ${endpointUrl}`); try { // Extraer el ID de sesión de la URL del endpoint const url = new URL(endpointUrl, MCP_SERVER_URL); const sessionId = url.searchParams.get('sessionId'); console.log(`ID de sesión MCP: ${sessionId}`); // Resolver la promesa con el ID de sesión sessionIdFound = true; resolve({ sessionId, response }); } catch (error) { reject(error); } } }); response.on('error', (error) => { reject(error); }); // Establecer un timeout setTimeout(() => { if (!sessionIdFound) { reject(new Error('Tiempo de espera agotado esperando el evento endpoint')); response.destroy(); } }, 5000); }); request.on('error', (error) => { reject(error); }); request.end(); }); mcpSessionId = mcpResponse.sessionId; console.log(`Conexión SSE establecida con el servidor MCP, ID de sesión: ${mcpSessionId}`); // Mantener la conexión con el servidor MCP abierta const mcpStream = mcpResponse.response; // Reenviar los eventos del servidor MCP al cliente mcpStream.on('data', (chunk) => { console.log(`Recibido del servidor MCP: ${chunk.toString()}`); }); // Manejar errores en la conexión con el servidor MCP mcpStream.on('error', (error) => { console.error(`Error en la conexión con el servidor MCP: ${error.message}`); }); // Manejar el cierre de la conexión con el servidor MCP mcpStream.on('end', () => { console.log('Conexión con el servidor MCP cerrada'); }); } catch (error) { console.error(`Error al obtener un ID de sesión válido: ${error.message}`); throw error; } // Generar un ID de cliente único const clientId = `client-${Date.now()}-${Math.random().toString(36).substring(2, 10)}`; // Almacenar la sesión del cliente sessions.set(clientId, { res, createdAt: new Date(), lastActivity: new Date(), mcpSessionId: mcpSessionId }); console.log(`ID de sesión MCP: ${mcpSessionId}`); // Enviar el evento endpoint al cliente const endpointUrl = `/message?sessionId=${clientId}`; res.write(`event: endpoint\ndata: ${endpointUrl}\n\n`); console.log(`Sesión creada para el cliente ${clientId} con ID de sesión MCP ${mcpSessionId}`); // Manejar la desconexión del cliente req.on('close', () => { console.log(`Cliente desconectado: ${clientId}`); // Eliminar la sesión sessions.delete(clientId); }); // Mantener la conexión viva enviando un comentario cada 30 segundos const keepAliveInterval = setInterval(() => { if (res.writableEnded) { clearInterval(keepAliveInterval); return; } res.write(': keepalive\n\n'); }, 30000); } catch (error) { console.error(`Error al establecer la conexión SSE: ${error.message}`); // Solo enviar una respuesta si los encabezados no se han enviado aún if (!res.headersSent) { res.status(500).send({ error: 'Error al establecer la conexión SSE', message: error.message }); } } }); // Endpoint para mensajes app.post('/message', async (req, res) => { try { // Obtener el ID de cliente del parámetro de consulta const clientId = req.query.sessionId?.toString(); if (!clientId) { throw new Error('Se requiere un ID de cliente'); } console.log(`Mensaje recibido del cliente: ${clientId}`); // Obtener la sesión const session = sessions.get(clientId); if (!session) { throw new Error(`No se encontró una sesión activa para el ID: ${clientId}`); } // Actualizar la última actividad session.lastActivity = new Date(); // Obtener el ID de sesión del servidor MCP const mcpSessionId = session.mcpSessionId; if (!mcpSessionId) { throw new Error('No hay un ID de sesión MCP disponible'); } console.log(`Reenviando mensaje al servidor MCP para la sesión: ${mcpSessionId}`); console.log(`URL: ${MCP_SERVER_URL}/message?sessionId=${mcpSessionId}`); console.log(`Cuerpo: ${JSON.stringify(req.body)}`); // Reenviar la solicitud al servidor MCP usando http.request const parsedUrl = new URL(`${MCP_SERVER_URL}/message?sessionId=${mcpSessionId}`); const requestOptions = { hostname: parsedUrl.hostname, port: parsedUrl.port, path: parsedUrl.pathname + parsedUrl.search, method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Session-ID': mcpSessionId } }; console.log(`Reenviando solicitud a: ${parsedUrl.href}`); // Crear una promesa para manejar la solicitud const httpRequest = new Promise((resolve, reject) => { const request = http.request(requestOptions, (response) => { let responseData = ''; response.on('data', (chunk) => { responseData += chunk; }); response.on('end', () => { resolve({ status: response.statusCode, headers: response.headers, data: responseData }); }); }); request.on('error', (error) => { reject(error); }); // Enviar el cuerpo de la solicitud request.write(JSON.stringify(req.body)); request.end(); }); try { // Esperar la respuesta const mcpResponse = await httpRequest; console.log(`Respuesta del servidor MCP: ${mcpResponse.status}`); // Obtener la respuesta del servidor MCP const mcpResponseText = mcpResponse.data; // Intentar parsear la respuesta como JSON let mcpResponseJson; try { mcpResponseJson = JSON.parse(mcpResponseText); console.log(`Respuesta JSON: ${JSON.stringify(mcpResponseJson)}`); } catch (error) { console.error(`Error al parsear la respuesta del servidor MCP: ${error.message}`); console.error(`Respuesta del servidor MCP: ${mcpResponseText}`); // Enviar la respuesta como texto res.status(mcpResponse.status).send(mcpResponseText); return; } // Enviar la respuesta al cliente res.status(mcpResponse.status).json(mcpResponseJson); } catch (error) { console.error(`Error al reenviar la solicitud al servidor MCP: ${error.message}`); // Enviar una respuesta de error al cliente res.status(500).json({ jsonrpc: '2.0', id: req.body?.id, error: { code: -32603, message: 'Error al comunicarse con el servidor MCP: ' + error.message } }); } } catch (error) { console.error(`Error al procesar el mensaje: ${error.message}`); // Enviar una respuesta de error res.status(500).json({ jsonrpc: '2.0', id: req.body?.id, error: { code: -32603, message: error.message || 'Error interno del servidor' } }); } }); // Iniciar el servidor app.listen(PORT, () => { console.log(`Proxy SSE para MCP Firebird escuchando en el puerto ${PORT}`); console.log(`Redirigiendo solicitudes a ${MCP_SERVER_URL}`); });

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/PuroDelphi/mcpFirebird'

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