mcp-server-motherduck
OfficialThis MotherDuck DuckDB MCP server provides SQL analytics capabilities for AI Assistants and IDEs by connecting to DuckDB and MotherDuck databases. With it, you can:
Initialize Connections: Connect to local DuckDB (in-memory, file-backed, read-only) or cloud-based MotherDuck databases (using access tokens)
Retrieve Databases: Access available databases after connection initialization
Read Schemas: Get table schemas from specific databases
Execute SQL Queries: Run analytics and data manipulation on connected databases
Hybrid Execution: Query data combining local and cloud sources
Cloud Storage Integration: Access data from Amazon S3 and other cloud storage
Data Sharing: Create and share databases (via MotherDuck functionality)
Serverless Analytics: Run analytics without configuring instances or clusters
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-motherduckquery the top 10 customers by total sales from last month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Connect AI assistants to your data using DuckDB's powerful analytical SQL engine. Supports connecting to local DuckDB files, in-memory databases, S3-hosted databases, and MotherDuck. Allows executing SQL read- and write-queries, browsing database catalogs, and switching between different database connections on-the-fly.
Looking for a fully-managed remote MCP server for MotherDuck? → Go to the MotherDuck Remote MCP docs
Remote vs Local MCP
Local MCP (this repo) | ||
Hosting | Hosted by MotherDuck | Runs locally/self-hosted |
Setup | Zero-setup | Requires local installation |
Access | Read-write supported | Read-write supported |
Local filesystem | - | Query across local and remote databases, ingest data from / export data to local filesystem |
📝 Migrating from v0.x?
Read-only by default: The server now runs in read-only mode by default. Add
--read-writeto enable write access. See Securing for Production.Default database changed:
--db-pathdefault changed frommd:to:memory:. Add--db-path md:explicitly for MotherDuck.MotherDuck read-only requires read-scaling token: MotherDuck connections in read-only mode require a read-scaling token. Regular tokens require
--read-write.
Quick Start
Prerequisites: Install uv via pip install uv or brew install uv
Connecting to In-Memory DuckDB (Dev Mode)
{
"mcpServers": {
"DuckDB (in-memory, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", ":memory:", "--read-write", "--allow-switch-databases"]
}
}
}Full flexibility with no guardrails — read-write access and the ability to switch to any database (local files, S3, or MotherDuck) at runtime.
Connecting to a Local DuckDB File in Read-Only Mode
{
"mcpServers": {
"DuckDB (read-only)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "/absolute/path/to/your.duckdb"]
}
}
}Connects to a specific DuckDB file in read-only mode. Won't hold on to the file lock, so convenient to use alongside a write connection to the same DuckDB file. You can also connect to remote DuckDB files on S3 using s3://bucket/path.duckdb — see Environment Variables for S3 authentication. If you're considering third-party access to the MCP, see Securing for Production.
Connecting to MotherDuck in Read-Write Mode
{
"mcpServers": {
"MotherDuck (local, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "md:", "--read-write"],
"env": {
"motherduck_token": "<YOUR_MOTHERDUCK_TOKEN>"
}
}
}
}See Command Line Parameters for more options, Securing for Production for deployment guidance, and Troubleshooting if you encounter issues.
Related MCP server: MotherDuck DuckDB MCP Server
Client Setup
Client | Config Location | One-Click Install |
Claude Desktop | Settings → Developer → Edit Config | |
Claude Code | Use CLI commands below | - |
Codex CLI | Use CLI commands below or | - |
Gemini CLI | Use CLI commands below or | - |
Cursor | Settings → MCP → Add new global MCP server | |
VS Code |
| |
Kiro |
|
Any MCP-compatible client can use this server. Add the JSON configuration from Quick Start to your client's MCP config file. Consult your client's documentation for the config file location.
In-Memory DuckDB (Dev Mode):
claude mcp add --scope user duckdb --transport stdio -- uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databasesLocal DuckDB (Read-Only):
claude mcp add --scope user duckdb --transport stdio -- uvx mcp-server-motherduck --db-path /absolute/path/to/db.duckdbMotherDuck (Read-Write):
claude mcp add --scope user motherduck --transport stdio --env motherduck_token=YOUR_TOKEN -- uvx mcp-server-motherduck --db-path md: --read-writeIn-Memory DuckDB (Dev Mode):
codex mcp add duckdb -- uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databasesLocal DuckDB (Read-Only):
codex mcp add duckdb -- uvx mcp-server-motherduck --db-path /absolute/path/to/db.duckdbMotherDuck (Read-Write):
codex mcp add motherduck --env motherduck_token=YOUR_TOKEN -- uvx mcp-server-motherduck --db-path md: --read-writeIn-Memory DuckDB (Dev Mode):
gemini mcp add -s user duckdb uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databasesLocal DuckDB (Read-Only):
gemini mcp add -s user duckdb uvx mcp-server-motherduck --db-path /absolute/path/to/db.duckdbMotherDuck (Read-Write):
gemini mcp add -s user -e motherduck_token=YOUR_TOKEN motherduck uvx mcp-server-motherduck --db-path md: --read-writeAdd the following to your Kiro MCP config file (~/.kiro/settings/mcp.json for global, or .kiro/settings/mcp.json for project-scoped). See the Kiro MCP documentation for more details.
In-Memory DuckDB (Dev Mode):
{
"mcpServers": {
"DuckDB (in-memory, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", ":memory:", "--read-write", "--allow-switch-databases"]
}
}
}MotherDuck (Read-Write):
{
"mcpServers": {
"MotherDuck (local, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "md:", "--read-write"],
"env": {
"motherduck_token": "<YOUR_MOTHERDUCK_TOKEN>"
}
}
}
}Tools
Tool | Description | Required Inputs | Optional Inputs |
| Execute SQL query (DuckDB dialect) |
| - |
| List all databases (useful for MotherDuck or multiple attached DBs) | - | - |
| List tables and views | - |
|
| List columns of a table/view |
|
|
| Switch to different database |
|
|
*Requires --allow-switch-databases flag
All tools return JSON. Results are limited to 1024 rows / 50,000 chars by default (configurable via --max-rows, --max-chars).
Securing for Production
When giving third parties access to a self-hosted MCP server, read-only mode alone is not sufficient — it still allows access to the local filesystem, changing DuckDB settings, and other potentially sensitive operations.
For production deployments with third-party access, we recommend MotherDuck Remote MCP — zero-setup, read-write capable, and hosted by MotherDuck.
Self-hosting MotherDuck MCP: Fork this repo and customize as needed. Use a service account with read-scaling tokens and enable SaaS mode to restrict local file access.
Self-hosting DuckDB MCP: Use --init-sql to apply security settings. See the Securing DuckDB guide for available options.
Docker
Build and run the server with Streamable HTTP on port 8000 (defaults to an in-memory DuckDB):
docker build -t mcp-server-motherduck .
docker run --rm -p 8000:8000 mcp-server-motherduckConnect to MotherDuck by passing a token and overriding the command:
docker run --rm -p 8000:8000 \
-e motherduck_token="$MOTHERDUCK_TOKEN" \
mcp-server-motherduck --transport http --db-path md:The MCP endpoint is available at http://localhost:8000/mcp. CLI flags and env vars from below still apply.
Command Line Parameters
Parameter | Default | Description |
|
| Database path: local file (absolute), |
|
| MotherDuck access token |
|
| Enable write access |
|
| MotherDuck SaaS mode (restricts local access) |
|
| Enable |
|
| Max rows returned |
|
| Max characters returned |
|
| Query timeout in seconds (-1 = disabled) |
|
| SQL to execute on startup |
|
| Additional MotherDuck connection string parameters ( |
|
| Use temporary connections for read-only local files |
|
| Transport type: |
|
| For protocol compatibility only (e.g. with AWS Bedrock AgentCore Runtime). Server still maintains global state via the shared DatabaseClient. |
|
| Port for HTTP transport |
|
| Host for HTTP transport |
Environment Variables
Variable | Description |
| MotherDuck access token (alternative to |
| Used by DuckDB for extensions and config. Override with |
| AWS access key for S3 database connections |
| AWS secret key for S3 database connections |
| AWS session token for temporary credentials (IAM roles, SSO, EC2 instance profiles) |
| AWS region for S3 connections |
| AWS endpoint for S3 connections |
Troubleshooting
spawn uvx ENOENT: Specify full path touvx(runwhich uvxto find it)File locked: Make sure
--ephemeral-connectionsis turned on (default: true) and that you're not connected in read-write mode
Resources
Development
To run from source:
{
"mcpServers": {
"Local DuckDB (Dev)": {
"command": "uv",
"args": ["--directory", "/path/to/mcp-server-motherduck", "run", "mcp-server-motherduck", "--db-path", "md:"],
"env": {
"motherduck_token": "<YOUR_MOTHERDUCK_TOKEN>"
}
}
}
}Release Process
Run the
Release New VersionGitHub ActionEnter version in
MAJOR.MINOR.PATCHformatThe workflow bumps version, publishes to PyPI/MCP registry, and creates the GitHub release with MCPB package
License
MIT License - see LICENSE file.
mcp-name: io.github.motherduckdb/mcp-server-motherduck
Available Tools
5 toolsexecute_queryExecute QueryADestructive
Execute a SQL query on the DuckDB or MotherDuck database. Unqualified table names resolve to current_database() and current_schema() automatically. Fully qualified names (database.schema.table) are only needed when multiple DuckDB databases are attached or when connected to MotherDuck.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL query to execute (DuckDB SQL dialect) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=false, so safety profile is covered. The description adds genuine behavioral context about unqualified name resolution, which is not in the annotations, but it never warns that arbitrary SQL can mutate or drop data — a meaningful omission for a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences, front-loaded with the core action, followed by the naming-resolution rules. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description adequately covers invocation semantics. It could go further by noting that the tool executes arbitrary statements including writes/DDL, but the destructiveHint annotation already signals that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With one parameter at 100% schema coverage the baseline is 3, but the description adds real meaning beyond 'SQL query to execute' by explaining how unqualified versus fully qualified table names resolve against current_database()/current_schema(). That directly informs how the agent should author the sql argument.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Execute a SQL query on the DuckDB or MotherDuck database', which is immediately distinguishable from the introspection siblings (list_databases, list_tables, list_columns). It does not explicitly name or contrast with those siblings, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful conditional guidance about when fully qualified names are needed ('only needed when multiple DuckDB databases are attached or when connected to MotherDuck'), but that is guidance about writing the SQL, not about when to choose this tool over switch_database_connection or the listing tools. Usage context is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_columnsList ColumnsARead-only
List all columns of a table or view with their types and comments. If database/schema are not specified, uses the current database/schema.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table or view name | |
| schema | No | Schema name (defaults to current schema) | |
| database | No | Database name (defaults to current database) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds the useful defaulting behavior for database/schema, but that same default is already stated in the input schema, so the incremental behavioral value is modest.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, and the defaulting constraint follows without redundancy or wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety and a full output schema covering return values, the description supplies the only remaining critical context: that database/schema fall back to the current session. Nothing needed to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters, including their defaulting behavior. The description repeats the database/schema default without adding syntax, format, or selection meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List all columns of a table or view with their types and comments.' This clearly distinguishes it from sibling tools like list_tables and list_databases, and an agent can tell exactly what it returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose implies usage (inspect table structure), and the description notes the default database/schema behavior, but it never states when to choose this over execute_query or list_tables, nor any prerequisites or exclusions. Adequate but with a clear gap in routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesList DatabasesARead-only
List all databases available in the connection. Useful when multiple DuckDB databases are attached or when connected to MotherDuck.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered. The description adds only the MotherDuck/multi-attach scenario and says nothing about result ordering, pagination, or scope limits beyond 'the connection'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core action front-loaded and the situational hint second. Nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero params, rich annotations, and an output schema that handles return values, the description covers what an agent needs. It could be marginally stronger by clarifying that it lists databases within the active connection rather than across all connections.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema carries no parameter semantics to explain; baseline for a no-arg tool is 4. The description correctly implies no filtering inputs are required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (databases) scoped to the current connection, which cleanly separates it from list_tables and list_columns. It does not explicitly name a sibling to route against, but the resource noun is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a usage condition ('when multiple DuckDB databases are attached or when connected to MotherDuck'), which is real implied guidance. However, it never says when NOT to use it or which sibling to pick instead (e.g., list_tables for table enumeration), so guidance stays implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesList TablesBRead-only
List all tables and views in a database with their comments. If database is not specified, uses the current database.
| Name | Required | Description | Default |
|---|---|---|---|
| schema | No | Optional schema name to filter by | |
| database | No | Database name to list tables from (defaults to current database) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description only adds that comments accompany each table and that the current database is the default scope; it says nothing about result size, filtering interaction, or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the primary action stated first and the fallback behavior second. Nothing redundant or padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the tool is a simple read with no credentials or side effects. The definition is essentially complete, with only minor room for a note on result limits or when to prefer list_columns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the 'schema' filter and the 'database' default are already documented in the schema. The description merely restates the database default, adding no format, syntax, or edge-case detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (tables and views in a database) with the added detail that comments are returned. The resource clearly separates it from siblings like list_databases and list_columns, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains a default (falls back to the current database) but gives no guidance on when to choose this tool over list_databases, list_columns, or execute_query. Usage must be inferred entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_database_connectionSwitch Database ConnectionA
Switch to a different database connection. For local files, use absolute paths only. The new connection respects the server's read-only/read-write mode. For local files, the file must exist unless create_if_not_exists=True (requires read-write mode).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Database path. For local files, must be an absolute path. Also accepts :memory:, md:database_name, or s3:// paths. | |
| create_if_not_exists | No | If True, create the database file if it doesn't exist. Only works in read-write mode. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false, openWorldHint=true and destructiveHint=false. The description adds real behavioral context beyond that: the new connection inherits the server's read/write mode, and creating a missing file is gated on read-write mode. It does not state what happens to the previous connection or whether switching mid-transaction is permitted, so this is strong but not complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, purpose first, then constraints in descending order of importance. No filler, no repetition of the title, and the preconditions are front-loaded where an agent will see them.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the main surprising preconditions (absolute paths, file existence, read-write mode) are covered. The one notable omission is the fate of the previously active connection, which matters for a state-switching tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents absolute-path requirements and the create_if_not_exists read-write constraint. The description largely restates those same facts, adding no syntax or format detail beyond the schema; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Switch to a different database connection"), which no sibling tool does — the siblings are all query/catalog tools. However, it never names or contrasts with any alternative (e.g., list_databases to discover targets), so it is clear but lacks explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives conditional usage rules (absolute paths for local files, create_if_not_exists=True only in read-write mode), which is genuine guidance. But it never says when to prefer this tool or how to find valid targets, leaving the agent to infer that from siblings like list_databases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v1.0.8- First observed
execute_query - First observed
list_columns - First observed
list_databases - First observed
list_tables - First observed
switch_database_connection
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: execute_query runs SQL, list_databases/tables/columns return metadata, switch_database_connection manages connections. Overlap is minimal because the listing tools target different entity levels (databases, tables, columns).
All tools use a consistent verb_noun snake_case pattern: execute_query, list_databases, list_tables, list_columns, switch_database_connection. The naming is predictable and readable.
Five tools is well-scoped for a database interface: one query executor, three metadata listers, and one connection switcher. No obvious missing core operations given the server's purpose.
The surface covers querying, schema exploration, and connection management. However, it lacks tools for database writing/DDL (e.g., create table, insert) or connection closing, which might be needed for full lifecycle management.
Maintenance
Related MCP Connectors
Query, join, profile, clean and convert CSV/JSON/Parquet with server-side DuckDB over MCP.
- SupabaseOAuthcom.supabase
MCP server for interacting with the Supabase platform
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceUniversal database MCP server connecting to MySQL, PostgreSQL, SQLite, DuckDB and etc.5 npm3,493MIT
- AlicenseAqualityDmaintenanceA local MCP server implementation that interacts with DuckDB and MotherDuck databases, providing SQL analytics capabilities to AI Assistants and IDEs.1MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server enabling AI assistants to query and analyze data via DuckDB SQL engine, supporting local files, memory, S3, and MotherDuck.125 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceMCP server for SQL analytics on DuckDB and MotherDuck databases, enabling AI assistants and IDEs to query data via natural language.1MIT