Skip to main content
Glama

QuestDB MCP Server

by brunoprela
server.ts5.7 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { QuestDBConfig } from "./types.js"; import { QuestDBClient } from "./questdb-client.js"; import { Logger } from "./logger.js"; import { registerTools } from "./tools/index.js"; /** * Options for QuestDBMCPServer */ export interface QuestDBMCPServerOptions { /** * Whether to set up process signal handlers (SIGINT, SIGTERM, etc.) * Defaults to true. Set to false when using as a library. */ setupProcessHandlers?: boolean; /** * Custom server name * Defaults to "questdb-mcp" */ serverName?: string; /** * Custom server version * Defaults to "1.0.0" */ serverVersion?: string; /** * Custom server instructions * If not provided, uses default instructions */ instructions?: string; } /** * Main MCP server class that orchestrates the QuestDB MCP server */ export class QuestDBMCPServer { private mcpServer: McpServer; private client: QuestDBClient; private logger: Logger; private config: QuestDBConfig; private transport: StdioServerTransport | null = null; private setupProcessHandlers: boolean; constructor(config: QuestDBConfig, options: QuestDBMCPServerOptions = {}) { this.config = config; this.setupProcessHandlers = options.setupProcessHandlers ?? true; const serverName = options.serverName || "questdb-mcp"; const serverVersion = options.serverVersion || "1.0.0"; const instructions = options.instructions || `QuestDB MCP Server provides tools to interact with QuestDB time-series database. Available tools: - query: Execute SELECT queries on QuestDB tables - insert: Insert data into QuestDB tables using InfluxDB Line Protocol - list_tables: List all tables in the database - describe_table: Get the schema of a specific table The server automatically creates tables and columns when inserting data. All queries are read-only (SELECT only) for safety.`; this.mcpServer = new McpServer( { name: serverName, version: serverVersion, }, { capabilities: { tools: {}, resources: {}, }, instructions, } ); this.logger = new Logger(this.mcpServer); this.client = new QuestDBClient(config, this.logger); this.setupTools(); if (this.setupProcessHandlers) { this.setupErrorHandling(); } } /** * Register all tools with the MCP server */ private setupTools(): void { registerTools(this.mcpServer, this.client, this.logger); } /** * Setup error handling for the server */ private setupErrorHandling(): void { // Handle server-level errors this.mcpServer.server.onerror = (error) => { console.error("[MCP Server Error]", error); }; // Handle transport errors process.on("SIGINT", async () => { await this.shutdown(); }); process.on("SIGTERM", async () => { await this.shutdown(); }); // Handle uncaught errors process.on("uncaughtException", async (error) => { console.error("[Uncaught Exception]", error); await this.shutdown(); process.exit(1); }); process.on("unhandledRejection", async (reason, promise) => { console.error("[Unhandled Rejection]", reason, "at", promise); }); } /** * Shutdown the server and cleanup resources */ async shutdown(): Promise<void> { try { // Log shutdown (may fail if server disconnected, that's OK) this.logger.info("Shutting down QuestDB MCP server").catch(() => { // Ignore logging errors during shutdown }); await this.client.close(); if (this.transport && this.mcpServer.isConnected()) { await this.mcpServer.close(); } } catch (error) { console.error("Error during shutdown:", error); } } /** * Get the underlying MCP server instance * Useful for advanced use cases */ get server(): McpServer { return this.mcpServer; } /** * Get the QuestDB client instance * Useful for custom tool implementations */ get questDBClient(): QuestDBClient { return this.client; } /** * Get the logger instance * Useful for custom tool implementations */ get log(): Logger { return this.logger; } /** * Start the MCP server */ async run(): Promise<void> { try { this.transport = new StdioServerTransport(); // Handle transport errors this.transport.onerror = (error) => { console.error("[Transport Error]", error); }; this.transport.onclose = () => { console.error("Transport closed"); }; await this.mcpServer.connect(this.transport); await this.logger.info("QuestDB MCP server started", { host: this.config.host, port: this.config.port, }); console.error("QuestDB MCP server running on stdio"); } catch (error) { console.error("Failed to start server:", error); process.exit(1); } } }

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/brunoprela/questdb-mcp'

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