UNPKG

sequelae-mcp

Version:

Let Claude, Cursor, and other AI agents run real SQL queries on live Postgres databases. No more copy-pasting SQL, stale schema docs, or hallucinated DB adapters — just raw, real-time access. Now with MCP support!

176 lines 6.6 kB
"use strict"; /** * MCP Tool Server for SQL Agent * This module handles tool discovery and registration for MCP protocol */ Object.defineProperty(exports, "__esModule", { value: true }); exports.McpToolHandler = exports.SQL_AGENT_TOOLS = exports.SqlAgentMcpServer = void 0; const tool_definition_1 = require("./tool-definition"); const tool_handler_1 = require("./tool-handler"); const rate_limiter_1 = require("../utils/rate-limiter"); class SqlAgentMcpServer { constructor(rateLimiterOptions) { this.handler = new tool_handler_1.McpToolHandler(); // Initialize rate limiter if options provided if (rateLimiterOptions) { this.rateLimiter = new rate_limiter_1.RateLimiter(rateLimiterOptions); // Clean up expired records every minute this.cleanupInterval = setInterval(() => { this.rateLimiter?.cleanup(); }, 60000); } } /** * Get server information */ getServerInfo() { return { name: 'sequelae-mcp', version: '1.0.0', description: 'PostgreSQL query executor for AI assistants', }; } /** * List available tools (for MCP discovery) */ listTools() { return { tools: tool_definition_1.SQL_AGENT_TOOLS.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema, })), }; } /** * Handle incoming MCP requests */ async handleRequest(request) { // Validate request structure if (!request || typeof request !== 'object') { return { error: { code: -32600, message: 'Invalid request', }, }; } const req = request; const method = req.method; const params = req.params; try { switch (method) { case 'initialize': return { serverInfo: this.getServerInfo(), capabilities: { tools: {}, }, }; case 'tools/list': return this.listTools(); case 'tools/call': if (!params || !params.name || !params.arguments) { throw new Error('Invalid tool call parameters'); } // Check rate limit if enabled if (this.rateLimiter) { // Use a connection identifier (could be enhanced with actual connection ID) const identifier = 'default'; // In real implementation, this would be from connection context const toolName = params.name; const limitCheck = this.rateLimiter.checkLimit(identifier, toolName); if (!limitCheck.allowed) { return { error: { code: -32000, message: 'Rate limit exceeded', data: { retryAfter: limitCheck.retryAfter, usage: this.rateLimiter.getUsage(identifier), }, }, }; } } return await this.handler.handleToolCall({ tool: params.name, arguments: params.arguments, }); default: return { error: { code: -32601, message: `Method not found: ${method}`, }, }; } } catch (error) { return { error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error', }, }; } } /** * Start the MCP server (stdio mode) */ async start() { process.stdin.setEncoding('utf8'); let buffer = ''; process.stdin.on('data', async (chunk) => { buffer += chunk; // Look for complete JSON-RPC messages const lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { const request = JSON.parse(line); const response = await this.handleRequest(request); // Add JSON-RPC fields const jsonRpcResponse = { jsonrpc: '2.0', id: request.id || null, ...response, }; process.stdout.write(JSON.stringify(jsonRpcResponse) + '\n'); } catch (_error) { const errorResponse = { jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error', }, }; process.stdout.write(JSON.stringify(errorResponse) + '\n'); } } } }); process.stdin.on('end', () => { this.close(); }); } /** * Close the server and cleanup */ async close() { // Clear rate limiter cleanup interval if (this.cleanupInterval) { clearInterval(this.cleanupInterval); } await this.handler.close(); } } exports.SqlAgentMcpServer = SqlAgentMcpServer; // Export everything needed for MCP var tool_definition_2 = require("./tool-definition"); Object.defineProperty(exports, "SQL_AGENT_TOOLS", { enumerable: true, get: function () { return tool_definition_2.SQL_AGENT_TOOLS; } }); var tool_handler_2 = require("./tool-handler"); Object.defineProperty(exports, "McpToolHandler", { enumerable: true, get: function () { return tool_handler_2.McpToolHandler; } }); //# sourceMappingURL=index.js.map