MotherDuck / DuckDB Local MCP Server

Runs DuckDB SQL from an assistant against local files, S3-hosted databases or MotherDuck

Official · MotherDuck Python Local · stdio, Streamable HTTP DatabasesData and analytics

76 popularity score ★ 540 ↓ 19k/mo

Connect your client

Local (once it is running)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add --transport http motherduck-duckdb-local http://localhost:8000/mcp
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "motherduck-duckdb-local": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "motherduck-duckdb-local": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.motherduck-duckdb-local]
url = "http://localhost:8000/mcp"
Gemini CLITerminal
gemini mcp add --scope user --transport http motherduck-duckdb-local http://localhost:8000/mcp
Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add motherduck-duckdb-local -- uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databases
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "motherduck-duckdb-local": {
      "command": "uvx",
      "args": [
        "mcp-server-motherduck",
        "--db-path",
        ":memory:",
        "--read-write",
        "--allow-switch-databases"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "motherduck-duckdb-local": {
      "command": "uvx",
      "args": [
        "mcp-server-motherduck",
        "--db-path",
        ":memory:",
        "--read-write",
        "--allow-switch-databases"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "motherduck-duckdb-local": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-server-motherduck",
        "--db-path",
        ":memory:",
        "--read-write",
        "--allow-switch-databases"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.motherduck-duckdb-local]
command = "uvx"
args = ["mcp-server-motherduck", "--db-path", ":memory:", "--read-write", "--allow-switch-databases"]
Gemini CLITerminal
gemini mcp add --scope user motherduck-duckdb-local uvx -- mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databases

Settings 7

motherduck_token Optional: MotherDuck access token, needed when --db-path is md:; MOTHERDUCK_TOKEN or --motherduck-token also work.
AWS_ACCESS_KEY_ID Optional: AWS access key for s3:// databases.
AWS_SECRET_ACCESS_KEY Optional: AWS secret key for s3:// databases.
AWS_SESSION_TOKEN Optional: Temporary AWS session token (SSO, IAM roles) for s3:// databases.
AWS_DEFAULT_REGION Optional: AWS region for s3:// databases.
AWS_ENDPOINT Optional: Custom S3-compatible endpoint.
HOME Optional: Where DuckDB keeps extensions and config; override with --home-dir if unset.

What it does

MotherDuck's local server puts a DuckDB engine on your own machine and hands an assistant five tools: one that runs any SQL in the DuckDB dialect, three that browse the catalog (databases, tables and views, columns), and an optional one that moves the session to a different database while it runs. The database is picked with `--db-path`: an in-memory database by default, an absolute path to a .duckdb file, an `s3://` URL, or `md:` for a MotherDuck cloud account.

It starts read-only unless `--read-write` is given, and answers are capped at 1024 rows and 50,000 characters by default (`--max-rows`, `--max-chars`). Because DuckDB can read CSV, Parquet and JSON files directly, the same query tool can pull local files into a table or write results back out, which is what makes it useful for data-engineering work and not only lookups. Startup SQL can be run with `--init-sql`, and it can also serve Streamable HTTP on 127.0.0.1:8000 with `--transport http`.

The code at v1.1.0 adds details the README leaves out: an `s3://` database is always attached READ_ONLY, even with `--read-write` (database.py); `switch_database_connection` refuses relative paths and will only create a new file when the server runs with `--read-write` (switch_database_connection.py); and opening MotherDuck in read-only mode requires a read-scaling token, refusing an ordinary read/write token. MotherDuck also runs a separate hosted remote server, which its makers point to for third-party or production use.

What it needs

RuntimePython

uv for the `uvx` command (`pip install uv` or `brew install uv`); it fetches Python and the package. For `md:` a MotherDuck account and access token (in `motherduck_token` or `--motherduck-token`); for private S3 databases AWS credentials. The Docker form is built from the repository (`docker build -t mcp-server-motherduck .`, then `docker run --rm -p 8000:8000 mcp-server-motherduck`) and serves HTTP at http://localhost:8000/mcp.

Limits

Results stop at 1024 rows and 50,000 characters unless `--max-rows`/`--max-chars` are raised; queries have no timeout unless `--query-timeout` is set. S3 databases are opened read-only whatever the flags (database.py). An in-memory database cannot be read-only, so switching to `:memory:` gives a writable session even on a read-only server. `switch_database_connection` exists only with `--allow-switch-databases`. Its makers state that read-only mode is not enough for third-party access: SQL can still read the local file system and change DuckDB settings. No Docker image is published; the container must be built locally.

Who it suits

Suits analysts and data engineers who want an assistant to query DuckDB files, Parquet or CSV on their own disk, or their MotherDuck warehouse, from the same local process, and who accept that it runs with their own file access. Start it read-only against a specific file for exploration and add `--read-write` only for pipeline work. For giving other people or a shared service access, its own README recommends MotherDuck's hosted remote MCP server instead, since the local one cannot fence off the file system by flags alone (SaaS mode helps for MotherDuck).

Tools 5

execute_query
Runs one SQL statement in DuckDB's dialect and returns the rows as JSON; writes only with --read-write.
list_databases
Lists the databases attached to the current connection.
list_tables
Lists tables and views, optionally within one database or schema.
list_columns
Lists the columns and their types for a given table or view.
switch_database_connection
Reconnects to another database (absolute file path, :memory:, md: or s3://), optionally creating a new file; needs --allow-switch-databases.

Similar servers