questdb-mcp

brunoprela/questdb-mcp

3.2

If you are the rightful owner of questdb-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The QuestDB MCP Server is a Model Context Protocol server designed to facilitate interaction between AI assistants and QuestDB databases, enabling efficient querying and data insertion.

Tools
4
Resources
0
Prompts
0

QuestDB MCP Server

A Model Context Protocol (MCP) server for QuestDB that enables AI assistants to interact with QuestDB databases through tools for querying and inserting data.

Features

  • Query Execution: Execute SELECT queries on QuestDB tables with structured output
  • Data Insertion: Insert data into QuestDB tables using the InfluxDB Line Protocol
  • Table Management: List tables and describe table schemas
  • Automatic Schema Creation: Tables and columns are created automatically on insert
  • Type Safety: Full TypeScript support with Zod schema validation
  • Structured Output: All tools return structured content with output schemas
  • MCP Logging: Integrated MCP logging messages for better observability
  • Error Handling: Comprehensive error handling with graceful degradation
  • Server Instructions: Built-in server instructions for AI assistants
  • Graceful Shutdown: Proper cleanup on SIGINT/SIGTERM signals

Prerequisites

Installation

As a Package

Install from npm:

npm install questdb-mcp

Note: This package is publicly available on npm. No authentication or configuration is required to install or use it.

From Source

  1. Clone this repository or navigate to the project directory:

    cd questdb-mcp
    
  2. Install dependencies:

    npm install
    
  3. Build the project:

    npm run build
    

Configuration

The server can be configured using environment variables:

  • QUESTDB_HOST - QuestDB host (default: localhost)
  • QUESTDB_PORT - QuestDB port (default: 9000)
  • QUESTDB_USERNAME - QuestDB username (optional, for authentication)
  • QUESTDB_PASSWORD - QuestDB password (optional, for authentication)
  • QUESTDB_AUTO_FLUSH_ROWS - Auto-flush after N rows (optional)
  • QUESTDB_AUTO_FLUSH_INTERVAL - Auto-flush interval in milliseconds (optional)

Usage

This package can be used in two ways:

1. CLI Usage

Run the MCP server directly:

npm start

Or for development:

npm run dev

Or install globally:

npm install -g questdb-mcp
questdb-mcp

2. Library Usage

Install as a dependency in your TypeScript project:

npm install questdb-mcp
Basic Usage
import { QuestDBMCPServer, loadConfig } from 'questdb-mcp';

// Load configuration from environment variables
const config = loadConfig();

// Create server instance
const server = new QuestDBMCPServer(config);

// Start the server
await server.run();
Custom Configuration
import { QuestDBMCPServer, QuestDBConfig } from 'questdb-mcp';

const config: QuestDBConfig = {
  host: 'localhost',
  port: 9000,
  username: 'admin',
  password: 'quest',
};

const server = new QuestDBMCPServer(config, {
  setupProcessHandlers: false, // Don't set up process handlers when using as library
  serverName: 'my-questdb-server',
  serverVersion: '1.0.0',
  instructions: 'Custom server instructions...',
});

await server.run();
Using with Custom Transport
import { QuestDBMCPServer, QuestDBConfig } from 'questdb-mcp';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';

const config: QuestDBConfig = {
  host: 'localhost',
  port: 9000,
};

const server = new QuestDBMCPServer(config, {
  setupProcessHandlers: false,
});

const app = express();
app.use(express.json());

app.post('/mcp', async (req, res) => {
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined,
    enableJsonResponse: true,
  });

  res.on('close', () => {
    transport.close();
  });

  await server.server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

app.listen(3000, () => {
  console.log('MCP server running on http://localhost:3000/mcp');
});
Accessing Internal Components
import { QuestDBMCPServer } from 'questdb-mcp';

const server = new QuestDBMCPServer(config);

// Access the underlying MCP server
const mcpServer = server.server;

// Access the QuestDB client
const client = server.questDBClient;

// Access the logger
const logger = server.log;

// Use the client directly
const tables = await client.listTables();
const result = await client.query('SELECT * FROM my_table LIMIT 10');

// Use the logger
await logger.info('Custom log message', { metadata: 'value' });
Creating Custom Tools
import { QuestDBMCPServer, QuestDBConfig } from 'questdb-mcp';
import { z } from 'zod';

const config: QuestDBConfig = {
  host: 'localhost',
  port: 9000,
};

const server = new QuestDBMCPServer(config, {
  setupProcessHandlers: false,
});

// Access the underlying MCP server to register custom tools
server.server.registerTool(
  'my-custom-tool',
  {
    title: 'My Custom Tool',
    description: 'A custom tool that uses QuestDB',
    inputSchema: {
      param: z.string().describe('A parameter'),
    },
  },
  async ({ param }) => {
    // Use the QuestDB client
    const client = server.questDBClient;
    const result = await client.query(`SELECT * FROM my_table WHERE col = '${param}'`);
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(result, null, 2),
        },
      ],
    };
  }
);

await server.run();
Shutdown
// Gracefully shutdown the server
await server.shutdown();
TypeScript Types

All types are exported and available for use:

import type {
  QuestDBConfig,
  QueryResult,
  QuestDBMCPServerOptions,
} from 'questdb-mcp';

Available Tools

1. query

Execute a SQL SELECT query on QuestDB.

Parameters:

  • query (string, required): The SQL query to execute (SELECT queries only)
  • format (string, optional): Output format - json or csv (default: json)

Example:

{
  "query": "SELECT * FROM trades LIMIT 10",
  "format": "json"
}
2. insert

Insert data into a QuestDB table. Tables and columns are created automatically if they don't exist.

Parameters:

  • table (string, required): The name of the table to insert into
  • data (object, required): An object containing the data to insert
    • Keys are column names
    • Values are the data (strings, numbers, booleans)
    • Use timestamp key for explicit timestamp (milliseconds since epoch)
    • If timestamp is not provided, the current time is used

Example:

{
  "table": "trades",
  "data": {
    "symbol": "ETH-USD",
    "side": "sell",
    "price": 2615.54,
    "amount": 0.00044,
    "timestamp": 1699123456789
  }
}
3. list_tables

List all tables in the QuestDB database.

Parameters: None

4. describe_table

Get the schema of a specific table.

Parameters:

  • table (string, required): The name of the table to describe

Example:

{
  "table": "trades"
}

QuestDB Setup

Quick Start with Docker

docker run \
  -p 9000:9000 -p 9009:9009 -p 8812:8812 -p 9003:9003 \
  questdb/questdb:9.1.1

Quick Start with Homebrew (macOS)

brew install questdb

The QuestDB Web Console will be available at: http://localhost:9000

Development

Building

npm run build

Type Checking

npm run typecheck

Development Mode

npm run dev

Data Types

The insert tool automatically maps JavaScript types to QuestDB types:

  • StringSYMBOL (indexed string type)
  • Number (integer)LONG
  • Number (float)DOUBLE
  • BooleanBOOLEAN
  • TimestampTIMESTAMP (when using the timestamp field)

Security Notes

  • Only SELECT queries are allowed through the query tool for safety
  • The server uses the QuestDB REST API for queries and the InfluxDB Line Protocol for inserts
  • Authentication is supported via username/password if your QuestDB instance requires it

Examples

Inserting Trade Data

{
  "tool": "insert",
  "arguments": {
    "table": "trades",
    "data": {
      "symbol": "BTC-USD",
      "side": "buy",
      "price": 39269.98,
      "amount": 0.001
    }
  }
}

Querying Data

{
  "tool": "query",
  "arguments": {
    "query": "SELECT symbol, price, amount FROM trades WHERE symbol = 'BTC-USD' ORDER BY timestamp DESC LIMIT 10"
  }
}

Listing Tables

{
  "tool": "list_tables",
  "arguments": {}
}

License

MIT

Resources