Skip to main content
Glama

RAGmonsters Custom PostgreSQL MCP Server

index.js6.44 kB
import express from 'express'; import path from 'path'; import { fileURLToPath } from 'url'; import dotenv from 'dotenv'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { initializeDbPool, createMCPServer } from './mcp-server/index.js'; import { createAgent, processMessage, getSystemMessage, formatResponse } from './llm.js'; import logger from './mcp-server/utils/logger.js'; // Load environment variables dotenv.config(); // Constants const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const PORT = process.env.PORT || 8080; /** * Create an MCP client that connects to the server * @param {Object} server - The MCP server instance * @returns {Promise<Client>} The MCP client */ async function createMCPClient(server) { console.log('Creating STDIO transport to communicate with the MCP server'); // Create a transport that communicates with the server via STDIO const transport = new StdioClientTransport({ command: "node", args: ["./src/mcp-server/index.js"], debug: process.env.NODE_ENV !== 'production' // Enable debug mode in development }); // Create the MCP client with a reasonable timeout console.log('Creating MCP client'); const client = new Client({ name: "RAGmonsters-mcp-pg-client", version: "1.0.0", timeout: 10000 // 10 second timeout }); await client.connect(transport); console.log("MCP client connected to server"); return client; } /** * Initialize the application */ async function initializeApp() { // Initialize database pool for the web application const dbPool = initializeDbPool(); // Create and start the MCP server const mcpServer = createMCPServer(dbPool); mcpServer.start({ transportType: "stdio", }); console.log('MCP server started with STDIO transport'); // Create an MCP client to communicate with the server const mcpClient = await createMCPClient(mcpServer); // List available tools try { const tools = await mcpClient.listTools(); console.log(`Available MCP tools: ${tools.tools.map(t => t.name).join(', ')}`); } catch (error) { console.error('Error listing MCP tools:', error); } // Create Express application const app = express(); // Middleware app.use(express.json()); app.use(express.static(path.join(__dirname, 'public'))); // Health check endpoint app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // MCP tools API endpoint app.get('/api/tools', async (req, res) => { try { const tools = await mcpClient.listTools(); res.json(tools); } catch (error) { console.error('Error listing MCP tools:', error); res.status(500).json({ error: 'Failed to list MCP tools' }); } }); // MCP tool execution endpoint app.post('/api/tools/:toolName', async (req, res) => { const { toolName } = req.params; const args = req.body; try { const result = await mcpClient.callTool({ name: toolName, arguments: args }); res.json(result); } catch (error) { console.error(`Error calling MCP tool ${toolName}:`, error); res.status(500).json({ error: `Failed to call MCP tool: ${error.message}` }); } }); // Initialize the LangChain agent with MCP tools let agent = null; // Chat endpoint for LLM interaction app.post('/api/chat', async (req, res) => { const { message, conversationId } = req.body; if (!message) { return res.status(400).json({ error: 'Message is required' }); } try { // Get conversation history from session or create new one let conversation = {}; if (conversationId && app.locals.conversations && app.locals.conversations[conversationId]) { conversation = app.locals.conversations[conversationId]; } else { // Initialize conversation storage if it doesn't exist if (!app.locals.conversations) { app.locals.conversations = {}; } // Create a new conversation with system message const newConversationId = Date.now().toString(); app.locals.conversations[newConversationId] = { id: newConversationId, messages: [ getSystemMessage() ] }; conversation = app.locals.conversations[newConversationId]; } // Create the agent if it doesn't exist if (!agent) { console.log('Creating LangChain agent with MCP tools'); const tools = await mcpClient.listTools(); agent = await createAgent(mcpClient); } // Process the message with LangChain agent console.log('Processing message with LangChain agent'); const response = await processMessage(message, agent, conversation.messages); // Add all new messages to conversation history // Skip the first message which is the user message we already have const newMessages = response.allMessages.slice(conversation.messages.length); conversation.messages = [...conversation.messages, ...newMessages]; // Format the response for the client const formattedResponse = formatResponse(response); // Return the response to the client return res.json({ conversationId: conversation.id, message: formattedResponse }); } catch (error) { console.error('Error processing chat message:', error); res.status(500).json({ error: `Failed to process message: ${error.message}` }); } }); // Start Express server const server = app.listen(PORT, () => { console.log(`Web server listening on port ${PORT}`); console.log(`Visit http://localhost:${PORT} to access the application`); console.log(`API available at http://localhost:${PORT}/api/tools`); console.log(`Chat API available at http://localhost:${PORT}/api/chat`); }); // Return the initialized components return { app, server, dbPool, mcpClient, mcpServer }; } // Start the application when this file is run directly if (import.meta.url === `file://${process.argv[1]}`) { initializeApp().catch(error => { console.error('Failed to initialize application:', error); process.exit(1); }); } export default initializeApp;

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/LostInBrittany/RAGmonsters-mcp-pg'

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