Skip to main content
Glama

QuestLLens

Give AI Eyes on Your Time-Series

The self-documenting QuestDB MCP server that turns any QuestDB instance into a rich, queryable knowledge source for AI agents — with first-class awareness of partitions, symbols, dedup keys, WAL state, ingestion health, and storage layout.

MCP SDK QuestDB TypeScript Node.js Docker License

Getting Started · Tools · Configuration · Docker · Security · Domain Context


Why QuestLLens?

AI models are powerful — but they're blind to your time-series database. They don't know your designated timestamp, your partition strategy, your symbol cardinality, or which tables are running behind on WAL apply.

QuestLLens fixes that. It connects any QuestDB instance to AI assistants via the Model Context Protocol (MCP), giving them 18 purpose-built tools to discover, understand, and query your data — safely, in read-only mode, with zero risk of accidental writes.

How this relates to QuestDB's built-in MCP server

QuestDB ships its own MCP server in the Web Console, and for interactive work at your desk it is the better tool — it has notebooks, charts, SQL/function documentation lookup, and two-way handoff with the console you already have open. Use it for that.

It solves a different problem than this one:

QuestDB Web Console MCP

QuestLLens

Transport

WebSocket, loopback only

HTTP/SSE, remote-reachable

Needs a live browser session

Yes — pairing and consent happen in the console

No

Write access

Yes — DDL/DML at the Write permission level

No — read-only enforced in-process

Auth for remote clients

Console session / Enterprise SSO

OAuth 2.1 + PKCE, or none for local use

Notebooks, charts, docs lookup

Yes

No

Partition, WAL, dedup, symbol, ingestion-health tools

No

Yes

Domain-context injection into tool descriptions

No

Yes

Reach for QuestLLens when the agent isn't sitting at your browser: a headless assistant, a container behind a tunnel, a shared team endpoint — or anywhere you need a hard read-only guarantee rather than a permission setting.

What makes QuestLLens different

  • Time-series native — Unlike generic SQL MCP servers, QuestLLens speaks QuestDB. Designated timestamps, time partitions, symbol capacity, dedup keys, and WAL state are all first-class concepts your AI assistant can reason about.

  • Self-documenting — Automatically extracts table metadata, column types, partitions, indexes, and materialized view definitions. Your AI assistant understands your schema the way your team does.

  • Domain-aware — Inject a simple markdown file with business context (what tables mean, common SAMPLE BY patterns, gotchas) and QuestLLens weaves it into every tool response.

  • Non-invasive — Plugs into any QuestDB instance over the standard PostgreSQL wire protocol. No agents, no extensions, no QuestDB config changes. Just a read-only user.

  • Security-first — Defense-in-depth: SQL keyword blocking tuned for QuestDB's full DDL surface, statement timeouts, row limits, and optional OAuth with rate limiting. Your data stays safe.


Related MCP server: django-mcp-sql

Getting Started

Prerequisites

  • Node.js 20+

  • QuestDB 7.4+ (any hosted or self-managed instance — WAL tables became the default in 7.4)

  • A QuestDB user with SELECT privileges (read-only recommended; see Security)

Quick Start (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 is now running at http://localhost:3000 with the MCP endpoint at /mcp.

Quick Start (Docker)

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

Connect to Claude Desktop

Add QuestLLens to your Claude Desktop configuration:

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

With OAuth enabled:

{
  "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"
    }
  }
}

Connect to Claude Code

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

Skills

skills/ bundles four Claude skills that teach Claude how to drive QuestLLens instead of guessing at tool names:

Skill

Use for

questllens-using

The orienting skill — read-only posture, the four time-series concepts that change every query (designated timestamp, partitions, SYMBOL, WAL), discovery-first workflow, and routing to the other three. Start here.

questllens-explore-a-database

Getting oriented in an unfamiliar instance: inventory, meaning, time coverage, cardinality, partitions, MV graph.

questllens-health-check

Triage-ordered ingestion sweep: WAL lag vs staleness, suspended tables, storage, running queries.

questllens-tune-a-query

The suggest_sample_byexplain_queryquery loop, partition pruning, and QuestDB-specific rewrites.

Copy the four directories under skills/ into your project's .claude/skills/ (or wherever your client loads skills from) to make them available; Claude Code will surface the right one automatically based on the trigger phrases in each skill's frontmatter.

Tools

QuestLLens exposes 18 MCP tools organized into six categories. Tools were designed for AI agents first — markdown output for token density, descriptions that explain when to use each one, and composite diagnostics that answer questions in one round-trip instead of three.

Query

Tool

Description

query

Execute read-only SQL SELECT queries. Results returned as markdown tables with row counts and truncation warnings.

explain_query

QuestDB execution plan for a SELECT. Use after a slow query — reveals SAMPLE BY / LATEST ON / ASOF JOIN behavior and chosen join algorithms.

suggest_sample_by

Recommend a SAMPLE BY interval given table, range, and target bucket count. Stops agents from picking 1m on a year of data.

Schema Discovery

Tool

Description

list_tables

Every table with designated timestamp, partition unit, WAL flag, dedup keys, and column count. Materialized views surface here too.

describe_table

One-stop description for a table or materialized view: columns, dedup keys, partition unit. Optional flags add time range (with_time_range) and per-symbol-column distinct counts (with_symbol_stats).

search_columns

Find columns by name pattern across every table. Case-insensitive substring match.

get_create_table

Round-trippable CREATE TABLE (or CREATE MATERIALIZED VIEW) DDL. Use when mirroring schema in code or diffing against a desired state.

get_table_params

Per-table ingestion knobs: o3MaxLag, maxUncommittedRows, commitLag, TTL, dedup state. Critical for ingestion troubleshooting.

refresh_schema

Manually force a schema-cache reload. Normally unnecessary — describe_table and friends auto-refresh on cache miss.

Data Exploration

Tool

Description

get_sample_data

1–20 sample rows. Pass latest=true for most-recent rows by designated timestamp; pass columns to project a subset on wide tables; pass where for a read-only filter.

get_table_stats

Row counts, null %, distinct counts per column — batched into one SQL. Pass sample_rows on large tables — a full scan can take minutes.

Storage & Partitions

Tool

Description

get_partitions

Per-partition listing with parquet/active/read-only flags. Pass from/to to bound long-retention tables, or summary=true for a roll-up (counts, first/last, native vs parquet split).

get_storage_summary

Top-N tables by disk with parquet vs native split. Single call to find disk hotspots without fanning get_partitions per table.

Operations

Tool

Description

get_wal_status

Per-table WAL apply state: sequencer txn, writer txn, lag, suspended flag.

get_ingestion_health

Composite ingestion diagnostic: WAL lag + suspended state + latest-timestamp staleness in one call. First stop for "why is data not arriving?".

get_running_queries

Currently executing queries via query_activity(). Optional min_duration_ms filter. Use when "the system feels slow."

get_mv_dependencies

Materialized view dependency graph with reverse index ("which views depend on table X?"). Drill into a single view with its SQL definition. Requires QuestDB 8.x.

Server

Tool

Description

server_info

Version, build, edition, uptime, plus feature detection for materialized_views() and query_activity(). Call early in a session — it tells the agent which optional features exist without trial-and-error.


Configuration

QuestLLens is configured via environment variables. Create a .env file or pass them directly.

Required

Variable

Description

Example

QUESTDB_URL

QuestDB connection string (PostgreSQL wire protocol)

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

QuestDB's default PG-wire credentials are admin / quest on port 8812. Change them, and create a read-only user — see Security.

Optional

Variable

Default

Description

MCP_PORT

3000

HTTP server port

QUERY_TIMEOUT_MS

30000

Maximum query execution time (ms)

MAX_ROWS

1000

Maximum rows returned per query

SCHEMA_REFRESH_INTERVAL_MS

300000

Schema cache refresh interval (ms)

DOMAIN_CONTEXT_FILE

Path to a markdown file with business context

DOMAIN_CONTEXT

Inline domain context string (alternative to file)

OAuth Options (when running with --oauth)

Variable

Default

Description

MCP_AUTH_PASSWORD

Password for OAuth login form

EXTERNAL_BASE_URL

http://localhost:3000

Public URL (for running behind a proxy)

MCP_ALLOWED_ORIGINS

empty — all origins allowed

Comma-separated CORS allowlist for browser origins (e.g. https://claude.ai). Empty or * allows any origin; tool routes still require a Bearer token when --oauth is on. Native MCP clients send Origin: null and are always allowed, so you never need to list them.

MCP_OAUTH_TOKEN_EXPIRES_IN

604800

Token lifetime in seconds (default: 7 days)

MCP_RATE_LIMIT_ATTEMPTS

5

Max login attempts per window

MCP_RATE_LIMIT_WINDOW_MS

900000

Rate limit window (ms, default: 15 min)

TRUST_PROXY_HEADERS

false

Derive the client IP from X-Forwarded-For so the rate limiter counts real clients instead of the proxy. Set true only when a proxy you control is the sole path to this server — otherwise the header is caller-supplied and spoofable.


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

Image Details

  • Base: node:20-alpine (multi-stage build)

  • Size: ~80MB

  • User: Non-root (nodejs:1001)

  • Health check: Built-in via /health endpoint


Security

Vulnerability reporting, and what is and isn't in scope, are in SECURITY.md. The short version: the read-only guarantee and the OAuth flow are in scope; anything reachable with legitimately granted read access is not — use a least-privilege database role.

QuestLLens is read-only by design and uses defense-in-depth. The application layer is not sufficient on its own — a read-only database role and network isolation are required, not optional. The sections below describe each layer.

Required: Read-Only Database Role

QuestDB does not honor PostgreSQL's BEGIN READ ONLY. The database is your only enforceable write barrier. Run QuestLLens with a read-only user:

QuestDB Enterprise (per-user RBAC):

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

QuestDB Open Source (no per-user RBAC yet):

OSS lacks per-user RBAC, so the application layer cannot fully isolate writes. Required mitigations:

  1. Change the default admin/quest credentials immediately.

  2. Network-isolate the PG-wire port (8812) so only QuestLLens can reach it. Do not expose it to operator workstations or other services.

  3. Run QuestLLens behind OAuth (--oauth) so MCP clients are also gated at the application layer.

If you cannot meet (1) and (2), do not run QuestLLens against a production OSS instance.

Application-Layer Read-Only Path (defense-in-depth)

Every user-supplied SQL statement passes through a real tokenizer (handles '…' with '' escapes, $tag$…$tag$, --, /* */) and is checked against:

  • Allowlist of leading verb — only SELECT, WITH, EXPLAIN, SHOW, or TABLES are accepted.

  • Multi-statement reject — anything after a ; is refused. The pg-wire simple-query path executes multiple statements; the safety check makes that impossible to reach.

  • Forbidden-keyword scan on tokenized inputINSERT · 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. Because the input is tokenized, WHERE message LIKE '%DROP%' does not trip the scan.

Internal introspection queries (tables(), wal_tables(), SHOW CREATE TABLE, …) bypass the safety check via an explicit internal: true flag in the database client. Every internal call site is an audit point; user input never reaches that path.

Statement Timeouts

Per-query statement_timeout is re-applied on every connection checkout (QuestDB has no SET LOCAL), so a previous internal call cannot leave a stale value on a pooled connection. Default 30 seconds.

Row Limits

Results are capped at a configurable maximum (default: 1,000 rows) with a truncation warning.

OAuth (when --oauth is enabled)

When running with --oauth, QuestLLens provides:

  • RFC 7591 Dynamic Client Registration

  • PKCE S256 — required when the client sends a code_challenge; verifier checked at the token endpoint with constant-time comparison

  • Authorization code binding — the code is bound to its client_id and redirect_uri; mismatch on redemption is rejected

  • Redirect URI validation — only registered URIs are accepted; scheme is restricted to https (or http://localhost/127.0.0.1 for development)

  • CORS allowlistMCP_ALLOWED_ORIGINS (comma-separated) pins which browser origins may call the server. Left empty it allows any origin, which is safe here because every tool route requires a Bearer token rather than a cookie — a cross-origin page has no ambient credential to use. Set it when you want browser origins restricted

  • Rate limiting on password attempts (5 per 15 minutes by default)

  • Timing-safe password comparison

  • Bearer token validation on all MCP endpoints; expired tokens are dropped from the in-memory store

  • Self-contained consent page — the login page loads no third-party fonts, scripts, or assets, so an authentication prompt never leaks a request to a CDN

  • Security headers on every response — Content-Security-Policy: default-src 'none' (inline styles only, frame-ancestors 'none', base-uri 'none'), plus X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy: no-referrer, and Cross-Origin-Opener-Policy. No form-action: the consent form's 302 goes to the client's registered redirect_uri, which for a native client is a loopback port — a different origin that browsers block under form-action 'self'. The redirect target is constrained server-side instead, against the client's registered URIs

  • 1 MB request body cap on both JSON and form-encoded bodies

Tokens and authorization codes are kept in memory; they do not survive a server restart. Persist them externally if you need long-lived sessions across restarts.

Behind a proxy or tunnel: set TRUST_PROXY_HEADERS=true, or the rate limiter sees every request as coming from the proxy's single address and one attacker's failed logins lock out every client. Only set it when that proxy is the sole route to the server.


Domain Context

This is QuestLLens's secret weapon. While schema introspection tells the AI what your tables look like, domain context tells it what they mean — and, for time-series data, how to query them well.

How It Works

Copy the template and describe your database's business logic, then point QuestLLens at it:

cp context.md.example context.md

context.md is gitignored — it is where your proprietary domain knowledge lives, so it never gets committed.

# 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 injects this context into tool descriptions, so your AI assistant understands your domain from the very first interaction.

Example 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

What Gets Enriched

Domain context is woven into:

  • The query tool description (so AI writes better SQL)

  • The get_partitions and describe_table --with_time_range results (so AI understands data lifecycle)

  • The describe_table --with_symbol_stats output (so AI respects cardinality constraints)

  • Schema discovery responses (so AI asks better follow-up questions)


API Reference

Health Check

GET /health

Returns server status and version:

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

MCP Endpoint

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

All MCP communication uses Streamable HTTP Transport with session management via the mcp-session-id header.

OAuth Endpoints (when --oauth enabled)

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

Development

# 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

Project Structure

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/

CI runs typecheck, tests, and the build on Node 20 and 22, then builds the image and asserts the read-only boundary still holds against a live QuestDB container (see .github/workflows/ci.yml).


Use Cases

Use Case

How QuestLLens Helps

AI-powered time-series analysis

Let Claude write SAMPLE BY, LATEST ON, and ASOF JOIN queries against your live data — safely in read-only mode. Use suggest_sample_by first so the agent picks a sane bucket size.

Capacity planning

Combine get_storage_summary, get_partitions --summary, and describe_table --with_symbol_stats to identify hot partitions, undersized symbol capacities, and disk-heavy tables in one pass.

Onboarding to time-series

Point an AI at QuestDB with domain context and let it explain "what does designated timestamp mean for this table?" or "why is this query slow?". server_info tells the agent which features are available.

Query optimization

Use explain_query plus describe_table --with_symbol_stats to surface missing indexes, low-capacity symbols, and inefficient time predicates. Use get_running_queries when "the system feels slow."

Ingestion debugging

get_ingestion_health is a single-call composite of WAL lag, suspended state, and latest-row staleness. Pair with get_table_params (o3MaxLag, maxUncommittedRows) to diagnose stuttering writes.

Data retention auditing

Use get_partitions (with from/to filters) and describe_table --with_time_range to confirm retention policies are working and that detached/parquet partitions match the expected schedule.

Schema portability

get_create_table returns round-trippable DDL — useful for mirroring schemas in code, diffing against desired state, or bootstrapping a sister environment.


Compatibility

QuestLLens works with any MCP-compatible client:

  • Claude Desktop (with or without OAuth)

  • Claude Code (CLI)

  • Cursor / Windsurf / VS Code (via MCP extensions)

  • Custom MCP clients (any client implementing the MCP specification)

And any QuestDB deployment:

  • QuestDB Open Source 7.4+

  • QuestDB Enterprise (recommended — enables per-user RBAC)

  • QuestDB Cloud

  • Self-managed Docker, Kubernetes, or bare-metal

get_mv_dependencies and the materialized-view branch of describe_table / get_create_table require QuestDB 8.x. get_running_queries requires a QuestDB version that exposes query_activity(). Run server_info to see what the connected instance supports. All other tools are compatible with 7.4+.


Troubleshooting

"Connection refused" on port 8812

QuestLLens connects via the PostgreSQL wire protocol on port 8812, not the HTTP API on 9000. Make sure the PG-wire listener is enabled (pg.enabled=true in server.conf) and reachable.

"Permission denied" on schema introspection

QuestLLens uses QuestDB's system functions (tables(), table_columns(), wal_tables(), table_partitions(), materialized_views()). On QuestDB OSS these are available to any authenticated user. On QuestDB Enterprise, ensure your role has been granted the necessary read privileges:

GRANT SELECT ON ALL TABLES TO questllens_readonly;

get_mv_dependencies returns empty

Materialized views require QuestDB 8.x. If you're on 7.x, this tool will return an empty result with a notice — upgrade to 8.0+ to use MVs.

get_wal_status shows "WAL not enabled"

WAL tables became the default in QuestDB 7.4. Tables created on older versions may still be non-WAL; they will appear in list_tables with wal_enabled = false and will not be included in get_wal_status.

Schema changes not reflected

QuestLLens caches schema metadata. Either wait for the next refresh cycle (default: 5 minutes) or call refresh_schema to update the MCP cache immediately.

OAuth login fails

Check MCP_AUTH_PASSWORD is set and the rate limiter hasn't kicked in (5 attempts per 15 minutes by default). Check server logs for details.


License

Apache-2.0. Free to use, modify, and distribute with attribution; includes an explicit patent grant. See LICENSE for the terms and NOTICE for third-party dependency licenses, the QuestDB trademark disclaimer, and the Abelara brand-asset carve-out — the logos and brand artwork are not covered by Apache-2.0.

Provided "as is" with no warranty of any kind — use at your own risk.

Built by Abelara

QuestLLens is part of the Abelara toolkit for industrial AI and edge computing, alongside PgLLens for PostgreSQL.

Report Bug · Request Feature · Learn More

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.
    92
    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