CLI tool
motherduckdb/mcp-server-motherduck avatar
motherduckdb/mcp-server-motherduck

A local MCP server that puts DuckDB and MotherDuck behind your assistant

Local MCP server for DuckDB and MotherDuck

532 stars89 forksPythonMIT

At a glance

What is it?
mcp-server-motherduck is a Python Model Context Protocol server that gives an AI assistant a SQL connection to a local DuckDB file, an in-memory database, a database on S3, or MotherDuck itself, with read and write modes and the ability to switch databases at runtime. It is MIT licensed, it runs through uvx, and the read-only mode is the one to start with.
Who is it for?
Adopt this server if you want an AI assistant to query real analytical data through SQL, and you are willing to run the server on your own machine rather than hand over credentials to a hosted service. Do not run it read-write against a database you care about until you have seen exactly what the assistant does with it, because the in-memory dev mode is deliberately unrestricted.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The pitch, and the two deployment models

This is a local MCP server for DuckDB and MotherDuck, and its purpose is SQL analytics and data engineering for AI assistants and IDEs.

The readme frames it as connecting AI assistants to your data using DuckDB's analytical SQL engine. It supports connecting to local DuckDB files, in-memory databases, S3-hosted databases and MotherDuck, and it allows executing SQL read and write queries, browsing database catalogs, and switching between different database connections on the fly.

What matters is that the project is explicit about the alternative. There is a fully managed remote MCP server hosted by MotherDuck, and the readme links to its documentation. The two are compared in a table.

Remote means hosted by MotherDuck, zero setup, read-write supported, and no local filesystem access. Local means it runs locally or self-hosted, requires a local installation, supports read-write, and can query across local and remote databases and ingest data from or export data to the local filesystem.

So the trade is between a hosted service that needs no installation and cannot touch your disk, and a server you install that can. The filesystem row is the one to look at, because that capability is what the local server exists for.

Three connection shapes, and what each one locks down

The quick start gives three configurations, and they differ in exactly one flag each.

The first is an in-memory DuckDB in dev mode, and it is the most permissive:

json
{
  "mcpServers": {
    "DuckDB (in-memory, r/w)": {
      "command": "uvx",
      "args": ["mcp-server-motherduck", "--db-path", ":memory:", "--read-write", "--allow-switch-databases"]
    }
  }
}

The readme describes this as full flexibility with no guardrails: read-write access and the ability to switch to any database, local files, S3 or MotherDuck, at runtime.

The second is a local DuckDB file in read-only mode:

json
{
  "mcpServers": {
    "DuckDB (read-only)": {
      "command": "uvx",
      "args": ["mcp-server-motherduck", "--db-path", "/absolute/path/to/your.duckdb"]
    }
  }
}

The readme notes a specific benefit of the read-only default: it will not hold on to the file lock, so it is convenient to use alongside a write connection to the same DuckDB file. That detail only matters if you have two servers open on one database, and it is the kind of thing that would otherwise cost an afternoon.

The third is MotherDuck in read-write mode, which needs a token:

json
{
  "mcpServers": {
    "MotherDuck (local, r/w)": {
      "command": "uvx",
      "args": ["mcp-server-motherduck", "--db-path", "md:", "--read-write"],
      "env": {
        "motherduck_token": "<YOUR_MOTHERDUCK_TOKEN>"
      }
    }
  }
}

Remote DuckDB files on S3 are also reachable with a path of the form s3://bucket/path.duckdb, with S3 authentication handled through environment variables.

Where the configuration lives for each client

The client setup table is where the practical work is, because every client wants the server configured somewhere different.

Claude Desktop uses Settings, then Developer, then Edit Config, and it is the one client with a one-click install, via an MCP bundle file on the releases page. Claude Code, Codex CLI and Gemini CLI use CLI commands or a config file, with the Codex path at ~/.codex/config.toml and the Gemini path at ~/.gemini/settings.json. Cursor uses Settings, then MCP, then Add new global MCP server, and it also has a one-click install link. VS Code opens the user settings JSON from the command palette, and Kiro uses ~/.kiro/settings/mcp.json globally or .kiro/settings/mcp.json per project.

The CLI variants are worth comparing, because the flag names differ. The Claude Code form is:

bash
claude mcp add --scope user duckdb --transport stdio -- uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databases

The Codex form drops the scope and transport flags:

bash
codex mcp add duckdb -- uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databases

And the Gemini form uses -s for scope and puts the arguments directly:

bash
gemini mcp add -s user duckdb uvx mcp-server-motherduck --db-path :memory: --read-write --allow-switch-databases

Any MCP-compatible client can use the server, since the JSON configuration from the quick start goes into the client's own config file, and the readme says to consult the client documentation for the location.

The dependency set, and what that tells you

The pyproject file is short, and each dependency has a clear job.

The project is mcp-server-motherduck at version 1.1.0, it requires Python 3.10 or newer, and it is built with hatchling with the package under src/mcp_server_motherduck. The console script is mcp-server-motherduck pointing at mcp_server_motherduck:main.

The runtime dependencies are duckdb pinned exactly at 1.5.6, fastmcp at 4.0.11 or newer, click at 8.5.0 or newer, and pytz at 2026.5.

The exact pin on duckdb is the detail to notice. Pinning the analytical engine exactly means the query behaviour cannot change under you, which matters a great deal for a tool that a model is writing SQL against: an engine upgrade can change a plan, a type coercion or a function, and the difference between a correct answer and a plausible wrong one.

fastmcp is the MCP framework the server is built on, click provides the command line interface, and pytz handles time zones. The dev extras add httpx, pytest, pytest-asyncio, python-dotenv and ruff, and the pytest configuration runs in auto asyncio mode with a function-scoped default fixture loop, a slow marker, and the tests directory as the test path.

The container image, and why the default is http on port 8000

The Dockerfile is a two-stage build that keeps the image small and the install reproducible.

The builder starts from the Astral uv image on python 3.12 bookworm slim, with byte compilation on and copy link mode, copies the pyproject, the lock file, the readme and the src directory, and runs uv sync with frozen, no-dev and no-editable.

The runtime stage is python:3.12-slim-bookworm, with the whole app copied from the builder, the virtual environment's bin directory prepended to the PATH, and two environment variables set: MCP_HOST to 0.0.0.0 and MCP_PORT to 8000. Port 8000 is exposed, and the entrypoint is the server itself.

The default command is what to look at:

dockerfile
ENTRYPOINT ["mcp-server-motherduck"]
CMD ["--transport", "http", "--db-path", ":memory:", "--read-write"]

So the container starts an HTTP transport server on an in-memory database with read-write enabled. For a container that is a sensible default for a demo, and it is also a default you should change before you put it anywhere reachable, since the host is bound to all interfaces and the database is writable by whoever connects.

The rest of the repository is conventional: a makefile, a manifest.json and a server.json for the MCP registry, a .mcpbignore for the bundle packaging, a uv.lock, a Dockerfile, a .python-version file, a pre-commit config, tests and the src directory.

Versioning, and where the release cadence is going

The release history is short and regular. The tags are v1.1.0 from 2026-10-07, v1.0.8 from 2026-08-19 and v1.0.7 from 2026-06-09, and the last push was on 2026-10-07, the same day as the newest tag.

The pyproject file shows how versioning is handled, and it is a small, tidy setup. The bumpver configuration has the current version at 1.1.0, a MAJOR.MINOR.PATCH pattern, and commits and tags switched off so the tool only edits files. The file patterns list tells it exactly which lines to rewrite: the version and current_version lines in pyproject.toml, the version in server.json, the version in manifest.json, and a SERVER_VERSION constant in src/mcp_server_motherduck/configs.py.

That last entry is the one that matters for a plugin-style tool. The version string is baked into the source, so the running server reports the same version as the registry manifest and the package metadata, rather than three drifting apart.

The ruff configuration is set to a line length of 100 with the py310 target version, and the lint rules selected are pycodestyle, pyflakes, isort and pycodestyle warnings, with the line length check ignored because the formatter handles it.

Editorial conclusion

Adopt this server if you want an AI assistant to query real analytical data through SQL, and you are willing to run the server on your own machine rather than hand over credentials to a hosted service. Do not run it read-write against a database you care about until you have seen exactly what the assistant does with it, because the in-memory dev mode is deliberately unrestricted. Before you connect it, check three things: which database path you point it at, whether you include the read-write and allow-switch-databases flags, and how the MotherDuck token reaches the process, since the documented route puts it in the environment of the client rather than in a config file on disk.

Frequently asked questions

What does the DuckDB and MotherDuck MCP server do?

It connects an AI assistant to your data using DuckDB's analytical SQL engine. You can point it at local DuckDB files, in-memory databases, S3-hosted databases or MotherDuck, and it can execute SQL read and write queries, browse database catalogs and switch between database connections at runtime.

How do I connect the MotherDuck MCP server to a local DuckDB file in read-only mode?

Add a server entry whose command is uvx and whose args are mcp-server-motherduck with the --db-path flag set to the absolute path of the file, and no --read-write flag. Read-only mode does not hold the file lock, so it can run alongside a write connection to the same file.

What is the difference between the remote and local MCP servers?

The remote one is hosted by MotherDuck with zero setup, while the local one runs on your own machine and needs a local installation. Both support read and write access, but only the local one can query across local and remote databases and ingest data from or export data to the local filesystem.

How do I add the MotherDuck MCP server to Claude Code or Codex?

In Claude Code use claude mcp add with a scope and transport flag, and in Codex use codex mcp add with the uvx command and its arguments, for example --db-path :memory: with --read-write and --allow-switch-databases for the in-memory dev mode. The Gemini CLI has its own form using -s for scope.

Which DuckDB version does the MCP server require?

The project pins duckdb exactly at 1.5.6, alongside fastmcp, click and pytz, and it requires Python 3.10 or newer. The exact pin keeps query behaviour stable for a tool that a model writes SQL against, and the project is MIT licensed with v1.1.0 released on 2026-10-07.

Official sources

  1. Issues
  2. License: MIT
  3. motherduckdb/mcp-server-motherduck on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/motherduckdb-mcp-server-motherduck.svg)](https://hysenlabs.com/projects/motherduckdb-mcp-server-motherduck)

Was this useful?