QuestLLens
Gives AI agents read-only access to any QuestDB instance, enabling schema discovery, time-series querying, and monitoring of partitions, WAL state, symbols, and ingestion health through MCP.
README
<div align="center">
<img src="images/Abelara_Icons_RGB-06.png" alt="QuestLLens" width="120">
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.
Getting Started · Tools · Configuration · Docker · Security · Domain Context
</div>
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 BYpatterns, 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.
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
SELECTprivileges (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_by → explain_query → query 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/queston port8812. 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
/healthendpoint
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:
- Change the default
admin/questcredentials immediately. - Network-isolate the PG-wire port (
8812) so only QuestLLens can reach it. Do not expose it to operator workstations or other services. - 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, orTABLESare 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 input —
INSERT·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_idandredirect_uri; mismatch on redemption is rejected - Redirect URI validation — only registered URIs are accepted; scheme is restricted to
https(orhttp://localhost/127.0.0.1for development) - CORS allowlist —
MCP_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'), plusX-Content-Type-Options,X-Frame-Options: DENY,Referrer-Policy: no-referrer, andCross-Origin-Opener-Policy. Noform-action: the consent form's 302 goes to the client's registeredredirect_uri, which for a native client is a loopback port — a different origin that browsers block underform-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
querytool description (so AI writes better SQL) - The
get_partitionsanddescribe_table --with_time_rangeresults (so AI understands data lifecycle) - The
describe_table --with_symbol_statsoutput (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_dependenciesand the materialized-view branch ofdescribe_table/get_create_tablerequire QuestDB 8.x.get_running_queriesrequires a QuestDB version that exposesquery_activity(). Runserver_infoto 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.
<br><br>
<div align="center">
<a href="https://abelara.com"> <img src="images/abelara-logo.svg" alt="Abelara" width="200"> </a>
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
</div>
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。