View Categories

How to Connect DuckDB to Claude / Cursor via MCP (DuckDB MCP Server Setup)

24 min read

MCP SERVER DUCKDB

Query DuckDB with Claude or Cursor via MCP.

Ask plain-English questions about your DuckDB data — events, users, transactions, daily aggregates, parquet / CSV / JSON files on local disk or in S3 — over a secure, outbound-only cloud link, with Schema Intelligence baked into the DuckDB MCP connector so the AI writes correct, analytics-first SQL on the first try.

No firewall holes One key, every connector Live data, no cache lag Bring your own AI tool

Query Streams is a secure, real-time data integration platform that brings every database and SaaS API in your account into Claude, Cursor, ChatGPT, and Grok — through a single MCP key with no firewall changes. This guide walks through wiring up the DuckDB MCP connector specifically, so your AI tool can answer plain-English questions about embedded analytics data — events, users, transactions, daily aggregates, cohort retention, parquet / CSV / JSON files in S3 — without you copy-pasting CSV exports out of the DuckDB CLI or hand-writing read_parquet() queries in a notebook. Learn more at QueryStreams.com and sign up for free to start asking your AI tool real DuckDB questions.

What Query Streams MCP gives you for DuckDB

Other “DuckDB MCP” servers on the open-source landscape connect the AI tool directly to a local .duckdb file. That works, but it pushes a database path into your AI client’s config, scopes the AI tool to only that one DuckDB file, and gives you no audit trail of what the AI actually asked. The Query Streams MCP server for DuckDB solves a wider problem: one key, every connector (your DuckDB files plus all your other databases and APIs), full audit trail, and the AI tool never holds your DuckDB file paths.

Zero inbound firewall holes

The Network Agent opens a single outbound encrypted cloud link to Query Streams. Your AI client connects to the cloud, never to your DuckDB instance. No port to open, no IP to allowlist, no VPN, and no DuckDB file path or credentials exposed in the AI client config.

One key, every connector

The same MCP key reaches every database and SaaS API your account has connected. Add a Stripe or PostgreSQL connector tomorrow and the AI tool sees it next to your DuckDB files — all in one catalog — without re-keying.

Schema Intelligence baked in

The AI sees AI-curated descriptions, semantic types, enum value lists, JSON / STRUCT-shape hints, and discovered foreign keys for every DuckDB column — not just bare information_schema output. It writes analytics-first DuckDB SQL on the first try (read_parquet, date_trunc, PIVOT, QUALIFY) even on heterogeneous schemas with mixed file-backed and table-backed sources.

Read-only enforced at the agent

Even a hallucinating LLM can’t issue DELETE, UPDATE, INSERT, or COPY ... TO through Query Streams MCP. The Network Agent rejects anything that isn’t SELECT, WITH, or EXPLAIN before DuckDB ever sees the SQL — and the agent opens local .duckdb files in read-only mode by default.

Per-key rate limits

Default 60 requests per minute and 10 execute calls per minute, configurable per key. A runaway AI tool-call loop hits a token bucket, not your DuckDB process memory or local disk.

How it works without opening firewall ports

The Query Streams Network Agent installs once on a machine that holds your local .duckdb file (a laptop, an on-prem box, or a small VM) and dials one outbound TLS link to the cloud — nothing inbound is ever exposed, and the AI tool never sees your .duckdb file path. how the outbound-only connection works →

AI Client

Cursor, Claude,
ChatGPT, Grok

QS MCP Server

Streamable HTTP
X-MCP-Key auth

Network Agent

On your network
Cloud link out

DuckDB

Local
.duckdb file

No inbound port required — the agent dials out, never the other way around

The MCP key you give Cursor or Claude is scoped (read / analyze / execute), revocable at any time, and rate-limited per-key. The AI tool calls these MCP tools to do its work:

querystreams-mcp · tool catalog
qs_list_organizationsread
Returns the org bound to the calling key.
qs_list_agentsread
Lists Network Agents and online state.
qs_list_connectorsread
Lists data connectors (one entry per database server or API).
qs_get_connector_schemaread
Returns the DuckDB databases, schemas, tables, and columns the AI can query (including JSON / STRUCT / LIST type hints), with Schema Intelligence enrichment when available.
qs_profile_tableanalyze
Sample values, distributions, enum detection, semantic types — on demand.
qs_list_saved_queriesread
Pre-built parameterized SQL templates the team trusts. The AI runs them without ever seeing the SQL.
qs_run_saved_queryexecute
Executes a saved query by pattern_key with optional parameter overrides.
qs_run_queryexecute
Executes a SELECT against a connector. Read-only validator runs at the agent, before DuckDB sees the SQL.

Why Schema Intelligence makes Query Streams MCP different

Most “MCP for DuckDB” servers in the open-source landscape hand your AI tool the same information_schema DuckDB hands a stranger. Column names. Data types. Maybe a primary key. The LLM is left to guess what event_type = 7 means, what payload stores inside its STRUCT, or whether events.user_id actually joins to users.id (DuckDB schemas often have no declared foreign keys, especially when tables are stitched together from read_parquet / read_csv_auto sources). That’s why the first SQL most LLMs write against a bare schema is wrong — not because the LLM is bad, but because it doesn’t have the data it needs to be right.

Query Streams MCP returns that same schema enriched with what we call Schema Intelligence (SI) — AI-curated metadata that’s generated by running profiling queries against your actual DuckDB data before the AI client ever asks. When SI is enabled on a connector and database, every schema tool the AI calls (qs_get_connector_schema, qs_get_table_schema, qs_profile_table, qs_get_relationships) returns the bare schema plus six layers of curated knowledge — including JSON / STRUCT shape hints and column-projection guidance for DuckDB’s columnar I/O. The LLM stops guessing.

To make this concrete, here is what the AI client gets back from a single qs_get_table_schema call against a typical DuckDB embedded-analytics warehouse (events, users, transactions, daily_aggregates, experiments) — first without Schema Intelligence, then with it.

Without Schema Intelligence data_source: captured_schema
// what the LLM sees == TABLE: events == – id UBIGINT [PK] – user_id UBIGINT NOT NULL – event_type VARCHAR NOT NULL – timestamp TIMESTAMP NOT NULL – payload STRUCT(…) – source VARCHAR == TABLE: users == – id UBIGINT [PK] – email VARCHAR – cohort VARCHAR – signup_at TIMESTAMP == TABLE: transactions == – id UBIGINT [PK] – user_id UBIGINT NOT NULL – amount DOUBLE NOT NULL – currency VARCHAR(3) – occurred_at TIMESTAMP NOT NULL == TABLE: daily_aggregates == – day DATE – metric_name VARCHAR – metric_value DOUBLE == TABLE: experiments == – id UBIGINT [PK] – name VARCHAR – variant VARCHAR Foreign Keys: (none declared) si_recommendation: state: “not_run” what_youre_missing_for_this_call: – AI-discovered foreign keys – Per-column sample values + enum detection – Table and column descriptions – Semantic type classifications – STRUCT / LIST shape hints (DuckDB) note: “types only, no semantic context”
With Schema Intelligence data_source: schema_intelligence
// what the LLM sees == TABLE: events [FACT, domain:product] == “Product analytics events; one row per user action. High-volume fact table.” – user_id UBIGINT identifier FK -> users.id (100% overlap, conf 0.99) – event_type VARCHAR status_code (enum) page_view (54%) | click (22%) | purchase (14%) | signup (6%) | churn (4%) – timestamp TIMESTAMP timestamp Sample: 2026-04-28 14:02:11.234 – payload STRUCT(…) structured (UNNEST recommended) Fields: page, referrer, ab_variant, device == TABLE: users [DIM, domain:customers] == “User dimension; cohort drives retention and segmentation analyses.” – email VARCHAR email Sample: [email protected], [email protected] – cohort VARCHAR segment (enum) 2026-Q1 (28%) | 2026-Q2 (24%) | 2025-Q4 (22%) | older (26%) – signup_at TIMESTAMP timestamp == TABLE: transactions [FACT, domain:revenue] == “Revenue events; SUM(amount) is GMV. amount is in major currency units.” – user_id UBIGINT identifier FK -> users.id (98% overlap, conf 0.96) – amount DOUBLE currency Range: 0.99 – 1,840.00 · mean 47.20 – occurred_at TIMESTAMP timestamp == TABLE: daily_aggregates [FACT, domain:product] == – metric_name VARCHAR status_code (enum) Sample: [‘DAU’,’WAU’,’MAU’,’revenue’,’retention_d7′] – metric_value DOUBLE numeric

The six layers Schema Intelligence adds

Each layer addresses a class of question the LLM would otherwise guess at. The opt-in SI profiling pass runs against your DuckDB data without changing your schema — and for the scan the agent opens local .duckdb files in read-only mode. what Schema Intelligence adds and how it stays current →

AI-curated descriptions

Plain-English purpose for every database, schema, table, and column — generated once, refreshed when your schema changes. Confidence-scored; user-authored descriptions always win.

events: “Product analytics
events; one row per action.”

Table classifications

Each table tagged FACT (transactional events), DIM (descriptive reference), or LOOKUP (small code maps), plus a business domain — product, sales, finance, support, and 16 more.

events [FACT, domain:product]
users [DIM, domain:customers]

Semantic types per column

Eighteen types — currency, email, timestamp, status_code, percentage, ranking_position, identifier, url, person_name, and more. The AI generates analytics-first DuckDB SQL appropriate to each type (e.g. date_trunc('week', ts) for timestamps).

amount: currency · email: email
timestamp: timestamp

Sample values from real data

Random rows surfaced to the LLM so it recognises patterns no schema can show — STRUCT field names, LIST element shapes, formatting conventions, and the actual encoding of your VARCHAR columns.

payload (STRUCT): {page, referrer,
ab_variant, device}

Enum detection with distributions

Low-cardinality columns (50 or fewer distinct values, at most 5% of rows unique) mapped to their full value list with row counts. The AI never guesses casing or spelling on enum-shaped VARCHAR columns.

event_type: page_view (54%) | click (22%)
| purchase (14%) | signup (6%) | churn (4%)

Implicit foreign-key discovery

Cross-table data overlap analysis finds joins that aren’t declared as DDL constraints — common in DuckDB schemas built on parquet / CSV file imports. Stored alongside formal FKs with confidence scores, returned by qs_get_relationships.

events.user_id -> users.id
(100% overlap, conf 0.99)

Same prompt, different SQL

The proof is in the SQL the AI tool actually writes. Same Cursor session, same Claude model, same prompt — “Show me revenue trends by cohort and event type for the last quarter, with weekly buckets.” Without Schema Intelligence the LLM has to guess. With it, the LLM writes idiomatic, columnar-friendly DuckDB SQL on the first try.

Without Schema Intelligence
— LLM’s first attempt against bare schema: SELECT *, EXTRACT(ISOWEEK FROM timestamp) AS wk, SUM(amount) AS rev FROM events JOIN transactions USING(user_id) WHERE timestamp >= ‘2025-01-01’ GROUP BY 1, 2 SELECT * defeats columnar projection EXTRACT(ISOWEEK …) — not DuckDB native amount is on transactions, not events no cohort — users.cohort is the segment hardcoded date — “last quarter” is dynamic no read_parquet() — if events is a file
With Schema Intelligence
— LLM’s first attempt with SI enabled: SELECT u.cohort, e.event_type, date_trunc(‘week’, e.timestamp) AS wk, SUM(t.amount) AS revenue FROM events e JOIN users u ON u.id = e.user_id JOIN transactions t ON t.user_id = e.user_id WHERE e.timestamp >= CURRENT_DATEINTERVAL 90 DAY GROUP BY u.cohort, e.event_type, wk QUALIFY RANK() OVER(PARTITION BY u.cohort ORDER BY revenue DESC) <= 5 ORDER BY u.cohort, wk Correct first try. Columnar projection. FACT/DIM tags guided the join structure FK discovery surfaced events.user_id -> users.id date_trunc(‘week’, ts) — DuckDB-native QUALIFY filters window results, no subquery CURRENT_DATE – INTERVAL n DAY — DuckDB idiom
Don’t want to run Schema Intelligence? MCP still works — schema tools return bare metadata (types, primary keys, formal foreign keys, indexes) and every degraded response carries an si_recommendation block telling the AI what it’s missing, including a one-call option to enable SI mid-conversation via qs_request_si_analysis. how Schema Intelligence runs and how long it takes →

Running a local DuckDB file through Query Streams MCP

Query Streams MCP connects to local DuckDB database files. The Network Agent opens your .duckdb file in DuckDB’s read-only mode and serves queries to your AI client through the same outbound cloud link and the same MCP key as every other connector — no separate database server to run.

Local .duckdb file

Read-only

The agent opens your .duckdb file in DuckDB’s read-only mode and serves queries via the embedded library. Supports any size that fits on local disk — no concurrent writers needed. Great for development laptops, CI fixtures, embedded reporting, and personal analytics on parquet / CSV imports built up via read_parquet() + CREATE TABLE AS. Register more than one .duckdb file on the same agent and let the LLM disambiguate by connector name.

connector/data/analytics.duckdb

Schema Intelligence runs against your local DuckDB file. The SI scan reads the .duckdb file through your Network Agent on your own machine — never in the cloud. The cloud link from the agent to Query Streams is one-per-agent regardless of how many DuckDB files you’ve registered.

Nova AI

MCP not for you? Try Nova AI instead.

Skip the JSON config entirely: Nova AI is built into the Query Streams web portal and asks the same plain-English DuckDB questions against your local .duckdb file — same agent, same read-only enforcement, same Schema Intelligence, no MCP plumbing.

Meet Nova AI

Prerequisites

Before you start, make sure you have:

  1. A free Query Streams account at my.querystreams.com.
  2. The Query Streams Network Agent installed on a machine that holds your local .duckdb file (a laptop, server, or small VM) — see Download the Query Streams Agent.
  3. A DuckDB connector configured against the agent — see the existing connector setup guides for the .duckdb file path. The agent holds the path; the AI tool never touches it.
  4. Any MCP-capable AI client. We’ll show Cursor, Claude Desktop, ChatGPT, and Grok in this guide; if you use Windsurf, Zed, Continue, Cline, VS Code Copilot, Codex, or Goose, the config block is essentially the same.
  5. Five minutes.
You only set up the agent once. The same agent that powers Query Streams’ Excel and Google Sheets add-ons, the web Query Builder, and Nova AI also serves MCP. Adding MCP to an existing Query Streams account is just generating a key — the agent and DuckDB connector are already running.
1

Generate an MCP key

From the /mcp page in Query Streams, mint a key with the scopes you want.

2

Drop it into your AI client

One JSON snippet for Cursor, Claude, ChatGPT, or Grok. Same key everywhere.

3

Ask a question

“What’s our cohort retention curve over the last 12 weeks?” — the AI calls the right tools, you get the answer.

Step 1: Generate an MCP key in Query Streams

Sign in to Query Streams and open the MCP page (or sign in first at my.querystreams.com and click MCP in the left navigation). Click Generate key, give the key a recognizable name (something like cursor-laptop or claude-desktop), and pick the scopes you want this key to have:

  • read — the AI can browse connectors and read schema. Required for everything else.
  • analyze — the AI can profile tables and discover relationships (sample values, distributions, semantic types, STRUCT / LIST shape hints). Optional but strongly recommended for DuckDB work, where understanding the shape of nested data and the cardinality of enum-style columns is what lets the LLM write columnar-friendly analytics SQL on the first try.
  • execute — the AI can actually run SQL. Without this, the AI is read-only against schema metadata only.

For a typical “let Claude analyse my DuckDB data” workflow, all three scopes are appropriate. For a key you’re handing to a teammate or a less-trusted client, drop execute and let them browse only. You can revoke any key at any time from the same page; the AI client will see MCP_KEY_REVOKED on its next call and stop working immediately. There’s no propagation delay.

Copy the key now — Query Streams shows it once, then stores only a hash. If you lose it, generate a new one. The key looks like qsmcp_ followed by 48 random characters and is what your AI client sends in the X-MCP-Key request header.

Step 2: Add Query Streams MCP to your AI client

The configuration is the same shape across every MCP-capable client — an MCP server entry pointing at https://mcp.querystreams.com with your key in the X-MCP-Key header. Pick your client below.

Cursor
Cursor ~/.cursor/mcp.json
// Edit ~/.cursor/mcp.json
{
  "mcpServers": {
    "querystreams": {
      "url": "https://mcp.querystreams.com",
      "headers": {
        "X-MCP-Key": "qsmcp_PASTE_KEY_HERE"
      }
    }
  }
}
Claude Desktop
Claude Desktop claude_desktop_config.json
// Settings → Developer → Edit Config
{
  "mcpServers": {
    "querystreams": {
      "url": "https://mcp.querystreams.com",
      "headers": {
        "X-MCP-Key": "qsmcp_PASTE_KEY_HERE"
      }
    }
  }
}
ChatGPT
ChatGPT Apps & Connectors
// Settings → Apps & Connectors → Add MCP
Server URL  https://mcp.querystreams.com
Auth header X-MCP-Key
Header value qsmcp_PASTE_KEY_HERE

// Requires a paid ChatGPT plan
// (Plus / Pro / Team / Enterprise).
Grok
Grok Remote MCP Tools
// Grok → Settings → Tools
{
  "mcp_servers": [{
    "name": "querystreams",
    "url": "https://mcp.querystreams.com",
    "auth_header": "X-MCP-Key",
    "auth_value": "qsmcp_..."
  }]
}

Restart your AI client. On its next start it will discover the eight Query Streams MCP tools listed above and surface them in its tool palette. In Cursor and Claude Desktop you can verify by typing “list connectors” — the AI should call qs_list_connectors and return your DuckDB connector along with anything else you have configured.

Step 3: Ask the AI a DuckDB question

You don’t write SQL — the AI does. You ask a question, the AI picks the right MCP tool, the agent runs the query against your DuckDB database, and the answer comes back as text plus tables. Three example prompts to try first:

“What’s our cohort retention curve over the last 12 weeks?”
Retention
The AI calls qs_get_connector_schema to discover the events, users, and transactions tables, then qs_run_query with a SELECT that joins users to events, buckets by date_trunc('week', signup_at) for the cohort axis and date_trunc('week', e.timestamp) - signup_at for the retention axis, and computes COUNT(DISTINCT user_id) normalised by cohort size. You’ll see the result inline as a triangular retention table with weekly buckets, plus a written interpretation flagging which cohorts retain best and where the curve drops off — the AI inferred all of it from the DuckDB data without you writing any SQL.
“Show me the 90-day moving average of revenue by category.”
Revenue
The AI uses DuckDB-idiomatic date math (CURRENT_DATE - INTERVAL 90 DAY) to bound the window, joins transactions to events for category attribution, and applies AVG(SUM(amount)) OVER (PARTITION BY category ORDER BY day ROWS BETWEEN 89 PRECEDING AND CURRENT ROW) as a window function. The result is a ranked table with category, current 90-day moving average, and percent change versus the prior 90-day window — the AI typically annotates the top mover and the biggest decliner without you having to ask. DuckDB’s columnar engine makes this fast even on multi-billion-row event streams.
“Which segments are growing fastest week-over-week?”
Growth
The AI uses Schema Intelligence’s enum-detection on users.cohort to enumerate the segments, then writes a CTE that aggregates active users per (cohort, week) via date_trunc('week', timestamp), applies QUALIFY with a LAG() window for the prior-week comparison, and returns segments ordered by week-over-week growth percentage. The result is a focused list with cohort, this-week active users, last-week active users, and WoW % change — usually the AI sorts by largest positive delta first and flags any segments that flipped from negative to positive growth as watch-list cohorts.

The first time the AI calls a tool, your client may pop up a confirmation prompt asking you to approve the tool call — that’s MCP’s standard consent flow, not anything Query Streams adds. Approve once and the AI proceeds with the rest of the conversation freely. You can revisit the consent at any time in your client’s settings.

Honest billing notice: MCP usage is charged on uncompressed bytes

Query Streams’ Excel add-in, Google Sheets add-on, web Query Builder, and Nova AI all run over our compressed cloud link — we measure and bill compressedBytes against your data realm. The MCP transport (Streamable HTTP per the official MCP spec) does not reliably support compression end-to-end across every client and intermediate proxy, so we measure and bill uncompressedBytes for MCP traffic.

  • What this means: a 2 MB DuckDB analytics result set costs ~2 MB of your data realm when fetched via MCP, vs. ~250–350 KB via Excel / Sheets / Nova / the Query Builder. DuckDB columnar data — especially aggregated output with repeated category and timestamp values — compresses ~6–8x via LZ4, so the size delta is larger here than for transactional databases. Same data, different transport, different billable size.
  • What this isn’t: a markup or a punishment for using MCP. We pass through actual bytes shipped. The other clients are cheaper because compression works reliably on those transports; we don’t punish you for the protocol choice, but we have to be transparent about the cost shape.
  • What you can do: for very large recurring queries (e.g. multi-million-row event exports straight off a DuckDB columnstore), prefer the Excel / Sheets / Nova path. For interactive AI tool calls (the typical 100–5,000 row aggregated DuckDB response that fits in an LLM context), MCP is the right choice and the cost difference is in cents.

Frequently asked questions

Do I need to open ports or run a VPN to use this? +
No inbound rules, port-forwarding, NAT punchthrough, or VPN. The Network Agent makes one outbound TLS connection (port 443) and your AI client reaches https://mcp.querystreams.com from the public internet — if outbound HTTPS works on the agent host, MCP works. See how the outbound-only connection works →
Which AI tools can I use with Query Streams MCP? +
Any client that speaks the open Model Context Protocol — Claude Desktop, Claude Code, Cursor, ChatGPT (paid), Grok, Gemini CLI, Windsurf, Zed, and 500+ more. Bring your own AI tool; you don’t have to switch. Full list of supported AI clients →
Can I revoke an MCP key? +
Yes — three independent kill-switches (per-key from the /mcp page, per-org via plan settings, and platform-level), none of which need a database password rotation or agent restart. More on MCP key security →
How is MCP usage billed against my data realm? +
MCP draws on the same data-realm budget as Excel, Sheets, the Query Builder, and Nova, but MCP’s Streamable HTTP transport can’t compress reliably end-to-end, so it bills uncompressedBytes rather than compressedBytes. For DuckDB this gap is wider than for transactional databases: columnar output compresses ~6–8x via LZ4 on the compressed clients, so a 2 MB analytics result costs ~250–350 KB via Excel / Sheets / Nova versus ~2 MB over MCP. how data-realm billing works across transports →
Does Query Streams MCP work with DuckDB 0.9 / 0.10 / 1.0, DuckDB read-only mode, and DuckDB extensions like httpfs / parquet / json / spatial? +
Yes — the Network Agent supports DuckDB 0.9+ via the standard duckdb library (currently bundling 1.0). Read-only mode is the agent’s default for safety, so multiple readers can share the same .duckdb file without write-lock contention. Extensions: httpfs (S3 / HTTPS reads, including signed-URL auth and IAM role chains), parquet (parquet I/O via read_parquet() and COPY ... TO — the latter blocked by the read-only validator), json (JSON read / extract via read_json_auto() and the json_extract family), and spatial (PostGIS-compatible geometry types, GDAL-backed read of GeoJSON / Shapefile / FlatGeobuf) are all supported. The agent loads them transparently when an SI scan detects their use. For custom extensions or community extensions, contact support — we can whitelist them at the agent layer. Each .duckdb file you register is a separate connector; you can register many DuckDB files at once and let the LLM pick by name (e.g. “query the staging duckdb, not production”).
How does this differ from running an open-source DuckDB MCP server myself? +
A direct DuckDB MCP server (community projects, including DuckDB Labs’ own, do exist) is one MCP per data source. To get Claude reading from your DuckDB + Google Search Console + your Stripe account + your Snowflake warehouse you’d need four MCP servers configured separately in every AI client, each with its own credentials, each with its own scope model, each with its own audit story. Query Streams MCP is one key reaching every connector your account has paired. You also pick up Schema Intelligence (with DuckDB-aware STRUCT / LIST shape hints and columnar projection guidance), agent-layer read-only enforcement, per-key rate limits, audit trail in event_logs, and the same data-realm billing pipeline you already use — none of which a direct DuckDB MCP gives you.
What happens if the AI tries to write or delete data? +
It’s rejected at the agent before the data source sees the SQL. Every qs_run_query call is parsed by a hardcoded read-only validator that allows only SELECT, WITH, and EXPLAIN statements; anything else (including COPY ... TO writes, CREATE TABLE, ATTACH, and DuckDB’s LOAD / INSTALL for non-whitelisted extensions) returns READONLY_VIOLATION and never reaches DuckDB. The validator runs in the agent process on your network, not in the cloud, so a compromised cloud surface couldn’t bypass it. For local .duckdb files, the agent additionally opens the file in DuckDB’s read-only mode, so even a hypothetical bypass of the validator can’t write through the database handle.
Can I see what the AI actually asked? +
Yes. Every MCP tool call writes a row to event_logs with the org, user, key, scope, latency, and result code. The org-admin can answer “who used MCP last week, which connector, and what did they ask?” with a single query. Note that we log the tool name and metadata, not the SQL text or returned rows — those flow through the cloud link and never land in cloud logs. If you want full SQL audit, enable engine-side logging where it exists; for DuckDB specifically that means using PRAGMA enable_profiling + PRAGMA profile_output on each session to capture EXPLAIN plans. Local .duckdb files don’t have a built-in audit log — if you need full per-query SQL capture, run the agent itself with verbose query logging enabled (the agent will write the parsed SQL to its local log file before forwarding to DuckDB).
Do I have to run Schema Intelligence to use Query Streams MCP? +
No — Schema Intelligence is opt-in and MCP works without it (the AI gets bare schema and writes basic queries). With SI on, the six curated layers add the DuckDB-specific context the LLM needs: STRUCT field names and LIST element shapes in the sample values, semantic types that drive analytics-first idioms (read_parquet, date_trunc, PIVOT, QUALIFY), and AI-discovered foreign keys via qs_get_relationships — especially valuable for DuckDB schemas stitched from read_parquet / read_csv_auto sources where formal FKs are rarely declared. Without SI, every schema-tool response carries an si_recommendation block the AI can act on to trigger a run mid-conversation via qs_request_si_analysis. the six layers Schema Intelligence adds and how long a scan takes →
What if I add another connector later, like Stripe or PostgreSQL? +
Nothing changes client-side — the same key reaches the new connector the moment the agent pairs it (qs_list_connectors picks it up automatically). One config block buys your whole account, present and future. Why one key covers every connector →
Do I have to set up MCP just to chat with my data? +
No — Nova AI is built into the Query Streams portal and works against every connector (DuckDB included) with no MCP setup or config files. Use Nova to chat with your data inside Query Streams; use MCP when you want your own AI client (Claude, Cursor, ChatGPT, …) to reach the same data — same agent, same connectors, same Schema Intelligence underneath. Learn more about Nova AI →
Can I register more than one DuckDB file, or analyze parquet / CSV data? +
Yes. The agent opens each local .duckdb file in read-only mode via the embedded library — no separate server process to babysit. To analyze parquet / CSV / JSON, build a .duckdb file with read_parquet() / read_csv_auto() + CREATE TABLE AS and point the agent at it. You can register several .duckdb files on one agent (e.g. local-dev.duckdb + analytics.duckdb) and let the LLM disambiguate by connector name in plain English (“query the staging duckdb, not production”). The cloud link to Query Streams is one outbound TLS connection per agent no matter how many files you register.

Get started

Connect your AI tool to your DuckDB data in five minutes.

One MCP key reaches your local DuckDB files, every other database, and every API connector in your Query Streams account, with full audit trail, per-key rate limits, and zero firewall changes. Claude, Cursor, ChatGPT, and Grok all work out of the box.

Related guides: Download the Query Streams Agent | Database Connector Setup | All MCP Server guides | Nova AI text-to-SQL

Category: MCP Server

Tags: mcp, claude, cursor, duckdb, analytics-database, developer-tools, embedded-analytics, columnar-database, parquet

Meta Description: Connect a local DuckDB file to Claude or Cursor via Query Streams MCP. Analytics-first, 5-min setup.

Updated on June 16, 2026

Powered by BetterDocs