UNPKG

celp-mcp

Version:

MCP Server providing database schema and indexes

138 lines (137 loc) 5.42 kB
"use strict"; // Example client for using the streaming endpoint from another TypeScript project // This can be used as a reference for how to connect to the streaming API Object.defineProperty(exports, "__esModule", { value: true }); exports.StreamingDatabaseClient = void 0; /** * Client class for interacting with the streaming database query endpoint */ class StreamingDatabaseClient { baseUrl; apiKey; /** * Create a new client instance * @param baseUrl Base URL of the API server (e.g., 'http://localhost:3000') * @param apiKey API key for authentication */ constructor(baseUrl, apiKey) { this.baseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; this.apiKey = apiKey; } /** * Query the database with streaming results * @param prompt User prompt/question to analyze * @param databaseConnection Database connection details * @param callbacks Callbacks for handling streaming events * @returns A promise that resolves when the stream ends */ async queryDatabase(prompt, databaseConnection, callbacks) { try { // Prepare the EventSource URL const url = `${this.baseUrl}/api/streaming/query-database`; // Make the POST request to initialize the streaming connection const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ prompt, databaseConnection, apiKey: this.apiKey, }), }); // Check if the response is OK if (!response.ok) { const errorText = await response.text(); throw new Error(`Failed to initialize streaming: ${response.status} ${errorText}`); } // Handle the stream (SSE) from the response const reader = response.body?.getReader(); if (!reader) { throw new Error('Response body is not readable'); } // Process the stream const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; // Convert chunk to text and add to buffer buffer += decoder.decode(value, { stream: true }); // Process complete SSE messages const lines = buffer.split('\n\n'); buffer = lines.pop() || ''; // Keep incomplete line in buffer for (const line of lines) { if (!line.trim() || !line.startsWith('data:')) continue; try { // Extract and parse the JSON data const data = JSON.parse(line.substring(5).trim()); // Handle different event types switch (data.type) { case 'FINAL_MARKDOWN_REPORT': callbacks.onFinalReport?.(data.data); break; case 'FINAL_MARKDOWN': callbacks.onFinalMarkdown?.(data.data); break; case 'ERROR': callbacks.onError?.(new Error(data.data)); break; case 'DONE': callbacks.onDone?.(); break; default: // Send progress updates callbacks.onProgress?.(data); } } catch (err) { console.error('Error parsing SSE message:', err, line); } } } } catch (error) { callbacks.onError?.(error instanceof Error ? error : new Error(String(error))); } } } exports.StreamingDatabaseClient = StreamingDatabaseClient; // Example usage async function exampleUsage() { // Create a client instance const client = new StreamingDatabaseClient('http://localhost:3000', 'your-api-key-here'); // Example database connection const dbConnection = { host: 'localhost', user: 'dbuser', password: 'dbpassword', database: 'mydb', databaseType: 'postgres', }; // Query with streaming results await client.queryDatabase('What are the top 10 customers by revenue?', dbConnection, { onProgress: (data) => { console.log('Progress:', data); }, onFinalReport: (report) => { console.log('Final Report:', report); }, onFinalMarkdown: (markdown) => { console.log('Final Markdown:', markdown); }, onError: (error) => { console.error('Error:', error); }, onDone: () => { console.log('Query completed'); }, }); } // Run the example if this file is executed directly if (require.main === module) { exampleUsage().catch(console.error); }