Skip to main content
Glama

QuestLLens

Dale ojos de IA a tus series temporales

El servidor MCP de QuestDB autodocumentado que convierte cualquier instancia de QuestDB en una fuente de conocimiento rica y consultable para agentes de IA, con conocimiento de primera clase de particiones, símbolos, claves de deduplicación, estado de WAL, salud de ingesta y disposición de almacenamiento.

MCP SDK QuestDB TypeScript Node.js Docker License

Primeros pasos · Herramientas · Configuración · Docker · Seguridad · Contexto de dominio


¿Por qué QuestLLens?

Los modelos de IA son potentes, pero son ciegos a tu base de datos de series temporales. No conocen tu timestamp designado, tu estrategia de particionado, la cardinalidad de tus símbolos ni qué tablas van con retraso en la aplicación de WAL.

QuestLLens lo soluciona. Conecta cualquier instancia de QuestDB a asistentes de IA mediante el Model Context Protocol (MCP), dándoles 18 herramientas diseñadas a medida para descubrir, comprender y consultar tus datos, de forma segura, en modo de solo lectura y con cero riesgo de escrituras accidentales.

Cómo se relaciona con el servidor MCP integrado de QuestDB

QuestDB incluye su propio servidor MCP en la Web Console, y para el trabajo interactivo en tu escritorio es la mejor herramienta: tiene cuadernos, gráficos, consulta de documentación de SQL/funciones y traspaso bidireccional con la consola que ya tienes abierta. Úsala para eso.

Resuelve un problema distinto al de esta herramienta:

QuestDB Web Console MCP

QuestLLens

Transporte

WebSocket, solo loopback

HTTP/SSE, accesible de forma remota

Necesita una sesión de navegador activa

Sí: el emparejamiento y el consentimiento ocurren en la consola

No

Acceso de escritura

: DDL/DML en el nivel de permiso de escritura

No: solo lectura aplicada en el proceso

Autenticación para clientes remotos

Sesión de consola / SSO empresarial

OAuth 2.1 + PKCE, o ninguno para uso local

Cuadernos, gráficos, consulta de documentación

No

Herramientas de partición, WAL, deduplicación, símbolos y salud de ingesta

No

Inyección de contexto de dominio en las descripciones de herramientas

No

Recurre a QuestLLens cuando el agente no esté en tu navegador: un asistente sin interfaz, un contenedor detrás de un túnel, un punto final compartido del equipo, o en cualquier lugar donde necesites una garantía estricta de solo lectura en lugar de una configuración de permisos.

Qué hace diferente a QuestLLens

  • Nativo de series temporales — A diferencia de los servidores MCP SQL genéricos, QuestLLens habla QuestDB. Los timestamps designados, las particiones de tiempo, la capacidad de símbolos, las claves de deduplicación y el estado de WAL son conceptos de primera clase sobre los que tu asistente de IA puede razonar.

  • Autodocumentado — Extrae automáticamente metadatos de tablas, tipos de columna, particiones, índices y definiciones de vistas materializadas. Tu asistente de IA entiende tu esquema como lo hace tu equipo.

  • Consciente del dominio — Inyecta un archivo markdown sencillo con contexto de negocio (qué significan las tablas, patrones comunes de SAMPLE BY, trampas) y QuestLLens lo integra en cada respuesta de herramienta.

  • No invasivo — Se conecta a cualquier instancia de QuestDB mediante el protocolo de cable estándar de PostgreSQL. Sin agentes, sin extensiones, sin cambios de configuración en QuestDB. Solo un usuario de solo lectura.

  • Seguridad ante todo — Defensa en profundidad: bloqueo de palabras clave SQL ajustado a toda la superficie DDL de QuestDB, tiempos de espera de sentencias, límites de filas y OAuth opcional con limitación de velocidad. Tus datos permanecen seguros.


Related MCP server: django-mcp-sql

Primeros pasos

Requisitos previos

  • Node.js 20+

  • QuestDB 7.4+ (cualquier instancia alojada o autogestionada: las tablas WAL se convirtieron en el valor predeterminado en 7.4)

  • Un usuario de QuestDB con privilegios SELECT (se recomienda solo lectura; consulta Seguridad)

Inicio rápido (npm)

# Clone and install
git clone https://github.com/DMDuFresne/questllens.git
cd questllens
npm install

# Configure
cp .env.example .env
cp context.md.example context.md
# Edit .env with your QUESTDB_URL

# Build and run
npm run build
npm start

QuestLLens ahora se ejecuta en http://localhost:3000 con el punto final MCP en /mcp.

Inicio rápido (Docker)

docker run -p 3000:3000 \
  -e QUESTDB_URL="postgresql://admin:quest@host:8812/qdb" \
  ghcr.io/dmdufresne/questllens:1.0.0

Conectar con Claude Desktop

Añade QuestLLens a tu configuración de Claude Desktop:

{
  "mcpServers": {
    "questllens": {
      "url": "http://localhost:3000/mcp"
    }
  }
}

Con OAuth habilitado:

{
  "mcpServers": {
    "questllens": {
      "url": "http://localhost:3000/mcp",
      "authorizationUrl": "http://localhost:3000/oauth/authorize",
      "tokenUrl": "http://localhost:3000/oauth/token",
      "registrationUrl": "http://localhost:3000/oauth/register"
    }
  }
}

Conectar con Claude Code

{
  "mcpServers": {
    "questllens": {
      "type": "url",
      "url": "http://localhost:3000/mcp"
    }
  }
}

Habilidades

skills/ incluye cuatro habilidades de Claude que enseñan a Claude a manejar QuestLLens en lugar de adivinar los nombres de las herramientas:

Habilidad

Úsala para

questllens-using

La habilidad de orientación: postura de solo lectura, los cuatro conceptos de series temporales que cambian cada consulta (timestamp designado, particiones, SYMBOL, WAL), flujo de trabajo de descubrimiento primero y enrutamiento a las otras tres. Empieza aquí.

questllens-explore-a-database

Orientarse en una instancia desconocida: inventario, significado, cobertura temporal, cardinalidad, particiones, grafo de MV.

questllens-health-check

Barrido de ingesta ordenado por triaje: retraso de WAL frente a obsolescencia, tablas suspendidas, almacenamiento, consultas en ejecución.

questllens-tune-a-query

El bucle suggest_sample_byexplain_queryquery, la poda de particiones y las reescrituras específicas de QuestDB.

Copia los cuatro directorios de skills/ a .claude/skills/ de tu proyecto (o donde tu cliente cargue las habilidades) para que estén disponibles; Claude Code mostrará automáticamente la adecuada según las frases de activación del frontmatter de cada habilidad.

Herramientas

QuestLLens expone 18 herramientas MCP organizadas en seis categorías. Las herramientas se diseñaron pensando primero en los agentes de IA: salida en markdown para densidad de tokens, descripciones que explican cuándo usar cada una y diagnósticos compuestos que responden preguntas en una sola ida y vuelta en lugar de tres.

Consulta

Herramienta

Descripción

query

Ejecuta consultas SQL SELECT de solo lectura. Los resultados se devuelven como tablas markdown con recuentos de filas y avisos de truncamiento.

explain_query

Plan de ejecución de QuestDB para un SELECT. Úsalo después de una query lenta: revela el comportamiento de SAMPLE BY / LATEST ON / ASOF JOIN y los algoritmos de unión elegidos.

suggest_sample_by

Recomienda un intervalo de SAMPLE BY según la tabla, el rango y el número de cubos objetivo. Evita que los agentes elijan 1m sobre un año de datos.

Descubrimiento de esquema

Herramienta

Descripción

list_tables

Cada tabla con timestamp designado, unidad de partición, indicador de WAL, claves de deduplicación y recuento de columnas. Las vistas materializadas también aparecen aquí.

describe_table

Descripción integral de una tabla o vista materializada: columnas, claves de deduplicación, unidad de partición. Los indicadores opcionales añaden rango de tiempo (with_time_range) y recuentos distintos por columna de símbolo (with_symbol_stats).

search_columns

Encuentra columnas por patrón de nombre en todas las tablas. Coincidencia de subcadena sin distinción de mayúsculas.

get_create_table

DDL CREATE TABLE (o CREATE MATERIALIZED VIEW) reutilizable. Úsalo al replicar el esquema en código o al compararlo con un estado deseado.

get_table_params

Parámetros de ingesta por tabla: o3MaxLag, maxUncommittedRows, commitLag, TTL, estado de deduplicación. Fundamental para solucionar problemas de ingesta.

refresh_schema

Fuerza manualmente una recarga de la caché de esquema. Normalmente innecesario: describe_table y compañía se actualizan automáticamente ante un fallo de caché.

Exploración de datos

Herramienta

Descripción

get_sample_data

De 1 a 20 filas de muestra. Pasa latest=true para las filas más recientes por timestamp designado; pasa columns para proyectar un subconjunto en tablas anchas; pasa where para un filtro de solo lectura.

get_table_stats

Recuentos de filas, % de nulos, recuentos distintos por columna, agrupados en una sola SQL. Pasa sample_rows en tablas grandes: un escaneo completo puede tardar minutos.

Almacenamiento y particiones

Herramienta

Descripción

get_partitions

Listado por partición con indicadores parquet/activa/solo lectura. Pasa from/to para acotar tablas de retención larga, o summary=true para un resumen (recuentos, primera/última, división nativa vs parquet).

get_storage_summary

Tablas Top-N por disco con división parquet vs nativa. Una sola llamada para encontrar puntos calientes de disco sin lanzar get_partitions por cada tabla.

Operaciones

Herramienta

Descripción

get_wal_status

Estado de aplicación de WAL por tabla: txn del secuenciador, txn del escritor, retraso, indicador de suspensión.

get_ingestion_health

Diagnóstico de ingesta compuesto: retraso de WAL + estado de suspensión + obsolescencia de la última marca de tiempo en una sola llamada. Primer paso para "¿por qué no llegan los datos?".

get_running_queries

Consultas en ejecución actualmente mediante query_activity(). Filtro opcional min_duration_ms. Úsalo cuando "el sistema se siente lento".

get_mv_dependencies

Grafo de dependencias de vistas materializadas con índice inverso ("¿qué vistas dependen de la tabla X?"). Profundiza en una sola vista con su definición SQL. Requiere QuestDB 8.x.

Servidor

Herramienta

Descripción

server_info

Versión, compilación, edición, tiempo de actividad, además de detección de funciones para materialized_views() y query_activity(). Llámala al inicio de una sesión: le indica al agente qué funciones opcionales existen sin necesidad de prueba y error.


Configuración

QuestLLens se configura mediante variables de entorno. Crea un archivo .env o pásalas directamente.

Obligatorias

Variable

Descripción

Ejemplo

QUESTDB_URL

Cadena de conexión de QuestDB (protocolo wire de PostgreSQL)

postgresql://admin:quest@host:8812/qdb

Las credenciales PG-wire predeterminadas de QuestDB son admin / quest en el puerto 8812. Cámbialas y crea un usuario de solo lectura; consulta Seguridad.

Opcionales

Variable

Valor predeterminado

Descripción

MCP_PORT

3000

Puerto del servidor HTTP

QUERY_TIMEOUT_MS

30000

Tiempo máximo de ejecución de consultas (ms)

MAX_ROWS

1000

Máximo de filas devueltas por consulta

SCHEMA_REFRESH_INTERVAL_MS

300000

Intervalo de actualización de la caché de esquema (ms)

DOMAIN_CONTEXT_FILE

Ruta a un archivo markdown con contexto de negocio

DOMAIN_CONTEXT

Cadena de contexto de dominio en línea (alternativa al archivo)

Opciones de OAuth (al ejecutar con --oauth)

Variable

Valor predeterminado

Descripción

MCP_AUTH_PASSWORD

Contraseña para el formulario de inicio de sesión de OAuth

EXTERNAL_BASE_URL

http://localhost:3000

URL pública (para ejecutar detrás de un proxy)

MCP_ALLOWED_ORIGINS

vacío: se permiten todos los orígenes

Lista de permitidos CORS separada por comas para orígenes de navegador (p. ej., https://claude.ai). Vacío o * permite cualquier origen; las rutas de herramientas siguen requiriendo un token Bearer cuando --oauth está activado. Los clientes MCP nativos envían Origin: null y siempre se les permite, por lo que nunca necesitas listarlos.

MCP_OAUTH_TOKEN_EXPIRES_IN

604800

Vida útil del token en segundos (predeterminado: 7 días)

MCP_RATE_LIMIT_ATTEMPTS

5

Máximo de intentos de inicio de sesión por ventana

MCP_RATE_LIMIT_WINDOW_MS

900000

Ventana de límite de velocidad (ms, predeterminado: 15 min)

TRUST_PROXY_HEADERS

false

Deriva la IP del cliente de X-Forwarded-For para que el limitador de velocidad cuente a los clientes reales en lugar del proxy. Establécelo en true solo cuando un proxy que controlas sea la única vía hacia este servidor; de lo contrario, la cabecera la proporciona el llamante y es falsificable.


Docker

Pull

docker pull ghcr.io/dmdufresne/questllens:1.0.0

Build

docker build -t questllens .

Run

# Without OAuth (local development, trusted networks)
docker run -p 3000:3000 \
  -e QUESTDB_URL="postgresql://readonly:password@host:8812/qdb" \
  questllens

# With OAuth (production, Claude Desktop)
docker run -p 3000:3000 \
  -e QUESTDB_URL="postgresql://readonly:password@host:8812/qdb" \
  -e MCP_AUTH_PASSWORD="your-secure-password" \
  questllens node dist/index.js --oauth

# With custom domain context
docker run -p 3000:3000 \
  -e QUESTDB_URL="postgresql://readonly:password@host:8812/qdb" \
  -v ./my-context.md:/app/context.md \
  -e DOMAIN_CONTEXT_FILE="context.md" \
  questllens

Docker Compose

services:
  questllens:
    image: ghcr.io/dmdufresne/questllens:1.0.0
    ports:
      - "3000:3000"
    environment:
      QUESTDB_URL: postgresql://readonly:password@questdb:8812/qdb
      MAX_ROWS: 500
    volumes:
      - ./context.md:/app/context.md
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped

Detalles de la imagen

  • Base: node:20-alpine (compilación multi-etapa)

  • Tamaño: ~80MB

  • Usuario: No root (nodejs:1001)

  • Comprobación de salud: Integrada mediante el endpoint /health


Seguridad

La notificación de vulnerabilidades y lo que está o no dentro del alcance se encuentran en SECURITY.md. La versión breve: la garantía de solo lectura y el flujo de OAuth están dentro del alcance; cualquier cosa accesible con acceso de lectura legítimamente concedido no lo está: usa un rol de base de datos con privilegios mínimos.

QuestLLens es de solo lectura por diseño y usa defensa en profundidad. La capa de aplicación no es suficiente por sí sola: un rol de base de datos de solo lectura y el aislamiento de red son obligatorios, no opcionales. Las secciones siguientes describen cada capa.

Obligatorio: Rol de base de datos de solo lectura

QuestDB no respeta BEGIN READ ONLY de PostgreSQL. La base de datos es tu única barrera de escritura aplicable. Ejecuta QuestLLens con un usuario de solo lectura:

QuestDB Enterprise (RBAC por usuario):

CREATE USER questllens_readonly WITH PASSWORD 'your-secure-password';
GRANT SELECT ON ALL TABLES TO questllens_readonly;

QuestDB Open Source (aún sin RBAC por usuario):

OSS carece de RBAC por usuario, por lo que la capa de aplicación no puede aislar completamente las escrituras. Mitigaciones obligatorias:

  1. Cambia las credenciales predeterminadas admin/quest de inmediato.

  2. Aísla por red el puerto PG-wire (8812) para que solo QuestLLens pueda alcanzarlo. No lo expongas a estaciones de trabajo de operadores ni a otros servicios.

  3. Ejecuta QuestLLens detrás de OAuth (--oauth) para que los clientes MCP también estén controlados en la capa de aplicación.

Si no puedes cumplir (1) y (2), no ejecutes QuestLLens contra una instancia OSS de producción.

Ruta de solo lectura en la capa de aplicación (defensa en profundidad)

Cada sentencia SQL proporcionada por el usuario pasa por un tokenizador real (maneja '…' con escapes '', $tag$…$tag$, --, /* */) y se comprueba contra:

  • Lista de permitidos del verbo inicial — solo se aceptan SELECT, WITH, EXPLAIN, SHOW o TABLES.

  • Rechazo de múltiples sentencias — cualquier cosa después de un ; se rechaza. La ruta de consulta simple de pg-wire ejecuta múltiples sentencias; la comprobación de seguridad hace que sea imposible alcanzarla.

  • Escaneo de palabras clave prohibidas en la entrada tokenizadaINSERT · UPDATE · DELETE · DROP · CREATE · ALTER · TRUNCATE · RENAME · REINDEX · VACUUM · BACKUP · SNAPSHOT · COPY · ATTACH · DETACH · GRANT · REVOKE · SET · RESET · RESUME · SUSPEND · CHECKPOINT · CANCEL · KILL · SQUASH · CONVERT · DEDUP · REFRESH · CALL · EXECUTE · PREPARE · DEALLOCATE. Como la entrada está tokenizada, WHERE message LIKE '%DROP%' no activa el escaneo.

Las consultas de introspección internas (tables(), wal_tables(), SHOW CREATE TABLE, …) omiten la comprobación de seguridad mediante un indicador explícito internal: true en el cliente de base de datos. Cada punto de llamada interna es un punto de auditoría; la entrada del usuario nunca llega a esa ruta.

Tiempos de espera de sentencias

El statement_timeout por consulta se vuelve a aplicar en cada extracción de conexión (QuestDB no tiene SET LOCAL), por lo que una llamada interna anterior no puede dejar un valor obsoleto en una conexión agrupada. Predeterminado: 30 segundos.

Límites de filas

Los resultados se limitan a un máximo configurable (predeterminado: 1000 filas) con una advertencia de truncamiento.

OAuth (cuando --oauth está habilitado)

Al ejecutar con --oauth, QuestLLens proporciona:

  • RFC 7591 Registro dinámico de clientes

  • PKCE S256 — obligatorio cuando el cliente envía un code_challenge; el verificador se comprueba en el endpoint de tokens con comparación de tiempo constante

  • Vinculación del código de autorización — el código está vinculado a su client_id y redirect_uri; cualquier discrepancia en el canje se rechaza

  • Validación de URI de redirección — solo se aceptan URIs registradas; el esquema está restringido a https (o http://localhost/127.0.0.1 para desarrollo)

  • Lista blanca CORSMCP_ALLOWED_ORIGINS (separada por comas) fija qué orígenes de navegador pueden llamar al servidor. Si se deja vacía, permite cualquier origen, lo cual es seguro aquí porque cada ruta de herramienta requiere un token Bearer en lugar de una cookie — una página de origen cruzado no tiene ninguna credencial ambiental que usar. Establézcala cuando quiera restringir los orígenes del navegador

  • Límite de velocidad en los intentos de contraseña (5 por 15 minutos por defecto)

  • Comparación de contraseñas segura frente a temporización

  • Validación de token Bearer en todos los endpoints MCP; los tokens caducados se eliminan del almacén en memoria

  • Página de consentimiento autocontenida — la página de inicio de sesión no carga fuentes, scripts ni recursos de terceros, por lo que una solicitud de autenticación nunca filtra una petición a una CDN

  • Cabeceras de seguridad en cada respuesta — Content-Security-Policy: default-src 'none' (solo estilos en línea, frame-ancestors 'none', base-uri 'none'), además de X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy: no-referrer y Cross-Origin-Opener-Policy. Sin form-action: el 302 del formulario de consentimiento va al redirect_uri registrado del cliente, que para un cliente nativo es un puerto de bucle local — un origen diferente que los navegadores bloquean bajo form-action 'self'. El destino de la redirección se restringe en su lugar en el servidor, contra las URIs registradas del cliente

  • Límite de 1 MB en el cuerpo de la solicitud tanto en cuerpos JSON como codificados en formulario

Los tokens y los códigos de autorización se mantienen en memoria; no sobreviven a un reinicio del servidor. Persístalos externamente si necesita sesiones de larga duración entre reinicios.

Detrás de un proxy o túnel: establezca TRUST_PROXY_HEADERS=true, o el limitador de velocidad verá cada solicitud como proveniente de la única dirección del proxy y los inicios de sesión fallidos de un atacante bloquearán a todos los clientes. Solo actívelo cuando ese proxy sea la única ruta al servidor.


Contexto del dominio

Esta es el arma secreta de QuestLLens. Mientras que la introspección de esquemas le dice a la IA qué aspecto tienen sus tablas, el contexto del dominio le dice qué significan — y, para datos de series temporales, cómo consultarlas bien.

Cómo funciona

Copie la plantilla y describa la lógica de negocio de su base de datos, y luego apunte QuestLLens hacia ella:

cp context.md.example context.md

context.md está en gitignore — es donde reside su conocimiento de dominio propietario, por lo que nunca se confirma en el repositorio.

# Via environment variable
DOMAIN_CONTEXT_FILE=context.md

# Or inline
DOMAIN_CONTEXT="This database stores sensor telemetry from industrial PLCs. Use SAMPLE BY for downsampled queries; never SELECT * across more than 1 hour of raw data."

QuestLLens inyecta este contexto en las descripciones de las herramientas, para que su asistente de IA entienda su dominio desde la primera interacción.

Ejemplo de context.md

# Industrial Telemetry Database

## Key Concepts
- Every table is partitioned by **DAY** with designated timestamp `ts`
- The `device_id` column is a SYMBOL — always filter on it before time ranges
- We use `LATEST ON ts PARTITION BY device_id` to get the most recent reading per device
- Hot data lives in the last 7 days; older partitions are detached to cold storage

## Common Queries
- 1-minute downsample: `SELECT ts, avg(value) FROM readings SAMPLE BY 1m`
- Latest per device: `SELECT * FROM readings LATEST ON ts PARTITION BY device_id`
- Aligned multi-sensor: `ASOF JOIN` on `ts`

## Gotchas
- The `value` column is in raw ADC counts, not engineering units — multiply by `scale` from `device_config`
- `ts` is always UTC; the device-local time is in `local_ts`
- Never run `SELECT *` on the `raw_packets` table — it's billions of rows

Qué se enriquece

El contexto del dominio se integra en:

  • La descripción de la herramienta query (para que la IA escriba mejor SQL)

  • Los resultados de get_partitions y describe_table --with_time_range (para que la IA entienda el ciclo de vida de los datos)

  • La salida de describe_table --with_symbol_stats (para que la IA respete las restricciones de cardinalidad)

  • Las respuestas de descubrimiento de esquemas (para que la IA haga mejores preguntas de seguimiento)


Referencia de la API

Comprobación de estado

GET /health

Devuelve el estado del servidor y la versión:

{
  "status": "healthy",
  "server": "questllens",
  "version": "1.0.0"
}

Endpoint MCP

POST /mcp          → JSON-RPC 2.0 request
GET  /mcp          → Server-Sent Events (SSE) stream
DELETE /mcp        → Session termination

Toda la comunicación MCP utiliza Streamable HTTP Transport con gestión de sesiones mediante la cabecera mcp-session-id.

Endpoints OAuth (cuando --oauth está habilitado)

GET  /.well-known/oauth-protected-resource  → Resource metadata
GET  /.well-known/oauth-authorization-server → Server metadata
POST /oauth/register                         → Dynamic client registration
GET  /oauth/authorize                        → Login form
POST /oauth/authorize                        → Authenticate
POST /oauth/token                            → Token exchange

Desarrollo

# Install dependencies
npm install

# Run in dev mode (hot reload)
npm run dev

# Run with OAuth in dev mode
npm run dev:oauth

# Type check
npm run typecheck

# Run tests (read-only SQL boundary, config validation, identifier quoting)
npm test

# Build for production
npm run build

Estructura del proyecto

src/
├── index.ts                       # Entry point
├── config.ts                      # Environment config with Zod validation
├── server.ts                      # Express + MCP server, OAuth, session management
├── database/
│   ├── client.ts                  # PG-wire connection pool, query execution
│   ├── schema-loader.ts           # QuestDB introspection + cache (auto-refresh on miss)
│   └── sql-safety.ts              # Lexer + allowlist enforcing the read-only path
├── tools/
│   ├── index.ts                   # Executor re-exports
│   ├── _util.ts                   # Shared identifier quoting
│   ├── query.ts                   # Execute SELECT queries (markdown output)
│   ├── explain-query.ts           # QuestDB EXPLAIN
│   ├── suggest-sample-by.ts       # Pick a SAMPLE BY interval for a target bucket count
│   ├── list-tables.ts             # Tables with TS / partitioning / WAL flags
│   ├── describe-table.ts          # Table or MV detail (with optional time range / symbol stats)
│   ├── search-columns.ts          # Cross-table column search
│   ├── get-create-table.ts        # Round-trippable CREATE TABLE / CREATE MATERIALIZED VIEW
│   ├── get-table-params.ts        # Per-table ingestion knobs (o3MaxLag, maxUncommittedRows, ttl)
│   ├── refresh-schema.ts          # Manual cache reload (auto-refresh on miss is the default)
│   ├── get-partitions.ts          # Partition list with from/to filter and summary mode
│   ├── get-storage-summary.ts     # Top-N tables by disk (parquet vs native)
│   ├── get-sample-data.ts         # Sample rows with optional columns/where projection
│   ├── get-table-stats.ts         # Per-column null % + distinct (single batched SQL)
│   ├── get-wal-status.ts          # WAL apply state, lag, suspended tables
│   ├── get-ingestion-health.ts    # Composite WAL lag + latest-row staleness diagnostic
│   ├── get-running-queries.ts     # query_activity() wrapper
│   ├── get-mv-dependencies.ts     # Materialized view graph (forward + reverse)
│   └── server-info.ts             # Version, build, feature detection
├── descriptions/
│   ├── generator.ts               # Dynamic description builder
│   └── static.ts                  # Static description blocks
├── types/
│   └── index.ts                   # TypeScript interfaces
└── ...

tests/
├── sql-safety.test.ts             # Read-only boundary: verbs, literals, injection shapes
├── config.test.ts                 # Env parsing, limits, domain-context loading
└── identifiers.test.ts            # quoteIdent breakout attempts

skills/                            # Claude skills — copy into .claude/skills/
├── questllens-using/
├── questllens-explore-a-database/
├── questllens-health-check/
└── questllens-tune-a-query/

El CI ejecuta la comprobación de tipos, las pruebas y la compilación en Node 20 y 22, luego construye la imagen y verifica que el límite de solo lectura se mantiene contra un contenedor QuestDB en vivo (consulte .github/workflows/ci.yml).


Casos de uso

Caso de uso

Cómo ayuda QuestLLens

Análisis de series temporales con IA

Deje que Claude escriba consultas SAMPLE BY, LATEST ON y ASOF JOIN contra sus datos en vivo — de forma segura en modo de solo lectura. Use suggest_sample_by primero para que el agente elija un tamaño de cubo razonable.

Planificación de capacidad

Combine get_storage_summary, get_partitions --summary y describe_table --with_symbol_stats para identificar particiones activas, capacidades de símbolos insuficientes y tablas con mucho uso de disco en una sola pasada.

Incorporación a series temporales

Apunte una IA a QuestDB con contexto de dominio y deje que explique "¿qué significa timestamp designado para esta tabla?" o "¿por qué esta consulta es lenta?". server_info le dice al agente qué funciones están disponibles.

Optimización de consultas

Use explain_query junto con describe_table --with_symbol_stats para detectar índices faltantes, símbolos de baja capacidad y predicados de tiempo ineficientes. Use get_running_queries cuando "el sistema se siente lento".

Depuración de ingesta

get_ingestion_health es un compuesto de una sola llamada de retraso WAL, estado suspendido y obsolescencia de la última fila. Combínelo con get_table_params (o3MaxLag, maxUncommittedRows) para diagnosticar escrituras entrecortadas.

Auditoría de retención de datos

Use get_partitions (con filtros from/to) y describe_table --with_time_range para confirmar que las políticas de retención funcionan y que las particiones desprendidas/parquet coinciden con el calendario esperado.

Portabilidad de esquemas

get_create_table devuelve DDL reutilizable — útil para reflejar esquemas en código, comparar con el estado deseado o arrancar un entorno hermano.


Compatibilidad

QuestLLens funciona con cualquier cliente compatible con MCP:

  • Claude Desktop (con o sin OAuth)

  • Claude Code (CLI)

  • Cursor / Windsurf / VS Code (mediante extensiones MCP)

  • Clientes MCP personalizados (cualquier cliente que implemente la especificación MCP)

Y con cualquier despliegue de QuestDB:

  • QuestDB Open Source 7.4+

  • QuestDB Enterprise (recomendado — habilita RBAC por usuario)

  • QuestDB Cloud

  • Docker autogestionado, Kubernetes o metal desnudo

get_mv_dependencies y la rama de vistas materializadas de describe_table / get_create_table requieren QuestDB 8.x. get_running_queries requiere una versión de QuestDB que exponga query_activity(). Ejecute server_info para ver qué admite la instancia conectada. Todas las demás herramientas son compatibles con 7.4+.


Solución de problemas

"Connection refused" en el puerto 8812

QuestLLens se conecta mediante el protocolo de cable de PostgreSQL en el puerto 8812, no mediante la API HTTP en 9000. Asegúrese de que el listener PG-wire esté habilitado (pg.enabled=true en server.conf) y sea accesible.

"Permission denied" en la introspección de esquemas

QuestLLens usa las funciones del sistema de QuestDB (tables(), table_columns(), wal_tables(), table_partitions(), materialized_views()). En QuestDB OSS están disponibles para cualquier usuario autenticado. En QuestDB Enterprise, asegúrese de que a su rol se le hayan concedido los privilegios de lectura necesarios:

GRANT SELECT ON ALL TABLES TO questllens_readonly;

get_mv_dependencies devuelve vacío

Las vistas materializadas requieren QuestDB 8.x. Si está en 7.x, esta herramienta devolverá un resultado vacío con un aviso — actualice a 8.0+ para usar MV.

get_wal_status muestra "WAL not enabled"

Las tablas WAL se convirtieron en el valor predeterminado en QuestDB 7.4. Las tablas creadas en versiones anteriores pueden seguir siendo no-WAL; aparecerán en list_tables con wal_enabled = false y no se incluirán en get_wal_status.

Los cambios de esquema no se reflejan

QuestLLens almacena en caché los metadatos del esquema. Espere al siguiente ciclo de actualización (predeterminado: 5 minutos) o llame a refresh_schema para actualizar la caché MCP inmediatamente.

El inicio de sesión OAuth falla

Compruebe que MCP_AUTH_PASSWORD está establecida y que el limitador de velocidad no se ha activado (5 intentos por 15 minutos por defecto). Consulte los registros del servidor para más detalles.


Licencia

Apache-2.0. Libre de usar, modificar y distribuir con atribución; incluye una concesión explícita de patentes. Consulte LICENSE para los términos y NOTICE para las licencias de dependencias de terceros, el aviso de marca comercial de QuestDB y la exclusión de activos de marca de Abelara — los logotipos y el material gráfico de marca no están cubiertos por Apache-2.0.

Proporcionado "tal cual" sin garantía de ningún tipo — úselo bajo su propio riesgo.

Construido por Abelara

QuestLLens forma parte del conjunto de herramientas de Abelara para IA industrial y computación en el borde, junto con PgLLens para PostgreSQL.

Informar de un error · Solicitar una función · Más información

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides a read-only PostgreSQL SQL surface for LLM agents via MCP, with defense-in-depth security layers for safe database queries.
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only access to databases for MCP-compatible AI tools, allowing schema exploration and SELECT queries without exposing credentials or risking data changes.
    51
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only access to PostgreSQL databases via MCP, enforcing least-privilege roles, row-level security, masked views, and SQL AST guardrails to prevent data leakage and unauthorized operations, enabling AI agents to safely query sensitive production data.
    MIT

View all related MCP servers

Related MCP Connectors

  • Read-only MCP access to sessions, funnels, campaigns, errors, live visitors, and anomalies.

  • Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.

  • Read-only Dant3 MCP for public rooms, agents, jobs and provisional machine onboarding.

View all MCP Connectors

Latest Blog Posts

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/DMDuFresne/questllens'

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